-
Notifications
You must be signed in to change notification settings - Fork 2.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Invoke multiple commands in series #726
Comments
The problem with that is that cobra allows subcommands which gradle or maven doesn't. How should cobra know if |
This is how I do that: var cmd = &cobra.Command{
Use: "and -- COMMAND1 - COMMAND2",
Short: "run multiple <my-cli> commands separated by -",
Run: func(cobraCmd *cobra.Command, args []string) {
var cmdParts []string
var cmdList [][]string
for _, arg := range args {
if arg == "-" {
if len(cmdParts) > 0 {
cmdList = append(cmdList, cmdParts)
cmdParts = []string{}
}
} else {
cmdParts = append(cmdParts, arg)
}
}
cmdList = append(cmdList, cmdParts)
for _, cmdParts := range cmdList {
cmdRoot.SetArgs(cmdParts)
cmdRoot.Execute()
}
},
}
cmd.Flags().SetInterspersed(false) and to run: my-cli and command1 - command2 - command3
my-cli and -- command1 - command2 - command3
my-cli --global-options and -- command1 --command1-options command1Arguments - command2 - command3 --command3-options |
This issue is being marked as stale due to a long period of inactivity |
I would like this feature as well. The biggest Python CLI framework |
@fkrauthan, would you mind elaborating on what you mean with "normal CLI execution"? It feels to me that |
@umarcor If you are trying to build a tool like The type of feature I would love to see would follow the same (or similar implementation) to how for example Python Click does it (https://click.palletsprojects.com/en/7.x/commands/#multi-command-chaining). Which is a common way development CLI tools work (like above mentioned |
Sure it will. See dbhi/run.
It is the user who decides which subcommands (better named tasks/targets/procedures) to execute, by providing them as a list of args. The (sub)command which handles it is only reponsible for taking the input (strings) and converting them to function calls.
I believe that is because @idetoile wanted to preserve the possibility for each command to have args. It seems you don't need that because you are using arguments as makefile targets (i.e. standalone symbols/tokens). Then, you should focus on the following lines: cmdRoot.SetArgs(cmdParts)
cmdRoot.Execute() Note it is very similar to #724 (comment). However, if your subcommands are not going to accept arguments (because the syntax you want doesn't allow so), I would suggest you to reconsider using subcommands in the first place. It feels that all the benefit you get from having subcommands is separate description messages. Apart from that, all the plumbing feels overkill. Instead, I would write a single command that accepts a list of strings (task names) and a map that translates those strings to a struct that contains a function and a description. With such an approach, you get the benefits of cobra and viper for easily using configuration files, generating a help message, etc. but you keep the complexity constrained to your needs.
That is exactly what you get with |
@umarcor No I explicitly want the capability of args. A real example of an application written (at the moment in Python) that I was going to port to Go.
which would build and startup service1 and service2 but only listen to logs of
which would build service1 and service2 including UI components and then start both services. In all of this cases I would like to be able to specify the sub commands to run AND have the capability of providing arguments to each subcommand without having to use a workaround/hack of a separator sign. |
Can you guarantee that all your subcommands have no additional subcommands? I.e. you only have the root command and a single level of subcommands in the hierarchy? |
In my particular case yes. I think the API could easily say if you enable this multi subcommand feature you can not have nested commands or something along that lines (I believe click does it that way). |
So, if you guarantee that:
Then, you can modify @idetoile's example to "break" commands when you get an arg with the first character being NOTE What you are calling "args" is named "flags" in the context of cobra. Args are positional while flags are prepended with |
But that is exactly my point. I have to pretty much write a light command processor on-top of cobra. While I think it is a valid use-case to be provided out of the box by cobra itself (maybe even with an elegant solution for supporting subcommands in a chaining scenario). It's ok if you don't think its worth implementing I was just commenting that I would support a feature implement like this and provided some samples where in the real world CLI interfaces that would require this are used. |
I see your point. However, I beg to differ. The "light command processor on-top of cobra" is, in fact, ~10 lines of code to split a single list of strings into multiple lists of strings. It's a single ordered for loop (two were used above, but that's not required) with a very light evaluation (always the first char). I can hardly imagine how it can be done easier... Just configuring whichever API that might be built-in (e.g. to use an explicit separator or not), would involve almost the same complexity. Moreover, given all the constraints, it would feel weird if it was a first class option in the root command, compared to the generally broad focus of the project. So, I'm not opposed to it, I just think it is not worth the effort because you can already do it easily.
Nevertheless, I think that this and other code examples should be easier to find. Cobra is lacking any "Documentation site" apart from the API. Info is scattered in markdown files and in some issues. I believe the project would benefit from a site hosted at GitHub Pages which might contain snippets for users to reuse. See #985. |
@umarcor just one quick question. After looking at @idetoile solution it seems like a sub command called |
My guess is that you can use it as part of the root command, but you need some "key" to skip the regular parsing. IIRC, the logic is as follows:
So, you might need to have a first arg which is NOT a subcommand. Otherwise, when you write I think that an easy solution would be to use e.g. Note that EDIT Of course, it that does not work, I agree with you: it'd be a legit request to have something done so it is possible. Also note that |
Hmm yeah I've noticed that. I don't think that is a very elegant solution and would require people to use this tool differently then before (something I would like to prevent and instead have a drop in solution). I guess for now I will be stuck with the Python version unless someone gets to implement this feature in cobra. |
I would like to see if multiple command execution can be triggered by providing the command names on the command line -
I see this issue but it actually triggers two command programmed to be executed from one program provide on the the command line.
#482
What I am trying to do it to execute two command once they are provided on the command line.
like -
mybuild.exe clean compile
It should execute clean command and after that compile command.
May be there is a way to do it ?
The text was updated successfully, but these errors were encountered: