Skip to content

Commit

Permalink
Implement goexportdefault
Browse files Browse the repository at this point in the history
  • Loading branch information
ernesto-jimenez committed Jun 8, 2016
1 parent 89eb372 commit 65907b9
Show file tree
Hide file tree
Showing 25 changed files with 898 additions and 0 deletions.
41 changes: 41 additions & 0 deletions cmd/goexportdefault/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# goexportdefault

It is a common pattern in Go packages to implement a default instance of an exported struct and export functions that call the underlying default instance.

A couple of examples from the stdlib:

- `net/http` has `http.DefaultClient` and functions like `http.Get` just call the default `http.DefaultClient.Get`
- `log` has `log.Logger` and functions like `log.Print` just call the default `log.std.Print`

The exported package functions simply call the corresponding methods from the default instance.

`goexportdefault` allows you to automatically generate a exported function for each method from a default struct.

# Usage

Given the following code:

```go
var DefaultClient = New()
//go:generate goexportdefault DefaultClient

type Client struct {}

func New() *Client {
return &Client{}
}

// Do won't really do anything in this example
func (c *Client) Do(interface{}) error {
return nil
}
```

The it will automatically generate a `default_client_funcs.go` file with the following contents:

```go
// Do is a wrapper around DefaultClient.Do
func Do(v interface{}) error {
return DefaultClient.Do(v)
}
```
49 changes: 49 additions & 0 deletions cmd/goexportdefault/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package main

import (
"flag"
"fmt"
"log"
"os"

"github.com/ernesto-jimenez/gogen/exportdefault"
"github.com/ernesto-jimenez/gogen/strconv"
)

var (
out = flag.String("o", "", "specify the name of the generated code. Default value is by generated based on the name of the variable, e.g.: DefaultClient -> default_client_funcs.go (use \"-\" to print to stdout)")
pref = flag.String("prefix", "", "prefix for the exported function names")
)

func main() {
flag.Parse()
log.SetFlags(0)

// Variable whose methods we want to wrap
v := flag.Arg(0)

gen, err := exportdefault.New(".", v)
if err != nil {
log.Fatal(err)
}

gen.FuncNamePrefix = *pref

w := os.Stdout
if *out == "" {
*out = fmt.Sprintf("%s_funcs.go", v)
}
if *out != "-" {
log.Printf("Generating funcs for %s", v)
*out = strconv.SnakeCase(*out)
w, err = os.OpenFile(*out, os.O_CREATE|os.O_RDWR|os.O_TRUNC, 0666)
if err != nil {
log.Fatal(err)
}
}

err = gen.Write(w)
if err != nil {
log.Fatal(err)
}
}
38 changes: 38 additions & 0 deletions exportdefault/_integration_test/funcs_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package integration

import (
"testing"

"github.com/ernesto-jimenez/gogen/exportdefault/_testpkg"
)

func TestGeneratedFuncs(t *testing.T) {
testpkg.EDEIEmbedded()
testpkg.EDEIWrappedVariadric("a", "b")
testpkg.EDESMethodPtr()
testpkg.EDESMethodVal()
testpkg.EDESPMethodPtr()
testpkg.EDESPMethodVal()
testpkg.EDUIEmbedded()
testpkg.EDUIWrappedVariadric("a", "b")
testpkg.EDUSMethodPtr()
testpkg.EDUSMethodVal()
testpkg.EDUSPMethodPtr()
testpkg.EDUSPMethodVal()
testpkg.UDEIEmbedded()
testpkg.UDEIWrappedVariadric("a", "b")
testpkg.UDESMethodPtr()
testpkg.UDESMethodVal()
testpkg.UDESPMethodPtr()
testpkg.UDESPMethodVal()
testpkg.UDUIEmbedded()
testpkg.UDUIWrappedVariadric("a", "b")
testpkg.UDUSMethodPtr()
testpkg.UDUSMethodVal()
testpkg.UDUSPMethodPtr()
testpkg.UDUSPMethodVal()
testpkg.EDEIWrapped("a")
testpkg.EDUIWrapped("a")
testpkg.UDEIWrapped("a")
testpkg.UDUIWrapped("a")
}
26 changes: 26 additions & 0 deletions exportdefault/_integration_test/integration_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package integration

import (
"os/exec"
"testing"
)

