@@ -50,6 +50,7 @@ import (
5050
5151 cli_errors "github.com/snyk/cli/cliv2/internal/errors"
5252 "github.com/snyk/cli/cliv2/pkg/basic_workflows"
53+ "github.com/snyk/cli/cliv2/pkg/helprouting"
5354)
5455
5556// Option configures the CLI runner.
@@ -225,13 +226,6 @@ func runWorkflowAndProcessData(ctx context.Context, engine workflow.Engine, logg
225226 return err
226227}
227228
228- func help (_ * cobra.Command , _ []string ) error {
229- helpProvided = true
230- args := utils .RemoveSimilar (os .Args [1 :], "--" ) // remove all double dash arguments to avoid issues with the help command
231- args = append (args , "--help" )
232- return defaultCmd (args )
233- }
234-
235229func defaultCmd (args []string ) error {
236230 inputDirectory := cliv2 .DetermineInputDirectory (args )
237231 if len (inputDirectory ) > 0 {
@@ -247,6 +241,11 @@ func defaultCmd(args []string) error {
247241 return err
248242}
249243
244+ func runLegacyHelp () error {
245+ filteredArgs := utils .RemoveSimilar (os .Args [1 :], "--" )
246+ return defaultCmd (append (filteredArgs , "--help" ))
247+ }
248+
250249func runTestCommandWithSarifEqualJson (cmd * cobra.Command , args []string , templateFiles []string ) error {
251250 // ensure legacy behavior, where sarif and json can be used interchangeably
252251 globalConfiguration .AddAlternativeKeys (output_workflow .OUTPUT_CONFIG_KEY_SARIF , []string {output_workflow .OUTPUT_CONFIG_KEY_JSON })
@@ -378,19 +377,21 @@ func createCommandsForWorkflows(rootCommand *cobra.Command, engine workflow.Engi
378377 }
379378}
380379
381- func prepareRootCommand () * cobra.Command {
380+ func prepareRootCommand (router * helprouting. Router ) * cobra.Command {
382381 rootCommand := cobra.Command {
383382 Use : "snyk" ,
384383 RunE : func (cmd * cobra.Command , _ []string ) error {
385384 return defaultCmd (os .Args [1 :])
386385 },
387386 }
388387
389- // help for all commands is handled by the legacy cli
390- // TODO: discuss how to move help to extensions
388+ // Help precedence: synced user-doc Markdown (legacy CLI) when available; otherwise Cobra help.
389+ root := & rootCommand
391390 helpCommand := cobra.Command {
392- Use : "help" ,
393- RunE : help ,
391+ Use : "help" ,
392+ RunE : func (c * cobra.Command , _ []string ) error {
393+ return router .Help (c , root , os .Args [1 :])
394+ },
394395 }
395396
396397 // some static/global cobra configuration
@@ -399,8 +400,7 @@ func prepareRootCommand() *cobra.Command {
399400 rootCommand .SilenceUsage = true
400401 rootCommand .FParseErrWhitelist .UnknownFlags = true
401402
402- // ensure that help and usage information comes from the legacy cli instead of cobra's default help
403- rootCommand .SetHelpFunc (func (c * cobra.Command , args []string ) { _ = help (c , args ) })
403+ rootCommand .SetHelpFunc (func (c * cobra.Command , _ []string ) { _ = router .Help (c , root , os .Args [1 :]) })
404404 rootCommand .SetHelpCommand (& helpCommand )
405405 rootCommand .PersistentFlags ().AddFlagSet (getGlobalFLags ())
406406
@@ -427,7 +427,7 @@ func handleError(err error) HandleError {
427427 if commandError {
428428 resultError = handleErrorFallbackToLegacyCLI
429429 } else if flagError {
430- // handle flag errors explicitly since we need to delegate the help to the legacy CLI. This includes disabling the cobra default help/usage
430+ // handle flag errors explicitly via help(): user-doc markdown when available, otherwise Cobra help
431431 resultError = handleErrorShowHelp
432432 }
433433 }
@@ -464,16 +464,16 @@ func displayError(err error, userInterface ui.UserInterface, config configuratio
464464}
465465
466466func handleRetryNotification (engine workflow.Engine , logger * zerolog.Logger , err error ) {
467- if ui := engine .GetUserInterface (); ui != nil {
468- if outputErr := ui .OutputError (err ); outputErr != nil {
467+ if userInterface := engine .GetUserInterface (); userInterface != nil {
468+ if outputErr := userInterface .OutputError (err ); outputErr != nil {
469469 logger .Warn ().Err (outputErr ).Msg ("failed to show rate-limit retry warning" )
470470 }
471471 } else {
472472 logger .Warn ().Msg ("rate-limit retry warning not shown: user interface not attached" )
473473 }
474474
475- if analytics := engine .GetAnalytics (); analytics != nil {
476- analytics .AddError (err )
475+ if engineAnalytics := engine .GetAnalytics (); engineAnalytics != nil {
476+ engineAnalytics .AddError (err )
477477 } else {
478478 logger .Warn ().Msg ("rate-limit retry not recorded in analytics: collector not initialized" )
479479 }
@@ -543,7 +543,11 @@ func mainWithErrorCode(additionalExts []workflow.ExtensionInit) int {
543543 var err error
544544 rInfo := runtimeinfo .New (runtimeinfo .WithName ("snyk-cli" ), runtimeinfo .WithVersion (cliv2 .GetFullVersion ()))
545545
546- rootCommand := prepareRootCommand ()
546+ helpRouter := & helprouting.Router {
547+ LegacyHelp : runLegacyHelp ,
548+ OnHelpCalled : func () { helpProvided = true },
549+ }
550+ rootCommand := prepareRootCommand (helpRouter )
547551 // omit the first arg which is always `snyk`
548552 _ = rootCommand .ParseFlags (os .Args [1 :])
549553
@@ -556,7 +560,7 @@ func mainWithErrorCode(additionalExts []workflow.ExtensionInit) int {
556560 )
557561 err = globalConfiguration .AddFlagSet (rootCommand .LocalFlags ())
558562 if err != nil {
559- fmt .Fprintln (os .Stderr , "Failed to add flags to root command" , err )
563+ _ , _ = fmt .Fprintln (os .Stderr , "Failed to add flags to root command" , err )
560564 }
561565
562566 // ensure to init configuration before using it
@@ -670,7 +674,7 @@ func mainWithErrorCode(additionalExts []workflow.ExtensionInit) int {
670674 globalLogger .Printf ("Using Legacy CLI to serve the command. (reason: %v)" , err )
671675 err = defaultCmd (os .Args [1 :])
672676 case handleErrorShowHelp :
673- err = help (nil , [] string {} )
677+ err = helpRouter . Help (nil , rootCommand , os . Args [ 1 :] )
674678 case handleErrorUnhandled :
675679 // ignore
676680 }
0 commit comments