From 729f2d0bd6884432d5db4591d2d3691d69536b30 Mon Sep 17 00:00:00 2001 From: Josh Hamill Date: Tue, 23 Jul 2024 13:22:46 -0400 Subject: [PATCH 1/2] fix: generated wire file to be compatible with workspaces --- cmd/wire/main.go | 3 ++ .../wire/testdata/ModeOverride/foo/foo.go | 29 ++++++++++++++++ .../wire/testdata/ModeOverride/foo/wire.go | 26 +++++++++++++++ internal/wire/testdata/ModeOverride/mode | 1 + internal/wire/testdata/ModeOverride/pkg | 1 + .../ModeOverride/want/program_out.txt | 1 + .../testdata/ModeOverride/want/wire_gen.go | 14 ++++++++ internal/wire/testdata/ModeUnset/foo/foo.go | 29 ++++++++++++++++ internal/wire/testdata/ModeUnset/foo/wire.go | 26 +++++++++++++++ internal/wire/testdata/ModeUnset/mode | 1 + internal/wire/testdata/ModeUnset/pkg | 1 + .../testdata/ModeUnset/want/program_out.txt | 1 + .../wire/testdata/ModeUnset/want/wire_gen.go | 14 ++++++++ internal/wire/wire.go | 33 +++++++++++++++++-- internal/wire/wire_test.go | 5 ++- 15 files changed, 181 insertions(+), 4 deletions(-) create mode 100644 internal/wire/testdata/ModeOverride/foo/foo.go create mode 100644 internal/wire/testdata/ModeOverride/foo/wire.go create mode 100644 internal/wire/testdata/ModeOverride/mode create mode 100644 internal/wire/testdata/ModeOverride/pkg create mode 100644 internal/wire/testdata/ModeOverride/want/program_out.txt create mode 100644 internal/wire/testdata/ModeOverride/want/wire_gen.go create mode 100644 internal/wire/testdata/ModeUnset/foo/foo.go create mode 100644 internal/wire/testdata/ModeUnset/foo/wire.go create mode 100644 internal/wire/testdata/ModeUnset/mode create mode 100644 internal/wire/testdata/ModeUnset/pkg create mode 100644 internal/wire/testdata/ModeUnset/want/program_out.txt create mode 100644 internal/wire/testdata/ModeUnset/want/wire_gen.go diff --git a/cmd/wire/main.go b/cmd/wire/main.go index fa37e51d..a6d7bfe0 100644 --- a/cmd/wire/main.go +++ b/cmd/wire/main.go @@ -101,6 +101,7 @@ type genCmd struct { headerFile string prefixFileName string tags string + mode string } func (*genCmd) Name() string { return "gen" } @@ -119,6 +120,7 @@ func (cmd *genCmd) SetFlags(f *flag.FlagSet) { f.StringVar(&cmd.headerFile, "header_file", "", "path to file to insert as a header in wire_gen.go") f.StringVar(&cmd.prefixFileName, "output_file_prefix", "", "string to prepend to output file names.") f.StringVar(&cmd.tags, "tags", "", "append build tags to the default wirebuild") + f.StringVar(&cmd.mode, "mod", "mod", "the build mode to use in the 'go run' command added to the generated header.") } func (cmd *genCmd) Execute(ctx context.Context, f *flag.FlagSet, args ...interface{}) subcommands.ExitStatus { @@ -135,6 +137,7 @@ func (cmd *genCmd) Execute(ctx context.Context, f *flag.FlagSet, args ...interfa opts.PrefixOutputFile = cmd.prefixFileName opts.Tags = cmd.tags + opts.Mode = cmd.mode outs, errs := wire.Generate(ctx, wd, os.Environ(), packages(f), opts) if len(errs) > 0 { diff --git a/internal/wire/testdata/ModeOverride/foo/foo.go b/internal/wire/testdata/ModeOverride/foo/foo.go new file mode 100644 index 00000000..67bc8a3e --- /dev/null +++ b/internal/wire/testdata/ModeOverride/foo/foo.go @@ -0,0 +1,29 @@ +// Copyright 2019 The Wire Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package main + +import ( + "fmt" +) + +func main() { + fmt.Println(injectFoo()) +} + +type Foo int + +func provideFoo() Foo { + return 41 +} diff --git a/internal/wire/testdata/ModeOverride/foo/wire.go b/internal/wire/testdata/ModeOverride/foo/wire.go new file mode 100644 index 00000000..957f1770 --- /dev/null +++ b/internal/wire/testdata/ModeOverride/foo/wire.go @@ -0,0 +1,26 @@ +// Copyright 2019 The Wire Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//+build wireinject + +package main + +import ( + "github.com/google/wire" +) + +func injectFoo() Foo { + wire.Build(provideFoo) + return Foo(0) +} diff --git a/internal/wire/testdata/ModeOverride/mode b/internal/wire/testdata/ModeOverride/mode new file mode 100644 index 00000000..3b3ccd2f --- /dev/null +++ b/internal/wire/testdata/ModeOverride/mode @@ -0,0 +1 @@ +readonly diff --git a/internal/wire/testdata/ModeOverride/pkg b/internal/wire/testdata/ModeOverride/pkg new file mode 100644 index 00000000..f7a5c8ce --- /dev/null +++ b/internal/wire/testdata/ModeOverride/pkg @@ -0,0 +1 @@ +example.com/foo diff --git a/internal/wire/testdata/ModeOverride/want/program_out.txt b/internal/wire/testdata/ModeOverride/want/program_out.txt new file mode 100644 index 00000000..87523dd7 --- /dev/null +++ b/internal/wire/testdata/ModeOverride/want/program_out.txt @@ -0,0 +1 @@ +41 diff --git a/internal/wire/testdata/ModeOverride/want/wire_gen.go b/internal/wire/testdata/ModeOverride/want/wire_gen.go new file mode 100644 index 00000000..c5c5044c --- /dev/null +++ b/internal/wire/testdata/ModeOverride/want/wire_gen.go @@ -0,0 +1,14 @@ +// Code generated by Wire. DO NOT EDIT. + +//go:generate go run -mod=readonly github.com/google/wire/cmd/wire +//go:build !wireinject +// +build !wireinject + +package main + +// Injectors from wire.go: + +func injectFoo() Foo { + foo := provideFoo() + return foo +} diff --git a/internal/wire/testdata/ModeUnset/foo/foo.go b/internal/wire/testdata/ModeUnset/foo/foo.go new file mode 100644 index 00000000..67bc8a3e --- /dev/null +++ b/internal/wire/testdata/ModeUnset/foo/foo.go @@ -0,0 +1,29 @@ +// Copyright 2019 The Wire Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package main + +import ( + "fmt" +) + +func main() { + fmt.Println(injectFoo()) +} + +type Foo int + +func provideFoo() Foo { + return 41 +} diff --git a/internal/wire/testdata/ModeUnset/foo/wire.go b/internal/wire/testdata/ModeUnset/foo/wire.go new file mode 100644 index 00000000..957f1770 --- /dev/null +++ b/internal/wire/testdata/ModeUnset/foo/wire.go @@ -0,0 +1,26 @@ +// Copyright 2019 The Wire Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//+build wireinject + +package main + +import ( + "github.com/google/wire" +) + +func injectFoo() Foo { + wire.Build(provideFoo) + return Foo(0) +} diff --git a/internal/wire/testdata/ModeUnset/mode b/internal/wire/testdata/ModeUnset/mode new file mode 100644 index 00000000..4eb25b6e --- /dev/null +++ b/internal/wire/testdata/ModeUnset/mode @@ -0,0 +1 @@ +unset diff --git a/internal/wire/testdata/ModeUnset/pkg b/internal/wire/testdata/ModeUnset/pkg new file mode 100644 index 00000000..f7a5c8ce --- /dev/null +++ b/internal/wire/testdata/ModeUnset/pkg @@ -0,0 +1 @@ +example.com/foo diff --git a/internal/wire/testdata/ModeUnset/want/program_out.txt b/internal/wire/testdata/ModeUnset/want/program_out.txt new file mode 100644 index 00000000..87523dd7 --- /dev/null +++ b/internal/wire/testdata/ModeUnset/want/program_out.txt @@ -0,0 +1 @@ +41 diff --git a/internal/wire/testdata/ModeUnset/want/wire_gen.go b/internal/wire/testdata/ModeUnset/want/wire_gen.go new file mode 100644 index 00000000..52d70b49 --- /dev/null +++ b/internal/wire/testdata/ModeUnset/want/wire_gen.go @@ -0,0 +1,14 @@ +// Code generated by Wire. DO NOT EDIT. + +//go:generate go run github.com/google/wire/cmd/wire +//go:build !wireinject +// +build !wireinject + +package main + +// Injectors from wire.go: + +func injectFoo() Foo { + foo := provideFoo() + return foo +} diff --git a/internal/wire/wire.go b/internal/wire/wire.go index 5cedeb1a..a1d5529a 100644 --- a/internal/wire/wire.go +++ b/internal/wire/wire.go @@ -66,6 +66,7 @@ type GenerateOptions struct { Header []byte PrefixOutputFile string Tags string + Mode string } // Generate performs dependency injection for the packages that match the given @@ -88,6 +89,10 @@ func Generate(ctx context.Context, wd string, env []string, patterns []string, o if len(errs) > 0 { return nil, errs } + validatedMode, err := validateMode(opts.Mode) + if err != nil { + return nil, []error{err} + } generated := make([]GenerateResult, len(pkgs)) for i, pkg := range pkgs { generated[i].PkgPath = pkg.PkgPath @@ -104,7 +109,7 @@ func Generate(ctx context.Context, wd string, env []string, patterns []string, o continue } copyNonInjectorDecls(g, injectorFiles, pkg.TypesInfo) - goSrc := g.frame(opts.Tags) + goSrc := g.frame(opts.Tags, validatedMode) if len(opts.Header) > 0 { goSrc = append(opts.Header, goSrc...) } @@ -134,6 +139,23 @@ func detectOutputDir(paths []string) (string, error) { return dir, nil } +// validateMode ensures that the value for mode is a value that can be expected by 'go build' +func validateMode(mode string) (string, error) { + // To maintain backwards compatibility, if mode is blank we can + // default to "mod" here for now + if mode == "" { + return "mod", nil + } + + // These are the modes defined by the 'mod' flag in + // https://pkg.go.dev/cmd/go#hdr-Compile_packages_and_dependencies + if mode != "unset" && mode != "mod" && mode != "vendor" && mode != "readonly" { + return "", fmt.Errorf("Invalid build mode: %s", mode) + } + + return mode, nil +} + // generateInjectors generates the injectors for a given package. func generateInjectors(g *gen, pkg *packages.Package) (injectorFiles []*ast.File, _ []error) { oc := newObjectCache([]*packages.Package{pkg}) @@ -258,7 +280,7 @@ func newGen(pkg *packages.Package) *gen { } // frame bakes the built up source body into an unformatted Go source file. -func (g *gen) frame(tags string) []byte { +func (g *gen) frame(tags, mode string) []byte { if g.buf.Len() == 0 { return nil } @@ -267,7 +289,12 @@ func (g *gen) frame(tags string) []byte { tags = fmt.Sprintf(" gen -tags \"%s\"", tags) } buf.WriteString("// Code generated by Wire. DO NOT EDIT.\n\n") - buf.WriteString("//go:generate go run -mod=mod github.com/google/wire/cmd/wire" + tags + "\n") + + if mode == "unset" { + buf.WriteString("//go:generate go run github.com/google/wire/cmd/wire" + tags + "\n") + } else { + buf.WriteString("//go:generate go run -mod=" + mode + " github.com/google/wire/cmd/wire" + tags + "\n") + } buf.WriteString("//+build !wireinject\n\n") buf.WriteString("package ") buf.WriteString(g.pkg.Name) diff --git a/internal/wire/wire_test.go b/internal/wire/wire_test.go index 6389ac6d..7f63bb0e 100644 --- a/internal/wire/wire_test.go +++ b/internal/wire/wire_test.go @@ -88,7 +88,7 @@ func TestWire(t *testing.T) { t.Fatal(err) } wd := filepath.Join(gopath, "src", "example.com") - gens, errs := Generate(ctx, wd, append(os.Environ(), "GOPATH="+gopath), []string{test.pkg}, &GenerateOptions{Header: test.header}) + gens, errs := Generate(ctx, wd, append(os.Environ(), "GOPATH="+gopath), []string{test.pkg}, &GenerateOptions{Header: test.header, Mode: test.mode}) var gen GenerateResult if len(gens) > 1 { t.Fatalf("got %d generated files, want 0 or 1", len(gens)) @@ -427,6 +427,7 @@ type testCase struct { name string pkg string header []byte + mode string goFiles map[string][]byte wantProgramOutput []byte wantWireOutput []byte @@ -470,6 +471,7 @@ func loadTestCase(root string, wireGoSrc []byte) (*testCase, error) { return nil, fmt.Errorf("load test case %s: %v", name, err) } header, _ := ioutil.ReadFile(filepath.Join(root, "header")) + mode, _ := ioutil.ReadFile(filepath.Join(root, "mode")) var wantProgramOutput []byte var wantWireOutput []byte wireErrb, err := ioutil.ReadFile(filepath.Join(root, "want", "wire_errs.txt")) @@ -521,6 +523,7 @@ func loadTestCase(root string, wireGoSrc []byte) (*testCase, error) { name: name, pkg: string(bytes.TrimSpace(pkg)), header: header, + mode: string(bytes.TrimSpace(mode)), goFiles: goFiles, wantWireOutput: wantWireOutput, wantProgramOutput: wantProgramOutput, From 6dea031966d3bf06d9617630416a99c964fcd041 Mon Sep 17 00:00:00 2001 From: Josh Hamill Date: Tue, 23 Jul 2024 20:26:09 -0400 Subject: [PATCH 2/2] fix: propogate mod flag to the generated file --- .../wire/testdata/ModeOverride/want/wire_gen.go | 2 +- .../wire/testdata/ModeUnset/want/wire_gen.go | 2 +- internal/wire/wire.go | 16 +++++++++++++--- 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/internal/wire/testdata/ModeOverride/want/wire_gen.go b/internal/wire/testdata/ModeOverride/want/wire_gen.go index c5c5044c..be173264 100644 --- a/internal/wire/testdata/ModeOverride/want/wire_gen.go +++ b/internal/wire/testdata/ModeOverride/want/wire_gen.go @@ -1,6 +1,6 @@ // Code generated by Wire. DO NOT EDIT. -//go:generate go run -mod=readonly github.com/google/wire/cmd/wire +//go:generate go run -mod=readonly github.com/google/wire/cmd/wire gen -mod=readonly //go:build !wireinject // +build !wireinject diff --git a/internal/wire/testdata/ModeUnset/want/wire_gen.go b/internal/wire/testdata/ModeUnset/want/wire_gen.go index 52d70b49..2fc3e80a 100644 --- a/internal/wire/testdata/ModeUnset/want/wire_gen.go +++ b/internal/wire/testdata/ModeUnset/want/wire_gen.go @@ -1,6 +1,6 @@ // Code generated by Wire. DO NOT EDIT. -//go:generate go run github.com/google/wire/cmd/wire +//go:generate go run github.com/google/wire/cmd/wire gen -mod=unset //go:build !wireinject // +build !wireinject diff --git a/internal/wire/wire.go b/internal/wire/wire.go index a1d5529a..5e45f92e 100644 --- a/internal/wire/wire.go +++ b/internal/wire/wire.go @@ -285,15 +285,25 @@ func (g *gen) frame(tags, mode string) []byte { return nil } var buf bytes.Buffer + suffix := "" + if len(tags) > 0 || (len(mode) > 0 && mode != "mod") { + suffix = " gen" + } + + if len(mode) > 0 && mode != "mod" { + suffix += fmt.Sprintf(" -mod=%s", mode) + } + if len(tags) > 0 { - tags = fmt.Sprintf(" gen -tags \"%s\"", tags) + suffix += fmt.Sprintf(" -tags \"%s\"", tags) } + buf.WriteString("// Code generated by Wire. DO NOT EDIT.\n\n") if mode == "unset" { - buf.WriteString("//go:generate go run github.com/google/wire/cmd/wire" + tags + "\n") + buf.WriteString("//go:generate go run github.com/google/wire/cmd/wire" + suffix + "\n") } else { - buf.WriteString("//go:generate go run -mod=" + mode + " github.com/google/wire/cmd/wire" + tags + "\n") + buf.WriteString("//go:generate go run -mod=" + mode + " github.com/google/wire/cmd/wire" + suffix + "\n") } buf.WriteString("//+build !wireinject\n\n") buf.WriteString("package ")