this repo has no description
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

cmd/cue: drop support for the deprecated short form of `cue cmd`

`cue foo` used to be a shortcut for `cue cmd foo`,
but was deprecated in v0.9.0 following https://cuelang.org/issue/2519.

The shortcut introduced a number of problems:
* The root `cue` command needed to be significantly more complex;
it had to know how to correctly capture flags and arguments for
`cue cmd` and pass them along to the subcommand.
* Spelling mistakes like `cue evla` instead of `cue eval` could easily
result in running arbitrary code if _tool.cue files existed.
* In some edge cases we would have to load _tool.cue files outside of
`cue cmd` to make sure the user wasn't trying to use a tool command.
This also caused confusing error messages, such as the `cue evla` typo
resulting in a suggestion to declare the command in a _tool.cue file.

The issues above existed so the user could save typing four characters,
which doesn't seem worth it. We now only support `cue cmd foo`,
which is more explicit and consistent.

One test case which covered running a command in "short" code now fails.
Two others which only tested fixed bugs in the short form are deleted,
as those edge cases are completely gone now.

Fixes #2519.

Signed-off-by: Daniel Martí <mvdan@mvdan.cc>
Change-Id: I1d80622f6db3fd0f0fb7494356e5360697b048be
Reviewed-on: https://review.gerrithub.io/c/cue-lang/cue/+/1199634
TryBot-Result: CUEcueckoo <cueckoo@cuelang.org>
Reviewed-by: Matthew Sackman <matthew@cue.works>
Unity-Result: CUE porcuepine <cue.porcuepine@gmail.com>

