Skip to content

Commit a3a0cc2

Browse files
committed
Remake dry-run=server optional
This is a follow-up on #499 which redoes it without relying on DisableParsing. DisableParsing turned out to break far many things than I imagined!
1 parent 83a48fe commit a3a0cc2

File tree

1 file changed

+12
-71
lines changed

1 file changed

+12
-71
lines changed

cmd/upgrade.go

Lines changed: 12 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ import (
1313
jsonpatch "github.com/evanphx/json-patch"
1414
jsoniterator "github.com/json-iterator/go"
1515
"github.com/spf13/cobra"
16-
"github.com/spf13/pflag"
1716
"helm.sh/helm/v3/pkg/action"
1817
"helm.sh/helm/v3/pkg/cli"
1918
"helm.sh/helm/v3/pkg/kube"
@@ -39,7 +38,6 @@ type diffCmd struct {
3938
disableValidation bool
4039
disableOpenAPIValidation bool
4140
dryRunMode string
42-
dryRunModeSpecified bool
4341
enableDNS bool
4442
namespace string // namespace to assume the release to be installed into. Defaults to the current kube config namespace.
4543
valueFiles valueFiles
@@ -89,7 +87,7 @@ func (d *diffCmd) isAllowUnreleased() bool {
8987
//
9088
// See also https://github.com/helm/helm/pull/9426#discussion_r1181397259
9189
func (d *diffCmd) clusterAccessAllowed() bool {
92-
clientOnly := (d.dryRunModeSpecified && d.dryRunMode == "") || d.dryRunMode == "true" || d.dryRunMode == "client"
90+
clientOnly := d.dryRunMode == "true" || d.dryRunMode == "client"
9391
return !clientOnly
9492
}
9593

@@ -111,10 +109,9 @@ func newChartCommand() *cobra.Command {
111109
unknownFlags := os.Getenv("HELM_DIFF_IGNORE_UNKNOWN_FLAGS") == "true"
112110

113111
cmd := &cobra.Command{
114-
Use: "upgrade [flags] [RELEASE] [CHART]",
115-
Short: "Show a diff explaining what a helm upgrade would change.",
116-
Long: globalUsage,
117-
DisableFlagParsing: true,
112+
Use: "upgrade [flags] [RELEASE] [CHART]",
113+
Short: "Show a diff explaining what a helm upgrade would change.",
114+
Long: globalUsage,
118115
Example: strings.Join([]string{
119116
" helm diff upgrade my-release stable/postgresql --values values.yaml",
120117
"",
@@ -153,71 +150,12 @@ func newChartCommand() *cobra.Command {
153150
"# Read the flag usage below for more information on --context.",
154151
"HELM_DIFF_OUTPUT_CONTEXT=5 helm diff upgrade my-release datadog/datadog",
155152
}, "\n"),
153+
Args: func(cmd *cobra.Command, args []string) error {
154+
return checkArgsLength(len(args), "release name", "chart path")
155+
},
156156
RunE: func(cmd *cobra.Command, args []string) error {
157-
// Note that we can't just move this block to PersistentPreRunE,
158-
// because cmd.SetArgs(args) does not persist between PersistentPreRunE and RunE.
159-
// The choice is between:
160-
// 1. Doing this in RunE
161-
// 2. Doing this in PersistentPreRunE, saving args somewhere, and calling cmd.SetArgs(args) again in RunE
162-
// 2 is more complicated without much benefit, so we choose 1.
163-
{
164-
const (
165-
dryRunUsage = "--dry-run, --dry-run=client, or --dry-run=true disables cluster access and show diff as if it was install. Implies --install, --reset-values, and --disable-validation." +
166-
" --dry-run=server enables the cluster access with helm-get and the lookup template function."
167-
)
168-
169-
cmdFlags := cmd.Flags()
170-
171-
// see: https://github.com/databus23/helm-diff/issues/537
172-
cmdFlags.ParseErrorsWhitelist.UnknownFlags = unknownFlags
173-
174-
legacyDryRunFlagSet := pflag.NewFlagSet("upgrade", pflag.ContinueOnError)
175-
legacyDryRun := legacyDryRunFlagSet.Bool("dry-run", false, dryRunUsage)
176-
if err := legacyDryRunFlagSet.Parse(args); err == nil && *legacyDryRun {
177-
diff.dryRunModeSpecified = true
178-
args = legacyDryRunFlagSet.Args()
179-
} else {
180-
cmdFlags.StringVar(&diff.dryRunMode, "dry-run", "", dryRunUsage)
181-
}
182-
183-
// Here we parse the flags ourselves so that we can support
184-
// both --dry-run and --dry-run=ARG syntaxes.
185-
//
186-
// If you don't do this, then cobra will treat --dry-run as
187-
// a "flag needs an argument: --dry-run" error.
188-
//
189-
// This works becase we have `DisableFlagParsing: true`` above.
190-
// Never turn that off, or you'll get the error again.
191-
if err := cmdFlags.Parse(args); err != nil {
192-
return err
193-
}
194-
195-
args = cmdFlags.Args()
196-
197-
if !diff.dryRunModeSpecified {
198-
dryRunModeSpecified := cmd.Flags().Changed("dry-run")
199-
diff.dryRunModeSpecified = dryRunModeSpecified
200-
201-
if dryRunModeSpecified && !(diff.dryRunMode == "client" || diff.dryRunMode == "server") {
202-
return fmt.Errorf("flag %q must take an argument of %q or %q but got %q", "dry-run", "client", "server", diff.dryRunMode)
203-
}
204-
}
205-
206-
cmd.SetArgs(args)
207-
208-
// We have to do this here because we have to sort out the
209-
// --dry-run flag ambiguity to determine the args to be checked.
210-
//
211-
// In other words, we can't just do:
212-
//
213-
// cmd.Args = func(cmd *cobra.Command, args []string) error {
214-
// return checkArgsLength(len(args), "release name", "chart path")
215-
// }
216-
//
217-
// Because it seems to take precedence over the PersistentPreRunE
218-
if err := checkArgsLength(len(args), "release name", "chart path"); err != nil {
219-
return err
220-
}
157+
if diff.dryRunMode != "true" && diff.dryRunMode != "false" && diff.dryRunMode != "client" && diff.dryRunMode != "server" {
158+
return fmt.Errorf("flag %q must take a bool value or either %q or %q, but got %q", "dry-run", "client", "server", diff.dryRunMode)
221159
}
222160

223161
// Suppress the command usage on error. See #77 for more info
@@ -293,6 +231,9 @@ func newChartCommand() *cobra.Command {
293231
f.BoolVar(&diff.devel, "devel", false, "use development versions, too. Equivalent to version '>0.0.0-0'. If --version is set, this is ignored.")
294232
f.BoolVar(&diff.disableValidation, "disable-validation", false, "disables rendered templates validation against the Kubernetes cluster you are currently pointing to. This is the same validation performed on an install")
295233
f.BoolVar(&diff.disableOpenAPIValidation, "disable-openapi-validation", false, "disables rendered templates validation against the Kubernetes OpenAPI Schema")
234+
f.StringVar(&diff.dryRunMode, "dry-run", "", "--dry-run, --dry-run=client, or --dry-run=true disables cluster access and show diff as if it was install. Implies --install, --reset-values, and --disable-validation."+
235+
" --dry-run=server enables the cluster access with helm-get and the lookup template function.")
236+
f.Lookup("dry-run").NoOptDefVal = "true"
296237
f.BoolVar(&diff.enableDNS, "enable-dns", false, "enable DNS lookups when rendering templates")
297238
f.StringVar(&diff.postRenderer, "post-renderer", "", "the path to an executable to be used for post rendering. If it exists in $PATH, the binary will be used, otherwise it will try to look for the executable at the given path")
298239
f.StringArrayVar(&diff.postRendererArgs, "post-renderer-args", []string{}, "an argument to the post-renderer (can specify multiple)")

0 commit comments

Comments
 (0)