From 2403871bed37958d4e90ad3893017ac1a2173555 Mon Sep 17 00:00:00 2001 From: Florian Klink Date: Sat, 26 Nov 2022 16:33:40 +0000 Subject: fix(third_party/nixpkgs): add support for --bytes-as-base64 in evans This is very helpful when calling an RPC method that accepts bytes. Upstreamed to https://github.com/ktr0731/evans/pull/611. Change-Id: Ibdaa1e3ff2aed9c86816e81de6f7652042c9fb11 Reviewed-on: https://cl.tvl.fyi/c/depot/+/7436 Reviewed-by: tazjin Tested-by: BuildkiteCI --- .../evans-add-support-for-bytes-as-base64.patch | 153 +++++++++++++++++++++ third_party/overlays/tvl.nix | 7 + 2 files changed, 160 insertions(+) create mode 100644 third_party/overlays/patches/evans-add-support-for-bytes-as-base64.patch (limited to 'third_party/overlays') diff --git a/third_party/overlays/patches/evans-add-support-for-bytes-as-base64.patch b/third_party/overlays/patches/evans-add-support-for-bytes-as-base64.patch new file mode 100644 index 0000000000..1c4e67cc40 --- /dev/null +++ b/third_party/overlays/patches/evans-add-support-for-bytes-as-base64.patch @@ -0,0 +1,153 @@ +From f3e26c276256cb053de94725c10fecf243f11a68 Mon Sep 17 00:00:00 2001 +From: Florian Klink +Date: Sat, 26 Nov 2022 12:16:53 +0000 +Subject: [PATCH] Add support for --bytes-as-base64 + +This allows entering bytes as a base64-encoded string, using the standard +encoding. +--- + README.md | 6 ++++++ + .../fixtures/teste2e_repl-call_--help.golden | 3 ++- + fill/filler.go | 2 ++ + fill/proto/interactive_filler.go | 8 +++++++- + repl/commands.go | 13 ++++++++++--- + usecase/call_rpc.go | 7 ++++--- + 6 files changed, 31 insertions(+), 8 deletions(-) + +diff --git a/README.md b/README.md +index 0f5932d..c02bf00 100644 +--- a/README.md ++++ b/README.md +@@ -279,6 +279,12 @@ data (TYPE_BYTES) => \u65e5\u672c\u8a9e + } + ``` + ++Or add the flag `--bytes-as-base64` to pass bytes as a base64-encoded string ++``` ++> call UnaryBytes --bytes-as-base64 ++data (TYPE_BYTES) => SGVsbG8gV29ybGQh ++``` ++ + Or add the flag `--bytes-from-file` to read bytes from the provided relative path + ``` + > call UnaryBytes --bytes-from-file +diff --git a/e2e/testdata/fixtures/teste2e_repl-call_--help.golden b/e2e/testdata/fixtures/teste2e_repl-call_--help.golden +index 3fb24b3..e9b83e1 100644 +--- a/e2e/testdata/fixtures/teste2e_repl-call_--help.golden ++++ b/e2e/testdata/fixtures/teste2e_repl-call_--help.golden +@@ -2,7 +2,8 @@ usage: call + + Options: + --add-repeated-manually prompt asks whether to add a value if it encountered to a repeated field +- --bytes-from-file interpret TYPE_BYTES input as a relative path to a file ++ --bytes-as-base64 interpret TYPE_BYTES input as base64-encoded string (mutually exclusive with --bytes-from-file) ++ --bytes-from-file interpret TYPE_BYTES input as a relative path to a file (mutually exclusive with --bytes-as-base64) + --dig-manually prompt asks whether to dig down if it encountered to a message field + --emit-defaults render fields with default values + --enrich enrich response output includes header, message, trailer and status +diff --git a/fill/filler.go b/fill/filler.go +index c53a62d..e0a96b9 100644 +--- a/fill/filler.go ++++ b/fill/filler.go +@@ -22,6 +22,8 @@ type Filler interface { + type InteractiveFillerOpts struct { + // DigManually is true, Fill asks whether to dig down if it encountered to a message field. + DigManually, ++ // BytesAsBase64 is true, Fill will interpret input as base64-encoded string ++ BytesAsBase64, + // BytesFromFile is true, Fill will read the contents of the file from the provided relative path. + BytesFromFile, + // AddRepeatedManually is true, Fill asks whether to add a repeated field value +diff --git a/fill/proto/interactive_filler.go b/fill/proto/interactive_filler.go +index fda0f8d..9b0d18c 100644 +--- a/fill/proto/interactive_filler.go ++++ b/fill/proto/interactive_filler.go +@@ -1,6 +1,7 @@ + package proto + + import ( ++ "encoding/base64" + "fmt" + "io" + "io/ioutil" +@@ -201,7 +202,12 @@ func (r *resolver) resolveField(f *desc.FieldDescriptor) error { + // So, we need to call strconv.Unquote to interpret backslashes as an escape sequence. + case descriptorpb.FieldDescriptorProto_TYPE_BYTES: + converter = func(v string) (interface{}, error) { +- if r.opts.BytesFromFile { ++ if r.opts.BytesAsBase64 { ++ b, err := base64.StdEncoding.DecodeString(v) ++ if err == nil { ++ return b, nil ++ } ++ } else if r.opts.BytesFromFile { + b, err := ioutil.ReadFile(v) + if err == nil { + return b, nil +diff --git a/repl/commands.go b/repl/commands.go +index 6ba677e..a203ab9 100644 +--- a/repl/commands.go ++++ b/repl/commands.go +@@ -155,7 +155,7 @@ func (c *showCommand) Run(w io.Writer, args []string) error { + } + + type callCommand struct { +- enrich, digManually, bytesFromFile, emitDefaults, repeatCall, addRepeatedManually bool ++ enrich, digManually, bytesAsBase64, bytesFromFile, emitDefaults, repeatCall, addRepeatedManually bool + } + + func (c *callCommand) FlagSet() (*pflag.FlagSet, bool) { +@@ -163,7 +163,8 @@ func (c *callCommand) FlagSet() (*pflag.FlagSet, bool) { + fs.Usage = func() {} // Disable help output when an error occurred. + fs.BoolVar(&c.enrich, "enrich", false, "enrich response output includes header, message, trailer and status") + fs.BoolVar(&c.digManually, "dig-manually", false, "prompt asks whether to dig down if it encountered to a message field") +- fs.BoolVar(&c.bytesFromFile, "bytes-from-file", false, "interpret TYPE_BYTES input as a relative path to a file") ++ fs.BoolVar(&c.bytesAsBase64, "bytes-as-base64", false, "interpret TYPE_BYTES input as base64-encoded string (mutually exclusive with --bytes-from-file)") ++ fs.BoolVar(&c.bytesFromFile, "bytes-from-file", false, "interpret TYPE_BYTES input as a relative path to a file (mutually exclusive with --bytes-as-base64)") + fs.BoolVar(&c.emitDefaults, "emit-defaults", false, "render fields with default values") + fs.BoolVarP(&c.repeatCall, "repeat", "r", false, "repeat previous unary or server streaming request (if exists)") + fs.BoolVar(&c.addRepeatedManually, "add-repeated-manually", false, "prompt asks whether to add a value if it encountered to a repeated field") +@@ -199,9 +200,15 @@ func (c *callCommand) Run(w io.Writer, args []string) error { + }, + ) + ++ // Ensure bytesAsBase64 and bytesFromFile are not both set ++ // pflag doesn't suppport mutually exclusive flags (https://github.com/spf13/pflag/issues/270) ++ if c.bytesAsBase64 && c.bytesFromFile { ++ return errors.New("only one of --bytes-as-base64 or --bytes-from-file can be specified") ++ } ++ + // here we create the request context + // we also add the call command flags here +- err := usecase.CallRPCInteractively(context.Background(), w, args[0], c.digManually, c.bytesFromFile, c.repeatCall, c.addRepeatedManually) ++ err := usecase.CallRPCInteractively(context.Background(), w, args[0], c.digManually, c.bytesAsBase64, c.bytesFromFile, c.repeatCall, c.addRepeatedManually) + if errors.Is(err, io.EOF) { + return errors.New("inputting canceled") + } +diff --git a/usecase/call_rpc.go b/usecase/call_rpc.go +index e5f9415..48e795e 100644 +--- a/usecase/call_rpc.go ++++ b/usecase/call_rpc.go +@@ -478,15 +478,16 @@ func (f *interactiveFiller) Fill(v interface{}) error { + return f.fillFunc(v) + } + +-func CallRPCInteractively(ctx context.Context, w io.Writer, rpcName string, digManually, bytesFromFile, rerunPrevious, addRepeatedManually bool) error { +- return dm.CallRPCInteractively(ctx, w, rpcName, digManually, bytesFromFile, rerunPrevious, addRepeatedManually) ++func CallRPCInteractively(ctx context.Context, w io.Writer, rpcName string, digManually, bytesAsBase64, bytesFromFile, rerunPrevious, addRepeatedManually bool) error { ++ return dm.CallRPCInteractively(ctx, w, rpcName, digManually, bytesAsBase64, bytesFromFile, rerunPrevious, addRepeatedManually) + } + +-func (m *dependencyManager) CallRPCInteractively(ctx context.Context, w io.Writer, rpcName string, digManually, bytesFromFile, rerunPrevious, addRepeatedManually bool) error { ++func (m *dependencyManager) CallRPCInteractively(ctx context.Context, w io.Writer, rpcName string, digManually, bytesAsBase64, bytesFromFile, rerunPrevious, addRepeatedManually bool) error { + return m.CallRPC(ctx, w, rpcName, rerunPrevious, &interactiveFiller{ + fillFunc: func(v interface{}) error { + return m.interactiveFiller.Fill(v, fill.InteractiveFillerOpts{ + DigManually: digManually, ++ BytesAsBase64: bytesAsBase64, + BytesFromFile: bytesFromFile, + AddRepeatedManually: addRepeatedManually, + }) +-- +2.38.1 + diff --git a/third_party/overlays/tvl.nix b/third_party/overlays/tvl.nix index 2d20264ff6..7dd9445eb0 100644 --- a/third_party/overlays/tvl.nix +++ b/third_party/overlays/tvl.nix @@ -92,6 +92,13 @@ in }; }); + # `Call $methodName --bytes-as-base64` support for evans + evans = super.evans.overrideAttrs (old: { + patches = old.patches or [ ] ++ [ + ./patches/evans-add-support-for-bytes-as-base64.patch + ]; + }); + # nix-serve does not work with nix 2.4 # https://github.com/edolstra/nix-serve/issues/28 nix-serve = super.nix-serve.override { nix = super.nix_2_3; }; -- cgit 1.4.1