diff --git a/README.md b/README.md index 5787e67..7ea52e7 100644 --- a/README.md +++ b/README.md @@ -32,17 +32,19 @@ go get github.com/twitchtv/circuitgen # Usage ```bash -circuitgen --pkg --name --out [--alias ] +circuitgen --pkg --name --out [--alias ] [--circuit-major-version ] ``` Add `./vendor/` to package path if the dependency is vendored. +Set the `circuit-major-version` flag if using Go modules and major version 3 or later. This makes the wrappers import the same version as the rest of your code. + ## Example Generating the DynamoDB client into the wrappers directory with circuits aliased as "DynamoDB" ```bash -circuitgen --pkg github.com/aws/aws-sdk-go/service/dynamodb/dynamodbiface --name DynamoDBAPI --alias DynamoDB --out internal/wrappers +circuitgen --pkg github.com/aws/aws-sdk-go/service/dynamodb/dynamodbiface --name DynamoDBAPI --alias DynamoDB --out internal/wrappers --circuit-major-version 3 ``` This generates a circuit wrapper that satifies the `github.com/aws/aws-sdk-go/service/dynamodb/dynamodbiface.DynamoDBAPI` interface. @@ -58,7 +60,7 @@ import ( "github.com/aws/aws-sdk-go/aws/request" "github.com/aws/aws-sdk-go/service/dynamodb" "github.com/aws/aws-sdk-go/service/dynamodb/dynamodbiface" - "github.com/cep21/circuit" + "github.com/cep21/circuit/v3" ) // CircuitWrapperDynamoDBConfig contains configuration for CircuitWrapperDynamoDB. All fields are optional diff --git a/circuit.go b/circuit.go index d93531b..78d5983 100644 --- a/circuit.go +++ b/circuit.go @@ -39,7 +39,7 @@ package {{ .PackageName }} import ( "context" - "github.com/cep21/circuit" + "github.com/cep21/circuit{{ .VersionSuffix }}" {{ range .TypeMetadata.Imports -}} "{{ .Path }}" {{ end -}} @@ -143,9 +143,10 @@ var _ {{ .EmbeddedType }} = (*{{ .WrapperStructName}})(nil) `)) type circuitWrapperTemplateContext struct { - PackageName string - Alias string - TypeMetadata TypeMetadata + PackageName string + Alias string + VersionSuffix string + TypeMetadata TypeMetadata } // ex. "dynamodbiface.DynamoDBAPI" @@ -169,12 +170,13 @@ func (t *circuitWrapperTemplateContext) IsInterface() bool { } type circuitCmd struct { - pkg string - name string - out string - alias string - debug bool - goimports bool + pkg string + name string + out string + alias string + majorVersion int + debug bool + goimports bool } func (c *circuitCmd) Cobra() *cobra.Command { @@ -201,6 +203,7 @@ func (c *circuitCmd) Cobra() *cobra.Command { pf.StringVar(&c.alias, "alias", "", "(Optional) The name used for the generated wrapper in the struct, constructor, and default circuit prefix. Defaults to name") pf.BoolVar(&c.debug, "debug", false, "Enable debug logging mode") pf.BoolVar(&c.goimports, "goimports", true, "Enable goimports formatting. If false, uses gofmt") + pf.IntVar(&c.majorVersion, "circuit-major-version", 2, "(Optional) The version of cep21/circuit to import. Use 3 or greater for go module compatibility.") return cmd } @@ -271,9 +274,10 @@ func (c *circuitCmd) gen() error { c.log("parseType took %v", time.Since(s)) templateCtx := circuitWrapperTemplateContext{ - PackageName: outPkgName, - TypeMetadata: typeMeta, - Alias: c.alias, + PackageName: outPkgName, + VersionSuffix: circuitVersionSuffix(c.majorVersion), + TypeMetadata: typeMeta, + Alias: c.alias, } s = time.Now() diff --git a/go.mod b/go.mod index f587be5..ccaebdb 100644 --- a/go.mod +++ b/go.mod @@ -4,6 +4,7 @@ go 1.12 require ( github.com/cep21/circuit v2.4.1+incompatible + github.com/cep21/circuit/v3 v3.1.0 github.com/inconshreveable/mousetrap v1.0.0 // indirect github.com/kisielk/errcheck v1.2.0 github.com/securego/gosec v0.0.0-20190510081509-ee80733faf72 diff --git a/go.sum b/go.sum index c3e3ed2..8a8962b 100644 --- a/go.sum +++ b/go.sum @@ -1,20 +1,31 @@ github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= +github.com/cactus/go-statsd-client v3.1.1+incompatible/go.mod h1:cMRcwZDklk7hXp+Law83urTHUiHMzCev/r4JMYr/zU0= +github.com/cenk/backoff v2.2.1+incompatible/go.mod h1:7FtoeaSnHoZnmZzz47cM35Y9nSW7tNyaidugnHTaFDE= github.com/cep21/circuit v2.4.1+incompatible h1:oER/H6loUKgdEEqboLlwCyXftZrxfdVx+GSN9lAaf9E= github.com/cep21/circuit v2.4.1+incompatible/go.mod h1:IYFTZLwEh0jvbURztvjxE45GH5IzZb884I/8xaiwEAA= +github.com/cep21/circuit v3.0.0+incompatible h1:hCh/r5YVX+2wRiatG4/DQ0IiouOvtoW3IXhj/mX0w2o= +github.com/cep21/circuit/v3 v3.1.0 h1:njzXJy6cVuwrqD7OIUlSoTXThTOl2roAH1KCqMTY0J4= +github.com/cep21/circuit/v3 v3.1.0/go.mod h1:BCYrZoMPDpaIZHncTqe3OyJjMCgG6ead5oaxBF1s5ac= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/facebookgo/clock v0.0.0-20150410010913-600d898af40a/go.mod h1:7Ga40egUymuWXxAe151lTNnCv97MddSOVsjpPPkityA= github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gopherjs/gopherjs v0.0.0-20190430165422-3e4dfb77656c/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/iand/circuit v0.0.0-20171204111915-2e03e581ff44/go.mod h1:uYGCxUEkNx+YWAP7rl7kG3HPPzQ+U0jL5aKW9SigAas= github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/kisielk/errcheck v1.2.0 h1:reN85Pxc5larApoH1keMBiu2GWtPqXQ1nc9gx+jOU+E= github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= @@ -32,16 +43,23 @@ github.com/onsi/ginkgo v1.8.0 h1:VkHVNpR4iVnU8XQR6DBm8BqYjN7CRzw+xKUbVVbbW9w= github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/gomega v1.5.0 h1:izbySO9zDPmjJ8rDjLvkA2zJHIo+HkYXHnf7eN7SSyo= github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/peterbourgon/g2s v0.0.0-20170223122336-d4e7ad98afea/go.mod h1:1VcHEd3ro4QMoHfiNl/j7Jkln9+KQuorp0PItHMJYNg= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rubyist/circuitbreaker v2.2.1+incompatible/go.mod h1:Ycs3JgJADPuzJDwffe12k6BZT8hxVi6lFK+gWYJLN4A= github.com/ryanuber/go-glob v1.0.0/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc= github.com/securego/gosec v0.0.0-20190510081509-ee80733faf72 h1:403cuEGt3niQPAau/if+Fp34KjBzMKGejdBCu486W3s= github.com/securego/gosec v0.0.0-20190510081509-ee80733faf72/go.mod h1:shk+oGa7JTGg9taMxXk2skTwpt9KQAbryuwFIHCm/fw= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= +github.com/smartystreets/assertions v1.0.0/go.mod h1:kHHU4qYBaI3q23Pp3VPrmWhuIUrLW/7eUrw0BU5VaoM= +github.com/smartystreets/goconvey v0.0.0-20190710185942-9d28bd7c0945/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= +github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY= github.com/spf13/cobra v0.0.3 h1:ZlrZ4XsMRm04Fr5pSFxBgfND2EBVa1nLpiy1stUsX/8= github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1 h1:2vfRuCMp5sSVIDSqO8oNnWJq7mPa6KVP3iPIwFBuy8A= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= @@ -68,6 +86,7 @@ golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190422233926-fe54fb35175b/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190513233021-7d589f28aaf4 h1:sIGsLZaMtLBc5sLK7s2xtr7VaKk8h31mrJyHwEZq2WQ= golang.org/x/tools v0.0.0-20190513233021-7d589f28aaf4/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= diff --git a/internal/circuitgentest/gen.go b/internal/circuitgentest/gen.go index d40858b..0b63527 100644 --- a/internal/circuitgentest/gen.go +++ b/internal/circuitgentest/gen.go @@ -19,4 +19,5 @@ package circuitgentest // Disable goimports to catch any import bugs //go:generate circuitgen circuit --goimports=true --pkg . --name Publisher --out ./publisher.gen.go +//go:generate circuitgen circuit --goimports=false --pkg . --name Publisher --alias PublisherCircuitV3 --out ./publishercircuitv3.gen.go --circuit-major-version 3 //go:generate circuitgen circuit --goimports=true --pkg . --name Aggregator --out ./ diff --git a/internal/circuitgentest/publishercircuitv3.gen.go b/internal/circuitgentest/publishercircuitv3.gen.go new file mode 100644 index 0000000..26dbfbc --- /dev/null +++ b/internal/circuitgentest/publishercircuitv3.gen.go @@ -0,0 +1,114 @@ +// Code generated by circuitgen tool. DO NOT EDIT + +package circuitgentest + +import ( + "context" + "github.com/cep21/circuit/v3" + "github.com/twitchtv/circuitgen/internal/circuitgentest/model" + "github.com/twitchtv/circuitgen/internal/circuitgentest/rep" +) + +// CircuitWrapperPublisherCircuitV3Config contains configuration for CircuitWrapperPublisherCircuitV3. All fields are optional +type CircuitWrapperPublisherCircuitV3Config struct { + // IsBadRequest is an optional bad request checker. It is useful to not count user errors as faults + IsBadRequest func(error) bool + + // Prefix is prepended to all circuit names + Prefix string + + // Defaults are used for all created circuits. Per-circuit configs override this + Defaults circuit.Config + + // CircuitPublish is the configuration used for the Publish circuit. This overrides values set by Defaults + CircuitPublish circuit.Config + // CircuitPublishWithResult is the configuration used for the PublishWithResult circuit. This overrides values set by Defaults + CircuitPublishWithResult circuit.Config +} + +// CircuitWrapperPublisherCircuitV3 is a circuit wrapper for Publisher +type CircuitWrapperPublisherCircuitV3 struct { + Publisher + + // IsBadRequest checks whether to count a user error against the circuit. It is recommended to set this + IsBadRequest func(error) bool + + // CircuitPublish is the circuit for method Publish + CircuitPublish *circuit.Circuit + // CircuitPublishWithResult is the circuit for method PublishWithResult + CircuitPublishWithResult *circuit.Circuit +} + +// NewCircuitWrapperPublisherCircuitV3 creates a new circuit wrapper and initializes circuits +func NewCircuitWrapperPublisherCircuitV3( + manager *circuit.Manager, + embedded Publisher, + conf CircuitWrapperPublisherCircuitV3Config, +) (*CircuitWrapperPublisherCircuitV3, error) { + if conf.IsBadRequest == nil { + conf.IsBadRequest = func(err error) bool { + return false + } + } + + w := &CircuitWrapperPublisherCircuitV3{ + Publisher: embedded, + IsBadRequest: conf.IsBadRequest, + } + + var err error + + w.CircuitPublish, err = manager.CreateCircuit(conf.Prefix+"PublisherCircuitV3.Publish", conf.CircuitPublish, conf.Defaults) + if err != nil { + return nil, err + } + + w.CircuitPublishWithResult, err = manager.CreateCircuit(conf.Prefix+"PublisherCircuitV3.PublishWithResult", conf.CircuitPublishWithResult, conf.Defaults) + if err != nil { + return nil, err + } + + return w, nil +} + +// Publish calls the embedded Publisher's method Publish with CircuitPublish +func (w *CircuitWrapperPublisherCircuitV3) Publish(ctx context.Context, p1 map[Seed][][]Grant, p2 TopicsList, p3 ...rep.PublishOption) (map[string]struct{}, error) { + var r0 map[string]struct{} + err := w.CircuitPublish.Run(ctx, func(ctx context.Context) error { + var err error + r0, err = w.Publisher.Publish(ctx, p1, p2, p3...) + + if w.IsBadRequest(err) { + return &circuit.SimpleBadRequest{Err: err} + } + return err + }) + + if berr, ok := err.(*circuit.SimpleBadRequest); ok { + err = berr.Err + } + + return r0, err +} + +// PublishWithResult calls the embedded Publisher's method PublishWithResult with CircuitPublishWithResult +func (w *CircuitWrapperPublisherCircuitV3) PublishWithResult(ctx context.Context, p1 rep.PublishInput) (*model.Result, error) { + var r0 *model.Result + err := w.CircuitPublishWithResult.Run(ctx, func(ctx context.Context) error { + var err error + r0, err = w.Publisher.PublishWithResult(ctx, p1) + + if w.IsBadRequest(err) { + return &circuit.SimpleBadRequest{Err: err} + } + return err + }) + + if berr, ok := err.(*circuit.SimpleBadRequest); ok { + err = berr.Err + } + + return r0, err +} + +var _ Publisher = (*CircuitWrapperPublisherCircuitV3)(nil) diff --git a/parsing.go b/parsing.go index e4688b6..0b5b9a0 100644 --- a/parsing.go +++ b/parsing.go @@ -18,6 +18,7 @@ import ( "fmt" "go/types" "path/filepath" + "strconv" "strings" "golang.org/x/tools/go/packages" // latest loader that supports modules @@ -286,3 +287,10 @@ func stripVendor(path string) string { return path } + +func circuitVersionSuffix(majorVersion int) string { + if majorVersion < 3 { + return "" + } + return "/v" + strconv.Itoa(majorVersion) +}