def compose_clis_using_parents(): """ Sometimes, several cli share a common set of arguments. Rather than repeating the definitions of these arguments, one or more parent clis with all the shared arguments can be passed to parents= argument to cli. https://docs.python.org/3/library/argparse.html#parents """ parent_foo_data = { "add_help": False, "arguments": [{ "name": "--foo-parent", "type": int }], } parent_bar_data = { "add_help": False, "arguments": [{ "name": "--bar-parent", "type": int }], } parent_foo_cli = cli(parent_foo_data) parent_bar_cli = cli(parent_bar_data) parents = [parent_foo_cli, parent_bar_cli] return parents
def test_exclusive_group_and_group_together_fail(self): """ Note: Exclusive group requires at least one arg before adding groups """ data = { "prog": "app", "arguments": [ { "name": "--install", "action": "store_true", "exclusive_group": "ops", "group": "cmd", }, { "name": "--purge", "action": "store_true", "exclusive_group": "ops", "group": "cmd", }, {"name": "--fear", "exclusive_group": "ops"}, ], } with pytest.raises(ValueError): cli(data)
def test_groups(self): data = examples.grouping_arguments() parser = cli(data) help_result = parser.format_help() assert "app" in help_result assert "package" in help_result
def main(): conf = config.read_cfg() parser = cli(data) # Show help if no arg provided if len(sys.argv) == 1: parser.print_help(sys.stderr) raise ExpectedExit() # This is for the command required constraint in 2.0 try: args = parser.parse_args() except TypeError: raise NoCommandFoundError() if args.name: conf.update({"name": args.name}) elif not args.name and not conf.path: conf.update({"name": "cz_conventional_commits"}) if args.debug: logging.getLogger("commitizen").setLevel(logging.DEBUG) sys.excepthook = commitizen_debug_excepthook args.func(conf, vars(args))()
def test_prefix_chars(self): data = examples.prefix_chars() parser = cli(data) args = parser.parse_args("+f X ++bar Y".split()) assert args.foo == "X" assert args.bar == "Y"
def test_compose_clis_using_parents_and_arguments(self): data = {"prog": "daddy", "arguments": [{"name": "--something"}]} parents = examples.compose_clis_using_parents() parser = cli(data, parents=parents) args = parser.parse_args(["--something", "XXX"]) assert args.something == "XXX"
def main_example(): """https://docs.python.org/3/library/argparse.html#example""" data = { "description": "Process some integers.", "arguments": [ { "name": "integers", "metavar": "N", "type": int, "nargs": "+", "help": "an integer for the accumulator", }, { "name": "--sum", "dest": "accumulate", "action": "store_const", "const": sum, "default": max, "help": "sum the integers (default: find the max)", }, ], } parser = cli(data) return parser
def main(): conf = config.read_cfg() parser = cli(data) # Show help if no arg provided if len(sys.argv) == 1: parser.print_help(sys.stderr) raise SystemExit() try: args = parser.parse_args() except TypeError: out.error("Command is required") raise SystemExit() if args.name: conf.update({"name": args.name}) if args.version: warnings.warn( "'cz --version' will be deprecated in next major version. " "Please use 'cz version' command from your scripts") logging.getLogger("commitizen").setLevel(logging.DEBUG) if args.debug: warnings.warn("Debug will be deprecated in next major version. " "Please remove it from your scripts") logging.getLogger("commitizen").setLevel(logging.DEBUG) # TODO: This try block can be removed after command is required in 2.0 try: args.func(conf, vars(args))() except AttributeError: out.error("Command is required")
def test_name_or_flags(self): data = examples.name_or_flags() parser = cli(data) args = parser.parse_args(["HELLO"]) assert args.bar == "HELLO" args = parser.parse_args(["BAR", "--foo", "FOO"]) assert args.bar == "BAR" assert args.foo == "FOO"
def main() -> None: """ Parses the cli arguments and runs the appropriate commands """ parser = cli(interface_spec) args = parser.parse_args() if "func" not in args: # No subcommand was specified: # $ mw_url_shortener parser.print_usage() sys.exit("Hint: try the 'config' sub-command") args.func(args=args)
def main(): conf = config.read_cfg() parser = cli(data) # Show help if no arg provided if len(sys.argv) == 1: parser.print_help(sys.stderr) raise SystemExit() # This is for the command required constraint in 2.0 try: args = parser.parse_args() except TypeError: out.error("Command is required") raise SystemExit() if args.name: conf.update({"name": args.name}) elif not args.name and not conf.path: conf.update({"name": "cz_conventional_commits"}) if args.version: warnings.warn( ("'cz --version' will be deprecated in next major version. " "Please use 'cz version' command from your scripts"), category=DeprecationWarning, ) args.func = commands.Version if args.debug: warnings.warn( ("Debug will be deprecated in next major version. " "Please remove it from your scripts"), category=DeprecationWarning, ) logging.getLogger("commitizen").setLevel(logging.DEBUG) # TODO: This try block can be removed after command is required in 2.0 # Handle the case that argument is given, but no command is provided try: args.func(conf, vars(args))() except AttributeError: out.error("Command is required") raise SystemExit()
def test_exclusive_group_fails_when_same_group_called(self): data = { "prog": "app", "arguments": [ { "name": "--install", "action": "store_true", "exclusive_group": "opas", }, { "name": "--purge", "action": "store_true", "exclusive_group": "opas", }, ], } parser = cli(data) with pytest.raises(SystemExit): parser.parse_args("--install --purge".split())
def test_exclusive_group_ok(self): data = { "prog": "app", "arguments": [ { "name": "--install", "action": "store_true", "exclusive_group": "ops", }, { "name": "--purge", "action": "store_true", "exclusive_group": "ops", }, ], } parser = cli(data) args = parser.parse_args(["--install"]) assert args.install is True assert args.purge is False
def test_subcommand_required(self): data = { "prog": "cz", "description": ("Commitizen is a cli tool to generate conventional commits.\n" "For more information about the topic go to " "https://conventionalcommits.org/"), "formatter_class": argparse.RawDescriptionHelpFormatter, "arguments": [ { "name": "--debug", "action": "store_true", "help": "use debug mode" }, { "name": ["-n", "--name"], "help": "use the given commitizen (default: cz_conventional_commits)", }, ], "subcommands": { "title": "commands", "required": True, "commands": [{ "name": ["init"], "help": "init commitizen configuration", }] } } parser = cli(data) args = parser.parse_args(["-n", "cz_jira", "init"]) assert args.debug is False assert args.name == "cz_jira"
def main(): conf = config.read_cfg() parser = cli(data) argcomplete.autocomplete(parser) # Show help if no arg provided if len(sys.argv) == 1: parser.print_help(sys.stderr) raise ExpectedExit() # This is for the command required constraint in 2.0 try: args = parser.parse_args() except (TypeError, SystemExit) as e: # https://github.com/commitizen-tools/commitizen/issues/429 # argparse raises TypeError when non exist command is provided on Python < 3.9 # but raise SystemExit with exit code == 2 on Python 3.9 if isinstance(e, TypeError) or (isinstance(e, SystemExit) and e.code == 2): raise NoCommandFoundError() raise e if args.name: conf.update({"name": args.name}) elif not args.name and not conf.path: conf.update({"name": "cz_conventional_commits"}) if args.debug: logging.getLogger("commitizen").setLevel(logging.DEBUG) sys.excepthook = commitizen_debug_excepthook elif args.no_raise: no_raise_exit_codes = parse_no_raise(args.no_raise) no_raise_debug_excepthook = partial(commitizen_excepthook, no_raise=no_raise_exit_codes) sys.excepthook = no_raise_debug_excepthook args.func(conf, vars(args))()
def main(): conf = config.read_cfg() parser = cli(data) # Show help if no arg provided if len(sys.argv) == 1: parser.print_help(sys.stderr) raise SystemExit() args = parser.parse_args() if args.name: conf.update({"name": args.name}) if args.debug: warnings.warn("Debug will be deprecated in next major version. " "Please remove it from your scripts") logging.getLogger("commitizen").setLevel(logging.DEBUG) if args.version: out.line(__version__) raise SystemExit() args.func(conf, vars(args))()
def test_name_or_flags_fail(self): data = examples.name_or_flags() parser = cli(data) with pytest.raises(SystemExit): parser.parse_args(["--foo", "FOO"])
def get_parser(cli_spec) -> argparse.ArgumentParser: cli_spec["formatter_class"] = argparse.ArgumentDefaultsHelpFormatter return cli(cli_spec)
def complete_example(): data = { "prog": "cz", "formatter_class": argparse.RawDescriptionHelpFormatter, "description": "The software does this and that", "epilog": "This is the epilooogpoe ", "arguments": [ { "name": "--debug", "action": "store_true", "default": False, "help": "use debug mode", }, { "name": ["-v", "--version"], "action": "store_true", "default": False, "help": "get the installed version", "group": "ops", }, { "name": "--save", "group": "ops" }, ], "subcommands": { "title": "main", "description": "main commands", "commands": [ { "name": "all", "help": "check every values is true", "func": all, }, { "name": ["sum", "s"], "help": "new project", "func": sum, "arguments": [ { "name": "integers", "metavar": "N", "type": int, "nargs": "+", "help": "an integer for the accumulator", }, { "name": "--name", "nargs": "?" }, ], }, ], }, } parser = cli(data) return parser
def test_cli_no_args(self): data = {"prog": "daddy", "description": "helloo"} parser = cli(data) args = parser.parse_args([]) assert args.__dict__ == {}
"arguments": [ { "name": "--install", "action": "store_true", "group": "opas" }, { "name": "--purge", "action": "store_false", "group": "opas" }, ], "subcommands": { "title": "main", "commands": [{ "name": "commit", "arguments": [{ "name": "--bocha", "action": "store_true", "group": "opas", }], }], }, } parser = cli(data) args = parser.parse_args() print(args)
def test_not_optional_arg_name_validation_fails(self): data = {"arguments": [{"name": ["f", "foo"]}]} with pytest.raises(ValueError): cli(data)