Skip to content
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

How can I call other subcommands? #1168

Closed
pencil001 opened this issue Jul 16, 2020 · 7 comments
Closed

How can I call other subcommands? #1168

pencil001 opened this issue Jul 16, 2020 · 7 comments

Comments

@pencil001
Copy link

I have built an cli application like this:

$ app apply sth1
$ app apply sth2
...
$ app apply sthn

Now, I want to add another subcommand all, like this

$ app apply all

This command will execute all the logic of sth1, sth2, ...., sthn.

Naturally, I don't want to duplicate codes, so I have two options:

  • use cmd.Run
allCmd := &cobra.Command{
  User: "all",
  Run: func(cmd *cobra.Command, args []string) {
    sth1Cmd.Run(cmd, args)
    sth2Cmd.Run(cmd, args)
    // ....
    sthnCmd.Run(cmd, args)
  }
}

This option has some cons. If other command has defined PreRun or PostRun, it will ignore those code. And those flags defined on those command will be ignored, too.

  • use Execute
allCmd := &cobra.Command{
  User: "all",
  Run: func(cmd *cobra.Command, args []string) {
    sth1Cmd.Execute()
    sth2Cmd.Execute()
    // ....
    sthnCmd.Execute()
  }
}

This option is just not work. Because Execute will find every command's root command to execute. And all subcommands have same parent command, it will cause stackoverflow.

Can anybody give me some advices? Thank you!

@umarcor
Copy link
Contributor

umarcor commented Jul 16, 2020

@pencil001 you might find the discussion in #726 interesting.

This option is just not work. Because Execute will find every command's root command to execute. And all subcommands have same parent command, it will cause stackoverflow.

You need to call the parent Execute by providing the subset of args that you want, instead of calling the Execute function of each child.

@github-actions
Copy link

This issue is being marked as stale due to a long period of inactivity

@saltperfect
Copy link

saltperfect commented Nov 6, 2021

@umarcor I did the exact thing that you described and still I am getting stack overflow.

Run: func(cmd *cobra.Command, args []string) {
		argsList := strings.FieldsFunc(args[0], func(r rune) bool { return r == ',' })
		fmt.Printf("arglist: %v\n", argsList)
		for _, arg := range argsList {
			fmt.Printf("%s\n", arg)
			_, ok := commandMap[arg]
			if !ok {
				fmt.Printf("%s is not a valid argument\n", arg)
				continue
			}

			deployCmd.SetArgs([]string{arg})
			deployCmd.Execute()
		}
	},

Here I am expecting this multi command to work like my-cli deploy multi alpha,beta,gamma
Anything you think I might be missing here?

@umarcor
Copy link
Contributor

umarcor commented Nov 6, 2021

@saltperfect please open a new issue and provide a complete reproducible example of what you are trying to achieve and how you are trying to do it.

@saltperfect
Copy link

@umarcor I have raised a seperate issue. #1526
can you please take a look and advice?

@johnSchnake
Copy link
Collaborator

With the new issue having been opened I'm going to close this one.

@migueleliasweb
Copy link

Also talked about here: #379

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants