diff --git a/docs/plugins.md b/docs/plugins.md index 3087d1b39..3e3c9a62b 100644 --- a/docs/plugins.md +++ b/docs/plugins.md @@ -90,7 +90,9 @@ Restrictions on `name`: The `ignoreFlags` switch tells Helm to _not_ pass flags to the plugin. So if a plugin is called with `helm myplugin --foo` and `ignoreFlags: true`, then `--foo` -is silently discarded. +is silently discarded. The arguments provided until the first tag are kept, so +`helm myplugin myarg --foo` and `ignoreFlags: true` will be equivalent to `helm +myplugin myarg`. The `useTunnel` switch indicates that the plugin needs a tunnel to Tiller. This should be set to `true` _anytime a plugin talks to Tiller_. It will cause Helm diff --git a/pkg/plugin/plugin.go b/pkg/plugin/plugin.go index b3458c2d8..b67c39928 100644 --- a/pkg/plugin/plugin.go +++ b/pkg/plugin/plugin.go @@ -105,9 +105,18 @@ func (p *Plugin) PrepareCommand(extraArgs []string) (string, []string) { if len(parts) > 1 { baseArgs = parts[1:] } - if !p.Metadata.IgnoreFlags { - baseArgs = append(baseArgs, extraArgs...) + extraIndex := len(extraArgs) + // determine the index of the first flag if we need to ignore them + if p.Metadata.IgnoreFlags { + for i, arg := range extraArgs { + if strings.HasPrefix(arg, "-") { + extraIndex = i + break + } + } } + baseArgs = append(baseArgs, extraArgs[0:extraIndex]...) + return main, baseArgs } diff --git a/pkg/plugin/plugin_test.go b/pkg/plugin/plugin_test.go index 5ddbf15f3..cbebf5dd9 100644 --- a/pkg/plugin/plugin_test.go +++ b/pkg/plugin/plugin_test.go @@ -28,38 +28,71 @@ func TestPrepareCommand(t *testing.T) { Command: "echo -n foo", }, } - argv := []string{"--debug", "--foo", "bar"} - - cmd, args := p.PrepareCommand(argv) - if cmd != "echo" { - t.Errorf("Expected echo, got %q", cmd) - } - - if l := len(args); l != 5 { - t.Errorf("expected 5 args, got %d", l) - } - - expect := []string{"-n", "foo", "--debug", "--foo", "bar"} - for i := 0; i < len(args); i++ { - if expect[i] != args[i] { - t.Errorf("Expected arg=%q, got %q", expect[i], args[i]) - } - } - - // Test with IgnoreFlags. This should omit --debug, --foo, bar - p.Metadata.IgnoreFlags = true - cmd, args = p.PrepareCommand(argv) - if cmd != "echo" { - t.Errorf("Expected echo, got %q", cmd) - } - if l := len(args); l != 2 { - t.Errorf("expected 2 args, got %d", l) + testCases := []struct { + description string + argv []string + expect []string + ignoreFlags bool + }{ + { + description: "no extra args", + argv: []string{}, + expect: []string{"-n", "foo"}, + }, + { + description: "extra args, all long flags, keep flags", + argv: []string{"--debug", "--foo", "bar"}, + expect: []string{"-n", "foo", "--debug", "--foo", "bar"}, + }, + { + description: "extra args, all long flags, ignore flags", + argv: []string{"--debug", "--foo", "bar"}, + expect: []string{"-n", "foo"}, + ignoreFlags: true, + }, + { + description: "extra args, arguments, long flags, ignore flags", + argv: []string{"arg1", "arg2", "--debug", "--foo", "bar", "arg3"}, + expect: []string{"-n", "foo", "arg1", "arg2"}, + ignoreFlags: true, + }, + { + description: "extra args, short (first) and long flags, ignore flags", + argv: []string{"-s", "--debug", "--foo", "bar", "arg3"}, + expect: []string{"-n", "foo"}, + ignoreFlags: true, + }, + { + description: "extra args, arguments, short (first) and long flags, ignore flags", + argv: []string{"arg1", "arg2", "-d", "--foo", "bar", "arg3"}, + expect: []string{"-n", "foo", "arg1", "arg2"}, + ignoreFlags: true, + }, + { + description: "extra args, long (first) and short flags, ignore flags", + argv: []string{"--debug", "-s", "--foo", "bar", "arg3"}, + expect: []string{"-n", "foo"}, + ignoreFlags: true, + }, } - expect = []string{"-n", "foo"} - for i := 0; i < len(args); i++ { - if expect[i] != args[i] { - t.Errorf("Expected arg=%q, got %q", expect[i], args[i]) - } + for _, tc := range testCases { + t.Run(tc.description, func(t *testing.T) { + p.Metadata.IgnoreFlags = tc.ignoreFlags + cmd, args := p.PrepareCommand(tc.argv) + if cmd != "echo" { + t.Errorf("Expected echo, got %q", cmd) + } + + if l, le := len(args), len(tc.expect); l != le { + t.Errorf("expected %d args, got %d", le, l) + } + + for i := 0; i < len(args); i++ { + if tc.expect[i] != args[i] { + t.Errorf("Expected arg=%q, got %q", tc.expect[i], args[i]) + } + } + }) } }