| 119 | } |
| 120 | |
| 121 | func (fc *FuncCommand) Command() *cobra.Command { |
| 122 | if fc.cmd == nil { |
| 123 | fc.cmd = &cobra.Command{ |
| 124 | Use: fc.Name, |
| 125 | Aliases: fc.Aliases, |
| 126 | Short: fc.Short, |
| 127 | Long: fc.Long, |
| 128 | Example: fc.Example, |
| 129 | Annotations: fc.Annotations, |
| 130 | GroupID: moduleGroup.ID, |
| 131 | |
| 132 | // We need to disable flag parsing because it'll act on --help |
| 133 | // and validate the args before we have a chance to add the |
| 134 | // subcommands. |
| 135 | DisableFlagParsing: true, |
| 136 | DisableFlagsInUseLine: true, |
| 137 | |
| 138 | PreRunE: func(c *cobra.Command, a []string) error { |
| 139 | // Recover what DisableFlagParsing disabled. |
| 140 | // In PreRunE it's, already past the --help check and |
| 141 | // args validation, but not flag validation which we want. |
| 142 | c.DisableFlagParsing = false |
| 143 | |
| 144 | // Do a first pass with interspersed=true to look for any |
| 145 | // --help flag in the arguments. This is needed to skip |
| 146 | // some validations while building the command tree, before |
| 147 | // parsing the command where the --help flag is. |
| 148 | help := pflag.NewFlagSet("help", pflag.ContinueOnError) |
| 149 | help.AddFlag(c.Flags().Lookup("help")) |
| 150 | |
| 151 | help.ParseErrorsAllowlist.UnknownFlags = true |
| 152 | help.ParseAll(a, func(flag *pflag.Flag, value string) error { |
| 153 | fc.needsHelp = value == flag.NoOptDefVal |
| 154 | return nil |
| 155 | }) |
| 156 | |
| 157 | // Stop parsing at the first possible dynamic sub-command |
| 158 | // since they've not been added yet. |
| 159 | c.Flags().SetInterspersed(false) |
| 160 | |
| 161 | // Global flags that affect the engine+TUI have already been |
| 162 | // parsed by the root command, but there's module specific |
| 163 | // flags (-m) that need to be parsed before initializing the |
| 164 | // module. |
| 165 | // Temporarily allow unknown flags so we can parse without |
| 166 | // erroring on flags that haven't been able to load yet. |
| 167 | c.FParseErrWhitelist.UnknownFlags = true |
| 168 | if err := c.ParseFlags(a); err != nil { |
| 169 | return c.FlagErrorFunc()(c, err) |
| 170 | } |
| 171 | c.FParseErrWhitelist.UnknownFlags = false |
| 172 | |
| 173 | return nil |
| 174 | }, |
| 175 | // Between PreRunE and RunE, flags are validated. |
| 176 | RunE: func(c *cobra.Command, a []string) error { |
| 177 | if isPrintTraceLinkEnabled(c.Annotations) { |
| 178 | c.SetContext(idtui.WithPrintTraceLink(c.Context(), true)) |