+19 -91
+1 -24
cmd/cue/cmd/cmd.go
··· 19 19 20 20 "cuelang.org/go/cue/errors" 21 21 "github.com/spf13/cobra" 22 - "github.com/spf13/pflag" 23 22 ) 24 23 25 24 // TODO: generate long description from documentation. ··· 135 134 Run "cue help commands" for more details on tasks and workflow commands. 136 135 `, 137 136 RunE: mkRunE(c, func(cmd *Command, args []string) error { 138 - // The behavior when there's no known subcommand is different 139 - // depending on whether we ran via `cue cmd` or the `cue` shortcut. 140 - isRootCmd := cmd.Command == cmd.root 141 - 142 137 if len(args) == 0 { 143 - // `cue` should print the top-level help like `cue -h`, 144 - // but `cue cmd` should explain that a custom command is required. 145 - if isRootCmd { 146 - return pflag.ErrHelp 147 - } 148 138 w := cmd.OutOrStderr() 149 139 fmt.Fprintln(w, "cmd must be run as one of its subcommands") 150 140 fmt.Fprintln(w, "Run 'cue help cmd' for known subcommands.") 151 141 return ErrPrintedError 152 142 } 153 143 tools, err := buildTools(cmd, args[1:]) 154 - if err != nil && !isRootCmd { 155 - // `cue cmd` fails immediately if there is no CUE package, 156 - // but `cue` does not in order to always show a useful error in `cue typo`. 144 + if err != nil { 157 145 return err 158 146 } 159 147 sub, err := customCommand(cmd, commandSection, args[0], tools) 160 148 if err != nil { 161 149 w := cmd.OutOrStderr() 162 - cmdline := "cue" 163 - if !isRootCmd { 164 - cmdline += " cmd" 165 - } 166 150 fmt.Fprint(w, errors.Details(err, &errors.Config{Cwd: rootWorkingDir})) 167 151 fmt.Fprintln(w, `Ensure custom commands are defined in a "_tool.cue" file.`) 168 152 fmt.Fprintln(w, "Run 'cue help cmd' to list available custom commands.") 169 - if isRootCmd { 170 - fmt.Fprintln(w, "Run 'cue help' to see the built-in 'cue' commands.") 171 - } 172 153 return ErrPrintedError 173 154 } 174 155 // Presumably the *cobra.Command argument should be cmd.Command, 175 156 // as that is the one which will have the right settings applied. 176 - if isRootCmd { 177 - cmd.PrintErrf("The short-form 'cue %[1]s' is deprecated; use 'cue cmd %[1]s'.\n", args[0]) 178 - cmd.PrintErrf("See: https://cuelang.org/issue/2519\n") 179 - } 180 157 return sub.RunE(cmd.Command, args[1:]) 181 158 }), 182 159 }
+7 -13
cmd/cue/cmd/common.go
··· 385 385 } 386 386 cfg.reFile = re 387 387 388 - setTags(cfg.loadCfg, cmd.Flags(), cmd.Parent().Flags()) 388 + setTags(cfg.loadCfg, cmd.Flags()) 389 389 390 390 return p, nil 391 391 } ··· 394 394 return p.cfg.reFile.MatchString(file) 395 395 } 396 396 397 - func setTags(cfg *load.Config, flags ...*pflag.FlagSet) { 398 - // setTags usually receives a subcommmand's flags, plus the parent (root) command's flags, 399 - // so that we can support "cue cmd -t foo=bar mycmd" as well as the short form "cue -t foo=bar mycmd". 400 - // TODO: once we remove "cue cmd" short-hand support, go back to a single FlagSet parameter. 401 - for _, f := range flags { 402 - tags, _ := f.GetStringArray(string(flagInject)) 403 - cfg.Tags = append(cfg.Tags, tags...) 404 - if b, _ := f.GetBool(string(flagInjectVars)); b { 405 - cfg.TagVars = load.DefaultTagVars() 406 - } 397 + func setTags(cfg *load.Config, flags *pflag.FlagSet) { 398 + tags, _ := flags.GetStringArray(string(flagInject)) 399 + cfg.Tags = append(cfg.Tags, tags...) 400 + if b, _ := flags.GetBool(string(flagInjectVars)); b { 401 + cfg.TagVars = load.DefaultTagVars() 407 402 } 408 403 } 409 404 ··· 780 775 } 781 776 loadCfg := *cfg.loadCfg 782 777 loadCfg.Tools = true 783 - f := cmd.cmd.Flags() 784 - setTags(&loadCfg, f, cmd.cmd.Parent().Flags()) 778 + setTags(&loadCfg, cmd.cmdCmd.Flags()) 785 779 786 780 binst := loadFromArgs(args, &loadCfg) 787 781 if len(binst) == 0 {
+5 -17
cmd/cue/cmd/root.go
··· 190 190 // TODO: the short help text below seems to refer to `cue cmd`, like helpTemplate. 191 191 Short: "cue emits configuration files to user-defined commands.", 192 192 193 - // ArbitraryArgs allows us to forward the top-level RunE to cmdCmd.RunE, 194 - // which supports `cue mycmd` as a short-cut for `cue cmd mycmd`. 195 - // Without ArbitraryArgs, cobra fails with "unknown command" errors. 196 - Args: cobra.ArbitraryArgs, 197 - 198 193 // We print errors ourselves in Main, which allows for ErrPrintedError. 199 194 // Similarly, we don't want to print the entire help text on any error. 200 195 // We can explicitly trigger help on certain errors via pflag.ErrHelp. ··· 203 198 204 199 // We currently support top-level custom commands like `cue mycmd` as an alias 205 200 // for `cue cmd mycmd`, so any sub-command suggestions might be confusing. 201 + // TODO(mvdan): remove this and test it, as we no longer support `cue mycmd`. 206 202 DisableSuggestions: true, 207 203 } 208 204 ··· 214 210 root: cmd, 215 211 ctx: cuecontext.New(rootContextOptions...), 216 212 } 217 - 218 - cmdCmd := newCmdCmd(c) 219 - c.cmd = cmdCmd 213 + c.cmdCmd = newCmdCmd(c) 220 214 221 215 addGlobalFlags(cmd.PersistentFlags()) 222 - // We add the injection flags to the root command for the sake of the short form "cue -t foo=bar mycmd". 223 - // Note that they are not persistent, so that they aren't inherited by sub-commands like "cue fmt". 224 - addInjectionFlags(cmd.Flags(), false, true) 225 216 226 217 // Cobra's --help flag shows up in help text by default, which is unnecessary. 227 218 cmd.InitDefaultHelpFlag() ··· 240 231 cmd.SetHelpTemplate(helpTemplate) 241 232 242 233 for _, sub := range []*cobra.Command{ 243 - cmdCmd, 234 + c.cmdCmd, 244 235 newCompletionCmd(c), 245 236 newEvalCmd(c), 246 237 newDefCmd(c), ··· 261 252 cmd.AddCommand(sub) 262 253 } 263 254 264 - // For `cue mycmd` to be a shortcut for `cue cmd mycmd`. 265 - cmd.RunE = cmdCmd.RunE 266 - 267 255 cmd.SetArgs(args) 268 256 return c, nil 269 257 } ··· 303 291 304 292 root *cobra.Command 305 293 306 - // Subcommands 307 - cmd *cobra.Command 294 + // _tool.cue subcommands. 295 + cmdCmd *cobra.Command 308 296 309 297 ctx *cue.Context 310 298
-19
cmd/cue/cmd/testdata/script/cmd_notool2.txtar
··· 1 - ! exec cue notool 2 - ! stdout . 3 - cmp stderr cmd_baddisplay.out 4 - 5 - -- cmd_baddisplay.out -- 6 - could not find command "notool" 7 - Ensure custom commands are defined in a "_tool.cue" file. 8 - Run 'cue help cmd' to list available custom commands. 9 - Run 'cue help' to see the built-in 'cue' commands. 10 - -- task.cue -- 11 - package home 12 - message: "Hello world!" 13 - 14 - command: notool: { 15 - task: display: { 16 - kind: "print" 17 - text: 42 18 - } 19 - }
+4 -6
cmd/cue/cmd/testdata/script/cmd_short.txtar
··· 2 2 stdout 'Hello world!' 3 3 ! stderr . 4 4 5 - exec cue hello 6 - stdout 'Hello world!' 7 - cmp stderr stderr-warning 5 + ! exec cue hello 6 + cmp stderr short-stderr 8 7 9 - -- stderr-warning -- 10 - The short-form 'cue hello' is deprecated; use 'cue cmd hello'. 11 - See: https://cuelang.org/issue/2519 8 + -- short-stderr -- 9 + unknown command "hello" for "cue" 12 10 -- task_tool.cue -- 13 11 package home 14 12
-5
cmd/cue/cmd/testdata/script/cmd_tags.txtar
··· 1 1 exec cue cmd -t prod -t name=bar tag tags.cue tags_tool.cue 2 2 cmp stdout expect-stdout 3 3 4 - # Same as before, but now with the short form. 5 - # See https://cuelang.org/issue/2510. 6 - exec cue -t prod -t name=bar tag tags.cue tags_tool.cue 7 - cmp stdout expect-stdout 8 - 9 4 # Verify that the new global -t flag added as a fix for issue 2510 above 10 5 # works with the explicit or implicit "cmd" sub-command, 11 6 # but not with other sub-commands like "fmt".
+1 -3
cmd/cue/cmd/testdata/script/help.txtar
··· 35 35 36 36 ! exec cue filetypes 37 37 ! stdout . 38 - stderr -count=1 '^no commands defined' 39 - # TODO(mvdan): once `cue somecmd` is phased out, we can give a better error message here. 40 - # stderr -count=1 '^unknown command' 38 + stderr -count=1 '^unknown command' 41 39 42 40 # Requesting help for missing commands and sub-commands fails and prints the help text. 43 41
+1 -4
cmd/cue/cmd/testdata/script/unknown_args.txtar
··· 7 7 cmp stderr unknown_flag.out 8 8 9 9 -- unknown_cmd.out -- 10 - no commands defined 11 - Ensure custom commands are defined in a "_tool.cue" file. 12 - Run 'cue help cmd' to list available custom commands. 13 - Run 'cue help' to see the built-in 'cue' commands. 10 + unknown command "unknown" for "cue" 14 11 -- unknown_flag.out -- 15 12 unknown flag: --unknown