func TestGenerateAndBuildTestPackage(t *testing.T) {
cmd := exec.Command("go", "generate", "github.com/ernesto-jimenez/gogen/exportdefault/_testpkg")
out, err := cmd.CombinedOutput()
if err != nil {
t.Fatalf("error generating wrappers: %s\nOutput:\n%s", err.Error(), out)
}

cmd = exec.Command("go", "build", "github.com/ernesto-jimenez/gogen/exportdefault/_testpkg")
out, err = cmd.CombinedOutput()
if err != nil {
t.Fatalf("error buildinjg package: %s\nOutput:\n%s", err.Error(), out)
}

cmd = exec.Command("go", "test", "github.com/ernesto-jimenez/gogen/exportdefault/_testpkg")
out, err = cmd.CombinedOutput()
if err != nil {
t.Fatalf("error testing package: %s\nOutput:\n%s", err.Error(), out)
}
}
13 changes: 13 additions & 0 deletions exportdefault/_testpkg/embedded.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package testpkg

type embeddedInterface interface {
Embedded()
}

type embeddedStruct struct {
}

func (_ embeddedStruct) EmbeddedVal() {}
func (_ *embeddedStruct) EmbeddedPtr() {}
func (_ embeddedStruct) unexportedEmbeddedVal() {}
func (_ *embeddedStruct) uenxportedEmbeddedPtr() {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* CODE GENERATED AUTOMATICALLY WITH goexportdefault
* THIS FILE MUST NOT BE EDITED BY HAND
*
* Install goexportdefault with:
* go get github.com/ernesto-jimenez/gogen/cmd/goexportdefault
*/

package testpkg

import (
io "io"
)

// EDEIEmbedded is a wrapper around ExportedDefaultExportedInterface.Embedded
func EDEIEmbedded() {
ExportedDefaultExportedInterface.Embedded()
}

// EDEIWrapped is a wrapper around ExportedDefaultExportedInterface.Wrapped
func EDEIWrapped(something string) (io.Writer, error) {
return ExportedDefaultExportedInterface.Wrapped(something)
}

// EDEIWrappedVariadric is a wrapper around ExportedDefaultExportedInterface.WrappedVariadric
func EDEIWrappedVariadric(something ...string) error {
return ExportedDefaultExportedInterface.WrappedVariadric(something...)
}
21 changes: 21 additions & 0 deletions exportdefault/_testpkg/exported_default_exported_struct_funcs.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/*
* CODE GENERATED AUTOMATICALLY WITH goexportdefault
* THIS FILE MUST NOT BE EDITED BY HAND
*
* Install goexportdefault with:
* go get github.com/ernesto-jimenez/gogen/cmd/goexportdefault
*/

package testpkg

import ()

// EDESMethodVal is a wrapper around ExportedDefaultExportedStruct.MethodVal
func EDESMethodVal() {
ExportedDefaultExportedStruct.MethodVal()
}

// EDESMethodPtr is a wrapper around ExportedDefaultExportedStruct.MethodPtr
func EDESMethodPtr() {
ExportedDefaultExportedStruct.MethodPtr()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/*
* CODE GENERATED AUTOMATICALLY WITH goexportdefault
* THIS FILE MUST NOT BE EDITED BY HAND
*
* Install goexportdefault with:
* go get github.com/ernesto-jimenez/gogen/cmd/goexportdefault
*/

package testpkg

import ()

// EDESPMethodVal is a wrapper around ExportedDefaultExportedStructPtr.MethodVal
func EDESPMethodVal() {
ExportedDefaultExportedStructPtr.MethodVal()
}

// EDESPMethodPtr is a wrapper around ExportedDefaultExportedStructPtr.MethodPtr
func EDESPMethodPtr() {
ExportedDefaultExportedStructPtr.MethodPtr()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* CODE GENERATED AUTOMATICALLY WITH goexportdefault
* THIS FILE MUST NOT BE EDITED BY HAND
*
* Install goexportdefault with:
* go get github.com/ernesto-jimenez/gogen/cmd/goexportdefault
*/

package testpkg

import (
io "io"
)

// EDUIEmbedded is a wrapper around ExportedDefaultUnexportedInterface.Embedded
func EDUIEmbedded() {
ExportedDefaultUnexportedInterface.Embedded()
}

// EDUIWrapped is a wrapper around ExportedDefaultUnexportedInterface.Wrapped
func EDUIWrapped(something string) (io.Writer, error) {
return ExportedDefaultUnexportedInterface.Wrapped(something)
}

// EDUIWrappedVariadric is a wrapper around ExportedDefaultUnexportedInterface.WrappedVariadric
func EDUIWrappedVariadric(something ...string) error {
return ExportedDefaultUnexportedInterface.WrappedVariadric(something...)
}
21 changes: 21 additions & 0 deletions exportdefault/_testpkg/exported_default_unexported_struct_funcs.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/*
* CODE GENERATED AUTOMATICALLY WITH goexportdefault
* THIS FILE MUST NOT BE EDITED BY HAND
*
* Install goexportdefault with:
* go get github.com/ernesto-jimenez/gogen/cmd/goexportdefault
*/

package testpkg

import ()

// EDUSMethodVal is a wrapper around ExportedDefaultUnexportedStruct.MethodVal
func EDUSMethodVal() {
ExportedDefaultUnexportedStruct.MethodVal()
}

// EDUSMethodPtr is a wrapper around ExportedDefaultUnexportedStruct.MethodPtr
func EDUSMethodPtr() {
ExportedDefaultUnexportedStruct.MethodPtr()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/*
* CODE GENERATED AUTOMATICALLY WITH goexportdefault
* THIS FILE MUST NOT BE EDITED BY HAND
*
* Install goexportdefault with:
* go get github.com/ernesto-jimenez/gogen/cmd/goexportdefault
*/

package testpkg

import ()

// EDUSPMethodVal is a wrapper around ExportedDefaultUnexportedStructPtr.MethodVal
func EDUSPMethodVal() {
ExportedDefaultUnexportedStructPtr.MethodVal()
}

// EDUSPMethodPtr is a wrapper around ExportedDefaultUnexportedStructPtr.MethodPtr
func EDUSPMethodPtr() {
ExportedDefaultUnexportedStructPtr.MethodPtr()
}
28 changes: 28 additions & 0 deletions exportdefault/_testpkg/exported_interface.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package testpkg

import (
"io"
)

//go:generate go run ../../cmd/goexportdefault/main.go -prefix=EDEI ExportedDefaultExportedInterface

// ExportedDefaultExportedInterface to be generated
var ExportedDefaultExportedInterface ExportedInterface = impl{}

//go:generate go run ../../cmd/goexportdefault/main.go -prefix=UDEI unexportedDefaultExportedInterface
var unexportedDefaultExportedInterface ExportedInterface = impl{}

// ExportedInterface for tests
type ExportedInterface interface {
embeddedInterface
// Wrapped documentation goes here
Wrapped(something string) (io.Writer, error)
WrappedVariadric(something ...string) error
}

type impl struct {
}

func (impl) Wrapped(string) (io.Writer, error) { return nil, nil }
func (impl) WrappedVariadric(...string) error { return nil }
func (impl) Embedded() {}
30 changes: 30 additions & 0 deletions exportdefault/_testpkg/exported_struct.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package testpkg

//go:generate go run ../../cmd/goexportdefault/main.go -prefix=EDES ExportedDefaultExportedStruct

// ExportedDefaultExportedStruct to be generated
var ExportedDefaultExportedStruct = ExportedStruct{}

//go:generate go run ../../cmd/goexportdefault/main.go -prefix=UDES unexportedDefaultExportedStruct
var unexportedDefaultExportedStruct = ExportedStruct{}

//go:generate go run ../../cmd/goexportdefault/main.go -prefix=EDESP ExportedDefaultExportedStructPtr

// ExportedDefaultExportedStructPtr to be generated
var ExportedDefaultExportedStructPtr = &ExportedStruct{}

//go:generate go run ../../cmd/goexportdefault/main.go -prefix=UDESP unexportedDefaultExportedStructPtr
var unexportedDefaultExportedStructPtr = &ExportedStruct{}

// ExportedStruct is a random test struct
type ExportedStruct struct {
embeddedStruct
}

// MethodVal docs
func (ExportedStruct) MethodVal() {}

// MethodPtr docs
func (*ExportedStruct) MethodPtr() {}
func (ExportedStruct) unexportedMethodVal() {}
func (*ExportedStruct) uenxportedMethodPtr() {}
Loading

0 comments on commit 65907b9

Please sign in to comment.