@@ -113,60 +113,6 @@ func newChartCommand() *cobra.Command {
113113 Short : "Show a diff explaining what a helm upgrade would change." ,
114114 Long : globalUsage ,
115115 DisableFlagParsing : true ,
116- PersistentPreRunE : func (cmd * cobra.Command , args []string ) error {
117- const (
118- 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." +
119- " --dry-run=server enables the cluster access with helm-get and the lookup template function."
120- )
121-
122- legacyDryRunFlagSet := pflag .NewFlagSet ("upgrade" , pflag .ContinueOnError )
123- legacyDryRun := legacyDryRunFlagSet .Bool ("dry-run" , false , dryRunUsage )
124- if err := legacyDryRunFlagSet .Parse (args ); err == nil && * legacyDryRun {
125- diff .dryRunModeSpecified = true
126- args = legacyDryRunFlagSet .Args ()
127- } else {
128- cmd .Flags ().StringVar (& diff .dryRunMode , "dry-run" , "" , dryRunUsage )
129- }
130-
131- fmt .Fprintf (os .Stderr , "args after legacy dry-run parsing: %v\n " , args )
132-
133- // Here we parse the flags ourselves so that we can support
134- // both --dry-run and --dry-run=ARG syntaxes.
135- //
136- // If you don't do this, then cobra will treat --dry-run as
137- // a "flag needs an argument: --dry-run" error.
138- //
139- // This works becase we have `DisableFlagParsing: true`` above.
140- // Never turn that off, or you'll get the error again.
141- if err := cmd .Flags ().Parse (args ); err != nil {
142- return err
143- }
144-
145- args = cmd .Flags ().Args ()
146-
147- if ! diff .dryRunModeSpecified {
148- dryRunModeSpecified := cmd .Flags ().Changed ("dry-run" )
149- diff .dryRunModeSpecified = dryRunModeSpecified
150-
151- if dryRunModeSpecified && ! (diff .dryRunMode == "client" || diff .dryRunMode == "server" ) {
152- return fmt .Errorf ("flag %q must take an argument of %q or %q but got %q" , "dry-run" , "client" , "server" , diff .dryRunMode )
153- }
154- }
155-
156- cmd .SetArgs (args )
157-
158- // We have to do this here because we have to sort out the
159- // --dry-run flag ambiguity to determine the args to be checked.
160- //
161- // In other words, we can't just do:
162- //
163- // cmd.Args = func(cmd *cobra.Command, args []string) error {
164- // return checkArgsLength(len(args), "release name", "chart path")
165- // }
166- //
167- // Because it seems to take precedence over the PersistentPreRunE
168- return checkArgsLength (len (args ), "release name" , "chart path" )
169- },
170116 Example : strings .Join ([]string {
171117 " helm diff upgrade my-release stable/postgresql --values values.yaml" ,
172118 "" ,
@@ -206,6 +152,69 @@ func newChartCommand() *cobra.Command {
206152 "HELM_DIFF_OUTPUT_CONTEXT=5 helm diff upgrade my-release datadog/datadog" ,
207153 }, "\n " ),
208154 RunE : func (cmd * cobra.Command , args []string ) error {
155+ // Note that we can't just move this block to PersistentPreRunE,
156+ // because cmd.SetArgs(args) does not persist between PersistentPreRunE and RunE.
157+ // The choice is between:
158+ // 1. Doing this in RunE
159+ // 2. Doing this in PersistentPreRunE, saving args somewhere, and calling cmd.SetArgs(args) again in RunE
160+ // 2 is more complicated without much benefit, so we choose 1.
161+ {
162+ const (
163+ 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." +
164+ " --dry-run=server enables the cluster access with helm-get and the lookup template function."
165+ )
166+
167+ legacyDryRunFlagSet := pflag .NewFlagSet ("upgrade" , pflag .ContinueOnError )
168+ legacyDryRun := legacyDryRunFlagSet .Bool ("dry-run" , false , dryRunUsage )
169+ if err := legacyDryRunFlagSet .Parse (args ); err == nil && * legacyDryRun {
170+ diff .dryRunModeSpecified = true
171+ args = legacyDryRunFlagSet .Args ()
172+ } else {
173+ cmd .Flags ().StringVar (& diff .dryRunMode , "dry-run" , "" , dryRunUsage )
174+ }
175+
176+ fmt .Fprintf (os .Stderr , "args after legacy dry-run parsing: %v\n " , args )
177+
178+ // Here we parse the flags ourselves so that we can support
179+ // both --dry-run and --dry-run=ARG syntaxes.
180+ //
181+ // If you don't do this, then cobra will treat --dry-run as
182+ // a "flag needs an argument: --dry-run" error.
183+ //
184+ // This works becase we have `DisableFlagParsing: true`` above.
185+ // Never turn that off, or you'll get the error again.
186+ if err := cmd .Flags ().Parse (args ); err != nil {
187+ return err
188+ }
189+
190+ args = cmd .Flags ().Args ()
191+
192+ if ! diff .dryRunModeSpecified {
193+ dryRunModeSpecified := cmd .Flags ().Changed ("dry-run" )
194+ diff .dryRunModeSpecified = dryRunModeSpecified
195+
196+ if dryRunModeSpecified && ! (diff .dryRunMode == "client" || diff .dryRunMode == "server" ) {
197+ return fmt .Errorf ("flag %q must take an argument of %q or %q but got %q" , "dry-run" , "client" , "server" , diff .dryRunMode )
198+ }
199+ }
200+
201+ cmd .SetArgs (args )
202+
203+ // We have to do this here because we have to sort out the
204+ // --dry-run flag ambiguity to determine the args to be checked.
205+ //
206+ // In other words, we can't just do:
207+ //
208+ // cmd.Args = func(cmd *cobra.Command, args []string) error {
209+ // return checkArgsLength(len(args), "release name", "chart path")
210+ // }
211+ //
212+ // Because it seems to take precedence over the PersistentPreRunE
213+ if err := checkArgsLength (len (args ), "release name" , "chart path" ); err != nil {
214+ return err
215+ }
216+ }
217+
209218 // Suppress the command usage on error. See #77 for more info
210219 cmd .SilenceUsage = true
211220
0 commit comments