title: How do you define control flow in a click CLI in Python based on a single option and pass the rest to another command?
body: <p>This question is about the Python <a href="https://click.palletsprojects.com" rel="nofollow noreferrer">click</a> package and relates to control flow based on arguments passed to the CLI.</p>
  
  <p>I'm trying to build a master CLI to sit at the top directory of my repo, which will control many different modes of operation from one central place. When you invoke this command, it will take perhaps <code>n</code> options, where the first will determine which module to invoke, and then pass along the <code>n-1</code> args to another module. But I want each module's commands and options to be defined within its respective module, not the main CLI controller, as I'm trying to keep the main controller simple and each module nicely abstracted away. </p>
  
  <p>Here is a simple example of what I want:</p>
  
  <pre><code>import click
  
  
  @click.command()
  @click.option('--foo-arg', default='asdf')
  def foo(foo_arg):
      click.echo(f"Hello from foo with arg {foo_arg}")
  
  
  @click.command()
  @click.option('--bar-arg', default='zxcv')
  def bar(bar_arg):
      click.echo(f"Hello from bar with arg {bar_arg}")
  
  
  @click.command()
  @click.option('--mode', type=click.Choice(["foo", "bar"]))
  def cli(mode):
      if mode == "foo":
          foo()
  
      if mode == "bar":
          bar()
  
  
  if __name__ == '__main__':
      cli()
  </code></pre>
  
  <p>In this example, <code>foo()</code> and <code>bar()</code> should be thought of as modules that are buried within the repo and which may also require a large number of CLI options, which I don't want to overload the main <code>cli.py</code> with. I feel like <code>foo()</code>'s CLI options should live within <code>foo</code> for contextual reasons. The following is how I want it to work.</p>
  
  <p>Example 1:</p>
  
  <pre><code>python -m cli --mode foo --foo-arg asdf
  </code></pre>
  
  <p>should produce</p>
  
  <pre><code>Hello from foo with arg asdf
  </code></pre>
  
  <p>Example 2:</p>
  
  <pre><code>python -m cli --mode bar --bar-arg zxcv
  </code></pre>
  
  <p>should produce</p>
  
  <pre><code>Hello from bar with arg zxcv
  </code></pre>
  
  <p>Example 3:</p>
  
  <pre><code>python -m cli --mode foo --bar-arg qwer
  </code></pre>
  
  <p>should fail since <code>foo()</code> doesn't have the <code>--bar-arg</code> option.</p>
  
  <p>Disclaimer: I know that I could register <code>foo</code> and <code>bar</code> as separate commands (invoked via <code>python -m cli foo --foo-arg asd</code>, i.e. with <code>foo</code> instead of <code>--foo</code>). However, due to a reason beyond the scope of this question, I need <code>foo</code> or <code>bar</code> to be specified by the <code>--mode</code> option identifier. This is a limitation of a tool that interacts with my app, which is unfortunately outside my control.</p>
  
  <p>Is there a way to parse the args and make control flow possible based on a subset of args and then pass the remaining ones to a subsequent module, while not defining every module's options as decorators on <code>def cli()</code>?</p>