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

Add support for command invocation with a 'default verb' #656

Merged
merged 5 commits into from
Jul 25, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 22 additions & 5 deletions colcon_core/command.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ def register_command_exit_handler(handler):

def main(
*, command_name='colcon', argv=None, verb_group_name=None,
environment_variable_group_name=None,
environment_variable_group_name=None, default_verb=None,
):
"""
Execute the main logic of the command.
Expand All @@ -114,13 +114,19 @@ def main(

:param str command_name: The name of the command invoked
:param list argv: The list of arguments
:param str verb_group_name: The extension point group name for verbs
:param str environment_variable_group_name: The extension point group name
for environment variables
:param VerbExtensionPoint default_verb: The verb to invoke if no explicit
verb was provided on the command line
:returns: The return code
"""
try:
return _main(
command_name=command_name, argv=argv,
verb_group_name=verb_group_name,
environment_variable_group_name=environment_variable_group_name)
environment_variable_group_name=environment_variable_group_name,
default_verb=default_verb)
except KeyboardInterrupt:
return signal.SIGINT
finally:
Expand All @@ -132,6 +138,7 @@ def main(

def _main(
*, command_name, argv, verb_group_name, environment_variable_group_name,
default_verb
):
# default log level, for searchability: COLCON_LOG_LEVEL
colcon_logger.setLevel(logging.WARNING)
Expand All @@ -151,6 +158,12 @@ def _main(

parser = create_parser(environment_variable_group_name)

if default_verb is not None:
parser.set_defaults(
verb_parser=parser, verb_extension=default_verb,
main=default_verb.main)
add_parser_arguments(parser, default_verb)

verb_extensions = get_verb_extensions(group_name=verb_group_name)

# add subparsers for all verb extensions but without arguments for now
Expand All @@ -163,7 +176,7 @@ def _main(
known_args, _ = parser.parse_known_args(args=argv)

# add the arguments for the requested verb
if known_args.verb_name:
if known_args.verb_name is not None:
add_parser_arguments(known_args.verb_parser, known_args.verb_extension)

args = parser.parse_args(args=argv)
Expand All @@ -176,17 +189,21 @@ def _main(
colcon_logger.debug(f'Parsed command line arguments: {args}')

# error: no verb provided
if args.verb_name is None:
if args.verb_name is None and default_verb is None:
print(parser.format_usage())
return 'Error: No verb provided'

# set default locations for log files, for searchability: COLCON_LOG_PATH
now = datetime.datetime.now()
now_str = str(now)[:-7].replace(' ', '_').replace(':', '-')
if args.verb_name is None:
subdirectory = now_str
else:
subdirectory = f'{args.verb_name}_{now_str}'
set_default_log_path(
base_path=args.log_base,
env_var=f'{command_name}_LOG_PATH'.upper(),
subdirectory=f'{args.verb_name}_{now_str}')
subdirectory=subdirectory)

# add a file handler writing all levels if logging isn't disabled
log_path = get_log_path()
Expand Down
24 changes: 24 additions & 0 deletions test/test_command.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,30 @@ def test_main_no_verbs_or_env():
assert e.value.code == 0


def test_main_default_verb():
default_verb = Extension2()
default_verb.main = Mock(wraps=default_verb.main)
with ExtensionPointContext():
with patch(
'colcon_core.argument_parser.get_argument_parser_extensions',
return_value={}
):
with pytest.raises(SystemExit) as e:
main(argv=['--help'], default_verb=default_verb)
assert e.value.code == 0

with pytest.raises(SystemExit) as e:
main(
argv=['--log-level', 'invalid'],
default_verb=default_verb)
assert e.value.code == 2

assert not main(
argv=['--log-base', '/dev/null'],
default_verb=default_verb)
default_verb.main.assert_called_once()


def test_create_parser():
with ExtensionPointContext():
parser = create_parser('colcon_core.environment_variable')
Expand Down
Loading