From 9caa70a2d497e0a9dbb9f19aa4957e91c0bd4f91 Mon Sep 17 00:00:00 2001 From: Tiernan Messmer Date: Fri, 28 Feb 2025 13:18:32 +1000 Subject: [PATCH 1/2] support running tools with go tool --- CHANGELOG.md | 1 + cmd/protoc-gen-go-patch/main.go | 15 +++++++++++---- patch/plugin.go | 26 +++++++++++++++++--------- 3 files changed, 29 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5276daa..5d7474b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ This module now requires [Go 1.21](https://go.dev/doc/go1.21) or higher. ### Added - Added support for [buf.build](https://buf.build/alta/protopatch). +- Added support for running tools with Go1.24's `go tool` by specifying use_go_tool=true ### Notes - Changelog from here forward will only include major dependency updates. diff --git a/cmd/protoc-gen-go-patch/main.go b/cmd/protoc-gen-go-patch/main.go index 6a6069d..ccb2058 100644 --- a/cmd/protoc-gen-go-patch/main.go +++ b/cmd/protoc-gen-go-patch/main.go @@ -2,10 +2,11 @@ package main import ( "fmt" - "io/ioutil" + "io" "log" "os" "path/filepath" + "strconv" "strings" "github.com/alta/protopatch/patch" @@ -36,12 +37,18 @@ func run() error { } var plugin string + var useGoTool bool opts := protogen.Options{ ParamFunc: func(name, value string) error { switch name { case "plugin": plugin = value + case "use_go_tool": + useGoTool, err = strconv.ParseBool(value) + if err != nil { + return err + } } return nil // Ignore unknown params. }, @@ -58,14 +65,14 @@ func run() error { } if os.Getenv("PROTO_PATCH_DEBUG_LOGGING") == "" { - log.SetOutput(ioutil.Discard) + log.SetOutput(io.Discard) } // Strip our custom param(s). - patch.StripParam(gen.Request, "plugin") + patch.StripParams(gen.Request, []string{"plugin", "use_go_tool"}) // Run the specified plugin and unmarshal the CodeGeneratorResponse. - res, err := patch.RunPlugin(plugin, gen.Request, nil) + res, err := patch.RunPlugin(plugin, gen.Request, nil, useGoTool) if err != nil { return err } diff --git a/patch/plugin.go b/patch/plugin.go index 51a01da..d2cd8a0 100644 --- a/patch/plugin.go +++ b/patch/plugin.go @@ -3,29 +3,29 @@ package patch import ( "bytes" "io" - "io/ioutil" "os" "os/exec" + "slices" "strings" "google.golang.org/protobuf/proto" "google.golang.org/protobuf/types/pluginpb" ) -// StripParam strips a named param from req. -func StripParam(req *pluginpb.CodeGeneratorRequest, p string) { +// StripParams strips a named param from req. +func StripParams(req *pluginpb.CodeGeneratorRequest, p []string) { if req.Parameter == nil { return } - v := stripParam(*req.Parameter, p) + v := stripParams(*req.Parameter, p) req.Parameter = &v } -func stripParam(s, p string) string { +func stripParams(s string, p []string) string { var b strings.Builder for _, param := range strings.Split(s, ",") { - if strings.SplitN(param, "=", 2)[0] != p { + if !slices.Contains(p, strings.SplitN(param, "=", 2)[0]) { if b.Len() > 0 { b.WriteString(",") } @@ -38,7 +38,7 @@ func stripParam(s, p string) string { // RunPlugin runs a protoc plugin named "protoc-gen-$plugin" // and returns the generated CodeGeneratorResponse or an error. // Supply a non-nil stderr to override stderr on the called plugin. -func RunPlugin(plugin string, req *pluginpb.CodeGeneratorRequest, stderr io.Writer) (*pluginpb.CodeGeneratorResponse, error) { +func RunPlugin(plugin string, req *pluginpb.CodeGeneratorRequest, stderr io.Writer, useGoTool bool) (*pluginpb.CodeGeneratorResponse, error) { if stderr == nil { stderr = os.Stderr } @@ -50,8 +50,16 @@ func RunPlugin(plugin string, req *pluginpb.CodeGeneratorRequest, stderr io.Writ } // Call the plugin with the modified CodeGeneratorRequest. + cmdName := "protoc-gen-" + plugin + var args []string + + if useGoTool { + args = []string{"tool", cmdName} + cmdName = "go" + } + var buf bytes.Buffer - cmd := exec.Command("protoc-gen-" + plugin) + cmd := exec.Command(cmdName, args...) cmd.Stdin = bytes.NewReader(b) cmd.Stdout = &buf cmd.Stderr = stderr @@ -71,7 +79,7 @@ func RunPlugin(plugin string, req *pluginpb.CodeGeneratorRequest, stderr io.Writ // ReadRequest reads and unmarshals a CodeGeneratorRequest. func ReadRequest(r io.Reader) (*pluginpb.CodeGeneratorRequest, error) { - in, err := ioutil.ReadAll(os.Stdin) + in, err := io.ReadAll(r) if err != nil { return nil, err } From e32a49b9470a99a2d80d363aaade8a0946e51eef Mon Sep 17 00:00:00 2001 From: Tiernan Messmer Date: Wed, 28 May 2025 14:04:20 +1000 Subject: [PATCH 2/2] change use_go_tool to tool --- CHANGELOG.md | 2 +- cmd/protoc-gen-go-patch/main.go | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5d7474b..1a5cbfa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,7 +8,7 @@ This module now requires [Go 1.21](https://go.dev/doc/go1.21) or higher. ### Added - Added support for [buf.build](https://buf.build/alta/protopatch). -- Added support for running tools with Go1.24's `go tool` by specifying use_go_tool=true +- Added support for running tools with Go1.24's `go tool` by specifying tool=true ### Notes - Changelog from here forward will only include major dependency updates. diff --git a/cmd/protoc-gen-go-patch/main.go b/cmd/protoc-gen-go-patch/main.go index ccb2058..bb5b308 100644 --- a/cmd/protoc-gen-go-patch/main.go +++ b/cmd/protoc-gen-go-patch/main.go @@ -44,7 +44,7 @@ func run() error { switch name { case "plugin": plugin = value - case "use_go_tool": + case "tool": useGoTool, err = strconv.ParseBool(value) if err != nil { return err @@ -69,7 +69,7 @@ func run() error { } // Strip our custom param(s). - patch.StripParams(gen.Request, []string{"plugin", "use_go_tool"}) + patch.StripParams(gen.Request, []string{"plugin", "tool"}) // Run the specified plugin and unmarshal the CodeGeneratorResponse. res, err := patch.RunPlugin(plugin, gen.Request, nil, useGoTool)