diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index 56b48c16..07f485dc 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -13,9 +13,9 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - go: ["1.15.x", "1.16.x"] + go: ["1.17.x", "1.18.x"] include: - - go: 1.16.x + - go: 1.18.x latest: true steps: diff --git a/.gitignore b/.gitignore index b29c5611..febf47a6 100644 --- a/.gitignore +++ b/.gitignore @@ -8,12 +8,3 @@ cover.full.out cover.html .idea/ -# We will explicitly whitelist vendored libraries that we want to check in. -vendor/* -!vendor/github.com/ - -/vendor/github.com/* -!vendor/github.com/fatih/ - -vendor/github.com/fatih/* -!vendor/github.com/fatih/structtag diff --git a/CHANGELOG.md b/CHANGELOG.md index 5a800437..ca6b23ac 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,13 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). +## [1.30.0] - 2023-04-04 +### Added +- AddTemplate template option. +- thriftbreak: support for changed types, new files, and optional JSON output. +### Changed +- String() performance improvements for string type definitions. + ## [1.29.2] - 2021-09-09 ### Fixed - Streaming now handles unrecongized fields and non-matching field types when @@ -427,6 +434,7 @@ this release. ### Added - Initial release. +[1.30.0]: https://github.com/thriftrw/thriftrw-go/compare/v1.29.2...v1.30.0 [1.29.2]: https://github.com/thriftrw/thriftrw-go/compare/v1.29.1...v1.29.2 [1.29.1]: https://github.com/thriftrw/thriftrw-go/compare/v1.29.0...v1.29.1 [1.29.0]: https://github.com/thriftrw/thriftrw-go/compare/v1.28.0...v1.29.0 diff --git a/Makefile b/Makefile index 3da99c19..2340b660 100644 --- a/Makefile +++ b/Makefile @@ -15,8 +15,7 @@ LINT_EXCLUDES = \ plugin/api/plugin.go \ plugin/api/plugin_client.go \ plugin/api/servicegenerator.go \ - plugin/api/servicegenerator_client.go \ - vendor/ + plugin/api/servicegenerator_client.go # For tests on generated code, ignore deprecated warnings. LINT_EXCLUDES += gen/.*_test.go:.*deprecated @@ -33,20 +32,20 @@ LINT_EXCLUDES += unknown.*JSON.*option.*required RAGEL_TAR = $(BUILD_DIR)/src/ragel-$(RAGEL_VERSION).tar.gz GO_FILES := $(shell \ - find . '(' -path '*/.*' -o -path './vendor' ')' -prune \ + find . -path '*/.*' -prune \ -o -name '*.go' -print | cut -b3-) -# Installs dependencies listed in tools_test.go. -.PHONY: tools -tools: - go list -json tools_test.go | jq -r '.TestImports | .[]' | xargs -n1 go install - .PHONY: build build: $(THRIFTRW) .PHONY: ragel ragel: $(RAGEL) +# Installs dependencies listed in tools_test.go. +.PHONY: tools +tools: + go list -json tools_test.go | jq -r '.TestImports | .[]' | xargs -n1 go install + $(THRIFTRW): $(GO_FILES) go install . @@ -122,8 +121,7 @@ COVER_IGNORE_FILES = \ $(wildcard plugin/api/*.go) # literal space -space := -space += +space := $(subst ,, ) .PHONY: cover cover: @@ -133,4 +131,5 @@ cover: .PHONY: clean clean: + rm $(THRIFTRW) go clean diff --git a/ast/annotation.go b/ast/annotation.go index 13646ea5..e98be197 100644 --- a/ast/annotation.go +++ b/ast/annotation.go @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Uber Technologies, Inc. +// Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/ast/basetypeid_string.go b/ast/basetypeid_string.go index c76694a0..5d07188e 100644 --- a/ast/basetypeid_string.go +++ b/ast/basetypeid_string.go @@ -1,6 +1,6 @@ // Code generated by "stringer -type=BaseTypeID"; DO NOT EDIT. -// Copyright (c) 2021 Uber Technologies, Inc. +// Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/ast/constant.go b/ast/constant.go index 956c416b..7dd74bf9 100644 --- a/ast/constant.go +++ b/ast/constant.go @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Uber Technologies, Inc. +// Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/ast/definition.go b/ast/definition.go index 913d54ea..cac3ec82 100644 --- a/ast/definition.go +++ b/ast/definition.go @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Uber Technologies, Inc. +// Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/ast/doc.go b/ast/doc.go index 4d47f046..9c494255 100644 --- a/ast/doc.go +++ b/ast/doc.go @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Uber Technologies, Inc. +// Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/ast/header.go b/ast/header.go index c57d4c2f..eb2642b6 100644 --- a/ast/header.go +++ b/ast/header.go @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Uber Technologies, Inc. +// Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/ast/mock_visitor_test.go b/ast/mock_visitor_test.go index 6c375aee..553da66b 100644 --- a/ast/mock_visitor_test.go +++ b/ast/mock_visitor_test.go @@ -5,34 +5,35 @@ package ast import ( - gomock "github.com/golang/mock/gomock" reflect "reflect" + + gomock "github.com/golang/mock/gomock" ) -// MockVisitor is a mock of Visitor interface +// MockVisitor is a mock of Visitor interface. type MockVisitor struct { ctrl *gomock.Controller recorder *MockVisitorMockRecorder } -// MockVisitorMockRecorder is the mock recorder for MockVisitor +// MockVisitorMockRecorder is the mock recorder for MockVisitor. type MockVisitorMockRecorder struct { mock *MockVisitor } -// NewMockVisitor creates a new mock instance +// NewMockVisitor creates a new mock instance. func NewMockVisitor(ctrl *gomock.Controller) *MockVisitor { mock := &MockVisitor{ctrl: ctrl} mock.recorder = &MockVisitorMockRecorder{mock} return mock } -// EXPECT returns an object that allows the caller to indicate expected use +// EXPECT returns an object that allows the caller to indicate expected use. func (m *MockVisitor) EXPECT() *MockVisitorMockRecorder { return m.recorder } -// Visit mocks base method +// Visit mocks base method. func (m *MockVisitor) Visit(arg0 Walker, arg1 Node) Visitor { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Visit", arg0, arg1) @@ -40,7 +41,7 @@ func (m *MockVisitor) Visit(arg0 Walker, arg1 Node) Visitor { return ret0 } -// Visit indicates an expected call of Visit +// Visit indicates an expected call of Visit. func (mr *MockVisitorMockRecorder) Visit(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Visit", reflect.TypeOf((*MockVisitor)(nil).Visit), arg0, arg1) diff --git a/ast/node.go b/ast/node.go index aeab75d6..45cee617 100644 --- a/ast/node.go +++ b/ast/node.go @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Uber Technologies, Inc. +// Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/ast/position.go b/ast/position.go index c692e74d..b10e33f5 100644 --- a/ast/position.go +++ b/ast/position.go @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Uber Technologies, Inc. +// Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/ast/program.go b/ast/program.go index 2a439d2f..00861a11 100644 --- a/ast/program.go +++ b/ast/program.go @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Uber Technologies, Inc. +// Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/ast/type.go b/ast/type.go index 3fd88eb7..4aef5f77 100644 --- a/ast/type.go +++ b/ast/type.go @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Uber Technologies, Inc. +// Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/ast/visitor.go b/ast/visitor.go index d788d33f..2c3548b0 100644 --- a/ast/visitor.go +++ b/ast/visitor.go @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Uber Technologies, Inc. +// Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/ast/walk.go b/ast/walk.go index 79a4ddf7..b8d48cc7 100644 --- a/ast/walk.go +++ b/ast/walk.go @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Uber Technologies, Inc. +// Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/cmd/thriftbreak/main.go b/cmd/thriftbreak/main.go new file mode 100644 index 00000000..c932367b --- /dev/null +++ b/cmd/thriftbreak/main.go @@ -0,0 +1,109 @@ +// Copyright (c) 2023 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +package main + +import ( + "encoding/json" + "errors" + "flag" + "fmt" + "io" + "log" + "os" + + "go.uber.org/thriftrw/internal/compare" + "go.uber.org/thriftrw/internal/git" +) + +func main() { + if err := run(os.Args[1:]); err != nil && !errors.Is(err, flag.ErrHelp) { + log.Fatalf("%+v", err) + } +} + +// readableOutput prints every lint error on a separate line. +func readableOutput(w io.Writer) func(compare.Diagnostic) error { + return func(diagnostic compare.Diagnostic) error { + if _, err := fmt.Fprintln(w, &diagnostic); err != nil { + return fmt.Errorf("failed to output a lint error: %v", err) + } + + return nil + } +} + +// jsonOutput prints out every lint error in JSON format. +func jsonOutput(w io.Writer) func(compare.Diagnostic) error { + enc := json.NewEncoder(w) + + return func(diagnostic compare.Diagnostic) error { + // Encode adds a trailing newline. + if err := enc.Encode(diagnostic); err != nil { + return fmt.Errorf("encode as JSON: %v", err) + } + + return nil + } +} + +func run(args []string) error { + flag := flag.NewFlagSet("thriftbreak", flag.ContinueOnError) + gitRepo := flag.String("C", "", + "location of git repository. Defaults to current directory.") + jsonOut := flag.Bool("json", false, + "output as a list of newline-delimited JSON objects with the following fields: FilePath and Message") + if err := flag.Parse(args); err != nil { + return err + } + + if *gitRepo == "" { + cwd, err := os.Getwd() + if err != nil { + return fmt.Errorf("cannot determine current directory: %v", err) + } + *gitRepo = cwd + } + + pass, err := git.Compare(*gitRepo) + // Errors in compiling phase, but not in backwards compatibility. + if err != nil { + return err + } + + var write func(compare.Diagnostic) error + if *jsonOut { + write = jsonOutput(os.Stdout) + } else { + write = readableOutput(os.Stdout) + } + lints := pass.Lints() + for _, l := range lints { + if err := write(l); err != nil { + return fmt.Errorf("failed to output error: %v", err) + } + } + + if len(lints) > 0 { + return fmt.Errorf("found %d issues", len(lints)) + } + + return nil +} diff --git a/cmd/thriftbreak/main_test.go b/cmd/thriftbreak/main_test.go new file mode 100644 index 00000000..528eb8bf --- /dev/null +++ b/cmd/thriftbreak/main_test.go @@ -0,0 +1,147 @@ +// Copyright (c) 2021 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +package main + +import ( + "bytes" + "io" + "io/ioutil" + "os" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "go.uber.org/thriftrw/internal/breaktest" + "go.uber.org/thriftrw/internal/compare" +) + +func TestThriftBreakIntegration(t *testing.T) { + tests := []struct { + desc string + want string + extraCmd string + }{ + { + desc: "output", + want: `c.thrift:deleting service "Baz"` + "\n" + + `d.thrift:deleting service "Qux"` + "\n" + + `v2.thrift:deleting service "Bar"` + "\n" + + `v1.thrift:removing method "methodA" in service "Foo"` + "\n" + + `v1.thrift:adding a required field "C" to "AddedRequiredField"` + "\n", + }, + { + desc: "json output", + want: `{"FilePath":"c.thrift","Message":"deleting service \"Baz\""}` + "\n" + + `{"FilePath":"d.thrift","Message":"deleting service \"Qux\""}` + "\n" + + `{"FilePath":"v2.thrift","Message":"deleting service \"Bar\""}` + "\n" + + `{"FilePath":"v1.thrift","Message":"removing method \"methodA\" in service \"Foo\""}` + "\n" + + `{"FilePath":"v1.thrift","Message":"adding a required field \"C\" to \"AddedRequiredField\""}` + "\n", + extraCmd: "--json", + }, + } + from := map[string]string{ + "v1.thrift": "namespace rb v1\n" + + "struct AddedRequiredField {\n" + + " 1: optional string A\n" + + " 2: optional string B\n" + + "}\n" + + "\nservice Foo {\n void methodA()\n}", + "test/v2.thrift": `service Bar {}`, + "test/c.thrift": `service Baz {}`, + "test/d.thrift": `include "../v1.thrift" + service Qux {}`, // d.thrift will be deleted below. + "somefile.go": `service Quux{}`, // a .go file, not a .thrift. + } + // For c.thrift we are also checking to make sure includes work as expected. + to := map[string]string{ + "v1.thrift": "namespace rb v1\n" + + "struct AddedRequiredField {\n" + + " 1: optional string A\n" + + " 2: optional string B\n" + + " 3: required string C\n}\n" + + "service Foo {}", + "test/v2.thrift": `service Foo {}`, + "test/c.thrift": `include "../v1.thrift" + service Bar {}`, + "somefile.go": `service Qux{}`, + } + remove := []string{"test/d.thrift"} + + for _, tt := range tests { + t.Run(tt.desc, func(t *testing.T) { + tmpDir := t.TempDir() + breaktest.CreateRepoAndCommit(t, tmpDir, from, to, remove) + + f, err := ioutil.TempFile(tmpDir, "stdout") + require.NoError(t, err, "create temporary file") + defer func(oldStdout *os.File) { + assert.NoError(t, f.Close()) + os.Stdout = oldStdout + }(os.Stdout) + os.Stdout = f + + err = run([]string{"-C=" + tmpDir, tt.extraCmd}) + + require.Error(t, err, "expected an error with Thrift backwards incompatible changes") + assert.EqualError(t, err, "found 5 issues") + + stderr, err := ioutil.ReadFile(f.Name()) + require.NoError(t, err) + + out := string(stderr) + assert.Equal(t, tt.want, out) + }) + } +} + +func TestDiagnosticPrinters(t *testing.T) { + t.Parallel() + tests := []struct { + desc string + want string + writer func(io.Writer) func(compare.Diagnostic) error + }{ + { + desc: "json writer", + want: `{"FilePath":"foo.thrift","Message":"error"}` + "\n", + writer: jsonOutput, + }, + { + desc: "readable writer", + want: "foo.thrift:error\n", + writer: readableOutput, + }, + } + for _, tt := range tests { + tt := tt + t.Run(tt.desc, func(t *testing.T) { + t.Parallel() + var b bytes.Buffer + w := tt.writer(&b) + err := w(compare.Diagnostic{ + FilePath: "foo.thrift", + Message: "error", + }) + require.NoError(t, err) + assert.Equal(t, tt.want, b.String()) + }) + } +} diff --git a/cmd/thriftrw-list-deps/main.go b/cmd/thriftrw-list-deps/main.go index e42ecfc0..5eaf8614 100644 --- a/cmd/thriftrw-list-deps/main.go +++ b/cmd/thriftrw-list-deps/main.go @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Uber Technologies, Inc. +// Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/compile/annotation.go b/compile/annotation.go index 75bc9d50..c8023867 100644 --- a/compile/annotation.go +++ b/compile/annotation.go @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Uber Technologies, Inc. +// Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/compile/compiler.go b/compile/compiler.go index 00760490..8a455731 100644 --- a/compile/compiler.go +++ b/compile/compiler.go @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Uber Technologies, Inc. +// Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/compile/constant.go b/compile/constant.go index 78c4b748..0877635b 100644 --- a/compile/constant.go +++ b/compile/constant.go @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Uber Technologies, Inc. +// Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/compile/constant_value.go b/compile/constant_value.go index 95fb808a..cc4bd22e 100644 --- a/compile/constant_value.go +++ b/compile/constant_value.go @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Uber Technologies, Inc. +// Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/compile/container.go b/compile/container.go index 9a8e2d51..15663dd0 100644 --- a/compile/container.go +++ b/compile/container.go @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Uber Technologies, Inc. +// Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/compile/cycle.go b/compile/cycle.go index b02899a1..06600d1b 100644 --- a/compile/cycle.go +++ b/compile/cycle.go @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Uber Technologies, Inc. +// Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/compile/doc.go b/compile/doc.go index 66433d97..024f878e 100644 --- a/compile/doc.go +++ b/compile/doc.go @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Uber Technologies, Inc. +// Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/compile/enum.go b/compile/enum.go index 1da3696f..c354ab1f 100644 --- a/compile/enum.go +++ b/compile/enum.go @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Uber Technologies, Inc. +// Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/compile/error.go b/compile/error.go index ac3d9fc6..93823bef 100644 --- a/compile/error.go +++ b/compile/error.go @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Uber Technologies, Inc. +// Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/compile/field.go b/compile/field.go index 0f433620..55fef1a3 100644 --- a/compile/field.go +++ b/compile/field.go @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Uber Technologies, Inc. +// Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/compile/module.go b/compile/module.go index cafe4672..8f53583b 100644 --- a/compile/module.go +++ b/compile/module.go @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Uber Technologies, Inc. +// Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/compile/namespace.go b/compile/namespace.go index c1c2465e..3c31c6e8 100644 --- a/compile/namespace.go +++ b/compile/namespace.go @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Uber Technologies, Inc. +// Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/compile/once.go b/compile/once.go index 0410508f..dbca24b0 100644 --- a/compile/once.go +++ b/compile/once.go @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Uber Technologies, Inc. +// Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/compile/options.go b/compile/options.go index cf4a741f..baca73ad 100644 --- a/compile/options.go +++ b/compile/options.go @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Uber Technologies, Inc. +// Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/compile/primitive.go b/compile/primitive.go index c8f0a412..5564ebcd 100644 --- a/compile/primitive.go +++ b/compile/primitive.go @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Uber Technologies, Inc. +// Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/compile/scope.go b/compile/scope.go index 5b92e2c9..2763f6aa 100644 --- a/compile/scope.go +++ b/compile/scope.go @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Uber Technologies, Inc. +// Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/compile/service.go b/compile/service.go index b05d5f03..f1eb92fc 100644 --- a/compile/service.go +++ b/compile/service.go @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Uber Technologies, Inc. +// Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/compile/string.go b/compile/string.go index 4e801ad8..7b80d49d 100644 --- a/compile/string.go +++ b/compile/string.go @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Uber Technologies, Inc. +// Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/compile/struct.go b/compile/struct.go index 11b2514a..d7b54615 100644 --- a/compile/struct.go +++ b/compile/struct.go @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Uber Technologies, Inc. +// Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/compile/type.go b/compile/type.go index 01d4c265..442cbf4c 100644 --- a/compile/type.go +++ b/compile/type.go @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Uber Technologies, Inc. +// Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/compile/typedef.go b/compile/typedef.go index b8a64950..525b695b 100644 --- a/compile/typedef.go +++ b/compile/typedef.go @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Uber Technologies, Inc. +// Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/envelope/envelope.go b/envelope/envelope.go index 374bac34..8845f686 100644 --- a/envelope/envelope.go +++ b/envelope/envelope.go @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Uber Technologies, Inc. +// Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/envelope/stream/envelope.go b/envelope/stream/envelope.go index af52caa8..8cfbda61 100644 --- a/envelope/stream/envelope.go +++ b/envelope/stream/envelope.go @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Uber Technologies, Inc. +// Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/gen/collision_test.go b/gen/collision_test.go index 3636822c..532f2da2 100644 --- a/gen/collision_test.go +++ b/gen/collision_test.go @@ -26,6 +26,7 @@ import ( "testing" tc "go.uber.org/thriftrw/gen/internal/tests/collision" + "go.uber.org/thriftrw/protocol" "go.uber.org/thriftrw/protocol/binary" "go.uber.org/thriftrw/ptr" "go.uber.org/thriftrw/wire" @@ -97,7 +98,9 @@ func TestStruct(t *testing.T) { }, } for _, tt := range tests { - roundTrip(t, tt.x, tt.x, tt.desc) + t.Run(tt.desc, func(t *testing.T) { + roundTrip(t, tt.x, tt.x) + }) } } @@ -441,11 +444,13 @@ func TestWithDefault(t *testing.T) { noDefault := &tc.WithDefault{} // expect FromWire values to have defaults and be equivalent - a := roundTrip(t, withDefault, withDefault, "WithDefault{filled in}").(*tc.WithDefault) - b := roundTrip(t, noDefault, withDefault, "WithDefault{}").(*tc.WithDefault) - if a != nil && b != nil { - require.Equal(t, a, b) - } + t.Run("WithDefault{filled in}", func(t *testing.T) { + roundTrip(t, withDefault, withDefault) + }) + + t.Run("WithDefault{}", func(t *testing.T) { + roundTrip(t, noDefault, withDefault) + }) } func TestWithDefaultEquals(t *testing.T) { @@ -532,39 +537,43 @@ func TestMyEnum2Equals(t *testing.T) { } } -func roundTrip(t *testing.T, give thriftType, want thriftType, msg string) thriftType { +func roundTrip(t *testing.T, give thriftType, want thriftType) { + t.Helper() + + var buf, sbuf bytes.Buffer + v, err := give.ToWire() - if !assert.NoError(t, err, "failed to serialize: %v", give) { - return nil - } + require.NoError(t, err, "failed to ToWire: %v", give) + require.NoError(t, binary.Default.Encode(v, &buf), "failed to serialize") - var buff bytes.Buffer - if !assert.NoError(t, binary.Default.Encode(v, &buff), "%v: failed to serialize", msg) { - return nil - } + sw := protocol.BinaryStreamer.Writer(&sbuf) + require.NoError(t, give.Encode(sw)) + require.NoError(t, sw.Close()) - newV, err := binary.Default.Decode(bytes.NewReader(buff.Bytes()), v.Type()) - if !assert.NoError(t, err, "%v: failed to deserialize", msg) { - return nil - } + for desc, giveBuf := range map[string]bytes.Buffer{"wire": buf, "stream": sbuf} { + t.Run(desc, func(t *testing.T) { + giveType := reflect.TypeOf(give) + if giveType.Kind() == reflect.Ptr { + giveType = giveType.Elem() + } - if !assert.True( - t, wire.ValuesAreEqual(newV, v), "%v: deserialize(serialize(%v.ToWire())) != %v", msg, give, v) { - return nil - } + r := bytes.NewReader(giveBuf.Bytes()) - xType := reflect.TypeOf(give) - if xType.Kind() == reflect.Ptr { - xType = xType.Elem() - } + newV, err := binary.Default.Decode(r, v.Type()) + require.NoError(t, err, "failed to decode %s buffer", desc) + assert.True(t, wire.ValuesAreEqual(newV, v), "deserialize(serialize(%v.ToWire())) != %v", give, v) - gotX := reflect.New(xType).Interface().(thriftType) - if err := gotX.FromWire(newV); !assert.NoError(t, err, "FromWire: %v", msg) { - return nil - } + got := reflect.New(giveType).Interface().(thriftType) + require.NoError(t, got.FromWire(newV), "failed to FromWire") + assert.Equal(t, want, got, "unexepected wire decoded thrift obj") - assert.Equal(t, want, gotX, "FromWire: %v", msg) - return gotX + r.Seek(0, 0) + sGot := reflect.New(giveType).Interface().(thriftType) + sr := protocol.BinaryStreamer.Reader(r) + require.NoError(t, sGot.Decode(sr)) + assert.Equal(t, want, sGot, "unexpected stream decoded thrift obj") + }) + } } func TestCollisionAccessors(t *testing.T) { diff --git a/gen/constant.go b/gen/constant.go index 60b42883..4fc40339 100644 --- a/gen/constant.go +++ b/gen/constant.go @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Uber Technologies, Inc. +// Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/gen/constant_test.go b/gen/constant_test.go index 0f40acd9..d049a8ff 100644 --- a/gen/constant_test.go +++ b/gen/constant_test.go @@ -45,6 +45,36 @@ func TestConstants(t *testing.T) { i interface{} o interface{} }{ + { + "int16", + tk.Int16, + int16(12345), + }, + { + "int32", + tk.Int32, + int32(1234567890), + }, + { + "int64", + tk.Int64, + int64(1234567890123456789), + }, + { + "hex16", + tk.Hex16, + int16(0x1234), + }, + { + "hex32", + tk.Hex32, + int32(0x12345678), + }, + { + "hex64", + tk.Hex64, + int64(0x1234567890abcdef), + }, { "primitiveContainers", tk.PrimitiveContainers, diff --git a/gen/container_test.go b/gen/container_test.go index c065c893..c3ac80e8 100644 --- a/gen/container_test.go +++ b/gen/container_test.go @@ -1338,16 +1338,13 @@ func TestContainerValidate(t *testing.T) { }) t.Run(tt.desc+"/streaming", func(t *testing.T) { - stt, ok := tt.value.(streamingThriftType) - require.True(t, ok) - var buf bytes.Buffer sw := binary.Default.Writer(&buf) defer func() { assert.NoError(t, sw.Close()) }() - err := stt.Encode(sw) + err := tt.value.Encode(sw) require.Error(t, err) assert.Equal(t, tt.wantError, err.Error()) }) @@ -1384,21 +1381,40 @@ func TestEmptyContainersRoundTrip(t *testing.T) { MapOfIntsToDoubles: make(map[int64]float64), } - b, err := json.Marshal(give) - require.NoError(t, err, "failed to encode to JSON") + t.Run("JSON", func(t *testing.T) { + b, err := json.Marshal(give) + require.NoError(t, err, "failed to encode to JSON") + + var decoded tc.PrimitiveContainersRequired + require.NoError(t, json.Unmarshal(b, &decoded), "failed to decode JSON") - var decoded tc.PrimitiveContainersRequired - require.NoError(t, json.Unmarshal(b, &decoded), "failed to decode JSON") + assert.Equal(t, give, decoded) + }) - assert.Equal(t, give, decoded) + t.Run("Wire", func(t *testing.T) { + v, err := give.ToWire() + require.NoError(t, err, "failed to convert to wire.Value") - v, err := decoded.ToWire() - require.NoError(t, err, "failed to convert to wire.Value") + var got tc.PrimitiveContainersRequired + require.NoError(t, got.FromWire(v), "failed to convert from wire.Value") + + assert.Equal(t, give, got) + }) - var got tc.PrimitiveContainersRequired - require.NoError(t, got.FromWire(v), "failed to convert from wire.Value") + t.Run("Stream", func(t *testing.T) { + var buff bytes.Buffer + sw := binary.Default.Writer(&buff) + defer sw.Close() + require.NoError(t, give.Encode(sw)) - assert.Equal(t, give, got) + sr := binary.Default.Reader(bytes.NewReader(buff.Bytes())) + defer sr.Close() + + var got tc.PrimitiveContainersRequired + require.NoError(t, got.Decode(sr)) + + assert.Equal(t, give, got) + }) }) t.Run("optional", func(t *testing.T) { @@ -1408,26 +1424,49 @@ func TestEmptyContainersRoundTrip(t *testing.T) { MapOfIntToString: make(map[int32]string), } - b, err := json.Marshal(give) - require.NoError(t, err, "failed to encode to JSON") + t.Run("JSON", func(t *testing.T) { + b, err := json.Marshal(give) + require.NoError(t, err, "failed to encode to JSON") - var decoded tc.PrimitiveContainers - require.NoError(t, json.Unmarshal(b, &decoded), "failed to decode JSON") + var decoded tc.PrimitiveContainers + require.NoError(t, json.Unmarshal(b, &decoded), "failed to decode JSON") - // We check individual fields because a full assert.Equal could mismatch - // on nil vs empty slice. - assert.Empty(t, decoded.ListOfInts) - assert.Empty(t, decoded.SetOfStrings) - assert.Empty(t, decoded.MapOfIntToString) + // We check individual fields because a full assert.Equal could mismatch + // on nil vs empty slice. + assert.Empty(t, decoded.ListOfInts) + assert.Empty(t, decoded.SetOfStrings) + assert.Empty(t, decoded.MapOfIntToString) - v, err := decoded.ToWire() - require.NoError(t, err, "failed to convert to wire.Value") + }) - var got tc.PrimitiveContainers - require.NoError(t, got.FromWire(v), "failed to convert from wire.Value") + t.Run("JSON", func(t *testing.T) { + v, err := give.ToWire() + require.NoError(t, err, "failed to convert to wire.Value") - assert.Empty(t, got.ListOfInts) - assert.Empty(t, got.SetOfStrings) - assert.Empty(t, got.MapOfIntToString) + var got tc.PrimitiveContainers + require.NoError(t, got.FromWire(v), "failed to convert from wire.Value") + + assert.Empty(t, got.ListOfInts) + assert.Empty(t, got.SetOfStrings) + assert.Empty(t, got.MapOfIntToString) + }) + + t.Run("stream", func(t *testing.T) { + var buff bytes.Buffer + sw := binary.Default.Writer(&buff) + defer sw.Close() + require.NoError(t, give.Encode(sw)) + + sr := binary.Default.Reader(bytes.NewReader(buff.Bytes())) + defer sr.Close() + + var got tc.PrimitiveContainers + require.NoError(t, got.Decode(sr)) + + assert.Empty(t, got.ListOfInts) + assert.Empty(t, got.SetOfStrings) + assert.Empty(t, got.MapOfIntToString) + + }) }) } diff --git a/gen/doc.go b/gen/doc.go index f167356c..627ca7c3 100644 --- a/gen/doc.go +++ b/gen/doc.go @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Uber Technologies, Inc. +// Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/gen/embedidl.go b/gen/embedidl.go index 4b210b41..ec11faac 100644 --- a/gen/embedidl.go +++ b/gen/embedidl.go @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Uber Technologies, Inc. +// Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/gen/enum.go b/gen/enum.go index f91c653d..95559232 100644 --- a/gen/enum.go +++ b/gen/enum.go @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Uber Technologies, Inc. +// Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/gen/enum_test.go b/gen/enum_test.go index 942ab793..60f55e2a 100644 --- a/gen/enum_test.go +++ b/gen/enum_test.go @@ -96,6 +96,37 @@ func TestEqualsEnumWithValues(t *testing.T) { } } +func TestValueOfEnumWithHexValues(t *testing.T) { + tests := []struct { + e te.EnumWithHexValues + i int32 + }{ + {te.EnumWithHexValuesX, 0x123}, + {te.EnumWithHexValuesY, 0x456}, + {te.EnumWithHexValuesZ, 0x789}, + } + for _, tt := range tests { + assert.Equal(t, int32(tt.e), tt.i, "Value for %v does not match", tt.e) + } +} + +func TestEqualsEnumWithHexValues(t *testing.T) { + tests := []struct { + lhs, rhs te.EnumWithHexValues + want bool + }{ + {te.EnumWithHexValuesX, te.EnumWithHexValuesX, true}, + {te.EnumWithHexValuesY, te.EnumWithHexValuesY, true}, + {te.EnumWithHexValuesZ, te.EnumWithHexValuesZ, true}, + {te.EnumWithHexValuesX, te.EnumWithHexValuesY, false}, + {te.EnumWithHexValuesY, te.EnumWithHexValuesZ, false}, + {te.EnumWithHexValuesZ, te.EnumWithHexValuesX, false}, + } + for _, tt := range tests { + assert.Equal(t, tt.lhs.Equals(tt.rhs), tt.want) + } +} + func TestEnumDefaultWire(t *testing.T) { tests := []struct { e te.EnumDefault @@ -160,10 +191,18 @@ func TestEnumWithDuplicateValuesWire(t *testing.T) { } func TestUnknownEnumValue(t *testing.T) { + wv := wire.NewValueI32(42) + var e te.EnumDefault - if assert.NoError(t, e.FromWire(wire.NewValueI32(42))) { + if assert.NoError(t, e.FromWire(wv)) { assert.Equal(t, te.EnumDefault(42), e) } + + var se te.EnumDefault + if assert.NoError(t, streamDecodeWireType(t, wv, &se)) { + assert.Equal(t, te.EnumDefault(42), se) + } + } func TestOptionalEnum(t *testing.T) { diff --git a/gen/equals.go b/gen/equals.go index 78243738..61394f00 100644 --- a/gen/equals.go +++ b/gen/equals.go @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Uber Technologies, Inc. +// Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/gen/error.go b/gen/error.go index 82e05549..91806158 100644 --- a/gen/error.go +++ b/gen/error.go @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Uber Technologies, Inc. +// Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/gen/field.go b/gen/field.go index a74a011b..6844e55e 100644 --- a/gen/field.go +++ b/gen/field.go @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Uber Technologies, Inc. +// Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/gen/gen.go b/gen/gen.go index e40e0eeb..8c65eb2c 100644 --- a/gen/gen.go +++ b/gen/gen.go @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Uber Technologies, Inc. +// Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/gen/generate.go b/gen/generate.go index dcc72a0c..5902f981 100644 --- a/gen/generate.go +++ b/gen/generate.go @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Uber Technologies, Inc. +// Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/gen/generator.go b/gen/generator.go index bf208e2b..9334eaac 100644 --- a/gen/generator.go +++ b/gen/generator.go @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Uber Technologies, Inc. +// Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal @@ -236,6 +236,7 @@ func (g *generator) TextTemplate(s string, data interface{}, opts ...TemplateOpt "setUsesMap": setUsesMap, "isListType": isListType, "isPrimitiveType": isPrimitiveType, + "isStringType": isStringType, "isStructType": isStructType, "newNamespace": g.Namespace.Child, "newVar": g.Namespace.Child().NewName, diff --git a/gen/gotype.go b/gen/gotype.go index f4a1b0e1..c8274fe2 100644 --- a/gen/gotype.go +++ b/gen/gotype.go @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Uber Technologies, Inc. +// Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/gen/imports.go b/gen/imports.go index 06760477..f0d733df 100644 --- a/gen/imports.go +++ b/gen/imports.go @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Uber Technologies, Inc. +// Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/gen/internal/tests/collision/collision.go b/gen/internal/tests/collision/collision.go index d7beec77..92a152a6 100644 --- a/gen/internal/tests/collision/collision.go +++ b/gen/internal/tests/collision/collision.go @@ -1,4 +1,4 @@ -// Code generated by thriftrw v1.29.2. DO NOT EDIT. +// Code generated by thriftrw v1.30.0. DO NOT EDIT. // @generated package collision diff --git a/gen/internal/tests/constants/constants.go b/gen/internal/tests/constants/constants.go index 61f6005f..3cd80eae 100644 --- a/gen/internal/tests/constants/constants.go +++ b/gen/internal/tests/constants/constants.go @@ -1,4 +1,4 @@ -// Code generated by thriftrw v1.29.2. DO NOT EDIT. +// Code generated by thriftrw v1.30.0. DO NOT EDIT. // @generated package constants @@ -265,11 +265,23 @@ var Graph *structs.Graph = &structs.Graph{ }, } +const Hex16 int16 = 4660 + +const Hex32 int32 = 305419896 + +const Hex64 int64 = 1311768467294899695 + var I128 *typedefs.I128 = &typedefs.I128{ High: 1234, Low: 5678, } +const Int16 int16 = 12345 + +const Int32 int32 = 1234567890 + +const Int64 int64 = 1234567890123456789 + var LastNode *structs.Node = &structs.Node{ Value: 3, } @@ -333,7 +345,7 @@ var ThriftModule = &thriftreflect.ThriftModule{ Name: "constants", Package: "go.uber.org/thriftrw/gen/internal/tests/constants", FilePath: "constants.thrift", - SHA1: "c174d3c52157a0b78e14ad7677b2128174517eb6", + SHA1: "9dcab618ffb2d35b6baacfaa01c23461e63dbf06", Includes: []*thriftreflect.ThriftModule{ containers.ThriftModule, enums.ThriftModule, @@ -346,4 +358,4 @@ var ThriftModule = &thriftreflect.ThriftModule{ Raw: rawIDL, } -const rawIDL = "include \"./other_constants.thrift\"\ninclude \"./containers.thrift\"\ninclude \"./enums.thrift\"\ninclude \"./exceptions.thrift\"\ninclude \"./structs.thrift\"\ninclude \"./unions.thrift\"\ninclude \"./typedefs.thrift\"\n\nconst containers.PrimitiveContainers primitiveContainers = {\n \"listOfInts\": other_constants.listOfInts, // imported constant\n \"setOfStrings\": [\"foo\", \"bar\"],\n \"setOfBytes\": other_constants.listOfInts, // imported constant with type casting\n \"mapOfIntToString\": {\n 1: \"1\",\n 2: \"2\",\n 3: \"3\",\n },\n \"mapOfStringToBool\": {\n \"1\": 0,\n \"2\": 1,\n \"3\": 1,\n }\n}\n\nconst containers.EnumContainers enumContainers = {\n \"listOfEnums\": [1, enums.EnumDefault.Foo],\n \"setOfEnums\": [123, enums.EnumWithValues.Y],\n \"mapOfEnums\": {\n 0: 1,\n enums.EnumWithDuplicateValues.Q: 2,\n },\n}\n\nconst containers.ContainersOfContainers containersOfContainers = {\n \"listOfLists\": [[1, 2, 3], [4, 5, 6]],\n \"listOfSets\": [[1, 2, 3], [4, 5, 6]],\n \"listOfMaps\": [{1: 2, 3: 4, 5: 6}, {7: 8, 9: 10, 11: 12}],\n \"setOfSets\": [[\"1\", \"2\", \"3\"], [\"4\", \"5\", \"6\"]],\n \"setOfLists\": [[\"1\", \"2\", \"3\"], [\"4\", \"5\", \"6\"]],\n \"setOfMaps\": [\n {\"1\": \"2\", \"3\": \"4\", \"5\": \"6\"},\n {\"7\": \"8\", \"9\": \"10\", \"11\": \"12\"},\n ],\n \"mapOfMapToInt\": {\n {\"1\": 1, \"2\": 2, \"3\": 3}: 100,\n {\"4\": 4, \"5\": 5, \"6\": 6}: 200,\n },\n \"mapOfListToSet\": {\n // more type casting\n other_constants.listOfInts: other_constants.listOfInts,\n [4, 5, 6]: [4, 5, 6],\n },\n \"mapOfSetToListOfDouble\": {\n [1, 2, 3]: [1.2, 3.4],\n [4, 5, 6]: [5.6, 7.8],\n },\n}\n\nconst enums.StructWithOptionalEnum structWithOptionalEnum = {\n \"e\": enums.EnumDefault.Baz\n}\n\nconst exceptions.EmptyException emptyException = {}\n\nconst structs.Graph graph = {\n \"edges\": [\n {\"startPoint\": other_constants.some_point, \"endPoint\": {\"x\": 3, \"y\": 4}},\n {\"startPoint\": {\"x\": 5, \"y\": 6}, \"endPoint\": {\"x\": 7, \"y\": 8}},\n ]\n}\n\nconst structs.Node lastNode = {\"value\": 3}\nconst structs.Node node = {\n \"value\": 1,\n \"tail\": {\"value\": 2, \"tail\": lastNode},\n}\n\nconst unions.ArbitraryValue arbitraryValue = {\n \"listValue\": [\n {\"boolValue\": 1},\n {\"int64Value\": 2},\n {\"stringValue\": \"hello\"},\n {\"mapValue\": {\"foo\": {\"stringValue\": \"bar\"}}},\n ],\n}\n// TODO: union validation for constants?\n\nconst typedefs.i128 i128 = uuid\nconst typedefs.UUID uuid = {\"high\": 1234, \"low\": 5678}\n\n/** Timestamp at which time began. */\nconst typedefs.Timestamp beginningOfTime = 0\n\n/**\n * An example frame group.\n *\n * Contains two frames.\n */\nconst typedefs.FrameGroup frameGroup = [\n {\n \"topLeft\": {\"x\": 1, \"y\": 2},\n \"size\": {\"width\": 100, \"height\": 200},\n }\n {\n \"topLeft\": {\"x\": 3, \"y\": 4},\n \"size\": {\"width\": 300, \"height\": 400},\n },\n]\n\nconst typedefs.MyEnum myEnum = enums.EnumWithValues.Y\n\nconst enums.RecordType NAME = enums.RecordType.NAME\nconst enums.RecordType HOME = enums.RecordType.HOME_ADDRESS\nconst enums.RecordType WORK_ADDRESS = enums.RecordType.WORK_ADDRESS\n\nconst enums.lowerCaseEnum lower = enums.lowerCaseEnum.items\n" +const rawIDL = "include \"./other_constants.thrift\"\ninclude \"./containers.thrift\"\ninclude \"./enums.thrift\"\ninclude \"./exceptions.thrift\"\ninclude \"./structs.thrift\"\ninclude \"./unions.thrift\"\ninclude \"./typedefs.thrift\"\n\nconst i16 int16 = 12345\nconst i32 int32 = 1234567890\nconst i64 int64 = 1234567890123456789\n\nconst i16 hex16 = 0x1234\nconst i32 hex32 = 0x12345678\nconst i64 hex64 = 0x1234567890abcdef\n\nconst containers.PrimitiveContainers primitiveContainers = {\n \"listOfInts\": other_constants.listOfInts, // imported constant\n \"setOfStrings\": [\"foo\", \"bar\"],\n \"setOfBytes\": other_constants.listOfInts, // imported constant with type casting\n \"mapOfIntToString\": {\n 1: \"1\",\n 2: \"2\",\n 3: \"3\",\n },\n \"mapOfStringToBool\": {\n \"1\": 0,\n \"2\": 1,\n \"3\": 1,\n }\n}\n\nconst containers.EnumContainers enumContainers = {\n \"listOfEnums\": [1, enums.EnumDefault.Foo],\n \"setOfEnums\": [123, enums.EnumWithValues.Y],\n \"mapOfEnums\": {\n 0: 1,\n enums.EnumWithDuplicateValues.Q: 2,\n },\n}\n\nconst containers.ContainersOfContainers containersOfContainers = {\n \"listOfLists\": [[1, 2, 3], [4, 5, 6]],\n \"listOfSets\": [[1, 2, 3], [4, 5, 6]],\n \"listOfMaps\": [{1: 2, 3: 4, 5: 6}, {7: 8, 9: 10, 11: 12}],\n \"setOfSets\": [[\"1\", \"2\", \"3\"], [\"4\", \"5\", \"6\"]],\n \"setOfLists\": [[\"1\", \"2\", \"3\"], [\"4\", \"5\", \"6\"]],\n \"setOfMaps\": [\n {\"1\": \"2\", \"3\": \"4\", \"5\": \"6\"},\n {\"7\": \"8\", \"9\": \"10\", \"11\": \"12\"},\n ],\n \"mapOfMapToInt\": {\n {\"1\": 1, \"2\": 2, \"3\": 3}: 100,\n {\"4\": 4, \"5\": 5, \"6\": 6}: 200,\n },\n \"mapOfListToSet\": {\n // more type casting\n other_constants.listOfInts: other_constants.listOfInts,\n [4, 5, 6]: [4, 5, 6],\n },\n \"mapOfSetToListOfDouble\": {\n [1, 2, 3]: [1.2, 3.4],\n [4, 5, 6]: [5.6, 7.8],\n },\n}\n\nconst enums.StructWithOptionalEnum structWithOptionalEnum = {\n \"e\": enums.EnumDefault.Baz\n}\n\nconst exceptions.EmptyException emptyException = {}\n\nconst structs.Graph graph = {\n \"edges\": [\n {\"startPoint\": other_constants.some_point, \"endPoint\": {\"x\": 3, \"y\": 4}},\n {\"startPoint\": {\"x\": 5, \"y\": 6}, \"endPoint\": {\"x\": 7, \"y\": 8}},\n ]\n}\n\nconst structs.Node lastNode = {\"value\": 3}\nconst structs.Node node = {\n \"value\": 1,\n \"tail\": {\"value\": 2, \"tail\": lastNode},\n}\n\nconst unions.ArbitraryValue arbitraryValue = {\n \"listValue\": [\n {\"boolValue\": 1},\n {\"int64Value\": 2},\n {\"stringValue\": \"hello\"},\n {\"mapValue\": {\"foo\": {\"stringValue\": \"bar\"}}},\n ],\n}\n// TODO: union validation for constants?\n\nconst typedefs.i128 i128 = uuid\nconst typedefs.UUID uuid = {\"high\": 1234, \"low\": 5678}\n\n/** Timestamp at which time began. */\nconst typedefs.Timestamp beginningOfTime = 0\n\n/**\n * An example frame group.\n *\n * Contains two frames.\n */\nconst typedefs.FrameGroup frameGroup = [\n {\n \"topLeft\": {\"x\": 1, \"y\": 2},\n \"size\": {\"width\": 100, \"height\": 200},\n }\n {\n \"topLeft\": {\"x\": 3, \"y\": 4},\n \"size\": {\"width\": 300, \"height\": 400},\n },\n]\n\nconst typedefs.MyEnum myEnum = enums.EnumWithValues.Y\n\nconst enums.RecordType NAME = enums.RecordType.NAME\nconst enums.RecordType HOME = enums.RecordType.HOME_ADDRESS\nconst enums.RecordType WORK_ADDRESS = enums.RecordType.WORK_ADDRESS\n\nconst enums.lowerCaseEnum lower = enums.lowerCaseEnum.items\n" diff --git a/gen/internal/tests/containers/containers.go b/gen/internal/tests/containers/containers.go index ed9cd389..c47e7b06 100644 --- a/gen/internal/tests/containers/containers.go +++ b/gen/internal/tests/containers/containers.go @@ -1,4 +1,4 @@ -// Code generated by thriftrw v1.29.2. DO NOT EDIT. +// Code generated by thriftrw v1.30.0. DO NOT EDIT. // @generated package containers diff --git a/gen/internal/tests/enum-text-marshal-strict/enum-text-marshal-strict.go b/gen/internal/tests/enum-text-marshal-strict/enum-text-marshal-strict.go index a39e778a..dd74b4e8 100644 --- a/gen/internal/tests/enum-text-marshal-strict/enum-text-marshal-strict.go +++ b/gen/internal/tests/enum-text-marshal-strict/enum-text-marshal-strict.go @@ -1,4 +1,4 @@ -// Code generated by thriftrw v1.29.2. DO NOT EDIT. +// Code generated by thriftrw v1.30.0. DO NOT EDIT. // @generated package enum_text_marshal_strict diff --git a/gen/internal/tests/enum_conflict/enum_conflict.go b/gen/internal/tests/enum_conflict/enum_conflict.go index 317301a8..293af370 100644 --- a/gen/internal/tests/enum_conflict/enum_conflict.go +++ b/gen/internal/tests/enum_conflict/enum_conflict.go @@ -1,4 +1,4 @@ -// Code generated by thriftrw v1.29.2. DO NOT EDIT. +// Code generated by thriftrw v1.30.0. DO NOT EDIT. // @generated package enum_conflict diff --git a/gen/internal/tests/enums/enums.go b/gen/internal/tests/enums/enums.go index e35b4d1c..3ee2cd56 100644 --- a/gen/internal/tests/enums/enums.go +++ b/gen/internal/tests/enums/enums.go @@ -1,4 +1,4 @@ -// Code generated by thriftrw v1.29.2. DO NOT EDIT. +// Code generated by thriftrw v1.30.0. DO NOT EDIT. // @generated package enums @@ -881,6 +881,218 @@ func (v *EnumWithDuplicateValues) UnmarshalJSON(text []byte) error { } } +type EnumWithHexValues int32 + +const ( + EnumWithHexValuesX EnumWithHexValues = 291 + EnumWithHexValuesY EnumWithHexValues = 1110 + EnumWithHexValuesZ EnumWithHexValues = 1929 +) + +// EnumWithHexValues_Values returns all recognized values of EnumWithHexValues. +func EnumWithHexValues_Values() []EnumWithHexValues { + return []EnumWithHexValues{ + EnumWithHexValuesX, + EnumWithHexValuesY, + EnumWithHexValuesZ, + } +} + +// UnmarshalText tries to decode EnumWithHexValues from a byte slice +// containing its name. +// +// var v EnumWithHexValues +// err := v.UnmarshalText([]byte("X")) +func (v *EnumWithHexValues) UnmarshalText(value []byte) error { + switch s := string(value); s { + case "X": + *v = EnumWithHexValuesX + return nil + case "Y": + *v = EnumWithHexValuesY + return nil + case "Z": + *v = EnumWithHexValuesZ + return nil + default: + val, err := strconv.ParseInt(s, 10, 32) + if err != nil { + return fmt.Errorf("unknown enum value %q for %q: %v", s, "EnumWithHexValues", err) + } + *v = EnumWithHexValues(val) + return nil + } +} + +// MarshalText encodes EnumWithHexValues to text. +// +// If the enum value is recognized, its name is returned. +// Otherwise, its integer value is returned. +// +// This implements the TextMarshaler interface. +func (v EnumWithHexValues) MarshalText() ([]byte, error) { + switch int32(v) { + case 291: + return []byte("X"), nil + case 1110: + return []byte("Y"), nil + case 1929: + return []byte("Z"), nil + } + return []byte(strconv.FormatInt(int64(v), 10)), nil +} + +// MarshalLogObject implements zapcore.ObjectMarshaler, enabling +// fast logging of EnumWithHexValues. +// Enums are logged as objects, where the value is logged with key "value", and +// if this value's name is known, the name is logged with key "name". +func (v EnumWithHexValues) MarshalLogObject(enc zapcore.ObjectEncoder) error { + enc.AddInt32("value", int32(v)) + switch int32(v) { + case 291: + enc.AddString("name", "X") + case 1110: + enc.AddString("name", "Y") + case 1929: + enc.AddString("name", "Z") + } + return nil +} + +// Ptr returns a pointer to this enum value. +func (v EnumWithHexValues) Ptr() *EnumWithHexValues { + return &v +} + +// Encode encodes EnumWithHexValues directly to bytes. +// +// sWriter := BinaryStreamer.Writer(writer) +// +// var v EnumWithHexValues +// return v.Encode(sWriter) +func (v EnumWithHexValues) Encode(sw stream.Writer) error { + return sw.WriteInt32(int32(v)) +} + +// ToWire translates EnumWithHexValues into a Thrift-level intermediate +// representation. This intermediate representation may be serialized +// into bytes using a ThriftRW protocol implementation. +// +// Enums are represented as 32-bit integers over the wire. +func (v EnumWithHexValues) ToWire() (wire.Value, error) { + return wire.NewValueI32(int32(v)), nil +} + +// FromWire deserializes EnumWithHexValues from its Thrift-level +// representation. +// +// x, err := binaryProtocol.Decode(reader, wire.TI32) +// if err != nil { +// return EnumWithHexValues(0), err +// } +// +// var v EnumWithHexValues +// if err := v.FromWire(x); err != nil { +// return EnumWithHexValues(0), err +// } +// return v, nil +func (v *EnumWithHexValues) FromWire(w wire.Value) error { + *v = (EnumWithHexValues)(w.GetI32()) + return nil +} + +// Decode reads off the encoded EnumWithHexValues directly off of the wire. +// +// sReader := BinaryStreamer.Reader(reader) +// +// var v EnumWithHexValues +// if err := v.Decode(sReader); err != nil { +// return EnumWithHexValues(0), err +// } +// return v, nil +func (v *EnumWithHexValues) Decode(sr stream.Reader) error { + i, err := sr.ReadInt32() + if err != nil { + return err + } + *v = (EnumWithHexValues)(i) + return nil +} + +// String returns a readable string representation of EnumWithHexValues. +func (v EnumWithHexValues) String() string { + w := int32(v) + switch w { + case 291: + return "X" + case 1110: + return "Y" + case 1929: + return "Z" + } + return fmt.Sprintf("EnumWithHexValues(%d)", w) +} + +// Equals returns true if this EnumWithHexValues value matches the provided +// value. +func (v EnumWithHexValues) Equals(rhs EnumWithHexValues) bool { + return v == rhs +} + +// MarshalJSON serializes EnumWithHexValues into JSON. +// +// If the enum value is recognized, its name is returned. +// Otherwise, its integer value is returned. +// +// This implements json.Marshaler. +func (v EnumWithHexValues) MarshalJSON() ([]byte, error) { + switch int32(v) { + case 291: + return ([]byte)("\"X\""), nil + case 1110: + return ([]byte)("\"Y\""), nil + case 1929: + return ([]byte)("\"Z\""), nil + } + return ([]byte)(strconv.FormatInt(int64(v), 10)), nil +} + +// UnmarshalJSON attempts to decode EnumWithHexValues from its JSON +// representation. +// +// This implementation supports both, numeric and string inputs. If a +// string is provided, it must be a known enum name. +// +// This implements json.Unmarshaler. +func (v *EnumWithHexValues) UnmarshalJSON(text []byte) error { + d := json.NewDecoder(bytes.NewReader(text)) + d.UseNumber() + t, err := d.Token() + if err != nil { + return err + } + + switch w := t.(type) { + case json.Number: + x, err := w.Int64() + if err != nil { + return err + } + if x > math.MaxInt32 { + return fmt.Errorf("enum overflow from JSON %q for %q", text, "EnumWithHexValues") + } + if x < math.MinInt32 { + return fmt.Errorf("enum underflow from JSON %q for %q", text, "EnumWithHexValues") + } + *v = (EnumWithHexValues)(x) + return nil + case string: + return v.UnmarshalText([]byte(w)) + default: + return fmt.Errorf("invalid JSON value %q (%T) to unmarshal into %q", t, t, "EnumWithHexValues") + } +} + type EnumWithLabel int32 const ( @@ -2212,8 +2424,8 @@ var ThriftModule = &thriftreflect.ThriftModule{ Name: "enums", Package: "go.uber.org/thriftrw/gen/internal/tests/enums", FilePath: "enums.thrift", - SHA1: "16921e977d77e214a9bac398d279f60889b055de", + SHA1: "03c37e20af4155181f2df17e69d40dbc831c5b28", Raw: rawIDL, } -const rawIDL = "enum EmptyEnum {}\n\nenum EnumDefault {\n Foo, Bar, Baz\n}\n\nenum EnumWithValues {\n X = 123,\n Y = 456,\n Z = 789,\n}\n\nenum EnumWithDuplicateValues {\n P, // 0\n Q = -1,\n R, // 0\n}\n\n// enum with item names conflicting with those of another enum\nenum EnumWithDuplicateName {\n A, B, C, P, Q, R, X, Y, Z\n}\n\n// Enum treated as optional inside a struct\nstruct StructWithOptionalEnum {\n 1: optional EnumDefault e\n}\n\n/**\n * Kinds of records stored in the database.\n */\nenum RecordType {\n /** Name of the user. */\n NAME,\n\n /**\n * Home address of the user.\n *\n * This record is always present.\n */\n HOME_ADDRESS,\n\n /**\n * Home address of the user.\n *\n * This record may not be present.\n */\n WORK_ADDRESS\n}\n\nenum lowerCaseEnum {\n containing, lower_case, items\n}\n\n// EnumWithLabel use label name in serialization/deserialization\nenum EnumWithLabel {\n USERNAME (go.label = \"surname\"),\n PASSWORD (go.label = \"hashed_password\"),\n SALT (go.label = \"\"),\n SUGAR (go.label),\n relay (go.label = \"RELAY\")\n NAIVE4_N1 (go.label = \"function\")\n\n}\n\n// collision with RecordType_Values() function.\nenum RecordType_Values { FOO, BAR }\n" +const rawIDL = "enum EmptyEnum {}\n\nenum EnumDefault {\n Foo, Bar, Baz\n}\n\nenum EnumWithValues {\n X = 123,\n Y = 456,\n Z = 789,\n}\n\nenum EnumWithHexValues {\n X = 0x123,\n Y = 0x456,\n Z = 0x789,\n}\n\nenum EnumWithDuplicateValues {\n P, // 0\n Q = -1,\n R, // 0\n}\n\n// enum with item names conflicting with those of another enum\nenum EnumWithDuplicateName {\n A, B, C, P, Q, R, X, Y, Z\n}\n\n// Enum treated as optional inside a struct\nstruct StructWithOptionalEnum {\n 1: optional EnumDefault e\n}\n\n/**\n * Kinds of records stored in the database.\n */\nenum RecordType {\n /** Name of the user. */\n NAME,\n\n /**\n * Home address of the user.\n *\n * This record is always present.\n */\n HOME_ADDRESS,\n\n /**\n * Home address of the user.\n *\n * This record may not be present.\n */\n WORK_ADDRESS\n}\n\nenum lowerCaseEnum {\n containing, lower_case, items\n}\n\n// EnumWithLabel use label name in serialization/deserialization\nenum EnumWithLabel {\n USERNAME (go.label = \"surname\"),\n PASSWORD (go.label = \"hashed_password\"),\n SALT (go.label = \"\"),\n SUGAR (go.label),\n relay (go.label = \"RELAY\")\n NAIVE4_N1 (go.label = \"function\")\n\n}\n\n// collision with RecordType_Values() function.\nenum RecordType_Values { FOO, BAR }\n" diff --git a/gen/internal/tests/exceptions/exceptions.go b/gen/internal/tests/exceptions/exceptions.go index 8b8a34d9..d7c5eac3 100644 --- a/gen/internal/tests/exceptions/exceptions.go +++ b/gen/internal/tests/exceptions/exceptions.go @@ -1,4 +1,4 @@ -// Code generated by thriftrw v1.29.2. DO NOT EDIT. +// Code generated by thriftrw v1.30.0. DO NOT EDIT. // @generated package exceptions diff --git a/gen/internal/tests/hyphenated-file/hyphenated-file.go b/gen/internal/tests/hyphenated-file/hyphenated-file.go index c5c95ddf..ee5cc6a2 100644 --- a/gen/internal/tests/hyphenated-file/hyphenated-file.go +++ b/gen/internal/tests/hyphenated-file/hyphenated-file.go @@ -1,4 +1,4 @@ -// Code generated by thriftrw v1.29.2. DO NOT EDIT. +// Code generated by thriftrw v1.30.0. DO NOT EDIT. // @generated package hyphenated_file diff --git a/gen/internal/tests/hyphenated_file/hyphenated_file.go b/gen/internal/tests/hyphenated_file/hyphenated_file.go index e59e9747..adf7a540 100644 --- a/gen/internal/tests/hyphenated_file/hyphenated_file.go +++ b/gen/internal/tests/hyphenated_file/hyphenated_file.go @@ -1,4 +1,4 @@ -// Code generated by thriftrw v1.29.2. DO NOT EDIT. +// Code generated by thriftrw v1.30.0. DO NOT EDIT. // @generated package hyphenated_file diff --git a/gen/internal/tests/non_hyphenated/non_hyphenated.go b/gen/internal/tests/non_hyphenated/non_hyphenated.go index aaaec27e..dfee594e 100644 --- a/gen/internal/tests/non_hyphenated/non_hyphenated.go +++ b/gen/internal/tests/non_hyphenated/non_hyphenated.go @@ -1,4 +1,4 @@ -// Code generated by thriftrw v1.29.2. DO NOT EDIT. +// Code generated by thriftrw v1.30.0. DO NOT EDIT. // @generated package non_hyphenated diff --git a/gen/internal/tests/nozap/nozap.go b/gen/internal/tests/nozap/nozap.go index 7e5381c6..f8bb037b 100644 --- a/gen/internal/tests/nozap/nozap.go +++ b/gen/internal/tests/nozap/nozap.go @@ -1,4 +1,4 @@ -// Code generated by thriftrw v1.29.2. DO NOT EDIT. +// Code generated by thriftrw v1.30.0. DO NOT EDIT. // @generated package nozap diff --git a/gen/internal/tests/other_constants/other_constants.go b/gen/internal/tests/other_constants/other_constants.go index 4f9dfd2f..5d682a65 100644 --- a/gen/internal/tests/other_constants/other_constants.go +++ b/gen/internal/tests/other_constants/other_constants.go @@ -1,4 +1,4 @@ -// Code generated by thriftrw v1.29.2. DO NOT EDIT. +// Code generated by thriftrw v1.30.0. DO NOT EDIT. // @generated package other_constants diff --git a/gen/internal/tests/services/services.go b/gen/internal/tests/services/services.go index 97fb0ac4..8f338cf4 100644 --- a/gen/internal/tests/services/services.go +++ b/gen/internal/tests/services/services.go @@ -1,4 +1,4 @@ -// Code generated by thriftrw v1.29.2. DO NOT EDIT. +// Code generated by thriftrw v1.30.0. DO NOT EDIT. // @generated package services @@ -537,7 +537,7 @@ func (v Key) ToWire() (wire.Value, error) { // String returns a readable string representation of Key. func (v Key) String() string { x := (string)(v) - return fmt.Sprint(x) + return x } func (v Key) Encode(sw stream.Writer) error { diff --git a/gen/internal/tests/set_to_slice/set_to_slice.go b/gen/internal/tests/set_to_slice/set_to_slice.go index 16b5b341..61cbecfb 100644 --- a/gen/internal/tests/set_to_slice/set_to_slice.go +++ b/gen/internal/tests/set_to_slice/set_to_slice.go @@ -1,4 +1,4 @@ -// Code generated by thriftrw v1.29.2. DO NOT EDIT. +// Code generated by thriftrw v1.30.0. DO NOT EDIT. // @generated package set_to_slice diff --git a/gen/internal/tests/structs/structs.go b/gen/internal/tests/structs/structs.go index 56c70c77..c0253e84 100644 --- a/gen/internal/tests/structs/structs.go +++ b/gen/internal/tests/structs/structs.go @@ -1,4 +1,4 @@ -// Code generated by thriftrw v1.29.2. DO NOT EDIT. +// Code generated by thriftrw v1.30.0. DO NOT EDIT. // @generated package structs diff --git a/gen/internal/tests/thrift/constants.thrift b/gen/internal/tests/thrift/constants.thrift index 78470d39..7f70e9a1 100644 --- a/gen/internal/tests/thrift/constants.thrift +++ b/gen/internal/tests/thrift/constants.thrift @@ -6,6 +6,14 @@ include "./structs.thrift" include "./unions.thrift" include "./typedefs.thrift" +const i16 int16 = 12345 +const i32 int32 = 1234567890 +const i64 int64 = 1234567890123456789 + +const i16 hex16 = 0x1234 +const i32 hex32 = 0x12345678 +const i64 hex64 = 0x1234567890abcdef + const containers.PrimitiveContainers primitiveContainers = { "listOfInts": other_constants.listOfInts, // imported constant "setOfStrings": ["foo", "bar"], diff --git a/gen/internal/tests/thrift/enums.thrift b/gen/internal/tests/thrift/enums.thrift index 36907a8b..17165513 100644 --- a/gen/internal/tests/thrift/enums.thrift +++ b/gen/internal/tests/thrift/enums.thrift @@ -10,6 +10,12 @@ enum EnumWithValues { Z = 789, } +enum EnumWithHexValues { + X = 0x123, + Y = 0x456, + Z = 0x789, +} + enum EnumWithDuplicateValues { P, // 0 Q = -1, diff --git a/gen/internal/tests/typedefs/typedefs.go b/gen/internal/tests/typedefs/typedefs.go index a317c7e4..b05a3973 100644 --- a/gen/internal/tests/typedefs/typedefs.go +++ b/gen/internal/tests/typedefs/typedefs.go @@ -1,4 +1,4 @@ -// Code generated by thriftrw v1.29.2. DO NOT EDIT. +// Code generated by thriftrw v1.30.0. DO NOT EDIT. // @generated package typedefs @@ -1934,7 +1934,7 @@ func (v State) ToWire() (wire.Value, error) { // String returns a readable string representation of State. func (v State) String() string { x := (string)(v) - return fmt.Sprint(x) + return x } func (v State) Encode(sw stream.Writer) error { diff --git a/gen/internal/tests/unions/unions.go b/gen/internal/tests/unions/unions.go index adec7a9f..b6ce5bbd 100644 --- a/gen/internal/tests/unions/unions.go +++ b/gen/internal/tests/unions/unions.go @@ -1,4 +1,4 @@ -// Code generated by thriftrw v1.29.2. DO NOT EDIT. +// Code generated by thriftrw v1.30.0. DO NOT EDIT. // @generated package unions diff --git a/gen/internal/tests/uuid_conflict/uuid_conflict.go b/gen/internal/tests/uuid_conflict/uuid_conflict.go index 10df1af2..0588f31b 100644 --- a/gen/internal/tests/uuid_conflict/uuid_conflict.go +++ b/gen/internal/tests/uuid_conflict/uuid_conflict.go @@ -1,4 +1,4 @@ -// Code generated by thriftrw v1.29.2. DO NOT EDIT. +// Code generated by thriftrw v1.30.0. DO NOT EDIT. // @generated package uuid_conflict @@ -33,7 +33,7 @@ func (v UUID) ToWire() (wire.Value, error) { // String returns a readable string representation of UUID. func (v UUID) String() string { x := (string)(v) - return fmt.Sprint(x) + return x } func (v UUID) Encode(sw stream.Writer) error { diff --git a/gen/label.go b/gen/label.go index 7a712d90..6884b4f5 100644 --- a/gen/label.go +++ b/gen/label.go @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Uber Technologies, Inc. +// Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/gen/list.go b/gen/list.go index 62feb4d3..449b4f84 100644 --- a/gen/list.go +++ b/gen/list.go @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Uber Technologies, Inc. +// Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/gen/list_test.go b/gen/list_test.go index 06bf084c..b491d0fb 100644 --- a/gen/list_test.go +++ b/gen/list_test.go @@ -21,11 +21,13 @@ package gen import ( + "bytes" "testing" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" tc "go.uber.org/thriftrw/gen/internal/tests/containers" + "go.uber.org/thriftrw/protocol/binary" "go.uber.org/thriftrw/wire" ) @@ -89,17 +91,40 @@ func TestListRequiredToWire(t *testing.T) { } for _, tt := range tests { t.Run(tt.desc, func(t *testing.T) { - w, err := tt.give.ToWire() - require.NoError(t, err, "failed to serialize: %v", tt.give) - require.True(t, wire.ValuesAreEqual(tt.want, w)) - assert.True(t, tt.give.Equals(tt.give)) - // Round trip them all. - got, ok := assertBinaryRoundTrip(t, w, tt.desc) - require.True(t, ok, "failed round trip") - // Allocate a new instance to deserialize from Thrift representation. - x := new(tc.ListOfRequiredPrimitives) - require.NoError(t, x.FromWire(got)) - assert.Equal(t, tt.wantList, x.ListOfStrings) + t.Run("Wire", func(t *testing.T) { + w, err := tt.give.ToWire() + require.NoError(t, err, "failed to serialize: %v", tt.give) + require.True(t, wire.ValuesAreEqual(tt.want, w)) + assert.True(t, tt.give.Equals(tt.give)) + // Round trip them all. + got, ok := assertBinaryRoundTrip(t, w, tt.desc) + require.True(t, ok, "failed round trip") + // Allocate a new instance to deserialize from Thrift representation. + x := new(tc.ListOfRequiredPrimitives) + require.NoError(t, x.FromWire(got)) + assert.Equal(t, tt.wantList, x.ListOfStrings) + }) + + t.Run("Stream", func(t *testing.T) { + var buff bytes.Buffer + sw := binary.Default.Writer(&buff) + defer sw.Close() + + require.NoError(t, tt.give.Encode(sw)) + + sr := binary.Default.Reader(bytes.NewReader(buff.Bytes())) + defer sr.Close() + + x := new(tc.ListOfRequiredPrimitives) + require.NoError(t, x.Decode(sr)) + assert.Equal(t, tt.wantList, x.ListOfStrings) + }) + + t.Run("StreamFromWire", func(t *testing.T) { + x := new(tc.ListOfRequiredPrimitives) + require.NoError(t, streamDecodeWireType(t, tt.want, x)) + assert.Equal(t, tt.wantList, x.ListOfStrings) + }) }) } } @@ -118,17 +143,28 @@ func TestListRequiredFromWire(t *testing.T) { got := new(tc.ListOfRequiredPrimitives) require.NoError(t, got.FromWire(give), "failed to decode") require.Equal(t, want, got) - _, ok := assertBinaryRoundTrip(t, give, t.Name()) - assert.True(t, ok, "failed round trip") + + testRoundTripCombos(t, want, give, "") }) // Error if required list is missing in the wire representation. t.Run("absent list field results in an error", func(t *testing.T) { give := wire.NewValueStruct(wire.Struct{}) - x := new(tc.ListOfRequiredPrimitives) - err := x.FromWire(give) - require.Error(t, err, "failed to decode") - assert.Equal(t, "field ListOfStrings of ListOfRequiredPrimitives is required", err.Error()) + + t.Run("FromWire", func(t *testing.T) { + x := new(tc.ListOfRequiredPrimitives) + err := x.FromWire(give) + require.Error(t, err, "failed to fromwire") + assert.Equal(t, "field ListOfStrings of ListOfRequiredPrimitives is required", err.Error()) + }) + + t.Run("StreamDecode", func(t *testing.T) { + x := new(tc.ListOfRequiredPrimitives) + err := streamDecodeWireType(t, give, x) + require.Error(t, err, "failed to stream decode") + assert.Equal(t, "field ListOfStrings of ListOfRequiredPrimitives is required", err.Error()) + }) + }) } @@ -195,9 +231,8 @@ func TestListOptionalFromWire(t *testing.T) { x := new(tc.ListOfOptionalPrimitives) require.NoError(t, x.FromWire(tt.give), tt.desc) assert.Equal(t, tt.want, x.ListOfStrings) - _, ok := assertBinaryRoundTrip(t, tt.give, tt.desc) - assert.True(t, ok, "failed round trip") + testRoundTripCombos(t, x, tt.give, "" /* test desc, not needed because already in a t.Run */) }) } } diff --git a/gen/literal.go b/gen/literal.go index ffd2ad11..d9b47506 100644 --- a/gen/literal.go +++ b/gen/literal.go @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Uber Technologies, Inc. +// Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/gen/mangle.go b/gen/mangle.go index 22488afd..bd3dda9a 100644 --- a/gen/mangle.go +++ b/gen/mangle.go @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Uber Technologies, Inc. +// Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/gen/map.go b/gen/map.go index f261a341..5c8a58d0 100644 --- a/gen/map.go +++ b/gen/map.go @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Uber Technologies, Inc. +// Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/gen/mock_zap_test.go b/gen/mock_zap_test.go index 25843a10..20670aeb 100644 --- a/gen/mock_zap_test.go +++ b/gen/mock_zap_test.go @@ -5,36 +5,37 @@ package gen import ( - gomock "github.com/golang/mock/gomock" - zapcore "go.uber.org/zap/zapcore" reflect "reflect" time "time" + + gomock "github.com/golang/mock/gomock" + zapcore "go.uber.org/zap/zapcore" ) -// MockObjectEncoder is a mock of ObjectEncoder interface +// MockObjectEncoder is a mock of ObjectEncoder interface. type MockObjectEncoder struct { ctrl *gomock.Controller recorder *MockObjectEncoderMockRecorder } -// MockObjectEncoderMockRecorder is the mock recorder for MockObjectEncoder +// MockObjectEncoderMockRecorder is the mock recorder for MockObjectEncoder. type MockObjectEncoderMockRecorder struct { mock *MockObjectEncoder } -// NewMockObjectEncoder creates a new mock instance +// NewMockObjectEncoder creates a new mock instance. func NewMockObjectEncoder(ctrl *gomock.Controller) *MockObjectEncoder { mock := &MockObjectEncoder{ctrl: ctrl} mock.recorder = &MockObjectEncoderMockRecorder{mock} return mock } -// EXPECT returns an object that allows the caller to indicate expected use +// EXPECT returns an object that allows the caller to indicate expected use. func (m *MockObjectEncoder) EXPECT() *MockObjectEncoderMockRecorder { return m.recorder } -// AddArray mocks base method +// AddArray mocks base method. func (m *MockObjectEncoder) AddArray(arg0 string, arg1 zapcore.ArrayMarshaler) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "AddArray", arg0, arg1) @@ -42,169 +43,169 @@ func (m *MockObjectEncoder) AddArray(arg0 string, arg1 zapcore.ArrayMarshaler) e return ret0 } -// AddArray indicates an expected call of AddArray +// AddArray indicates an expected call of AddArray. func (mr *MockObjectEncoderMockRecorder) AddArray(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddArray", reflect.TypeOf((*MockObjectEncoder)(nil).AddArray), arg0, arg1) } -// AddBinary mocks base method +// AddBinary mocks base method. func (m *MockObjectEncoder) AddBinary(arg0 string, arg1 []byte) { m.ctrl.T.Helper() m.ctrl.Call(m, "AddBinary", arg0, arg1) } -// AddBinary indicates an expected call of AddBinary +// AddBinary indicates an expected call of AddBinary. func (mr *MockObjectEncoderMockRecorder) AddBinary(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddBinary", reflect.TypeOf((*MockObjectEncoder)(nil).AddBinary), arg0, arg1) } -// AddBool mocks base method +// AddBool mocks base method. func (m *MockObjectEncoder) AddBool(arg0 string, arg1 bool) { m.ctrl.T.Helper() m.ctrl.Call(m, "AddBool", arg0, arg1) } -// AddBool indicates an expected call of AddBool +// AddBool indicates an expected call of AddBool. func (mr *MockObjectEncoderMockRecorder) AddBool(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddBool", reflect.TypeOf((*MockObjectEncoder)(nil).AddBool), arg0, arg1) } -// AddByteString mocks base method +// AddByteString mocks base method. func (m *MockObjectEncoder) AddByteString(arg0 string, arg1 []byte) { m.ctrl.T.Helper() m.ctrl.Call(m, "AddByteString", arg0, arg1) } -// AddByteString indicates an expected call of AddByteString +// AddByteString indicates an expected call of AddByteString. func (mr *MockObjectEncoderMockRecorder) AddByteString(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddByteString", reflect.TypeOf((*MockObjectEncoder)(nil).AddByteString), arg0, arg1) } -// AddComplex128 mocks base method +// AddComplex128 mocks base method. func (m *MockObjectEncoder) AddComplex128(arg0 string, arg1 complex128) { m.ctrl.T.Helper() m.ctrl.Call(m, "AddComplex128", arg0, arg1) } -// AddComplex128 indicates an expected call of AddComplex128 +// AddComplex128 indicates an expected call of AddComplex128. func (mr *MockObjectEncoderMockRecorder) AddComplex128(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddComplex128", reflect.TypeOf((*MockObjectEncoder)(nil).AddComplex128), arg0, arg1) } -// AddComplex64 mocks base method +// AddComplex64 mocks base method. func (m *MockObjectEncoder) AddComplex64(arg0 string, arg1 complex64) { m.ctrl.T.Helper() m.ctrl.Call(m, "AddComplex64", arg0, arg1) } -// AddComplex64 indicates an expected call of AddComplex64 +// AddComplex64 indicates an expected call of AddComplex64. func (mr *MockObjectEncoderMockRecorder) AddComplex64(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddComplex64", reflect.TypeOf((*MockObjectEncoder)(nil).AddComplex64), arg0, arg1) } -// AddDuration mocks base method +// AddDuration mocks base method. func (m *MockObjectEncoder) AddDuration(arg0 string, arg1 time.Duration) { m.ctrl.T.Helper() m.ctrl.Call(m, "AddDuration", arg0, arg1) } -// AddDuration indicates an expected call of AddDuration +// AddDuration indicates an expected call of AddDuration. func (mr *MockObjectEncoderMockRecorder) AddDuration(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddDuration", reflect.TypeOf((*MockObjectEncoder)(nil).AddDuration), arg0, arg1) } -// AddFloat32 mocks base method +// AddFloat32 mocks base method. func (m *MockObjectEncoder) AddFloat32(arg0 string, arg1 float32) { m.ctrl.T.Helper() m.ctrl.Call(m, "AddFloat32", arg0, arg1) } -// AddFloat32 indicates an expected call of AddFloat32 +// AddFloat32 indicates an expected call of AddFloat32. func (mr *MockObjectEncoderMockRecorder) AddFloat32(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddFloat32", reflect.TypeOf((*MockObjectEncoder)(nil).AddFloat32), arg0, arg1) } -// AddFloat64 mocks base method +// AddFloat64 mocks base method. func (m *MockObjectEncoder) AddFloat64(arg0 string, arg1 float64) { m.ctrl.T.Helper() m.ctrl.Call(m, "AddFloat64", arg0, arg1) } -// AddFloat64 indicates an expected call of AddFloat64 +// AddFloat64 indicates an expected call of AddFloat64. func (mr *MockObjectEncoderMockRecorder) AddFloat64(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddFloat64", reflect.TypeOf((*MockObjectEncoder)(nil).AddFloat64), arg0, arg1) } -// AddInt mocks base method +// AddInt mocks base method. func (m *MockObjectEncoder) AddInt(arg0 string, arg1 int) { m.ctrl.T.Helper() m.ctrl.Call(m, "AddInt", arg0, arg1) } -// AddInt indicates an expected call of AddInt +// AddInt indicates an expected call of AddInt. func (mr *MockObjectEncoderMockRecorder) AddInt(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddInt", reflect.TypeOf((*MockObjectEncoder)(nil).AddInt), arg0, arg1) } -// AddInt16 mocks base method +// AddInt16 mocks base method. func (m *MockObjectEncoder) AddInt16(arg0 string, arg1 int16) { m.ctrl.T.Helper() m.ctrl.Call(m, "AddInt16", arg0, arg1) } -// AddInt16 indicates an expected call of AddInt16 +// AddInt16 indicates an expected call of AddInt16. func (mr *MockObjectEncoderMockRecorder) AddInt16(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddInt16", reflect.TypeOf((*MockObjectEncoder)(nil).AddInt16), arg0, arg1) } -// AddInt32 mocks base method +// AddInt32 mocks base method. func (m *MockObjectEncoder) AddInt32(arg0 string, arg1 int32) { m.ctrl.T.Helper() m.ctrl.Call(m, "AddInt32", arg0, arg1) } -// AddInt32 indicates an expected call of AddInt32 +// AddInt32 indicates an expected call of AddInt32. func (mr *MockObjectEncoderMockRecorder) AddInt32(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddInt32", reflect.TypeOf((*MockObjectEncoder)(nil).AddInt32), arg0, arg1) } -// AddInt64 mocks base method +// AddInt64 mocks base method. func (m *MockObjectEncoder) AddInt64(arg0 string, arg1 int64) { m.ctrl.T.Helper() m.ctrl.Call(m, "AddInt64", arg0, arg1) } -// AddInt64 indicates an expected call of AddInt64 +// AddInt64 indicates an expected call of AddInt64. func (mr *MockObjectEncoderMockRecorder) AddInt64(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddInt64", reflect.TypeOf((*MockObjectEncoder)(nil).AddInt64), arg0, arg1) } -// AddInt8 mocks base method +// AddInt8 mocks base method. func (m *MockObjectEncoder) AddInt8(arg0 string, arg1 int8) { m.ctrl.T.Helper() m.ctrl.Call(m, "AddInt8", arg0, arg1) } -// AddInt8 indicates an expected call of AddInt8 +// AddInt8 indicates an expected call of AddInt8. func (mr *MockObjectEncoderMockRecorder) AddInt8(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddInt8", reflect.TypeOf((*MockObjectEncoder)(nil).AddInt8), arg0, arg1) } -// AddObject mocks base method +// AddObject mocks base method. func (m *MockObjectEncoder) AddObject(arg0 string, arg1 zapcore.ObjectMarshaler) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "AddObject", arg0, arg1) @@ -212,13 +213,13 @@ func (m *MockObjectEncoder) AddObject(arg0 string, arg1 zapcore.ObjectMarshaler) return ret0 } -// AddObject indicates an expected call of AddObject +// AddObject indicates an expected call of AddObject. func (mr *MockObjectEncoderMockRecorder) AddObject(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddObject", reflect.TypeOf((*MockObjectEncoder)(nil).AddObject), arg0, arg1) } -// AddReflected mocks base method +// AddReflected mocks base method. func (m *MockObjectEncoder) AddReflected(arg0 string, arg1 interface{}) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "AddReflected", arg0, arg1) @@ -226,144 +227,144 @@ func (m *MockObjectEncoder) AddReflected(arg0 string, arg1 interface{}) error { return ret0 } -// AddReflected indicates an expected call of AddReflected +// AddReflected indicates an expected call of AddReflected. func (mr *MockObjectEncoderMockRecorder) AddReflected(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddReflected", reflect.TypeOf((*MockObjectEncoder)(nil).AddReflected), arg0, arg1) } -// AddString mocks base method +// AddString mocks base method. func (m *MockObjectEncoder) AddString(arg0, arg1 string) { m.ctrl.T.Helper() m.ctrl.Call(m, "AddString", arg0, arg1) } -// AddString indicates an expected call of AddString +// AddString indicates an expected call of AddString. func (mr *MockObjectEncoderMockRecorder) AddString(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddString", reflect.TypeOf((*MockObjectEncoder)(nil).AddString), arg0, arg1) } -// AddTime mocks base method +// AddTime mocks base method. func (m *MockObjectEncoder) AddTime(arg0 string, arg1 time.Time) { m.ctrl.T.Helper() m.ctrl.Call(m, "AddTime", arg0, arg1) } -// AddTime indicates an expected call of AddTime +// AddTime indicates an expected call of AddTime. func (mr *MockObjectEncoderMockRecorder) AddTime(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddTime", reflect.TypeOf((*MockObjectEncoder)(nil).AddTime), arg0, arg1) } -// AddUint mocks base method +// AddUint mocks base method. func (m *MockObjectEncoder) AddUint(arg0 string, arg1 uint) { m.ctrl.T.Helper() m.ctrl.Call(m, "AddUint", arg0, arg1) } -// AddUint indicates an expected call of AddUint +// AddUint indicates an expected call of AddUint. func (mr *MockObjectEncoderMockRecorder) AddUint(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddUint", reflect.TypeOf((*MockObjectEncoder)(nil).AddUint), arg0, arg1) } -// AddUint16 mocks base method +// AddUint16 mocks base method. func (m *MockObjectEncoder) AddUint16(arg0 string, arg1 uint16) { m.ctrl.T.Helper() m.ctrl.Call(m, "AddUint16", arg0, arg1) } -// AddUint16 indicates an expected call of AddUint16 +// AddUint16 indicates an expected call of AddUint16. func (mr *MockObjectEncoderMockRecorder) AddUint16(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddUint16", reflect.TypeOf((*MockObjectEncoder)(nil).AddUint16), arg0, arg1) } -// AddUint32 mocks base method +// AddUint32 mocks base method. func (m *MockObjectEncoder) AddUint32(arg0 string, arg1 uint32) { m.ctrl.T.Helper() m.ctrl.Call(m, "AddUint32", arg0, arg1) } -// AddUint32 indicates an expected call of AddUint32 +// AddUint32 indicates an expected call of AddUint32. func (mr *MockObjectEncoderMockRecorder) AddUint32(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddUint32", reflect.TypeOf((*MockObjectEncoder)(nil).AddUint32), arg0, arg1) } -// AddUint64 mocks base method +// AddUint64 mocks base method. func (m *MockObjectEncoder) AddUint64(arg0 string, arg1 uint64) { m.ctrl.T.Helper() m.ctrl.Call(m, "AddUint64", arg0, arg1) } -// AddUint64 indicates an expected call of AddUint64 +// AddUint64 indicates an expected call of AddUint64. func (mr *MockObjectEncoderMockRecorder) AddUint64(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddUint64", reflect.TypeOf((*MockObjectEncoder)(nil).AddUint64), arg0, arg1) } -// AddUint8 mocks base method +// AddUint8 mocks base method. func (m *MockObjectEncoder) AddUint8(arg0 string, arg1 byte) { m.ctrl.T.Helper() m.ctrl.Call(m, "AddUint8", arg0, arg1) } -// AddUint8 indicates an expected call of AddUint8 +// AddUint8 indicates an expected call of AddUint8. func (mr *MockObjectEncoderMockRecorder) AddUint8(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddUint8", reflect.TypeOf((*MockObjectEncoder)(nil).AddUint8), arg0, arg1) } -// AddUintptr mocks base method +// AddUintptr mocks base method. func (m *MockObjectEncoder) AddUintptr(arg0 string, arg1 uintptr) { m.ctrl.T.Helper() m.ctrl.Call(m, "AddUintptr", arg0, arg1) } -// AddUintptr indicates an expected call of AddUintptr +// AddUintptr indicates an expected call of AddUintptr. func (mr *MockObjectEncoderMockRecorder) AddUintptr(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddUintptr", reflect.TypeOf((*MockObjectEncoder)(nil).AddUintptr), arg0, arg1) } -// OpenNamespace mocks base method +// OpenNamespace mocks base method. func (m *MockObjectEncoder) OpenNamespace(arg0 string) { m.ctrl.T.Helper() m.ctrl.Call(m, "OpenNamespace", arg0) } -// OpenNamespace indicates an expected call of OpenNamespace +// OpenNamespace indicates an expected call of OpenNamespace. func (mr *MockObjectEncoderMockRecorder) OpenNamespace(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OpenNamespace", reflect.TypeOf((*MockObjectEncoder)(nil).OpenNamespace), arg0) } -// MockArrayEncoder is a mock of ArrayEncoder interface +// MockArrayEncoder is a mock of ArrayEncoder interface. type MockArrayEncoder struct { ctrl *gomock.Controller recorder *MockArrayEncoderMockRecorder } -// MockArrayEncoderMockRecorder is the mock recorder for MockArrayEncoder +// MockArrayEncoderMockRecorder is the mock recorder for MockArrayEncoder. type MockArrayEncoderMockRecorder struct { mock *MockArrayEncoder } -// NewMockArrayEncoder creates a new mock instance +// NewMockArrayEncoder creates a new mock instance. func NewMockArrayEncoder(ctrl *gomock.Controller) *MockArrayEncoder { mock := &MockArrayEncoder{ctrl: ctrl} mock.recorder = &MockArrayEncoderMockRecorder{mock} return mock } -// EXPECT returns an object that allows the caller to indicate expected use +// EXPECT returns an object that allows the caller to indicate expected use. func (m *MockArrayEncoder) EXPECT() *MockArrayEncoderMockRecorder { return m.recorder } -// AppendArray mocks base method +// AppendArray mocks base method. func (m *MockArrayEncoder) AppendArray(arg0 zapcore.ArrayMarshaler) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "AppendArray", arg0) @@ -371,157 +372,157 @@ func (m *MockArrayEncoder) AppendArray(arg0 zapcore.ArrayMarshaler) error { return ret0 } -// AppendArray indicates an expected call of AppendArray +// AppendArray indicates an expected call of AppendArray. func (mr *MockArrayEncoderMockRecorder) AppendArray(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AppendArray", reflect.TypeOf((*MockArrayEncoder)(nil).AppendArray), arg0) } -// AppendBool mocks base method +// AppendBool mocks base method. func (m *MockArrayEncoder) AppendBool(arg0 bool) { m.ctrl.T.Helper() m.ctrl.Call(m, "AppendBool", arg0) } -// AppendBool indicates an expected call of AppendBool +// AppendBool indicates an expected call of AppendBool. func (mr *MockArrayEncoderMockRecorder) AppendBool(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AppendBool", reflect.TypeOf((*MockArrayEncoder)(nil).AppendBool), arg0) } -// AppendByteString mocks base method +// AppendByteString mocks base method. func (m *MockArrayEncoder) AppendByteString(arg0 []byte) { m.ctrl.T.Helper() m.ctrl.Call(m, "AppendByteString", arg0) } -// AppendByteString indicates an expected call of AppendByteString +// AppendByteString indicates an expected call of AppendByteString. func (mr *MockArrayEncoderMockRecorder) AppendByteString(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AppendByteString", reflect.TypeOf((*MockArrayEncoder)(nil).AppendByteString), arg0) } -// AppendComplex128 mocks base method +// AppendComplex128 mocks base method. func (m *MockArrayEncoder) AppendComplex128(arg0 complex128) { m.ctrl.T.Helper() m.ctrl.Call(m, "AppendComplex128", arg0) } -// AppendComplex128 indicates an expected call of AppendComplex128 +// AppendComplex128 indicates an expected call of AppendComplex128. func (mr *MockArrayEncoderMockRecorder) AppendComplex128(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AppendComplex128", reflect.TypeOf((*MockArrayEncoder)(nil).AppendComplex128), arg0) } -// AppendComplex64 mocks base method +// AppendComplex64 mocks base method. func (m *MockArrayEncoder) AppendComplex64(arg0 complex64) { m.ctrl.T.Helper() m.ctrl.Call(m, "AppendComplex64", arg0) } -// AppendComplex64 indicates an expected call of AppendComplex64 +// AppendComplex64 indicates an expected call of AppendComplex64. func (mr *MockArrayEncoderMockRecorder) AppendComplex64(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AppendComplex64", reflect.TypeOf((*MockArrayEncoder)(nil).AppendComplex64), arg0) } -// AppendDuration mocks base method +// AppendDuration mocks base method. func (m *MockArrayEncoder) AppendDuration(arg0 time.Duration) { m.ctrl.T.Helper() m.ctrl.Call(m, "AppendDuration", arg0) } -// AppendDuration indicates an expected call of AppendDuration +// AppendDuration indicates an expected call of AppendDuration. func (mr *MockArrayEncoderMockRecorder) AppendDuration(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AppendDuration", reflect.TypeOf((*MockArrayEncoder)(nil).AppendDuration), arg0) } -// AppendFloat32 mocks base method +// AppendFloat32 mocks base method. func (m *MockArrayEncoder) AppendFloat32(arg0 float32) { m.ctrl.T.Helper() m.ctrl.Call(m, "AppendFloat32", arg0) } -// AppendFloat32 indicates an expected call of AppendFloat32 +// AppendFloat32 indicates an expected call of AppendFloat32. func (mr *MockArrayEncoderMockRecorder) AppendFloat32(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AppendFloat32", reflect.TypeOf((*MockArrayEncoder)(nil).AppendFloat32), arg0) } -// AppendFloat64 mocks base method +// AppendFloat64 mocks base method. func (m *MockArrayEncoder) AppendFloat64(arg0 float64) { m.ctrl.T.Helper() m.ctrl.Call(m, "AppendFloat64", arg0) } -// AppendFloat64 indicates an expected call of AppendFloat64 +// AppendFloat64 indicates an expected call of AppendFloat64. func (mr *MockArrayEncoderMockRecorder) AppendFloat64(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AppendFloat64", reflect.TypeOf((*MockArrayEncoder)(nil).AppendFloat64), arg0) } -// AppendInt mocks base method +// AppendInt mocks base method. func (m *MockArrayEncoder) AppendInt(arg0 int) { m.ctrl.T.Helper() m.ctrl.Call(m, "AppendInt", arg0) } -// AppendInt indicates an expected call of AppendInt +// AppendInt indicates an expected call of AppendInt. func (mr *MockArrayEncoderMockRecorder) AppendInt(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AppendInt", reflect.TypeOf((*MockArrayEncoder)(nil).AppendInt), arg0) } -// AppendInt16 mocks base method +// AppendInt16 mocks base method. func (m *MockArrayEncoder) AppendInt16(arg0 int16) { m.ctrl.T.Helper() m.ctrl.Call(m, "AppendInt16", arg0) } -// AppendInt16 indicates an expected call of AppendInt16 +// AppendInt16 indicates an expected call of AppendInt16. func (mr *MockArrayEncoderMockRecorder) AppendInt16(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AppendInt16", reflect.TypeOf((*MockArrayEncoder)(nil).AppendInt16), arg0) } -// AppendInt32 mocks base method +// AppendInt32 mocks base method. func (m *MockArrayEncoder) AppendInt32(arg0 int32) { m.ctrl.T.Helper() m.ctrl.Call(m, "AppendInt32", arg0) } -// AppendInt32 indicates an expected call of AppendInt32 +// AppendInt32 indicates an expected call of AppendInt32. func (mr *MockArrayEncoderMockRecorder) AppendInt32(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AppendInt32", reflect.TypeOf((*MockArrayEncoder)(nil).AppendInt32), arg0) } -// AppendInt64 mocks base method +// AppendInt64 mocks base method. func (m *MockArrayEncoder) AppendInt64(arg0 int64) { m.ctrl.T.Helper() m.ctrl.Call(m, "AppendInt64", arg0) } -// AppendInt64 indicates an expected call of AppendInt64 +// AppendInt64 indicates an expected call of AppendInt64. func (mr *MockArrayEncoderMockRecorder) AppendInt64(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AppendInt64", reflect.TypeOf((*MockArrayEncoder)(nil).AppendInt64), arg0) } -// AppendInt8 mocks base method +// AppendInt8 mocks base method. func (m *MockArrayEncoder) AppendInt8(arg0 int8) { m.ctrl.T.Helper() m.ctrl.Call(m, "AppendInt8", arg0) } -// AppendInt8 indicates an expected call of AppendInt8 +// AppendInt8 indicates an expected call of AppendInt8. func (mr *MockArrayEncoderMockRecorder) AppendInt8(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AppendInt8", reflect.TypeOf((*MockArrayEncoder)(nil).AppendInt8), arg0) } -// AppendObject mocks base method +// AppendObject mocks base method. func (m *MockArrayEncoder) AppendObject(arg0 zapcore.ObjectMarshaler) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "AppendObject", arg0) @@ -529,13 +530,13 @@ func (m *MockArrayEncoder) AppendObject(arg0 zapcore.ObjectMarshaler) error { return ret0 } -// AppendObject indicates an expected call of AppendObject +// AppendObject indicates an expected call of AppendObject. func (mr *MockArrayEncoderMockRecorder) AppendObject(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AppendObject", reflect.TypeOf((*MockArrayEncoder)(nil).AppendObject), arg0) } -// AppendReflected mocks base method +// AppendReflected mocks base method. func (m *MockArrayEncoder) AppendReflected(arg0 interface{}) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "AppendReflected", arg0) @@ -543,103 +544,103 @@ func (m *MockArrayEncoder) AppendReflected(arg0 interface{}) error { return ret0 } -// AppendReflected indicates an expected call of AppendReflected +// AppendReflected indicates an expected call of AppendReflected. func (mr *MockArrayEncoderMockRecorder) AppendReflected(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AppendReflected", reflect.TypeOf((*MockArrayEncoder)(nil).AppendReflected), arg0) } -// AppendString mocks base method +// AppendString mocks base method. func (m *MockArrayEncoder) AppendString(arg0 string) { m.ctrl.T.Helper() m.ctrl.Call(m, "AppendString", arg0) } -// AppendString indicates an expected call of AppendString +// AppendString indicates an expected call of AppendString. func (mr *MockArrayEncoderMockRecorder) AppendString(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AppendString", reflect.TypeOf((*MockArrayEncoder)(nil).AppendString), arg0) } -// AppendTime mocks base method +// AppendTime mocks base method. func (m *MockArrayEncoder) AppendTime(arg0 time.Time) { m.ctrl.T.Helper() m.ctrl.Call(m, "AppendTime", arg0) } -// AppendTime indicates an expected call of AppendTime +// AppendTime indicates an expected call of AppendTime. func (mr *MockArrayEncoderMockRecorder) AppendTime(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AppendTime", reflect.TypeOf((*MockArrayEncoder)(nil).AppendTime), arg0) } -// AppendUint mocks base method +// AppendUint mocks base method. func (m *MockArrayEncoder) AppendUint(arg0 uint) { m.ctrl.T.Helper() m.ctrl.Call(m, "AppendUint", arg0) } -// AppendUint indicates an expected call of AppendUint +// AppendUint indicates an expected call of AppendUint. func (mr *MockArrayEncoderMockRecorder) AppendUint(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AppendUint", reflect.TypeOf((*MockArrayEncoder)(nil).AppendUint), arg0) } -// AppendUint16 mocks base method +// AppendUint16 mocks base method. func (m *MockArrayEncoder) AppendUint16(arg0 uint16) { m.ctrl.T.Helper() m.ctrl.Call(m, "AppendUint16", arg0) } -// AppendUint16 indicates an expected call of AppendUint16 +// AppendUint16 indicates an expected call of AppendUint16. func (mr *MockArrayEncoderMockRecorder) AppendUint16(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AppendUint16", reflect.TypeOf((*MockArrayEncoder)(nil).AppendUint16), arg0) } -// AppendUint32 mocks base method +// AppendUint32 mocks base method. func (m *MockArrayEncoder) AppendUint32(arg0 uint32) { m.ctrl.T.Helper() m.ctrl.Call(m, "AppendUint32", arg0) } -// AppendUint32 indicates an expected call of AppendUint32 +// AppendUint32 indicates an expected call of AppendUint32. func (mr *MockArrayEncoderMockRecorder) AppendUint32(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AppendUint32", reflect.TypeOf((*MockArrayEncoder)(nil).AppendUint32), arg0) } -// AppendUint64 mocks base method +// AppendUint64 mocks base method. func (m *MockArrayEncoder) AppendUint64(arg0 uint64) { m.ctrl.T.Helper() m.ctrl.Call(m, "AppendUint64", arg0) } -// AppendUint64 indicates an expected call of AppendUint64 +// AppendUint64 indicates an expected call of AppendUint64. func (mr *MockArrayEncoderMockRecorder) AppendUint64(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AppendUint64", reflect.TypeOf((*MockArrayEncoder)(nil).AppendUint64), arg0) } -// AppendUint8 mocks base method +// AppendUint8 mocks base method. func (m *MockArrayEncoder) AppendUint8(arg0 byte) { m.ctrl.T.Helper() m.ctrl.Call(m, "AppendUint8", arg0) } -// AppendUint8 indicates an expected call of AppendUint8 +// AppendUint8 indicates an expected call of AppendUint8. func (mr *MockArrayEncoderMockRecorder) AppendUint8(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AppendUint8", reflect.TypeOf((*MockArrayEncoder)(nil).AppendUint8), arg0) } -// AppendUintptr mocks base method +// AppendUintptr mocks base method. func (m *MockArrayEncoder) AppendUintptr(arg0 uintptr) { m.ctrl.T.Helper() m.ctrl.Call(m, "AppendUintptr", arg0) } -// AppendUintptr indicates an expected call of AppendUintptr +// AppendUintptr indicates an expected call of AppendUintptr. func (mr *MockArrayEncoderMockRecorder) AppendUintptr(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AppendUintptr", reflect.TypeOf((*MockArrayEncoder)(nil).AppendUintptr), arg0) diff --git a/gen/namespace.go b/gen/namespace.go index dbd53ca5..f8e34384 100644 --- a/gen/namespace.go +++ b/gen/namespace.go @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Uber Technologies, Inc. +// Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/gen/plugin.go b/gen/plugin.go index 3ba0b645..bb56d7a2 100644 --- a/gen/plugin.go +++ b/gen/plugin.go @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Uber Technologies, Inc. +// Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/gen/quick_test.go b/gen/quick_test.go index e9478acd..6c072897 100644 --- a/gen/quick_test.go +++ b/gen/quick_test.go @@ -535,6 +535,11 @@ func TestQuickSuite(t *testing.T) { Generator: enumValueGenerator(te.EnumWithValues_Values), Kind: thriftEnum, }, + { + Sample: te.EnumWithHexValues(0), + Generator: enumValueGenerator(te.EnumWithHexValues_Values), + Kind: thriftEnum, + }, { Sample: te.LowerCaseEnum(0), Generator: enumValueGenerator(te.LowerCaseEnum_Values), @@ -785,22 +790,16 @@ func (q *quickSuite) testThriftRoundTripStreaming(t *testing.T, give, defaults t want := populateDefaults(give, defaults) shouldCheckForMutation := defaults != nil && !assert.ObjectsAreEqual(want, give) - sGive, ok := give.(streamingThriftType) - require.True(t, ok, "given thrift type must satisfy streaming requirements") - - sWant, ok := want.(streamingThriftType) - require.True(t, ok, "default thrift type must satisfy streaming requirements") - sw := binary.NewStreamWriter(&buf) - require.NoError(t, sGive.Encode(sw), "failed to streaming encode %v", sGive) + require.NoError(t, give.Encode(sw), "failed to streaming encode %v", give) require.NoError(t, sw.Close()) - gType := reflect.TypeOf(sGive) + gType := reflect.TypeOf(give) if gType.Kind() == reflect.Ptr { gType = gType.Elem() } - got := reflect.New(gType).Interface().(streamingThriftType) + got := reflect.New(gType).Interface().(thriftType) sr := binary.NewStreamReader(&buf) require.NoError(t, got.Decode(sr), "failed to streaming decode from %v", buf) @@ -809,7 +808,7 @@ func (q *quickSuite) testThriftRoundTripStreaming(t *testing.T, give, defaults t assert.Equal(t, want, got) if shouldCheckForMutation { // assert that give has not been mutated to the want object during the ToWire call - assert.NotEqual(t, sWant, sGive) + assert.NotEqual(t, want, give) } } diff --git a/gen/roundtrip_test.go b/gen/roundtrip_test.go index 0800aa50..f500490a 100644 --- a/gen/roundtrip_test.go +++ b/gen/roundtrip_test.go @@ -110,9 +110,7 @@ func testRoundTripCombos(t *testing.T, x thriftType, v wire.Value, msg string) { if streaming.encode { w := binary.NewStreamWriter(&buff) - give, ok := x.(streamingThriftType) - require.True(t, ok) - require.NoError(t, give.Encode(w), "%v: failed to stream encode", msg) + require.NoError(t, x.Encode(w), "%v: failed to stream encode", msg) require.NoError(t, w.Close()) } else { w, err := x.ToWire() @@ -123,9 +121,8 @@ func testRoundTripCombos(t *testing.T, x thriftType, v wire.Value, msg string) { if streaming.decode { reader := streamer.Reader(bytes.NewReader(buff.Bytes())) - gotX, ok := reflect.New(xType).Interface().(streamingThriftType) - require.True(t, ok) + gotX := reflect.New(xType).Interface().(thriftType) require.NoError(t, gotX.Decode(reader), "streaming decode") assert.Equal(t, x, gotX) } else { diff --git a/gen/service.go b/gen/service.go index c257f3c3..7f65c4b1 100644 --- a/gen/service.go +++ b/gen/service.go @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Uber Technologies, Inc. +// Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal @@ -122,7 +122,7 @@ func ServiceFunction(g Generator, s *compile.ServiceSpec, f *compile.FunctionSpe resultName, s.Name, f.Name, f.Name, ) if f.ResultSpec.ReturnType != nil { - resultDoc += fmt.Sprintf("\n\nSuccess is set only if the function did not throw an exception.") + resultDoc += "\n\nSuccess is set only if the function did not throw an exception." } resultGen := fieldGroupGenerator{ diff --git a/gen/service_test.go b/gen/service_test.go index 9b09f775..2bc34320 100644 --- a/gen/service_test.go +++ b/gen/service_test.go @@ -24,6 +24,7 @@ import ( "bytes" "errors" "fmt" + "io/ioutil" "reflect" "testing" @@ -31,7 +32,9 @@ import ( tx "go.uber.org/thriftrw/gen/internal/tests/exceptions" tv "go.uber.org/thriftrw/gen/internal/tests/services" tu "go.uber.org/thriftrw/gen/internal/tests/unions" + "go.uber.org/thriftrw/protocol" "go.uber.org/thriftrw/protocol/binary" + "go.uber.org/thriftrw/protocol/stream" "go.uber.org/thriftrw/ptr" "go.uber.org/thriftrw/wire" @@ -43,8 +46,7 @@ import ( type serviceType interface { fmt.Stringer envelope.Enveloper - - FromWire(wire.Value) error + thriftType } func TestServiceArgsAndResult(t *testing.T) { @@ -514,25 +516,29 @@ func TestServiceTypesEnveloper(t *testing.T) { require.NoError(t, err, "Failed to get successful GetValue response") tests := []struct { + desc string s envelope.Enveloper wantEnvelope wire.Envelope }{ { - s: tv.KeyValue_GetValue_Helper.Args((*tv.Key)(stringp("foo"))), + desc: "'getValue' call", + s: tv.KeyValue_GetValue_Helper.Args((*tv.Key)(stringp("foo"))), wantEnvelope: wire.Envelope{ Name: "getValue", Type: wire.Call, }, }, { - s: getResponse, + desc: "reply, with wrapped response", + s: getResponse, wantEnvelope: wire.Envelope{ Name: "getValue", Type: wire.Reply, }, }, { - s: tv.KeyValue_DeleteValue_Helper.Args((*tv.Key)(stringp("foo"))), + desc: "'deleteValue' call", + s: tv.KeyValue_DeleteValue_Helper.Args((*tv.Key)(stringp("foo"))), wantEnvelope: wire.Envelope{ Name: "deleteValue", Type: wire.Call, @@ -541,21 +547,60 @@ func TestServiceTypesEnveloper(t *testing.T) { } for _, tt := range tests { - buf := &bytes.Buffer{} - err := envelope.Write(binary.Default, buf, 1234, tt.s) - require.NoError(t, err, "envelope.Write for %v failed", tt) - - // Decode the payload and validate the payload. - reader := bytes.NewReader(buf.Bytes()) - envelope, err := binary.Default.DecodeEnveloped(reader) - require.NoError(t, err, "Failed to read enveloped data for %v", tt) - - expected := tt.wantEnvelope - expected.SeqID = 1234 - expected.Value, err = tt.s.ToWire() - if assert.NoError(t, err, "Error serializing %v", tt.s) { + t.Run(tt.desc+"/wire", func(t *testing.T) { + buf := &bytes.Buffer{} + err := envelope.Write(binary.Default, buf, 1234, tt.s) + require.NoError(t, err, "envelope.Write for %v failed", tt) + + // Decode the payload and validate the payload. + reader := bytes.NewReader(buf.Bytes()) + envelope, err := binary.Default.DecodeEnveloped(reader) + require.NoError(t, err, "Failed to read enveloped data for %v", tt) + + expected := tt.wantEnvelope + expected.SeqID = 1234 + expected.Value, err = tt.s.ToWire() + require.NoError(t, err, "Error serializing %v", tt.s) assert.Equal(t, expected, envelope, "Envelope mismatch for %v", tt) - } + }) + + t.Run(tt.desc+"/stream", func(t *testing.T) { + buf := &bytes.Buffer{} + wantEh := stream.EnvelopeHeader{ + Name: tt.s.MethodName(), + SeqID: 1234, + } + + sw := protocol.BinaryStreamer.Writer(buf) + defer func() { + assert.NoError(t, sw.Close()) + }() + + require.NoError(t, sw.WriteEnvelopeBegin(wantEh)) + require.NoError(t, tt.s.(stream.Enveloper).Encode(sw)) + require.NoError(t, sw.WriteEnvelopeEnd()) + + reader := bytes.NewReader(buf.Bytes()) + sr := protocol.BinaryStreamer.Reader(reader) + defer func() { + assert.NoError(t, sr.Close()) + }() + + gotEh, err := sr.ReadEnvelopeBegin() + require.NoError(t, err) + assert.Equal(t, wantEh, gotEh) + + sType := reflect.TypeOf(tt.s) + if sType.Kind() == reflect.Ptr { + sType = sType.Elem() + } + + gotS := reflect.New(sType).Interface().(stream.BodyReader) + require.NoError(t, gotS.Decode(sr)) + assert.Equal(t, tt.s, gotS) + + require.NoError(t, sr.ReadEnvelopeEnd()) + }) } } @@ -654,27 +699,49 @@ func TestArgsAndResultValidation(t *testing.T) { } for _, tt := range tests { - var typ reflect.Type - if tt.serialize != nil { - typ = reflect.TypeOf(tt.serialize).Elem() - v, err := tt.serialize.ToWire() - if err == nil { - err = wire.EvaluateValue(v) + t.Run(tt.desc, func(t *testing.T) { + var typ reflect.Type + if tt.serialize != nil { + typ = reflect.TypeOf(tt.serialize).Elem() + + t.Run("WireEncode", func(t *testing.T) { + v, err := tt.serialize.ToWire() + if err == nil { + err = wire.EvaluateValue(v) + } + require.Error(t, err) + assert.Contains(t, err.Error(), tt.wantError) + }) + + t.Run("StreamEncode", func(t *testing.T) { + sw := binary.Default.Writer(ioutil.Discard) + defer sw.Close() + + err := tt.serialize.Encode(sw) + require.Error(t, err) + assert.Contains(t, err.Error(), tt.wantError) + }) + } else { + typ = tt.typ } - if assert.Error(t, err, "%v: expected failure but got %v", tt.desc, v) { - assert.Contains(t, err.Error(), tt.wantError, tt.desc) + + if typ == nil { + t.Fatalf("invalid test %q: either typ or serialize must be set", tt.desc) } - } else { - typ = tt.typ - } - if typ == nil { - t.Fatalf("invalid test %q: either typ or serialize must be set", tt.desc) - } + t.Run("WireDecode", func(t *testing.T) { + x := reflect.New(typ).Interface().(serviceType) + err := x.FromWire(tt.deserialize) + require.Error(t, err) + assert.Contains(t, err.Error(), tt.wantError) + }) - x := reflect.New(typ).Interface().(serviceType) - if err := x.FromWire(tt.deserialize); assert.Errorf(t, err, "%v: expected failure but got %v", tt.desc, x) { - assert.Contains(t, err.Error(), tt.wantError, tt.desc) - } + t.Run("StreamDecode", func(t *testing.T) { + x := reflect.New(typ).Interface().(serviceType) + err := streamDecodeWireType(t, tt.deserialize, x) + require.Error(t, err) + assert.Contains(t, err.Error(), tt.wantError) + }) + }) } } diff --git a/gen/set.go b/gen/set.go index fc760460..b3d82685 100644 --- a/gen/set.go +++ b/gen/set.go @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Uber Technologies, Inc. +// Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/gen/sort.go b/gen/sort.go index c39cb7ec..aaaaf59a 100644 --- a/gen/sort.go +++ b/gen/sort.go @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Uber Technologies, Inc. +// Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal @@ -21,7 +21,6 @@ package gen import ( - "fmt" "reflect" "sort" ) @@ -31,8 +30,7 @@ func sortStringKeys(m interface{}) []string { v := reflect.ValueOf(m) t := v.Type() if t.Kind() != reflect.Map || t.Key().Kind() != reflect.String { - panic(fmt.Sprintf( - "sortStringKeys may be called with a map[string]* only")) + panic("sortStringKeys may be called with a map[string]* only") } keys := v.MapKeys() diff --git a/gen/stream.go b/gen/stream.go index f369a551..7d2ec56d 100644 --- a/gen/stream.go +++ b/gen/stream.go @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Uber Technologies, Inc. +// Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/gen/string.go b/gen/string.go index 62bd9b3d..83e2b681 100644 --- a/gen/string.go +++ b/gen/string.go @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Uber Technologies, Inc. +// Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/gen/struct.go b/gen/struct.go index 7687bf72..3902dd12 100644 --- a/gen/struct.go +++ b/gen/struct.go @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Uber Technologies, Inc. +// Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/gen/struct_test.go b/gen/struct_test.go index b09e3b09..9a082733 100644 --- a/gen/struct_test.go +++ b/gen/struct_test.go @@ -21,9 +21,9 @@ package gen import ( - "bytes" "encoding/json" "fmt" + "io/ioutil" "reflect" "testing" @@ -596,11 +596,21 @@ func TestPrimitiveRequiredMissingFields(t *testing.T) { } for _, tt := range tests { - var s ts.PrimitiveRequiredStruct - err := s.FromWire(tt.v) - if assert.Error(t, err, tt.desc) { - assert.Contains(t, err.Error(), tt.wantError, tt.desc) - } + t.Run(tt.desc+"/wire", func(t *testing.T) { + var s ts.PrimitiveRequiredStruct + err := s.FromWire(tt.v) + if assert.Error(t, err, tt.desc) { + assert.Contains(t, err.Error(), tt.wantError, tt.desc) + } + }) + + t.Run(tt.desc+"/streaming", func(t *testing.T) { + var s ts.PrimitiveRequiredStruct + err := streamDecodeWireType(t, tt.v, &s) + if assert.Error(t, err, tt.desc) { + assert.Contains(t, err.Error(), tt.wantError, tt.desc) + } + }) } } @@ -757,18 +767,8 @@ func TestStructFromWireUnrecognizedField(t *testing.T) { }) t.Run(tt.desc+"/streaming", func(t *testing.T) { - var ( - o ts.ContactInfo - buf bytes.Buffer - ) - - require.NoError(t, binary.Default.Encode(tt.give, &buf)) - - r := bytes.NewReader(buf.Bytes()) - sr := binary.Default.Reader(r) - defer sr.Close() - - err := o.Decode(sr) + var o ts.ContactInfo + err := streamDecodeWireType(t, tt.give, &o) if tt.wantError != "" { if assert.Error(t, err, tt.desc) { assert.Contains(t, err.Error(), tt.wantError) @@ -778,8 +778,6 @@ func TestStructFromWireUnrecognizedField(t *testing.T) { assert.Equal(t, tt.want, o) } } - - assert.Zero(t, r.Len(), "expected to be at end of read") }) } } @@ -831,7 +829,7 @@ func TestUnionFromWireInconsistencies(t *testing.T) { } for _, tt := range tests { - t.Run(tt.desc+"/streaming", func(t *testing.T) { + t.Run(tt.desc+"/wire", func(t *testing.T) { var o tu.Document err := o.FromWire(tt.input) if tt.success != nil { @@ -846,18 +844,8 @@ func TestUnionFromWireInconsistencies(t *testing.T) { }) t.Run(tt.desc+"/streaming", func(t *testing.T) { - var ( - o tu.Document - buf bytes.Buffer - ) - - require.NoError(t, binary.Default.Encode(tt.input, &buf)) - - r := bytes.NewReader(buf.Bytes()) - sr := binary.Default.Reader(r) - defer sr.Close() - - err := o.Decode(sr) + var o tu.Document + err := streamDecodeWireType(t, tt.input, &o) if tt.success != nil { if assert.NoError(t, err, tt.desc) { assert.Equal(t, tt.success, &o, tt.desc) @@ -867,8 +855,6 @@ func TestUnionFromWireInconsistencies(t *testing.T) { assert.Contains(t, err.Error(), tt.failure, tt.desc) } } - - assert.Zero(t, r.Len(), "expected to be at end of read") }) } } @@ -1098,6 +1084,11 @@ func TestStructWithDefaults(t *testing.T) { if err := gotFromWire.FromWire(tt.giveWire); assert.NoError(t, err) { assert.Equal(t, tt.wantFromWire, &gotFromWire) } + + var sGotFromWire ts.DefaultsStruct + if err := streamDecodeWireType(t, tt.giveWire, &sGotFromWire); assert.NoError(t, err) { + assert.Equal(t, tt.wantFromWire, &sGotFromWire) + } } } @@ -1812,28 +1803,49 @@ func TestStructValidation(t *testing.T) { } for _, tt := range tests { - var typ reflect.Type - if tt.serialize != nil { - typ = reflect.TypeOf(tt.serialize).Elem() - v, err := tt.serialize.ToWire() - if err == nil { - err = wire.EvaluateValue(v) + t.Run(tt.desc, func(t *testing.T) { + var typ reflect.Type + if tt.serialize != nil { + typ = reflect.TypeOf(tt.serialize).Elem() + t.Run("ToWire", func(t *testing.T) { + v, err := tt.serialize.ToWire() + if err == nil { + err = wire.EvaluateValue(v) + } + require.Error(t, err) + assert.Contains(t, err.Error(), tt.wantError) + }) + + t.Run("StreamEncode", func(t *testing.T) { + sw := binary.Default.Writer(ioutil.Discard) + defer sw.Close() + + err := tt.serialize.Encode(sw) + require.Error(t, err) + assert.Contains(t, err.Error(), tt.wantError) + }) + } else { + typ = tt.typ } - if assert.Error(t, err, "%v: expected failure but got %v", tt.desc, v) { - assert.Contains(t, err.Error(), tt.wantError, tt.desc) + + if typ == nil { + t.Fatalf("invalid test %q: either typ or serialize must be set", tt.desc) } - } else { - typ = tt.typ - } - if typ == nil { - t.Fatalf("invalid test %q: either typ or serialize must be set", tt.desc) - } + t.Run("FromWire", func(t *testing.T) { + x := reflect.New(typ).Interface().(thriftType) + err := x.FromWire(tt.deserialize) + require.Error(t, err) + assert.Contains(t, err.Error(), tt.wantError) + }) - x := reflect.New(typ).Interface().(thriftType) - if err := x.FromWire(tt.deserialize); assert.Error(t, err, "%v: expected failure but got %v", tt.desc, x) { - assert.Contains(t, err.Error(), tt.wantError, tt.desc) - } + t.Run("StreamDecode", func(t *testing.T) { + x := reflect.New(typ).Interface().(thriftType) + err := streamDecodeWireType(t, tt.deserialize, x) + require.Error(t, err) + assert.Contains(t, err.Error(), tt.wantError) + }) + }) } } @@ -2075,6 +2087,10 @@ func TestEmptyPrimitivesRoundTrip(t *testing.T) { var got ts.PrimitiveRequiredStruct require.NoError(t, got.FromWire(v), "failed to convert from wire.Value") assert.Equal(t, give, got) + + var sGot ts.PrimitiveRequiredStruct + require.NoError(t, streamDecodeWireType(t, v, &sGot), "failed to stream deserialize") + assert.Equal(t, give, sGot) }) t.Run("optional", func(t *testing.T) { @@ -2103,6 +2119,10 @@ func TestEmptyPrimitivesRoundTrip(t *testing.T) { var got ts.PrimitiveOptionalStruct require.NoError(t, got.FromWire(v), "failed to convert from wire.Value") assert.Equal(t, give, got) + + var sGot ts.PrimitiveOptionalStruct + require.NoError(t, streamDecodeWireType(t, v, &sGot), "failed to stream deserialize") + assert.Equal(t, give, sGot) }) } diff --git a/gen/type.go b/gen/type.go index b0a2502b..ea787805 100644 --- a/gen/type.go +++ b/gen/type.go @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Uber Technologies, Inc. +// Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal @@ -74,6 +74,13 @@ func isPrimitiveType(spec compile.TypeSpec) bool { return isEnum } +// isStringType returns true if the given type is a string type +func isStringType(spec compile.TypeSpec) bool { + spec = compile.RootTypeSpec(spec) + _, ok := spec.(*compile.StringSpec) + return ok +} + // isReferenceType checks if the given TypeSpec represents a reference type. // // Sets, maps, lists, and slices are reference types. diff --git a/gen/typedef.go b/gen/typedef.go index 21d7b3a9..ed1447d4 100644 --- a/gen/typedef.go +++ b/gen/typedef.go @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Uber Technologies, Inc. +// Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal @@ -112,7 +112,11 @@ func typedef(g Generator, spec *compile.TypedefSpec) error { // String returns a readable string representation of . func (<$v> <$typedefType>) String() string { <$x> := ()(<$v>) - return <$fmt>.Sprint(<$x>) + + return <$x> + <- else -> + return <$fmt>.Sprint(<$x>) + <- end> } func (<$v> <$typedefType>) Encode(<$sw> <$stream>.Writer) error { diff --git a/gen/util_for_test.go b/gen/util_for_test.go index dbbff235..1f1dddbe 100644 --- a/gen/util_for_test.go +++ b/gen/util_for_test.go @@ -21,8 +21,13 @@ package gen import ( + "bytes" "fmt" + "testing" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "go.uber.org/thriftrw/protocol/binary" "go.uber.org/thriftrw/protocol/stream" "go.uber.org/thriftrw/wire" ) @@ -37,14 +42,28 @@ type thriftType interface { ToWire() (wire.Value, error) FromWire(wire.Value) error + Encode(stream.Writer) error + Decode(stream.Reader) error } -// streamingThriftType is implemented by all generated types that know how to -// write and read themselves to the Thrift Protocol, skipping over the -// intermediary wire.Type -type streamingThriftType interface { - thriftType +func streamDecodeWireType(t *testing.T, wv wire.Value, tt thriftType) error { + t.Helper() - Encode(stream.Writer) error - Decode(stream.Reader) error + var buf bytes.Buffer + require.NoError(t, binary.Default.Encode(wv, &buf)) + + r := bytes.NewReader(buf.Bytes()) + sr := binary.Default.Reader(r) + defer func() { + assert.NoError(t, sr.Close()) + }() + + err := tt.Decode(sr) + if err == nil { + // We expect to read the entire payload only if it was a valid + // request. Invalid requests may return early because, say, one + // of the fields failed to decode because it was invalid. + assert.Zero(t, r.Len(), "expected to be end of read") + } + return err } diff --git a/gen/version.go b/gen/version.go index 5bd3635f..7bbad94d 100644 --- a/gen/version.go +++ b/gen/version.go @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Uber Technologies, Inc. +// Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/gen/wire.go b/gen/wire.go index 701271da..42b1bdf6 100644 --- a/gen/wire.go +++ b/gen/wire.go @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Uber Technologies, Inc. +// Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/gen/zap.go b/gen/zap.go index dd19a2ee..038956ff 100644 --- a/gen/zap.go +++ b/gen/zap.go @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Uber Technologies, Inc. +// Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/go.mod b/go.mod index 3e58f17f..33829b73 100644 --- a/go.mod +++ b/go.mod @@ -1,20 +1,46 @@ module go.uber.org/thriftrw -go 1.13 +go 1.17 require ( github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239 - github.com/fatih/structtag v1.0.0 - github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568 // indirect - github.com/golang/mock v1.2.0 - github.com/jessevdk/go-flags v1.4.0 - github.com/kr/pretty v0.1.0 - github.com/pkg/errors v0.8.1 // indirect - github.com/stretchr/testify v1.4.0 + github.com/fatih/structtag v1.2.0 + github.com/go-git/go-git/v5 v5.4.2 + github.com/golang/mock v1.6.0 + github.com/jessevdk/go-flags v1.5.0 + github.com/kr/pretty v0.2.1 + github.com/stretchr/testify v1.7.0 go.uber.org/atomic v1.3.2 go.uber.org/multierr v1.1.0 go.uber.org/zap v1.9.1 golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f - golang.org/x/tools v0.1.5 - honnef.co/go/tools v0.0.1-2019.2.3 + golang.org/x/tools v0.1.10 + honnef.co/go/tools v0.3.0-0.dev.0.20220306074811-23e1086441d2 +) + +require ( + github.com/BurntSushi/toml v1.0.0 // indirect + github.com/Microsoft/go-winio v0.4.16 // indirect + github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7 // indirect + github.com/acomagu/bufpipe v1.0.3 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/emirpasic/gods v1.12.0 // indirect + github.com/go-git/gcfg v1.5.0 // indirect + github.com/go-git/go-billy/v5 v5.3.1 // indirect + github.com/imdario/mergo v0.3.12 // indirect + github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect + github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351 // indirect + github.com/kr/text v0.2.0 // indirect + github.com/mitchellh/go-homedir v1.1.0 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/sergi/go-diff v1.1.0 // indirect + github.com/xanzy/ssh-agent v0.3.0 // indirect + golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 // indirect + golang.org/x/exp/typeparams v0.0.0-20220314205449-43aec2f8a4e7 // indirect + golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3 // indirect + golang.org/x/net v0.7.0 // indirect + golang.org/x/sys v0.5.0 // indirect + golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect + gopkg.in/warnings.v0 v0.1.2 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 299f4fd5..eb294f60 100644 --- a/go.sum +++ b/go.sum @@ -1,77 +1,173 @@ -github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= -github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/BurntSushi/toml v0.4.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= +github.com/BurntSushi/toml v1.0.0 h1:dtDWrepsVPfW9H/4y7dDgFc2MBUSeJhlaDtK13CxFlU= +github.com/BurntSushi/toml v1.0.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= +github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA= +github.com/Microsoft/go-winio v0.4.16 h1:FtSW/jqD+l4ba5iPBj9CODVtgfYAD8w2wS923g/cFDk= +github.com/Microsoft/go-winio v0.4.16/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0= +github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7 h1:YoJbenK9C67SkzkDfmQuVln04ygHj3vjZfd9FL+GmQQ= +github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7/go.mod h1:z4/9nQmJSSwwds7ejkxaJwO37dru3geImFUdJlaLzQo= +github.com/acomagu/bufpipe v1.0.3 h1:fxAGrHZTgQ9w5QqVItgzwj235/uYZYgbXitB+dLupOk= +github.com/acomagu/bufpipe v1.0.3/go.mod h1:mxdxdup/WdsKVreO5GpW4+M/1CE2sMG4jeGJ2sYmHc4= github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239 h1:kFOfPq6dUM1hTo4JG6LR5AXSUEsOjtdm0kw0FtQtMJA= github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= -github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= +github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= +github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/fatih/structtag v1.0.0 h1:pTHj65+u3RKWYPSGaU290FpI/dXxTaHdVwVwbcPKmEc= -github.com/fatih/structtag v1.0.0/go.mod h1:IKitwq45uXL/yqi5mYghiD3w9H6eTOvI9vnk8tXMphA= +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/emirpasic/gods v1.12.0 h1:QAUIPSaCu4G+POclxeqb3F+WPpdKqFGlw36+yOzGlrg= +github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o= +github.com/fatih/structtag v1.2.0 h1:/OdNE99OxoI/PqaW/SuSK9uxxT3f/tcSZgon/ssNSx4= +github.com/fatih/structtag v1.2.0/go.mod h1:mBJUNpUnHmRKrKlQQlmCrh5PuhftFbNv8Ys4/aAZl94= github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568 h1:BHsljHzVlRcyQhjrss6TZTdY2VfCqZPbv5k3iBFa2ZQ= github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= -github.com/golang/mock v1.2.0 h1:28o5sBqPkBsMGnC6b4MvE2TzSr5/AT4c/1fLqVGIwlk= -github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= -github.com/jessevdk/go-flags v1.4.0 h1:4IU2WS7AumrZ/40jfhf4QVDMsQwqA7VEHozFRrGARJA= -github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= -github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= +github.com/gliderlabs/ssh v0.2.2 h1:6zsha5zo/TWhRhwqCD3+EarCAgZ2yN28ipRnGPnwkI0= +github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= +github.com/go-git/gcfg v1.5.0 h1:Q5ViNfGF8zFgyJWPqYwA7qGFoMTEiBmdlkcfRmpIMa4= +github.com/go-git/gcfg v1.5.0/go.mod h1:5m20vg6GwYabIxaOonVkTdrILxQMpEShl1xiMF4ua+E= +github.com/go-git/go-billy/v5 v5.2.0/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0= +github.com/go-git/go-billy/v5 v5.3.1 h1:CPiOUAzKtMRvolEKw+bG1PLRpT7D3LIs3/3ey4Aiu34= +github.com/go-git/go-billy/v5 v5.3.1/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0= +github.com/go-git/go-git-fixtures/v4 v4.2.1 h1:n9gGL1Ct/yIw+nfsfr8s4+sbhT+Ncu2SubfXjIWgci8= +github.com/go-git/go-git-fixtures/v4 v4.2.1/go.mod h1:K8zd3kDUAykwTdDCr+I0per6Y6vMiRR/nnVTBtavnB0= +github.com/go-git/go-git/v5 v5.4.2 h1:BXyZu9t0VkbiHtqrsvdq39UDhGJTl1h55VW6CSC4aY4= +github.com/go-git/go-git/v5 v5.4.2/go.mod h1:gQ1kArt6d+n+BGd+/B/I74HwRTLhth2+zti4ihgckDc= +github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= +github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= +github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU= +github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= +github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= +github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= +github.com/jessevdk/go-flags v1.5.0 h1:1jKYvbxEjfUl0fmqTCOfonvskHHXMjBySTLW4y9LFvc= +github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4= +github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351 h1:DowS9hvgyYSX4TO5NpyC606/Z4SxnNYbT+WX27or6Ck= +github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/matryer/is v1.2.0 h1:92UTHpy8CDwaJ08GqLDzhhuixiBUUD1p3AU6PHddz4A= +github.com/matryer/is v1.2.0/go.mod h1:2fLPjFQM9rhQ15aVEtbuwhJinnOqrmgXPNdZsdwlWXA= +github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= +github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 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/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0= +github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= +github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= +github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/xanzy/ssh-agent v0.3.0 h1:wUMzuKtKilRgBAD1sUb8gOwwRr2FGoBVumcjoOACClI= +github.com/xanzy/ssh-agent v0.3.0/go.mod h1:3s9xbODqPuuhK9JV1R321M/FlMZSBvE5aY6eAcqrDh0= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= go.uber.org/atomic v1.3.2 h1:2Oa65PReHzfn29GpvgsYwloV9AVFHPDk8tYxt2c2tr4= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/multierr v1.1.0 h1:HoEmRHQPVSqub6w2z2d2EOVs2fjyFRGyofhKuyDq0QI= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/zap v1.9.1 h1:XCJQEf3W6eZaVwhRBof6ImoYGJSITeKWsyeh3HFu/5o= go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= +golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 h1:7I4JAnoQBe7ZtJcBaYHi5UtiO8tQHbUSXxL+pnGRANg= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/exp/typeparams v0.0.0-20220218215828-6cf2b201936e/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= +golang.org/x/exp/typeparams v0.0.0-20220314205449-43aec2f8a4e7 h1:mzVEuUhnztMdHb426A1o6cjz5ha6YV3t6zFTBXqSon4= +golang.org/x/exp/typeparams v0.0.0-20220314205449-43aec2f8a4e7/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f h1:J5lckAjkw6qYlOZNj90mLYNTEKDvWeuc1yieZ8qUzUE= golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= -golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= -golang.org/x/mod v0.4.2 h1:Gz96sIWK3OalVv/I/qNygP42zyoKp3xptRVCWRFEBvo= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= +golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3 h1:kQgndtyPBW/JIYERgdxfwMYh3AVStj88WQTlNDi2a+o= +golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210326060303-6b1517762897/go.mod h1:uSPa2vr4CLtc/ILN5odXGNXS6mhrKVzTaCXzk9m6W3k= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g= +golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210510120138-977fb7262007 h1:gG67DSER+11cZvqIMb8S8bt0vZtiN6xWYARwirrOSfE= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210502180810-71e4cd670f79/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.5.0 h1:n2a8QNdAb0sZNpU9R1ALUXBbY+w51fCQDN+7EdxNBsY= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.1.5 h1:ouewzE6p+/VEB31YYnTbEJdi8pFqKp4P4n85vwo3DHA= -golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.8/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= +golang.org/x/tools v0.1.10 h1:QjFRCZxdOhBJ/UNgnBZLbNV13DlbnK0quyivTnXJM20= +golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= +golang.org/x/tools v0.1.12 h1:VveCTK38A2rkS8ZqFY25HIDFscX5X9OoEhJd3quQmXU= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= -gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME= +gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -honnef.co/go/tools v0.0.1-2019.2.3 h1:3JgtbtFHMiCmsznwGVTUWbgGov+pVqnlf1dEJTNAXeM= -honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +honnef.co/go/tools v0.3.0-0.dev.0.20220306074811-23e1086441d2 h1:utiSabORbG/JeX7MlmKMdmsjwom2+v8zmdb6SoBe4UY= +honnef.co/go/tools v0.3.0-0.dev.0.20220306074811-23e1086441d2/go.mod h1:dZI0HmIvwDMW8owtLBJxTHoeX48yuF5p5pDy3y73jGU= diff --git a/idl/config.go b/idl/config.go index 91b9208d..bcfbdf80 100644 --- a/idl/config.go +++ b/idl/config.go @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Uber Technologies, Inc. +// Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/idl/error.go b/idl/error.go index fe7de4eb..e342c659 100644 --- a/idl/error.go +++ b/idl/error.go @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Uber Technologies, Inc. +// Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/idl/info.go b/idl/info.go index 9f371693..2d30b17c 100644 --- a/idl/info.go +++ b/idl/info.go @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Uber Technologies, Inc. +// Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/idl/internal/docstring.go b/idl/internal/docstring.go index 87747b0e..3de845b0 100644 --- a/idl/internal/docstring.go +++ b/idl/internal/docstring.go @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Uber Technologies, Inc. +// Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/idl/internal/error.go b/idl/internal/error.go index 56cb79dc..0c361952 100644 --- a/idl/internal/error.go +++ b/idl/internal/error.go @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Uber Technologies, Inc. +// Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/idl/internal/field.go b/idl/internal/field.go index 1e3edc05..047dc56e 100644 --- a/idl/internal/field.go +++ b/idl/internal/field.go @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Uber Technologies, Inc. +// Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/idl/internal/lex.go b/idl/internal/lex.go index e21a8f06..a5e12b26 100644 --- a/idl/internal/lex.go +++ b/idl/internal/lex.go @@ -1,6 +1,6 @@ // @generated Code generated by ragel -// Copyright (c) 2021 Uber Technologies, Inc. +// Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal @@ -1264,6 +1264,8 @@ func (lex *lexer) Lex(out *yySymType) int { base := 10 if len(str) > 2 && str[0:2] == "0x" { // Hex constant + // strconv.ParseInt doesn't want the "0x" prefix if we explicitly set the base. + str = str[2:] base = 16 } @@ -1345,6 +1347,8 @@ func (lex *lexer) Lex(out *yySymType) int { base := 10 if len(str) > 2 && str[0:2] == "0x" { // Hex constant + // strconv.ParseInt doesn't want the "0x" prefix if we explicitly set the base. + str = str[2:] base = 16 } @@ -1398,6 +1402,8 @@ func (lex *lexer) Lex(out *yySymType) int { base := 10 if len(str) > 2 && str[0:2] == "0x" { // Hex constant + // strconv.ParseInt doesn't want the "0x" prefix if we explicitly set the base. + str = str[2:] base = 16 } diff --git a/idl/internal/lex.rl b/idl/internal/lex.rl index 51968011..1ab52cb9 100644 --- a/idl/internal/lex.rl +++ b/idl/internal/lex.rl @@ -283,6 +283,8 @@ func (lex *lexer) Lex(out *yySymType) int { base := 10 if len(str) > 2 && str[0:2] == "0x" { // Hex constant + // strconv.ParseInt doesn't want the "0x" prefix if we explicitly set the base. + str = str[2:] base = 16 } diff --git a/idl/internal/parser.go b/idl/internal/parser.go index 52400e6d..9a9bb159 100644 --- a/idl/internal/parser.go +++ b/idl/internal/parser.go @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Uber Technologies, Inc. +// Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/idl/internal/quote.go b/idl/internal/quote.go index 194642c7..161caf02 100644 --- a/idl/internal/quote.go +++ b/idl/internal/quote.go @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Uber Technologies, Inc. +// Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/idl/internal/y.go b/idl/internal/y.go index cd1c194c..7ac6e7eb 100644 --- a/idl/internal/y.go +++ b/idl/internal/y.go @@ -1,6 +1,6 @@ // Code generated by goyacc -l thrift.y. DO NOT EDIT. -// Copyright (c) 2021 Uber Technologies, Inc. +// Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal @@ -167,7 +167,7 @@ const yyEofCode = 1 const yyErrCode = 2 const yyInitialStackSize = 16 -var yyExca = [...]int{ +var yyExca = [...]int8{ -1, 1, 1, -1, -2, 0, @@ -185,7 +185,7 @@ const yyPrivate = 57344 const yyLast = 177 -var yyAct = [...]int{ +var yyAct = [...]uint8{ 32, 59, 66, 5, 7, 69, 120, 31, 11, 67, 124, 83, 90, 89, 85, 86, 12, 12, 95, 14, 13, 13, 126, 97, 96, 63, 62, 61, 163, 34, @@ -206,7 +206,7 @@ var yyAct = [...]int{ 48, 49, 50, 51, 40, 41, 42, } -var yyPact = [...]int{ +var yyPact = [...]int16{ -1000, -1000, -1000, -1000, -1000, 96, -30, -1000, 74, 76, 70, -1000, -1000, -1000, 69, -1000, 71, -1000, 117, 116, 83, 83, 114, 111, 109, -1000, -1000, -1000, -1000, -1000, @@ -226,13 +226,13 @@ var yyPact = [...]int{ -1000, -1000, -16, -1000, } -var yyPgo = [...]int{ +var yyPgo = [...]uint8{ 0, 0, 11, 155, 7, 149, 147, 145, 144, 142, 2, 141, 140, 139, 9, 136, 135, 134, 133, 5, 132, 131, 127, 1, 8, 126, 123, 122, } -var yyR1 = [...]int{ +var yyR1 = [...]int8{ 0, 3, 12, 12, 11, 11, 11, 11, 11, 18, 18, 17, 17, 17, 17, 17, 17, 8, 8, 8, 16, 16, 15, 15, 10, 10, 9, 9, 6, 6, @@ -243,7 +243,7 @@ var yyR1 = [...]int{ 22, 22, 22, 1, 2, 24, 24, 24, } -var yyR2 = [...]int{ +var yyR2 = [...]int8{ 0, 2, 0, 2, 3, 4, 3, 4, 4, 0, 3, 7, 6, 8, 8, 8, 11, 1, 1, 1, 0, 3, 4, 6, 0, 3, 7, 9, 2, 0, @@ -254,7 +254,7 @@ var yyR2 = [...]int{ 0, 6, 4, 0, 0, 1, 1, 0, } -var yyChk = [...]int{ +var yyChk = [...]int16{ -1000, -3, -12, -18, -11, -1, -17, -1, 9, 10, 8, -24, 46, 50, -2, 5, 4, 5, 38, 4, 33, 25, 32, -8, 31, 26, 27, 28, 5, 4, @@ -274,7 +274,7 @@ var yyChk = [...]int{ -23, 43, -10, 44, } -var yyDef = [...]int{ +var yyDef = [...]int8{ 2, -2, -2, -2, 3, 0, 77, 74, 0, 0, 0, 10, 75, 76, 0, 4, 0, 6, 0, 0, 73, 73, 0, 0, 0, 17, 18, 19, 5, 7, @@ -294,7 +294,7 @@ var yyDef = [...]int{ 35, 24, 73, 41, } -var yyTok1 = [...]int{ +var yyTok1 = [...]int8{ 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, @@ -310,14 +310,14 @@ var yyTok1 = [...]int{ 3, 3, 3, 40, 3, 41, } -var yyTok2 = [...]int{ +var yyTok2 = [...]int8{ 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, } -var yyTok3 = [...]int{ +var yyTok3 = [...]int8{ 0, } @@ -397,9 +397,9 @@ func yyErrorMessage(state, lookAhead int) string { expected := make([]int, 0, 4) // Look for shiftable tokens. - base := yyPact[state] + base := int(yyPact[state]) for tok := TOKSTART; tok-1 < len(yyToknames); tok++ { - if n := base + tok; n >= 0 && n < yyLast && yyChk[yyAct[n]] == tok { + if n := base + tok; n >= 0 && n < yyLast && int(yyChk[int(yyAct[n])]) == tok { if len(expected) == cap(expected) { return res } @@ -409,13 +409,13 @@ func yyErrorMessage(state, lookAhead int) string { if yyDef[state] == -2 { i := 0 - for yyExca[i] != -1 || yyExca[i+1] != state { + for yyExca[i] != -1 || int(yyExca[i+1]) != state { i += 2 } // Look for tokens that we accept or reduce. for i += 2; yyExca[i] >= 0; i += 2 { - tok := yyExca[i] + tok := int(yyExca[i]) if tok < TOKSTART || yyExca[i+1] == 0 { continue } @@ -446,30 +446,30 @@ func yylex1(lex yyLexer, lval *yySymType) (char, token int) { token = 0 char = lex.Lex(lval) if char <= 0 { - token = yyTok1[0] + token = int(yyTok1[0]) goto out } if char < len(yyTok1) { - token = yyTok1[char] + token = int(yyTok1[char]) goto out } if char >= yyPrivate { if char < yyPrivate+len(yyTok2) { - token = yyTok2[char-yyPrivate] + token = int(yyTok2[char-yyPrivate]) goto out } } for i := 0; i < len(yyTok3); i += 2 { - token = yyTok3[i+0] + token = int(yyTok3[i+0]) if token == char { - token = yyTok3[i+1] + token = int(yyTok3[i+1]) goto out } } out: if token == 0 { - token = yyTok2[1] /* unknown char */ + token = int(yyTok2[1]) /* unknown char */ } if yyDebug >= 3 { __yyfmt__.Printf("lex %s(%d)\n", yyTokname(token), uint(char)) @@ -524,7 +524,7 @@ yystack: yyS[yyp].yys = yystate yynewstate: - yyn = yyPact[yystate] + yyn = int(yyPact[yystate]) if yyn <= yyFlag { goto yydefault /* simple state */ } @@ -535,8 +535,8 @@ yynewstate: if yyn < 0 || yyn >= yyLast { goto yydefault } - yyn = yyAct[yyn] - if yyChk[yyn] == yytoken { /* valid shift */ + yyn = int(yyAct[yyn]) + if int(yyChk[yyn]) == yytoken { /* valid shift */ yyrcvr.char = -1 yytoken = -1 yyVAL = yyrcvr.lval @@ -549,7 +549,7 @@ yynewstate: yydefault: /* default state action */ - yyn = yyDef[yystate] + yyn = int(yyDef[yystate]) if yyn == -2 { if yyrcvr.char < 0 { yyrcvr.char, yytoken = yylex1(yylex, &yyrcvr.lval) @@ -558,18 +558,18 @@ yydefault: /* look through exception table */ xi := 0 for { - if yyExca[xi+0] == -1 && yyExca[xi+1] == yystate { + if yyExca[xi+0] == -1 && int(yyExca[xi+1]) == yystate { break } xi += 2 } for xi += 2; ; xi += 2 { - yyn = yyExca[xi+0] + yyn = int(yyExca[xi+0]) if yyn < 0 || yyn == yytoken { break } } - yyn = yyExca[xi+1] + yyn = int(yyExca[xi+1]) if yyn < 0 { goto ret0 } @@ -591,10 +591,10 @@ yydefault: /* find a state where "error" is a legal shift action */ for yyp >= 0 { - yyn = yyPact[yyS[yyp].yys] + yyErrCode + yyn = int(yyPact[yyS[yyp].yys]) + yyErrCode if yyn >= 0 && yyn < yyLast { - yystate = yyAct[yyn] /* simulate a shift of "error" */ - if yyChk[yystate] == yyErrCode { + yystate = int(yyAct[yyn]) /* simulate a shift of "error" */ + if int(yyChk[yystate]) == yyErrCode { goto yystack } } @@ -630,7 +630,7 @@ yydefault: yypt := yyp _ = yypt // guard against "declared and not used" - yyp -= yyR2[yyn] + yyp -= int(yyR2[yyn]) // yyp is now the index of $0. Perform the default action. Iff the // reduced production is ε, $1 is possibly out of range. if yyp+1 >= len(yyS) { @@ -641,16 +641,16 @@ yydefault: yyVAL = yyS[yyp+1] /* consult goto table to find next state */ - yyn = yyR1[yyn] - yyg := yyPgo[yyn] + yyn = int(yyR1[yyn]) + yyg := int(yyPgo[yyn]) yyj := yyg + yyS[yyp].yys + 1 if yyj >= yyLast { - yystate = yyAct[yyg] + yystate = int(yyAct[yyg]) } else { - yystate = yyAct[yyj] - if yyChk[yystate] != -yyn { - yystate = yyAct[yyg] + yystate = int(yyAct[yyj]) + if int(yyChk[yystate]) != -yyn { + yystate = int(yyAct[yyg]) } } // dummy call; replaced with literal code diff --git a/idl/parser.go b/idl/parser.go index cddbbeb8..af3c8c6f 100644 --- a/idl/parser.go +++ b/idl/parser.go @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Uber Technologies, Inc. +// Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/internal/breaktest/repo.go b/internal/breaktest/repo.go new file mode 100644 index 00000000..b688c210 --- /dev/null +++ b/internal/breaktest/repo.go @@ -0,0 +1,106 @@ +// Copyright (c) 2023 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +package breaktest + +import ( + "io/ioutil" + "os" + "path/filepath" + "testing" + "time" + + "github.com/go-git/go-git/v5" + "github.com/go-git/go-git/v5/plumbing/object" + "github.com/stretchr/testify/require" +) + +type writeThrift struct { + tmpDir string + contents map[string]string + worktree *git.Worktree + toRemove []string +} + +func newWriteThrift(tmpDir string, contents map[string]string, worktree *git.Worktree, toRemove []string) *writeThrift { + return &writeThrift{ + tmpDir: tmpDir, + contents: contents, + worktree: worktree, + toRemove: toRemove, + } +} + +// commit commits all changes staged before it is called. +func (w *writeThrift) commit(extra string) error { + err := w.worktree.AddWithOptions(&git.AddOptions{All: true}) + if err != nil { + return err + } + for _, f := range w.toRemove { + if _, err := w.worktree.Remove(f); err != nil { + return err + } + } + + _, err = w.worktree.Commit("thrift update file"+extra, &git.CommitOptions{ + Author: &object.Signature{ + Name: "update v1.thrift", + Email: "thriftforeverornever@example.com", + When: time.Now(), + }, + }) + + return err +} + +func (w *writeThrift) writeThrifts(extraMsg string) error { + for name, content := range w.contents { + path := filepath.Join(w.tmpDir, name) + if err := os.MkdirAll(filepath.Dir(path), 0755); err != nil { + return err + } + if err := ioutil.WriteFile(path, []byte(content), 0600); err != nil { + return err + } + } + + return w.commit(extraMsg) +} + +// CreateRepoAndCommit creates a temporary repository and adds +// a commit of a thrift files for us to look up later. +// TODO(GO-891): finish implementation of this integration. +func CreateRepoAndCommit(t *testing.T, tmpDir string, from map[string]string, + to map[string]string, remove []string) *git.Repository { + t.Helper() + // Create a new repo in temp directory. + repository, err := git.PlainInit(tmpDir, false) + require.NoError(t, err) + worktree, err := repository.Worktree() + require.NoError(t, err) + + w := newWriteThrift(tmpDir, from, worktree, nil) + require.NoError(t, w.writeThrifts("")) + w = newWriteThrift(tmpDir, to, worktree, remove) + require.NoError(t, w.writeThrifts("second")) + + return repository +} diff --git a/internal/compare/compare.go b/internal/compare/compare.go new file mode 100644 index 00000000..daa4d90c --- /dev/null +++ b/internal/compare/compare.go @@ -0,0 +1,174 @@ +// Copyright (c) 2023 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +package compare + +import ( + "fmt" + "path/filepath" + "strings" + + "go.uber.org/thriftrw/compile" +) + +// Diagnostic is a message associated with an error and a file name. +type Diagnostic struct { + FilePath string // FilePath where error was discovered. + Message string // Message contains error message. +} + +func (d *Diagnostic) String() string { + return fmt.Sprintf("%s:%s", d.FilePath, d.Message) +} + +// Pass provides all reported errors. +type Pass struct { + lints []Diagnostic + GitDir string +} + +// Report reports an error. +func (p *Pass) Report(d Diagnostic) { + p.lints = append(p.lints, d) +} + +// Lints returns all errors. +func (p *Pass) Lints() []Diagnostic { + return p.lints +} + +func (p *Pass) String() string { + var b strings.Builder + for _, l := range p.lints { + _, _ = fmt.Fprintf(&b, "%s\n", l.String()) + } + + return b.String() +} + +// CompareModules looks for removed methods and added required fields. +func (p *Pass) CompareModules(from, to *compile.Module) { + for name, fromService := range from.Services { + p.service(fromService, to.Services[name]) + } + + file := p.getRelativePath(from.ThriftPath) + for n, fromType := range from.Types { + p.typ(fromType, to.Types[n], file) + } +} + +func (p *Pass) typ(from, to compile.TypeSpec, file string) { + if f, ok := from.(*compile.StructSpec); ok { + t, ok := to.(*compile.StructSpec) + if !ok { + // A struct was deleted which is ok if it's unused or + // it's usage was also removed. + return + } + p.structSpecs(f, t, file) + } +} + +func (p *Pass) requiredField(fromField, toField *compile.FieldSpec, to *compile.StructSpec, file string) { + fromRequired := fromField.Required + if !fromRequired && toField.Required { + p.Report(Diagnostic{ + FilePath: file, + Message: fmt.Sprintf( + "changing an optional field %q in %q to required", + toField.ThriftName(), to.ThriftName()), + }) + } +} + +func (p *Pass) changedTypes(fromField, toField *compile.FieldSpec, to *compile.StructSpec, file string) { + if fromField.Type == nil || toField.Type == nil { + return + } + + if fromField.Type.ThriftName() != toField.Type.ThriftName() { + p.Report(Diagnostic{ + FilePath: file, + Message: fmt.Sprintf( + "changing type of field %q in struct %q from %q to %q", + toField.ThriftName(), to.ThriftName(), fromField.Type.ThriftName(), + toField.Type.ThriftName()), + }) + } +} + +// StructSpecs compares two structs defined in a Thrift file. +func (p *Pass) structSpecs(from, to *compile.StructSpec, file string) { + fields := make(map[int16]*compile.FieldSpec, len(from.Fields)) + // Assume that these two should be compared. + for _, f := range from.Fields { + fields[f.ID] = f + } + for _, toField := range to.Fields { + if fromField, ok := fields[toField.ID]; ok { + p.requiredField(fromField, toField, to, file) + p.changedTypes(fromField, toField, to, file) + } else if toField.Required { + p.Report(Diagnostic{ + FilePath: file, + Message: fmt.Sprintf("adding a required field %q to %q", + toField.ThriftName(), to.ThriftName()), + }) + } + } +} + +func (p *Pass) service(from, to *compile.ServiceSpec) { + if to == nil { + // Service was deleted, which is not backwards compatible. + p.Report(Diagnostic{ + FilePath: filepath.Base(from.File), // toModule could have been deleted. + Message: fmt.Sprintf("deleting service %q", from.Name), + }) + + return + } + file := p.getRelativePath(from.File) + for n := range from.Functions { + p.function(to.Functions[n], n, file, from.Name) + } +} + +// getRelativePath returns a relative path to a file or +// fallbacks to file name for cases when it was deleted. +func (p *Pass) getRelativePath(filePath string) string { + if file, err := filepath.Rel(p.GitDir, filePath); err == nil { + return file + } + // If a file was deleted, then we will not be able to + // find a relative path to it. + return filepath.Base(filePath) +} + +func (p *Pass) function(to *compile.FunctionSpec, fn string, path string, service string) { + file := p.getRelativePath(path) + if to == nil { + p.Report(Diagnostic{ + FilePath: file, + Message: fmt.Sprintf("removing method %q in service %q", fn, service), + }) + } +} diff --git a/internal/compare/compare_test.go b/internal/compare/compare_test.go new file mode 100644 index 00000000..4292f492 --- /dev/null +++ b/internal/compare/compare_test.go @@ -0,0 +1,274 @@ +// Copyright (c) 2021 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +package compare + +import ( + "fmt" + "testing" + + "github.com/stretchr/testify/assert" + "go.uber.org/thriftrw/compile" +) + +func TestErrorRequiredCase(t *testing.T) { + t.Parallel() + type test struct { + desc string + fromStruct *compile.StructSpec + toStruct *compile.StructSpec + wantError string + } + tests := []test{ + { + desc: "changed an optional field to required", + fromStruct: &compile.StructSpec{ + Name: "structA", + Fields: compile.FieldGroup{ + &compile.FieldSpec{ + Required: false, + Name: "fieldA", + }, + }, + }, + toStruct: &compile.StructSpec{ + Name: "structA", + Fields: compile.FieldGroup{ + &compile.FieldSpec{ + Required: true, + Name: "fieldA", + }, + }, + }, + wantError: `foo.thrift:changing an optional field "fieldA" in "structA" to required`, + }, + { + desc: "found a new required field", + fromStruct: &compile.StructSpec{ + Fields: compile.FieldGroup{}, + }, + toStruct: &compile.StructSpec{ + Name: "structA", + Fields: compile.FieldGroup{ + &compile.FieldSpec{ + Required: true, + Name: "fieldA", + }, + }, + }, + wantError: `foo.thrift:adding a required field "fieldA" to "structA"`, + }, + { + desc: "found a new required and changed optional field", + fromStruct: &compile.StructSpec{ + Fields: compile.FieldGroup{ + &compile.FieldSpec{ + Required: false, + Name: "fieldA", + }, + }, + }, + toStruct: &compile.StructSpec{ + Name: "structA", + Fields: compile.FieldGroup{ + &compile.FieldSpec{ + Required: true, + Name: "fieldA", + }, + &compile.FieldSpec{ + Required: true, + Name: "fieldB", + }, + }, + }, + wantError: `foo.thrift:changing an optional field "fieldA" in "structA" to required` + + "\n" + `foo.thrift:changing an optional field "fieldB" in "structA" to required`, + }, + { + desc: "found a type changed", + fromStruct: &compile.StructSpec{ + Name: "structA", + Fields: compile.FieldGroup{ + &compile.FieldSpec{ + Name: "fieldA", + Type: &compile.BinarySpec{}, + }, + }, + }, + toStruct: &compile.StructSpec{ + Name: "structA", + Fields: compile.FieldGroup{ + &compile.FieldSpec{ + Name: "fieldA", + Type: &compile.BoolSpec{}, + }, + &compile.FieldSpec{ + Name: "fieldB", + Type: &compile.BinarySpec{}, + }, + }, + }, + wantError: `foo.thrift:changing type of field "fieldA" in struct "structA" from "binary" to "bool"`, + }, + } + + for _, tt := range tests { + tt := tt + t.Run(tt.desc, func(t *testing.T) { + t.Parallel() + pass := Pass{} + pass.structSpecs(tt.fromStruct, tt.toStruct, "foo.thrift") + want := fmt.Sprintf("%s\n", tt.wantError) + assert.Equal(t, want, pass.String(), "wrong lint diagnostics") + }) + } +} + +func TestRequiredCaseOk(t *testing.T) { + t.Parallel() + type test struct { + desc string + fromStruct *compile.StructSpec + toStruct *compile.StructSpec + } + tests := []test{ + { + desc: "adding an optional field", + fromStruct: &compile.StructSpec{ + Fields: compile.FieldGroup{ + &compile.FieldSpec{ + Required: false, + Name: "fieldA", + }, + }, + }, + toStruct: &compile.StructSpec{ + Fields: compile.FieldGroup{ + &compile.FieldSpec{ + Required: false, + Name: "fieldA", + }, + &compile.FieldSpec{ + Required: false, + Name: "fieldA", + }, + }, + }, + }, + { + desc: "removing a field from a struct", + fromStruct: &compile.StructSpec{ + Fields: compile.FieldGroup{ + &compile.FieldSpec{ + Required: false, + }, + }, + }, + toStruct: &compile.StructSpec{ + Fields: compile.FieldGroup{}, + }, + }, + } + + for _, tt := range tests { + tt := tt + t.Run(tt.desc, func(t *testing.T) { + t.Parallel() + pass := Pass{} + pass.structSpecs(tt.fromStruct, tt.toStruct, "foo.thrift") + assert.Equal(t, "", pass.String(), "wrong lint diagnostics") + }) + } +} + +func TestServicesError(t *testing.T) { + t.Parallel() + type test struct { + desc string + from *compile.ServiceSpec + to *compile.ServiceSpec + wantError string + } + tests := []test{ + { + desc: "removing service", + from: &compile.ServiceSpec{ + Name: "foo", + File: "foo.thrift", + }, + to: nil, + wantError: `foo.thrift:deleting service "foo"`, + }, + { + desc: "removing a method", + from: &compile.ServiceSpec{ + Name: "foo", + File: "foo.thrift", + Functions: map[string]*compile.FunctionSpec{"bar": {}}, + }, + to: &compile.ServiceSpec{ + Name: "foo", + File: "foo.thrift", + }, + wantError: `foo.thrift:removing method "bar" in service "foo"`, + }, + } + for _, tt := range tests { + tt := tt + t.Run(tt.desc, func(t *testing.T) { + t.Parallel() + pass := Pass{} + pass.service(tt.from, tt.to) + want := fmt.Sprintf("%s\n", tt.wantError) + assert.Equal(t, want, pass.String(), "wrong error message") + }) + } +} + +func TestRelativePath(t *testing.T) { + t.Parallel() + tests := []struct { + desc string + path string + want string + }{ + { + desc: "good case", + path: "/home/foo/bar/buz/buz.go", + want: "buz/buz.go", + }, + { + desc: "fallback case where we just return file name", + path: "foo/buz.go", + want: "buz.go", + }, + } + for _, tt := range tests { + tt := tt + t.Run(tt.desc, func(t *testing.T) { + t.Parallel() + p := Pass{ + GitDir: "/home/foo/bar", + } + assert.Equal(t, tt.want, p.getRelativePath(tt.path)) + }) + } + +} diff --git a/internal/concurrent/range.go b/internal/concurrent/range.go index ce08e214..9ef8aabe 100644 --- a/internal/concurrent/range.go +++ b/internal/concurrent/range.go @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Uber Technologies, Inc. +// Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/internal/curry/one.go b/internal/curry/one.go index 61aa039e..28804be4 100644 --- a/internal/curry/one.go +++ b/internal/curry/one.go @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Uber Technologies, Inc. +// Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/internal/envelope/client.go b/internal/envelope/client.go index 1bc899f7..6368f3bc 100644 --- a/internal/envelope/client.go +++ b/internal/envelope/client.go @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Uber Technologies, Inc. +// Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/internal/envelope/envelopetest/client.go b/internal/envelope/envelopetest/client.go index fe5d99c1..4fec73ce 100644 --- a/internal/envelope/envelopetest/client.go +++ b/internal/envelope/envelopetest/client.go @@ -1,6 +1,6 @@ // Code generated by MockGen. DO NOT EDIT. -// Copyright (c) 2021 Uber Technologies, Inc. +// Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal @@ -25,35 +25,36 @@ package envelopetest import ( + reflect "reflect" + gomock "github.com/golang/mock/gomock" wire "go.uber.org/thriftrw/wire" - reflect "reflect" ) -// MockTransport is a mock of Transport interface +// MockTransport is a mock of Transport interface. type MockTransport struct { ctrl *gomock.Controller recorder *MockTransportMockRecorder } -// MockTransportMockRecorder is the mock recorder for MockTransport +// MockTransportMockRecorder is the mock recorder for MockTransport. type MockTransportMockRecorder struct { mock *MockTransport } -// NewMockTransport creates a new mock instance +// NewMockTransport creates a new mock instance. func NewMockTransport(ctrl *gomock.Controller) *MockTransport { mock := &MockTransport{ctrl: ctrl} mock.recorder = &MockTransportMockRecorder{mock} return mock } -// EXPECT returns an object that allows the caller to indicate expected use +// EXPECT returns an object that allows the caller to indicate expected use. func (m *MockTransport) EXPECT() *MockTransportMockRecorder { return m.recorder } -// Send mocks base method +// Send mocks base method. func (m *MockTransport) Send(arg0 []byte) ([]byte, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Send", arg0) @@ -62,36 +63,36 @@ func (m *MockTransport) Send(arg0 []byte) ([]byte, error) { return ret0, ret1 } -// Send indicates an expected call of Send +// Send indicates an expected call of Send. func (mr *MockTransportMockRecorder) Send(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Send", reflect.TypeOf((*MockTransport)(nil).Send), arg0) } -// MockClient is a mock of Client interface +// MockClient is a mock of Client interface. type MockClient struct { ctrl *gomock.Controller recorder *MockClientMockRecorder } -// MockClientMockRecorder is the mock recorder for MockClient +// MockClientMockRecorder is the mock recorder for MockClient. type MockClientMockRecorder struct { mock *MockClient } -// NewMockClient creates a new mock instance +// NewMockClient creates a new mock instance. func NewMockClient(ctrl *gomock.Controller) *MockClient { mock := &MockClient{ctrl: ctrl} mock.recorder = &MockClientMockRecorder{mock} return mock } -// EXPECT returns an object that allows the caller to indicate expected use +// EXPECT returns an object that allows the caller to indicate expected use. func (m *MockClient) EXPECT() *MockClientMockRecorder { return m.recorder } -// Send mocks base method +// Send mocks base method. func (m *MockClient) Send(name string, body wire.Value) (wire.Value, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Send", name, body) @@ -100,7 +101,7 @@ func (m *MockClient) Send(name string, body wire.Value) (wire.Value, error) { return ret0, ret1 } -// Send indicates an expected call of Send +// Send indicates an expected call of Send. func (mr *MockClientMockRecorder) Send(name, body interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Send", reflect.TypeOf((*MockClient)(nil).Send), name, body) diff --git a/internal/envelope/envelopetest/gen.go b/internal/envelope/envelopetest/gen.go index 3bf2996d..bdaca58b 100644 --- a/internal/envelope/envelopetest/gen.go +++ b/internal/envelope/envelopetest/gen.go @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Uber Technologies, Inc. +// Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/internal/envelope/envelopetest/server.go b/internal/envelope/envelopetest/server.go index 4c74d5c2..dc88a864 100644 --- a/internal/envelope/envelopetest/server.go +++ b/internal/envelope/envelopetest/server.go @@ -1,6 +1,6 @@ // Code generated by MockGen. DO NOT EDIT. -// Copyright (c) 2021 Uber Technologies, Inc. +// Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal @@ -25,35 +25,36 @@ package envelopetest import ( + reflect "reflect" + gomock "github.com/golang/mock/gomock" wire "go.uber.org/thriftrw/wire" - reflect "reflect" ) -// MockHandler is a mock of Handler interface +// MockHandler is a mock of Handler interface. type MockHandler struct { ctrl *gomock.Controller recorder *MockHandlerMockRecorder } -// MockHandlerMockRecorder is the mock recorder for MockHandler +// MockHandlerMockRecorder is the mock recorder for MockHandler. type MockHandlerMockRecorder struct { mock *MockHandler } -// NewMockHandler creates a new mock instance +// NewMockHandler creates a new mock instance. func NewMockHandler(ctrl *gomock.Controller) *MockHandler { mock := &MockHandler{ctrl: ctrl} mock.recorder = &MockHandlerMockRecorder{mock} return mock } -// EXPECT returns an object that allows the caller to indicate expected use +// EXPECT returns an object that allows the caller to indicate expected use. func (m *MockHandler) EXPECT() *MockHandlerMockRecorder { return m.recorder } -// Handle mocks base method +// Handle mocks base method. func (m *MockHandler) Handle(name string, body wire.Value) (wire.Value, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Handle", name, body) @@ -62,7 +63,7 @@ func (m *MockHandler) Handle(name string, body wire.Value) (wire.Value, error) { return ret0, ret1 } -// Handle indicates an expected call of Handle +// Handle indicates an expected call of Handle. func (mr *MockHandlerMockRecorder) Handle(name, body interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Handle", reflect.TypeOf((*MockHandler)(nil).Handle), name, body) diff --git a/internal/envelope/exception/exception.go b/internal/envelope/exception/exception.go index be871368..35f47143 100644 --- a/internal/envelope/exception/exception.go +++ b/internal/envelope/exception/exception.go @@ -1,7 +1,7 @@ -// Code generated by thriftrw v1.29.2. DO NOT EDIT. +// Code generated by thriftrw v1.30.0. DO NOT EDIT. // @generated -// Copyright (c) 2021 Uber Technologies, Inc. +// Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/internal/envelope/gen.go b/internal/envelope/gen.go index eea50c45..13945896 100644 --- a/internal/envelope/gen.go +++ b/internal/envelope/gen.go @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Uber Technologies, Inc. +// Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/internal/envelope/mock_protocol_test.go b/internal/envelope/mock_protocol_test.go index 6f2cd2f6..804260b4 100644 --- a/internal/envelope/mock_protocol_test.go +++ b/internal/envelope/mock_protocol_test.go @@ -5,36 +5,37 @@ package envelope import ( - gomock "github.com/golang/mock/gomock" - wire "go.uber.org/thriftrw/wire" io "io" reflect "reflect" + + gomock "github.com/golang/mock/gomock" + wire "go.uber.org/thriftrw/wire" ) -// MockProtocol is a mock of Protocol interface +// MockProtocol is a mock of Protocol interface. type MockProtocol struct { ctrl *gomock.Controller recorder *MockProtocolMockRecorder } -// MockProtocolMockRecorder is the mock recorder for MockProtocol +// MockProtocolMockRecorder is the mock recorder for MockProtocol. type MockProtocolMockRecorder struct { mock *MockProtocol } -// NewMockProtocol creates a new mock instance +// NewMockProtocol creates a new mock instance. func NewMockProtocol(ctrl *gomock.Controller) *MockProtocol { mock := &MockProtocol{ctrl: ctrl} mock.recorder = &MockProtocolMockRecorder{mock} return mock } -// EXPECT returns an object that allows the caller to indicate expected use +// EXPECT returns an object that allows the caller to indicate expected use. func (m *MockProtocol) EXPECT() *MockProtocolMockRecorder { return m.recorder } -// Decode mocks base method +// Decode mocks base method. func (m *MockProtocol) Decode(arg0 io.ReaderAt, arg1 wire.Type) (wire.Value, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Decode", arg0, arg1) @@ -43,13 +44,13 @@ func (m *MockProtocol) Decode(arg0 io.ReaderAt, arg1 wire.Type) (wire.Value, err return ret0, ret1 } -// Decode indicates an expected call of Decode +// Decode indicates an expected call of Decode. func (mr *MockProtocolMockRecorder) Decode(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Decode", reflect.TypeOf((*MockProtocol)(nil).Decode), arg0, arg1) } -// DecodeEnveloped mocks base method +// DecodeEnveloped mocks base method. func (m *MockProtocol) DecodeEnveloped(arg0 io.ReaderAt) (wire.Envelope, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "DecodeEnveloped", arg0) @@ -58,13 +59,13 @@ func (m *MockProtocol) DecodeEnveloped(arg0 io.ReaderAt) (wire.Envelope, error) return ret0, ret1 } -// DecodeEnveloped indicates an expected call of DecodeEnveloped +// DecodeEnveloped indicates an expected call of DecodeEnveloped. func (mr *MockProtocolMockRecorder) DecodeEnveloped(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DecodeEnveloped", reflect.TypeOf((*MockProtocol)(nil).DecodeEnveloped), arg0) } -// Encode mocks base method +// Encode mocks base method. func (m *MockProtocol) Encode(arg0 wire.Value, arg1 io.Writer) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Encode", arg0, arg1) @@ -72,13 +73,13 @@ func (m *MockProtocol) Encode(arg0 wire.Value, arg1 io.Writer) error { return ret0 } -// Encode indicates an expected call of Encode +// Encode indicates an expected call of Encode. func (mr *MockProtocolMockRecorder) Encode(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Encode", reflect.TypeOf((*MockProtocol)(nil).Encode), arg0, arg1) } -// EncodeEnveloped mocks base method +// EncodeEnveloped mocks base method. func (m *MockProtocol) EncodeEnveloped(arg0 wire.Envelope, arg1 io.Writer) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "EncodeEnveloped", arg0, arg1) @@ -86,7 +87,7 @@ func (m *MockProtocol) EncodeEnveloped(arg0 wire.Envelope, arg1 io.Writer) error return ret0 } -// EncodeEnveloped indicates an expected call of EncodeEnveloped +// EncodeEnveloped indicates an expected call of EncodeEnveloped. func (mr *MockProtocolMockRecorder) EncodeEnveloped(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EncodeEnveloped", reflect.TypeOf((*MockProtocol)(nil).EncodeEnveloped), arg0, arg1) diff --git a/internal/envelope/server.go b/internal/envelope/server.go index 10866164..ced4489f 100644 --- a/internal/envelope/server.go +++ b/internal/envelope/server.go @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Uber Technologies, Inc. +// Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/internal/frame/client.go b/internal/frame/client.go index 6bfd51c1..b967fad7 100644 --- a/internal/frame/client.go +++ b/internal/frame/client.go @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Uber Technologies, Inc. +// Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/internal/frame/doc.go b/internal/frame/doc.go index 5e7da53a..06bae0ab 100644 --- a/internal/frame/doc.go +++ b/internal/frame/doc.go @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Uber Technologies, Inc. +// Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/internal/frame/mock_reader_test.go b/internal/frame/mock_reader_test.go index 91df2fd4..ba28f0cc 100644 --- a/internal/frame/mock_reader_test.go +++ b/internal/frame/mock_reader_test.go @@ -5,34 +5,35 @@ package frame import ( - gomock "github.com/golang/mock/gomock" reflect "reflect" + + gomock "github.com/golang/mock/gomock" ) -// MockReader is a mock of Reader interface +// MockReader is a mock of Reader interface. type MockReader struct { ctrl *gomock.Controller recorder *MockReaderMockRecorder } -// MockReaderMockRecorder is the mock recorder for MockReader +// MockReaderMockRecorder is the mock recorder for MockReader. type MockReaderMockRecorder struct { mock *MockReader } -// NewMockReader creates a new mock instance +// NewMockReader creates a new mock instance. func NewMockReader(ctrl *gomock.Controller) *MockReader { mock := &MockReader{ctrl: ctrl} mock.recorder = &MockReaderMockRecorder{mock} return mock } -// EXPECT returns an object that allows the caller to indicate expected use +// EXPECT returns an object that allows the caller to indicate expected use. func (m *MockReader) EXPECT() *MockReaderMockRecorder { return m.recorder } -// Read mocks base method +// Read mocks base method. func (m *MockReader) Read(arg0 []byte) (int, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Read", arg0) @@ -41,36 +42,36 @@ func (m *MockReader) Read(arg0 []byte) (int, error) { return ret0, ret1 } -// Read indicates an expected call of Read +// Read indicates an expected call of Read. func (mr *MockReaderMockRecorder) Read(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Read", reflect.TypeOf((*MockReader)(nil).Read), arg0) } -// MockReadCloser is a mock of ReadCloser interface +// MockReadCloser is a mock of ReadCloser interface. type MockReadCloser struct { ctrl *gomock.Controller recorder *MockReadCloserMockRecorder } -// MockReadCloserMockRecorder is the mock recorder for MockReadCloser +// MockReadCloserMockRecorder is the mock recorder for MockReadCloser. type MockReadCloserMockRecorder struct { mock *MockReadCloser } -// NewMockReadCloser creates a new mock instance +// NewMockReadCloser creates a new mock instance. func NewMockReadCloser(ctrl *gomock.Controller) *MockReadCloser { mock := &MockReadCloser{ctrl: ctrl} mock.recorder = &MockReadCloserMockRecorder{mock} return mock } -// EXPECT returns an object that allows the caller to indicate expected use +// EXPECT returns an object that allows the caller to indicate expected use. func (m *MockReadCloser) EXPECT() *MockReadCloserMockRecorder { return m.recorder } -// Close mocks base method +// Close mocks base method. func (m *MockReadCloser) Close() error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Close") @@ -78,13 +79,13 @@ func (m *MockReadCloser) Close() error { return ret0 } -// Close indicates an expected call of Close +// Close indicates an expected call of Close. func (mr *MockReadCloserMockRecorder) Close() *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockReadCloser)(nil).Close)) } -// Read mocks base method +// Read mocks base method. func (m *MockReadCloser) Read(arg0 []byte) (int, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Read", arg0) @@ -93,7 +94,7 @@ func (m *MockReadCloser) Read(arg0 []byte) (int, error) { return ret0, ret1 } -// Read indicates an expected call of Read +// Read indicates an expected call of Read. func (mr *MockReadCloserMockRecorder) Read(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Read", reflect.TypeOf((*MockReadCloser)(nil).Read), arg0) diff --git a/internal/frame/mock_writer_test.go b/internal/frame/mock_writer_test.go index c3c4700a..d0f3f340 100644 --- a/internal/frame/mock_writer_test.go +++ b/internal/frame/mock_writer_test.go @@ -5,34 +5,35 @@ package frame import ( - gomock "github.com/golang/mock/gomock" reflect "reflect" + + gomock "github.com/golang/mock/gomock" ) -// MockWriter is a mock of Writer interface +// MockWriter is a mock of Writer interface. type MockWriter struct { ctrl *gomock.Controller recorder *MockWriterMockRecorder } -// MockWriterMockRecorder is the mock recorder for MockWriter +// MockWriterMockRecorder is the mock recorder for MockWriter. type MockWriterMockRecorder struct { mock *MockWriter } -// NewMockWriter creates a new mock instance +// NewMockWriter creates a new mock instance. func NewMockWriter(ctrl *gomock.Controller) *MockWriter { mock := &MockWriter{ctrl: ctrl} mock.recorder = &MockWriterMockRecorder{mock} return mock } -// EXPECT returns an object that allows the caller to indicate expected use +// EXPECT returns an object that allows the caller to indicate expected use. func (m *MockWriter) EXPECT() *MockWriterMockRecorder { return m.recorder } -// Write mocks base method +// Write mocks base method. func (m *MockWriter) Write(arg0 []byte) (int, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Write", arg0) @@ -41,36 +42,36 @@ func (m *MockWriter) Write(arg0 []byte) (int, error) { return ret0, ret1 } -// Write indicates an expected call of Write +// Write indicates an expected call of Write. func (mr *MockWriterMockRecorder) Write(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Write", reflect.TypeOf((*MockWriter)(nil).Write), arg0) } -// MockWriteCloser is a mock of WriteCloser interface +// MockWriteCloser is a mock of WriteCloser interface. type MockWriteCloser struct { ctrl *gomock.Controller recorder *MockWriteCloserMockRecorder } -// MockWriteCloserMockRecorder is the mock recorder for MockWriteCloser +// MockWriteCloserMockRecorder is the mock recorder for MockWriteCloser. type MockWriteCloserMockRecorder struct { mock *MockWriteCloser } -// NewMockWriteCloser creates a new mock instance +// NewMockWriteCloser creates a new mock instance. func NewMockWriteCloser(ctrl *gomock.Controller) *MockWriteCloser { mock := &MockWriteCloser{ctrl: ctrl} mock.recorder = &MockWriteCloserMockRecorder{mock} return mock } -// EXPECT returns an object that allows the caller to indicate expected use +// EXPECT returns an object that allows the caller to indicate expected use. func (m *MockWriteCloser) EXPECT() *MockWriteCloserMockRecorder { return m.recorder } -// Close mocks base method +// Close mocks base method. func (m *MockWriteCloser) Close() error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Close") @@ -78,13 +79,13 @@ func (m *MockWriteCloser) Close() error { return ret0 } -// Close indicates an expected call of Close +// Close indicates an expected call of Close. func (mr *MockWriteCloserMockRecorder) Close() *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockWriteCloser)(nil).Close)) } -// Write mocks base method +// Write mocks base method. func (m *MockWriteCloser) Write(arg0 []byte) (int, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Write", arg0) @@ -93,7 +94,7 @@ func (m *MockWriteCloser) Write(arg0 []byte) (int, error) { return ret0, ret1 } -// Write indicates an expected call of Write +// Write indicates an expected call of Write. func (mr *MockWriteCloserMockRecorder) Write(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Write", reflect.TypeOf((*MockWriteCloser)(nil).Write), arg0) diff --git a/internal/frame/reader.go b/internal/frame/reader.go index d90ebdd4..df4f0965 100644 --- a/internal/frame/reader.go +++ b/internal/frame/reader.go @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Uber Technologies, Inc. +// Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/internal/frame/server.go b/internal/frame/server.go index d8b71221..5471c2b8 100644 --- a/internal/frame/server.go +++ b/internal/frame/server.go @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Uber Technologies, Inc. +// Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/internal/frame/writer.go b/internal/frame/writer.go index af436d56..37293566 100644 --- a/internal/frame/writer.go +++ b/internal/frame/writer.go @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Uber Technologies, Inc. +// Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/internal/git/git.go b/internal/git/git.go new file mode 100644 index 00000000..33094b84 --- /dev/null +++ b/internal/git/git.go @@ -0,0 +1,191 @@ +// Copyright (c) 2023 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +package git + +import ( + "context" + "fmt" + "path/filepath" + + "github.com/go-git/go-git/v5" + "github.com/go-git/go-git/v5/plumbing/object" + "github.com/go-git/go-git/v5/utils/merkletrie" + "go.uber.org/thriftrw/compile" + "go.uber.org/thriftrw/internal/compare" +) + +// FS holds reference to components needed for git FS. +type FS struct { + repo *git.Repository + root string + tree *object.Tree +} + +// NewGitFS creates an implementation of FS to use git to discover +// Thrift changes and previous version of a Thrift file. +func NewGitFS(gitDir string, repo *git.Repository, tree *object.Tree) *FS { + return &FS{ + repo: repo, + root: gitDir, + tree: tree, + } +} + +// Compare takes a path to a git repository and returns errors between HEAD and HEAD~ +// for any incompatible Thrift changes between the two shas. +func Compare(path string) (compare.Pass, error) { + pass := compare.Pass{ + GitDir: path, + } + r, err := git.PlainOpenWithOptions(path, &git.PlainOpenOptions{ + DetectDotGit: true, + EnableDotGitCommonDir: true, + }) + if err != nil { + return pass, err + } + + h, err := findChangedThrift(r) + if err != nil { + return pass, fmt.Errorf("failed to find changed thrift files: %w", err) + } + fs := NewGitFS(path, r, h.to) + fsFrom := NewGitFS(path, r, h.from) + var errs error + for _, c := range h.changes { + var toModule *compile.Module + if c.change == merkletrie.Modify { + toModule, err = compile.Compile(c.file, compile.Filesystem(fs)) + if err != nil { + return pass, err + } + } else if c.change == merkletrie.Delete { + // something got deleted, so we are creating an empty module here. + toModule = &compile.Module{ + Name: c.file, + } + } + + fromModule, err := compile.Compile(c.file, compile.Filesystem(fsFrom)) + if err != nil { + return pass, err + } + pass.CompareModules(fromModule, toModule) + } + // p will have lints as a field which we can sort in cli. + + return pass, errs +} + +func (fs FS) Read(path string) ([]byte, error) { + // filename is going to be the full path. We don't want that. + filename, err := filepath.Rel(fs.root, path) + if err != nil { + return nil, err + } + + // It's possible that file was deleted and it will not exist. + f, err := fs.tree.File(filename) + if err != nil { + return nil, fmt.Errorf("open %q: %w", filename, err) + } + s, err := f.Contents() + if err != nil { + return nil, err + } + body := []byte(s) + + return body, nil +} + +// Abs returns absolute path to a file. +func (fs FS) Abs(p string) (string, error) { + // Sometimes p can be a full path already on includes, and sometimes it can be relative. + if filepath.IsAbs(p) { + return p, nil + } + + return filepath.Join(fs.root, p), nil +} + +type treeChanges struct { + from *object.Tree + to *object.Tree + changes []*change +} + +type change struct { + file string + change merkletrie.Action +} + +// findChangedThrift reads a git repo and finds any Thrift files that got changed +// between HEAD and previous commit. +func findChangedThrift(r *git.Repository) (*treeChanges, error) { + // Get Repo's HEAD + refHead, err := r.Head() // *plumbing.Reference + if err != nil { + return nil, err + } + commit, err := r.CommitObject(refHead.Hash()) // *object.Commit + if err != nil { + return nil, err + } + parentCommit, err := commit.Parent(0) // *object.Commit + if err != nil { + return nil, err + } + // Get the two commit trees. + c, err := commit.Tree() // *object.Tree + if err != nil { + return nil, err + } + pc, err := parentCommit.Tree() // *object.Tree + if err != nil { + return nil, err + } + // Diff the trees and find what changed. + objects, _ := object.DiffTreeWithOptions(context.Background(), + pc, c, &object.DiffTreeOptions{DetectRenames: true}) // *object.Changes + var changed []*change + for _, o := range objects { + a, err := o.Action() // Insert, delete or modify. + if err != nil { + return nil, err + } + from, _, _ := o.Files() + // New file was added which doesnt have a name. + if from == nil { + continue + } + if filepath.Ext(from.Name) == ".thrift" { + changed = append(changed, &change{ + file: o.From.Name, + change: a, + }) + } + } + + return &treeChanges{ + from: pc, + to: c, + changes: changed}, nil +} diff --git a/internal/git/git_test.go b/internal/git/git_test.go new file mode 100644 index 00000000..300c7e0c --- /dev/null +++ b/internal/git/git_test.go @@ -0,0 +1,124 @@ +// Copyright (c) 2021 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +package git + +import ( + "testing" + + "github.com/go-git/go-git/v5" + "github.com/go-git/go-git/v5/utils/merkletrie" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "go.uber.org/thriftrw/internal/breaktest" +) + +func TestOpenRepoWithErrors(t *testing.T) { + tmpDir := t.TempDir() + from := map[string]string{ + "v1.thrift": "namespace rb v1\n" + + "struct AddedRequiredField {\n" + + " 1: optional string A\n" + + " 2: optional string B\n" + + "}\n" + + "\nservice Foo {\n void methodA()\n}", + "test/v2.thrift": `service Bar {}`, + "test/c.thrift": `service Baz {}`, + "test/d.thrift": `include "../v1.thrift" + service Qux {}`, // d.thrift will be deleted below. + "somefile.go": `service Quux{}`, // a .go file, not a .thrift. + } + // For c.thrift we are also checking to make sure includes work as expected. + to := map[string]string{ + "v1.thrift": "namespace rb v1\n" + + "struct AddedRequiredField {\n" + + " 1: optional string A\n" + + " 2: optional string B\n" + + " 3: required string C\n}\n" + + "service Foo {}", + "test/v2.thrift": `service Foo {}`, + "test/c.thrift": `include "../v1.thrift" + service Bar {}`, + "somefile.go": `service Qux{}`, + } + remove := []string{"test/d.thrift"} + repo := breaktest.CreateRepoAndCommit(t, tmpDir, from, to, remove) + treechanges, err := findChangedThrift(repo) + assert.NoError(t, err) + assert.Equal(t, []*change{ + {file: "test/c.thrift", change: merkletrie.Modify}, + {file: "test/d.thrift", change: merkletrie.Delete}, + {file: "test/v2.thrift", change: merkletrie.Modify}, + {file: "v1.thrift", change: merkletrie.Modify}, + }, treechanges.changes) + + pass, err := Compare(tmpDir) + require.NoError(t, err) + assert.Equal(t, + `c.thrift:deleting service "Baz"`+"\n"+ + `d.thrift:deleting service "Qux"`+"\n"+ + `v2.thrift:deleting service "Bar"`+"\n"+ + `v1.thrift:removing method "methodA" in service "Foo"`+"\n"+ + `v1.thrift:adding a required field "C" to "AddedRequiredField"`+"\n", + pass.String()) +} + +func TestNewFileAdded(t *testing.T) { + tmpDir := t.TempDir() + from := map[string]string{ + "v1.thrift": "namespace rb v1\n" + + "struct AddedRequiredField {\n" + + " 1: optional string A\n" + + " 2: optional string B\n" + + "}\n" + + "\nservice Foo {\n void methodA()\n}", + } + // For c.thrift we are also checking to make sure includes work as expected. + to := map[string]string{ + "v1.thrift": "namespace rb v1\n" + + "struct AddedRequiredField {\n" + + " 1: optional string A\n" + + " 2: optional string B\n" + + " 3: required string C\n}\n" + + "service Foo {}", + "foo.proto": "", // Testing that we support new files being added. + } + repo := breaktest.CreateRepoAndCommit(t, tmpDir, from, to, nil) + treechanges, err := findChangedThrift(repo) + assert.NoError(t, err) + assert.Equal(t, []*change{ + {file: "v1.thrift", change: merkletrie.Modify}, + }, treechanges.changes) + + pass, err := Compare(tmpDir) + require.NoError(t, err) + assert.Equal(t, + `v1.thrift:removing method "methodA" in service "Foo"`+"\n"+ + `v1.thrift:adding a required field "C" to "AddedRequiredField"`+"\n", + pass.String()) +} + +func TestFindChangedThriftError(t *testing.T) { + tmpDir := t.TempDir() + repository, err := git.PlainInit(tmpDir, false) + require.NoError(t, err, "expect no error when creating a temporary repo") + _, err = findChangedThrift(repository) + assert.Error(t, err) +} diff --git a/internal/goast/package.go b/internal/goast/package.go index 41a44c46..21d063e3 100644 --- a/internal/goast/package.go +++ b/internal/goast/package.go @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Uber Technologies, Inc. +// Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal @@ -30,9 +30,7 @@ import ( // path. func DeterminePackageName(importPath string) string { packageName := filepath.Base(importPath) - if strings.HasSuffix(packageName, "-go") { - packageName = packageName[:len(packageName)-3] - } + packageName = strings.TrimSuffix(packageName, "-go") return strings.Map(func(c rune) rune { switch { diff --git a/internal/goast/reserved.go b/internal/goast/reserved.go index eb783148..4f83fdcc 100644 --- a/internal/goast/reserved.go +++ b/internal/goast/reserved.go @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Uber Technologies, Inc. +// Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/internal/iotest/chunk.go b/internal/iotest/chunk.go index 858e28b8..ec2d623f 100644 --- a/internal/iotest/chunk.go +++ b/internal/iotest/chunk.go @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Uber Technologies, Inc. +// Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/internal/multiplex/client.go b/internal/multiplex/client.go index cf219b37..9ab5a3c5 100644 --- a/internal/multiplex/client.go +++ b/internal/multiplex/client.go @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Uber Technologies, Inc. +// Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/internal/multiplex/handler.go b/internal/multiplex/handler.go index 0662668b..5cb44989 100644 --- a/internal/multiplex/handler.go +++ b/internal/multiplex/handler.go @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Uber Technologies, Inc. +// Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/internal/plugin/builtin/pluginapigen/handle.go b/internal/plugin/builtin/pluginapigen/handle.go index d8c602ff..7755e75a 100644 --- a/internal/plugin/builtin/pluginapigen/handle.go +++ b/internal/plugin/builtin/pluginapigen/handle.go @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Uber Technologies, Inc. +// Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/internal/plugin/empty.go b/internal/plugin/empty.go index bb369f6c..dad01025 100644 --- a/internal/plugin/empty.go +++ b/internal/plugin/empty.go @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Uber Technologies, Inc. +// Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/internal/plugin/errors.go b/internal/plugin/errors.go index 729af037..18f15861 100644 --- a/internal/plugin/errors.go +++ b/internal/plugin/errors.go @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Uber Technologies, Inc. +// Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/internal/plugin/flag.go b/internal/plugin/flag.go index 1c3b7323..b6b08935 100644 --- a/internal/plugin/flag.go +++ b/internal/plugin/flag.go @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Uber Technologies, Inc. +// Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/internal/plugin/gen.go b/internal/plugin/gen.go index 24da7fd8..c5b46a3b 100644 --- a/internal/plugin/gen.go +++ b/internal/plugin/gen.go @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Uber Technologies, Inc. +// Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/internal/plugin/handle.go b/internal/plugin/handle.go index 6b5e564f..a89332df 100644 --- a/internal/plugin/handle.go +++ b/internal/plugin/handle.go @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Uber Technologies, Inc. +// Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/internal/plugin/handletest/mock.go b/internal/plugin/handletest/mock.go index d7fbffba..38cd29f4 100644 --- a/internal/plugin/handletest/mock.go +++ b/internal/plugin/handletest/mock.go @@ -1,6 +1,6 @@ // Code generated by MockGen. DO NOT EDIT. -// Copyright (c) 2021 Uber Technologies, Inc. +// Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal @@ -25,36 +25,37 @@ package handletest import ( + reflect "reflect" + gomock "github.com/golang/mock/gomock" plugin "go.uber.org/thriftrw/internal/plugin" api "go.uber.org/thriftrw/plugin/api" - reflect "reflect" ) -// MockHandle is a mock of Handle interface +// MockHandle is a mock of Handle interface. type MockHandle struct { ctrl *gomock.Controller recorder *MockHandleMockRecorder } -// MockHandleMockRecorder is the mock recorder for MockHandle +// MockHandleMockRecorder is the mock recorder for MockHandle. type MockHandleMockRecorder struct { mock *MockHandle } -// NewMockHandle creates a new mock instance +// NewMockHandle creates a new mock instance. func NewMockHandle(ctrl *gomock.Controller) *MockHandle { mock := &MockHandle{ctrl: ctrl} mock.recorder = &MockHandleMockRecorder{mock} return mock } -// EXPECT returns an object that allows the caller to indicate expected use +// EXPECT returns an object that allows the caller to indicate expected use. func (m *MockHandle) EXPECT() *MockHandleMockRecorder { return m.recorder } -// Close mocks base method +// Close mocks base method. func (m *MockHandle) Close() error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Close") @@ -62,13 +63,13 @@ func (m *MockHandle) Close() error { return ret0 } -// Close indicates an expected call of Close +// Close indicates an expected call of Close. func (mr *MockHandleMockRecorder) Close() *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockHandle)(nil).Close)) } -// Name mocks base method +// Name mocks base method. func (m *MockHandle) Name() string { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Name") @@ -76,13 +77,13 @@ func (m *MockHandle) Name() string { return ret0 } -// Name indicates an expected call of Name +// Name indicates an expected call of Name. func (mr *MockHandleMockRecorder) Name() *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Name", reflect.TypeOf((*MockHandle)(nil).Name)) } -// ServiceGenerator mocks base method +// ServiceGenerator mocks base method. func (m *MockHandle) ServiceGenerator() plugin.ServiceGenerator { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ServiceGenerator") @@ -90,36 +91,36 @@ func (m *MockHandle) ServiceGenerator() plugin.ServiceGenerator { return ret0 } -// ServiceGenerator indicates an expected call of ServiceGenerator +// ServiceGenerator indicates an expected call of ServiceGenerator. func (mr *MockHandleMockRecorder) ServiceGenerator() *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ServiceGenerator", reflect.TypeOf((*MockHandle)(nil).ServiceGenerator)) } -// MockServiceGenerator is a mock of ServiceGenerator interface +// MockServiceGenerator is a mock of ServiceGenerator interface. type MockServiceGenerator struct { ctrl *gomock.Controller recorder *MockServiceGeneratorMockRecorder } -// MockServiceGeneratorMockRecorder is the mock recorder for MockServiceGenerator +// MockServiceGeneratorMockRecorder is the mock recorder for MockServiceGenerator. type MockServiceGeneratorMockRecorder struct { mock *MockServiceGenerator } -// NewMockServiceGenerator creates a new mock instance +// NewMockServiceGenerator creates a new mock instance. func NewMockServiceGenerator(ctrl *gomock.Controller) *MockServiceGenerator { mock := &MockServiceGenerator{ctrl: ctrl} mock.recorder = &MockServiceGeneratorMockRecorder{mock} return mock } -// EXPECT returns an object that allows the caller to indicate expected use +// EXPECT returns an object that allows the caller to indicate expected use. func (m *MockServiceGenerator) EXPECT() *MockServiceGeneratorMockRecorder { return m.recorder } -// Generate mocks base method +// Generate mocks base method. func (m *MockServiceGenerator) Generate(arg0 *api.GenerateServiceRequest) (*api.GenerateServiceResponse, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Generate", arg0) @@ -128,13 +129,13 @@ func (m *MockServiceGenerator) Generate(arg0 *api.GenerateServiceRequest) (*api. return ret0, ret1 } -// Generate indicates an expected call of Generate +// Generate indicates an expected call of Generate. func (mr *MockServiceGeneratorMockRecorder) Generate(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Generate", reflect.TypeOf((*MockServiceGenerator)(nil).Generate), arg0) } -// Handle mocks base method +// Handle mocks base method. func (m *MockServiceGenerator) Handle() plugin.Handle { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Handle") @@ -142,7 +143,7 @@ func (m *MockServiceGenerator) Handle() plugin.Handle { return ret0 } -// Handle indicates an expected call of Handle +// Handle indicates an expected call of Handle. func (mr *MockServiceGeneratorMockRecorder) Handle() *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Handle", reflect.TypeOf((*MockServiceGenerator)(nil).Handle)) diff --git a/internal/plugin/multi.go b/internal/plugin/multi.go index ddeca1b6..0a398a70 100644 --- a/internal/plugin/multi.go +++ b/internal/plugin/multi.go @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Uber Technologies, Inc. +// Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/internal/plugin/transport.go b/internal/plugin/transport.go index a5305950..919ca6f2 100644 --- a/internal/plugin/transport.go +++ b/internal/plugin/transport.go @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Uber Technologies, Inc. +// Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/internal/process/client.go b/internal/process/client.go index bcf43ddf..e7d63398 100644 --- a/internal/process/client.go +++ b/internal/process/client.go @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Uber Technologies, Inc. +// Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/internal/semver/compat.go b/internal/semver/compat.go index 3fa8680d..a477321c 100644 --- a/internal/semver/compat.go +++ b/internal/semver/compat.go @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Uber Technologies, Inc. +// Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/internal/semver/range.go b/internal/semver/range.go index 8d5d246f..a74f150a 100644 --- a/internal/semver/range.go +++ b/internal/semver/range.go @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Uber Technologies, Inc. +// Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/internal/semver/semver.go b/internal/semver/semver.go index 5d697d16..dbf05cfc 100644 --- a/internal/semver/semver.go +++ b/internal/semver/semver.go @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Uber Technologies, Inc. +// Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/main.go b/main.go index be293522..daf81988 100644 --- a/main.go +++ b/main.go @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Uber Technologies, Inc. +// Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/plugin/api/api.go b/plugin/api/api.go index 93b528ad..a14c0a54 100644 --- a/plugin/api/api.go +++ b/plugin/api/api.go @@ -1,7 +1,7 @@ -// Code generated by thriftrw v1.29.2. DO NOT EDIT. +// Code generated by thriftrw v1.30.0. DO NOT EDIT. // @generated -// Copyright (c) 2021 Uber Technologies, Inc. +// Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal @@ -47,13 +47,13 @@ const APIVersion int32 = 4 // Argument is a single Argument inside a Function. // For, // -// void setValue(1: string key, 2: string value) +// void setValue(1: string key, 2: string value) // // You get the arguments, // -// Argument{Name: "Key", Type: Type{SimpleType: SimpleTypeString}} +// Argument{Name: "Key", Type: Type{SimpleType: SimpleTypeString}} // -// Argument{Name: "Value", Type: Type{SimpleType: SimpleTypeString}} +// Argument{Name: "Value", Type: Type{SimpleType: SimpleTypeString}} type Argument struct { // Name of the argument. This is also the name of the argument field // inside the args/result struct for that function. diff --git a/plugin/api/plugin.go b/plugin/api/plugin.go index 9a172b2b..24281ca5 100644 --- a/plugin/api/plugin.go +++ b/plugin/api/plugin.go @@ -1,7 +1,7 @@ // Code generated by thriftrw --generate-plugin-api // @generated -// Copyright (c) 2021 Uber Technologies, Inc. +// Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/plugin/api/plugin_client.go b/plugin/api/plugin_client.go index f2c0ff85..7d45b979 100644 --- a/plugin/api/plugin_client.go +++ b/plugin/api/plugin_client.go @@ -1,7 +1,7 @@ // Code generated by thriftrw --generate-plugin-api // @generated -// Copyright (c) 2021 Uber Technologies, Inc. +// Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/plugin/api/plugin_handler.go b/plugin/api/plugin_handler.go index d980f0a4..db3b4772 100644 --- a/plugin/api/plugin_handler.go +++ b/plugin/api/plugin_handler.go @@ -1,7 +1,7 @@ // Code generated by thriftrw --generate-plugin-api // @generated -// Copyright (c) 2021 Uber Technologies, Inc. +// Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/plugin/api/servicegenerator.go b/plugin/api/servicegenerator.go index 471a86f4..82fd802a 100644 --- a/plugin/api/servicegenerator.go +++ b/plugin/api/servicegenerator.go @@ -1,7 +1,7 @@ // Code generated by thriftrw --generate-plugin-api // @generated -// Copyright (c) 2021 Uber Technologies, Inc. +// Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/plugin/api/servicegenerator_client.go b/plugin/api/servicegenerator_client.go index 201a32fd..7217db49 100644 --- a/plugin/api/servicegenerator_client.go +++ b/plugin/api/servicegenerator_client.go @@ -1,7 +1,7 @@ // Code generated by thriftrw --generate-plugin-api // @generated -// Copyright (c) 2021 Uber Technologies, Inc. +// Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/plugin/api/servicegenerator_handler.go b/plugin/api/servicegenerator_handler.go index 5c487301..bbcca1c8 100644 --- a/plugin/api/servicegenerator_handler.go +++ b/plugin/api/servicegenerator_handler.go @@ -1,7 +1,7 @@ // Code generated by thriftrw --generate-plugin-api // @generated -// Copyright (c) 2021 Uber Technologies, Inc. +// Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/plugin/doc.go b/plugin/doc.go index b3a2325f..487e050c 100644 --- a/plugin/doc.go +++ b/plugin/doc.go @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Uber Technologies, Inc. +// Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/plugin/gen.go b/plugin/gen.go index 9d68b6f6..6237b74c 100644 --- a/plugin/gen.go +++ b/plugin/gen.go @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Uber Technologies, Inc. +// Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/plugin/plugin.go b/plugin/plugin.go index a91e2bc4..fd22e9fc 100644 --- a/plugin/plugin.go +++ b/plugin/plugin.go @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Uber Technologies, Inc. +// Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/plugin/plugintest/api.go b/plugin/plugintest/api.go index 8ca2fb96..409f14f3 100644 --- a/plugin/plugintest/api.go +++ b/plugin/plugintest/api.go @@ -1,6 +1,6 @@ // Code generated by MockGen. DO NOT EDIT. -// Copyright (c) 2021 Uber Technologies, Inc. +// Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal @@ -25,35 +25,36 @@ package plugintest import ( + reflect "reflect" + gomock "github.com/golang/mock/gomock" api "go.uber.org/thriftrw/plugin/api" - reflect "reflect" ) -// MockPlugin is a mock of Plugin interface +// MockPlugin is a mock of Plugin interface. type MockPlugin struct { ctrl *gomock.Controller recorder *MockPluginMockRecorder } -// MockPluginMockRecorder is the mock recorder for MockPlugin +// MockPluginMockRecorder is the mock recorder for MockPlugin. type MockPluginMockRecorder struct { mock *MockPlugin } -// NewMockPlugin creates a new mock instance +// NewMockPlugin creates a new mock instance. func NewMockPlugin(ctrl *gomock.Controller) *MockPlugin { mock := &MockPlugin{ctrl: ctrl} mock.recorder = &MockPluginMockRecorder{mock} return mock } -// EXPECT returns an object that allows the caller to indicate expected use +// EXPECT returns an object that allows the caller to indicate expected use. func (m *MockPlugin) EXPECT() *MockPluginMockRecorder { return m.recorder } -// Goodbye mocks base method +// Goodbye mocks base method. func (m *MockPlugin) Goodbye() error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Goodbye") @@ -61,13 +62,13 @@ func (m *MockPlugin) Goodbye() error { return ret0 } -// Goodbye indicates an expected call of Goodbye +// Goodbye indicates an expected call of Goodbye. func (mr *MockPluginMockRecorder) Goodbye() *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Goodbye", reflect.TypeOf((*MockPlugin)(nil).Goodbye)) } -// Handshake mocks base method +// Handshake mocks base method. func (m *MockPlugin) Handshake(arg0 *api.HandshakeRequest) (*api.HandshakeResponse, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Handshake", arg0) @@ -76,36 +77,36 @@ func (m *MockPlugin) Handshake(arg0 *api.HandshakeRequest) (*api.HandshakeRespon return ret0, ret1 } -// Handshake indicates an expected call of Handshake +// Handshake indicates an expected call of Handshake. func (mr *MockPluginMockRecorder) Handshake(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Handshake", reflect.TypeOf((*MockPlugin)(nil).Handshake), arg0) } -// MockServiceGenerator is a mock of ServiceGenerator interface +// MockServiceGenerator is a mock of ServiceGenerator interface. type MockServiceGenerator struct { ctrl *gomock.Controller recorder *MockServiceGeneratorMockRecorder } -// MockServiceGeneratorMockRecorder is the mock recorder for MockServiceGenerator +// MockServiceGeneratorMockRecorder is the mock recorder for MockServiceGenerator. type MockServiceGeneratorMockRecorder struct { mock *MockServiceGenerator } -// NewMockServiceGenerator creates a new mock instance +// NewMockServiceGenerator creates a new mock instance. func NewMockServiceGenerator(ctrl *gomock.Controller) *MockServiceGenerator { mock := &MockServiceGenerator{ctrl: ctrl} mock.recorder = &MockServiceGeneratorMockRecorder{mock} return mock } -// EXPECT returns an object that allows the caller to indicate expected use +// EXPECT returns an object that allows the caller to indicate expected use. func (m *MockServiceGenerator) EXPECT() *MockServiceGeneratorMockRecorder { return m.recorder } -// Generate mocks base method +// Generate mocks base method. func (m *MockServiceGenerator) Generate(arg0 *api.GenerateServiceRequest) (*api.GenerateServiceResponse, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Generate", arg0) @@ -114,7 +115,7 @@ func (m *MockServiceGenerator) Generate(arg0 *api.GenerateServiceRequest) (*api. return ret0, ret1 } -// Generate indicates an expected call of Generate +// Generate indicates an expected call of Generate. func (mr *MockServiceGeneratorMockRecorder) Generate(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Generate", reflect.TypeOf((*MockServiceGenerator)(nil).Generate), arg0) diff --git a/plugin/template.go b/plugin/template.go index b2584011..80044cae 100644 --- a/plugin/template.go +++ b/plugin/template.go @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Uber Technologies, Inc. +// Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal @@ -45,11 +45,11 @@ type TemplateOption struct { // // The function may be anything accepted by text/template. // -// GoFileFromTemplate( -// filename, -// `package `, -// TemplateFunc("lower", strings.ToLower), -// ) +// GoFileFromTemplate( +// filename, +// `package `, +// TemplateFunc("lower", strings.ToLower), +// ) func TemplateFunc(name string, f interface{}) TemplateOption { return TemplateOption{apply: func(t *goFileGenerator) { t.templateFuncs[name] = f @@ -59,11 +59,11 @@ func TemplateFunc(name string, f interface{}) TemplateOption { // GoFileImportPath is a TemplateOption that specifies the intended absolute // import path for the file being generated. // -// GoFileFromTemplate( -// filename, -// mytemplate, -// GoFileImportPath("go.uber.org/thriftrw/myservice"), -// ) +// GoFileFromTemplate( +// filename, +// mytemplate, +// GoFileImportPath("go.uber.org/thriftrw/myservice"), +// ) // // If specified, this changes the behavior of the `formatType` template // function to NOT import this package and instead use the types directly @@ -74,6 +74,25 @@ func GoFileImportPath(path string) TemplateOption { }} } +// AddTemplate is a TemplateOption that adds a new template into the rendering +// context of the main template. +// +// GoFileFromTemplate( +// filename, +// mytemplate, +// AddTemplate("example", "Reusable block<.>"), +// ) +// +// If specified, you can reference any defined block in the additional template +// inside of the main template. +// +// tmpl should be a string version of a template, not a filename. +func AddTemplate(tmplName string, tmpl string) TemplateOption { + return TemplateOption{apply: func(t *goFileGenerator) { + t.additionalTmpls[tmplName] = tmpl + }} +} + // goFileGenerator generates a single Go file. type goFileGenerator struct { importPath string @@ -84,13 +103,17 @@ type goFileGenerator struct { // import path -> import name imports map[string]string + + // additional templates that can contain reusable blocks + additionalTmpls map[string]string } func newGoFileGenerator(opts []TemplateOption) *goFileGenerator { t := goFileGenerator{ - templateFuncs: make(template.FuncMap), - globals: make(map[string]struct{}), - imports: make(map[string]string), + templateFuncs: make(template.FuncMap), + globals: make(map[string]struct{}), + imports: make(map[string]string), + additionalTmpls: make(map[string]string), } for _, opt := range opts { opt.apply(&t) @@ -203,6 +226,13 @@ func (g *goFileGenerator) Generate(filename, tmpl string, data interface{}) ([]b return nil, fmt.Errorf("failed to parse template %q: %v", filename, err) } + for tmplName, additionalTmpl := range g.additionalTmpls { + _, err = t.New(tmplName).Parse(additionalTmpl) + if err != nil { + return nil, fmt.Errorf("failed to parse additional template %s for file %s: %w", tmplName, filename, err) + } + } + var buff bytes.Buffer if err := t.Execute(&buff, data); err != nil { return nil, err @@ -251,8 +281,8 @@ func (g *goFileGenerator) Generate(filename, tmpl string, data interface{}) ([]b // imported name of the package. Use the return value of this function to // reference the imported package. // -// <$wire := import "go.uber.org/thriftrw/wire"> -// var value <$wire>.Value +// <$wire := import "go.uber.org/thriftrw/wire"> +// var value <$wire>.Value // // formatType: Formats an api.Type into a Go type representation, automatically // importing packages needed for type references. By default, this imports all @@ -260,7 +290,7 @@ func (g *goFileGenerator) Generate(filename, tmpl string, data interface{}) ([]b // specified, types from that package will not be imported and instead, will be // assumed to be available in the same package. // -// var value +// var value // // More functions may be added to the template using the TemplateFunc template // option. If the name of a TemplateFunc conflicts with a pre-defined function, diff --git a/plugin/template_test.go b/plugin/template_test.go index 66578dfb..91a4b619 100644 --- a/plugin/template_test.go +++ b/plugin/template_test.go @@ -261,6 +261,46 @@ func TestGoFileFromTemplate(t *testing.T) { `var x foo_bar.Foo1 = foo_bar2.Foo2`, ), }, + { + desc: "use define block", + template: ` + package hello + +