def catkin_main(sysargs): # Initialize config try: initialize_config() except RuntimeError as exc: sys.exit("Failed to initialize config: {0}".format(exc)) # Create a top level parser parser = argparse.ArgumentParser( description="catkin command", formatter_class=argparse.RawDescriptionHelpFormatter) add = parser.add_argument add('-a', '--list-aliases', action="store_true", default=False, help="Lists the current verb aliases and then quits, all other arguments are ignored") add('--test-colors', action='store_true', default=False, help="Prints a color test pattern to the screen and then quits, all other arguments are ignored") add('--version', action='store_true', default=False, help="Prints the catkin_tools version.") color_control_group = parser.add_mutually_exclusive_group() add = color_control_group.add_argument add('--force-color', action='store_true', default=False, help='Forces catkin to output in color, even when the terminal does not appear to support it.') add('--no-color', action='store_true', default=False, help='Forces catkin to not use color in the output, regardless of the detect terminal type.') # Deprecated, moved to `catkin locate --shell-verbs add('--locate-extra-shell-verbs', action='store_true', help=argparse.SUPPRESS) # Generate a list of verbs available verbs = list_verbs() # Create the subparsers for each verb and collect the argument preprocessors argument_preprocessors = create_subparsers(parser, verbs) # Get verb aliases verb_aliases = get_verb_aliases() # Setup sysargs sysargs = sys.argv[1:] if sysargs is None else sysargs # Get colors config no_color = False force_color = os.environ.get('CATKIN_TOOLS_FORCE_COLOR', False) for arg in sysargs: if arg == '--no-color': no_color = True if arg == '--force-color': force_color = True if no_color or not force_color and not is_tty(sys.stdout): set_color(False) # Check for version if '--version' in sysargs: print('catkin_tools {} (C) 2014-{} Open Source Robotics Foundation'.format( pkg_resources.get_distribution('catkin_tools').version, date.today().year) ) print('catkin_tools is released under the Apache License,' ' Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0)') print('---') print('Using Python {}'.format(''.join(sys.version.split('\n')))) sys.exit(0) # Deprecated option if '--locate-extra-shell-verbs' in sysargs: print('Please use `catkin locate --shell-verbs` instead of `catkin --locate-extra-shell-verbs`', file=sys.stderr) sys.exit(0) # Check for --test-colors for arg in sysargs: if arg == '--test-colors': test_colors() sys.exit(0) if not arg.startswith('-'): break # Check for --list-aliases for arg in sysargs: if arg == '--list-aliases' or arg == '-a': for alias in sorted(list(verb_aliases.keys())): print("{0}: {1}".format(alias, ' '.join([cmd_quote(aarg) for aarg in verb_aliases[alias]]))) sys.exit(0) if not arg.startswith('-'): break # Do verb alias expansion sysargs = expand_verb_aliases(sysargs, verb_aliases) # Determine the verb, splitting arguments into pre and post verb verb = None pre_verb_args = [] post_verb_args = [] for index, arg in enumerate(sysargs): # If the arg does not start with a `-` then it is a positional argument # The first positional argument must be the verb if not arg.startswith('-'): verb = arg post_verb_args = sysargs[index + 1:] break # If the `-h` or `--help` option comes before the verb, parse_args if arg in ['-h', '--help']: parser.parse_args(sysargs) # Otherwise it is a pre-verb option pre_verb_args.append(arg) # Error on no verb provided if verb is None: print(parser.format_usage()) sys.exit("Error: No verb provided.") # Error on unknown verb provided if verb not in verbs: print(parser.format_usage()) sys.exit("Error: Unknown verb '{0}' provided.".format(verb)) # First allow the verb's argument preprocessor to strip any args # and return any "extra" information it wants as a dict processed_post_verb_args, extras = argument_preprocessors[verb](post_verb_args) # Then allow argparse to process the left over post-verb arguments along # with the pre-verb arguments and the verb itself args = parser.parse_args(pre_verb_args + [verb] + processed_post_verb_args) # Extend the argparse result with the extras from the preprocessor for key, value in extras.items(): setattr(args, key, value) # Finally call the subparser's main function with the processed args # and the extras which the preprocessor may have returned sys.exit(args.main(args) or 0)
def test_get_verb_aliases(): cwd = os.getcwd() test_folder = os.path.join(cwd, 'test') # Test failure case where config folder does not exist with assert_raises_regexp(RuntimeError, "Cannot get verb aliases because the catkin config path"): config.get_verb_aliases(test_folder) # Test failure case where aliases folder does not exist with mock.patch('catkin_tools.config.initialize_verb_aliases'): config.initialize_config(test_folder) with assert_raises_regexp(RuntimeError, "Cannot get verb aliases because the verb aliases config path"): config.get_verb_aliases(test_folder) shutil.rmtree(test_folder) # Test the normal case config.initialize_config(test_folder) aliases = config.get_verb_aliases(test_folder) assert 'b' in aliases assert aliases['b'] == ['build'] # Test a custom file base_path = os.path.join(test_folder, 'verb_aliases') with open(os.path.join(base_path, '01-my-custom-aliases.yaml'), 'w') as f: f.write("""\ b: build --isolate-devel ls: null """) aliases = config.get_verb_aliases(test_folder) assert 'b' in aliases assert aliases['b'] == ['build', '--isolate-devel'], aliases['b'] assert 'ls' not in aliases # Test a bad alias files bad_path = os.path.join(base_path, '02-bad.yaml') with open(bad_path, 'w') as f: f.write("""\ - foo - bar """) with assert_raises_regexp(RuntimeError, "Invalid alias file"): config.get_verb_aliases(test_folder) os.remove(bad_path) with open(bad_path, 'w') as f: f.write("""\ null: foo """) with assert_raises_regexp(RuntimeError, "Invalid alias in file"): config.get_verb_aliases(test_folder) os.remove(bad_path) with open(bad_path, 'w') as f: f.write("""\ foo: 13.4 """) with assert_raises_regexp(RuntimeError, "Invalid alias expansion in file"): config.get_verb_aliases(test_folder) os.remove(bad_path) # Test with an empty custom file empty_path = os.path.join(base_path, '02-my-empty.yaml') with open(empty_path, 'a') as f: os.utime(empty_path, None) aliases = config.get_verb_aliases(test_folder)
def catkin_main(sysargs): # Initialize config try: initialize_config() except RuntimeError as exc: sys.exit("Failed to initialize config: {0}".format(exc)) # Create a top level parser parser = argparse.ArgumentParser( description="catkin command", formatter_class=argparse.RawDescriptionHelpFormatter) add = parser.add_argument add('-a', '--list-aliases', action="store_true", default=False, help="Lists the current verb aliases and then quits, all other arguments are ignored") add('--test-colors', action='store_true', default=False, help="Prints a color test pattern to the screen and then quits, all other arguments are ignored") color_control_group = parser.add_mutually_exclusive_group() add = color_control_group.add_argument add('--force-color', action='store_true', default=False, help='Forces catkin to output in color, even when the terminal does not appear to support it.') add('--no-color', action='store_true', default=False, help='Forces catkin to not use color in the output, regardless of the detect terminal type.') add('--locate-extra-shell-verbs', action='store_true', help='Returns the full path of the file to source for extra shell verbs, then exits.') # Generate a list of verbs available verbs = list_verbs() # Create the subparsers for each verb and collect the argument preprocessors argument_preprocessors = create_subparsers(parser, verbs) # Get verb aliases verb_aliases = get_verb_aliases() # Setup sysargs sysargs = sys.argv[1:] if sysargs is None else sysargs # Get colors config no_color = False force_color = False for arg in sysargs: if arg == '--no-color': no_color = True if arg == '--force-color': force_color = True if no_color or not force_color and not is_tty(sys.stdout): set_color(False) # Check for --test-colors for arg in sysargs: if arg == '--test-colors': test_colors() sys.exit(0) if not arg.startswith('-'): break # Check for --list-aliases for arg in sysargs: if arg == '--list-aliases' or arg == '-a': for alias in sorted(list(verb_aliases.keys())): print("{0}: {1}".format(alias, verb_aliases[alias])) sys.exit(0) if not arg.startswith('-'): break # Do verb alias expansion sysargs = expand_verb_aliases(sysargs, verb_aliases) # Check for --locate-extra-shell-verbs for arg in sysargs: if arg == '--locate-extra-shell-verbs': this_dir = os.path.dirname(__file__) shell_verbs = os.path.join(this_dir, '..', 'verbs', 'catkin_shell_verbs.bash') print(os.path.normpath(shell_verbs)) sys.exit(0) # Determine the verb, splitting arguments into pre and post verb verb = None pre_verb_args = [] post_verb_args = [] for index, arg in enumerate(sysargs): # If the arg does not start with a `-` then it is a positional argument # The first positional argument must be the verb if not arg.startswith('-'): verb = arg post_verb_args = sysargs[index + 1:] break # If the `-h` or `--help` option comes before the verb, parse_args if arg in ['-h', '--help']: parser.parse_args(sysargs) # Otherwise it is a pre-verb option pre_verb_args.append(arg) # Error on no verb provided if verb is None: print(parser.format_usage()) sys.exit("Error: No verb provided.") # Error on unknown verb provided if verb not in verbs: print(parser.format_usage()) sys.exit("Error: Unknown verb '{0}' provided.".format(verb)) # First allow the verb's argument preprocessor to strip any args # and return any "extra" information it wants as a dict processed_post_verb_args, extras = argument_preprocessors[verb](post_verb_args) # Then allow argparse to process the left over post-verb arguments along # with the pre-verb arguments and the verb itself args = parser.parse_args(pre_verb_args + [verb] + processed_post_verb_args) # Extend the argparse result with the extras from the preprocessor for key, value in extras.items(): setattr(args, key, value) # Finally call the subparser's main function with the processed args # and the extras which the preprocessor may have returned sys.exit(args.main(args) or 0)
def main(sysargs=None): # Initialize config try: initialize_config() except RuntimeError as exc: sys.exit("Failed to initialize config: {0}".format(exc)) # Create a top level parser parser = argparse.ArgumentParser(description="catkin command") add = parser.add_argument add('-a', '--list-aliases', action="store_true", default=False, help="lists the current verb aliases and then quits, all other arguments are ignored") add('--test-colors', action='store_true', default=False, help="prints a color test pattern to the screen and then quits, all other arguments are ignored") # Generate a list of verbs available verbs = list_verbs() # Create the subparsers for each verb and collect the argument preprocessors argument_preprocessors = create_subparsers(parser, verbs) # Get verb aliases verb_aliases = get_verb_aliases() # Setup sysargs sysargs = sys.argv[1:] if sysargs is None else sysargs cmd = os.path.basename(sys.argv[0]) # Check for --test-colors for arg in sysargs: if arg == '--test-colors': test_colors() sys.exit(0) if not arg.startswith('-'): break # Check for --list-aliases for arg in sysargs: if arg == '--list-aliases' or arg == '-a': for alias in sorted(list(verb_aliases.keys())): print("{0}: {1}".format(alias, verb_aliases[alias])) sys.exit(0) if not arg.startswith('-'): break # Do alias expansion expanding_verb_aliases = True used_aliases = [] while expanding_verb_aliases: expanding_verb_aliases = False for index, arg in enumerate(sysargs): if not arg.startswith('-'): if arg in used_aliases: print(fmt( "@!@{gf}==>@| Expanding alias '@!@{yf}" + arg + "@|' was previously expanded, ignoring this time to prevent infinite recursion." )) if arg in verb_aliases: before = [] if index == 0 else sysargs[:index - 1] after = [] if index == len(sysargs) else sysargs[index + 1:] sysargs = before + verb_aliases[arg].split() + after print(fmt( "@!@{gf}==>@| Expanding alias " "'@!@{yf}{alias}@|' " "from '@{yf}{before} @!{alias}@{boldoff}{after}@|' " "to '@{yf}{before} @!{expansion}@{boldoff}{after}@|'" ).format( alias=arg, expansion=verb_aliases[arg], before=' '.join([cmd] + before), after=(' '.join([''] + after) if after else '') )) expanding_verb_aliases = True # Prevent the alias from being used again, to prevent infinite recursion used_aliases.append(arg) del verb_aliases[arg] break # Determine the verb, splitting arguments into pre and post verb verb = None pre_verb_args = [] post_verb_args = [] for index, arg in enumerate(sysargs): # If the arg does not start with a `-` then it is a positional argument # The first positional argument must be the verb if not arg.startswith('-'): verb = arg post_verb_args = sysargs[index + 1:] break # If the `-h` or `--help` option comes before the verb, parse_args if arg in ['-h', '--help']: parser.parse_args(sysargs) # Otherwise it is a pre-verb option pre_verb_args.append(arg) # Error on no verb provided if verb is None: print(parser.format_usage()) sys.exit("Error: No verb provided.") # Error on unknown verb provided if verb not in verbs: print(parser.format_usage()) sys.exit("Error: Unknown verb '{0}' provided.".format(verb)) # First allow the verb's argument preprocessor to strip any args # and return any "extra" information it wants as a dict processed_post_verb_args, extras = argument_preprocessors[verb](post_verb_args) # Then allow argparse to process the left over post-verb arguments along # with the pre-verb arguments and the verb itself args = parser.parse_args(pre_verb_args + [verb] + processed_post_verb_args) # Extend the argparse result with the extras from the preprocessor for key, value in extras.items(): setattr(args, key, value) # Finally call the subparser's main function with the processed args # and the extras which the preprocessor may have returned sys.exit(args.main(args) or 0)
def test_get_verb_aliases(): cwd = os.getcwd() test_folder = os.path.join(cwd, 'test') # Test failure case where config folder does not exist with assert_raises_regexp( RuntimeError, "Cannot get verb aliases because the catkin config path"): config.get_verb_aliases(test_folder) # Test failure case where aliases folder does not exist with mock.patch('catkin_tools.config.initialize_verb_aliases'): config.initialize_config(test_folder) with assert_raises_regexp( RuntimeError, "Cannot get verb aliases because the verb aliases config path"): config.get_verb_aliases(test_folder) shutil.rmtree(test_folder) # Test the normal case config.initialize_config(test_folder) aliases = config.get_verb_aliases(test_folder) assert 'b' in aliases assert aliases['b'] == ['build'] # Test a custom file base_path = os.path.join(test_folder, 'verb_aliases') with open(os.path.join(base_path, '01-my-custom-aliases.yaml'), 'w') as f: f.write("""\ b: build --isolate-devel ls: null """) aliases = config.get_verb_aliases(test_folder) assert 'b' in aliases assert aliases['b'] == ['build', '--isolate-devel'], aliases['b'] assert 'ls' not in aliases # Test a bad alias files bad_path = os.path.join(base_path, '02-bad.yaml') with open(bad_path, 'w') as f: f.write("""\ - foo - bar """) with assert_raises_regexp(RuntimeError, "Invalid alias file"): config.get_verb_aliases(test_folder) os.remove(bad_path) with open(bad_path, 'w') as f: f.write("""\ null: foo """) with assert_raises_regexp(RuntimeError, "Invalid alias in file"): config.get_verb_aliases(test_folder) os.remove(bad_path) with open(bad_path, 'w') as f: f.write("""\ foo: 13.4 """) with assert_raises_regexp(RuntimeError, "Invalid alias expansion in file"): config.get_verb_aliases(test_folder) os.remove(bad_path) # Test with an empty custom file empty_path = os.path.join(base_path, '02-my-empty.yaml') with open(empty_path, 'a') as f: os.utime(empty_path, None) aliases = config.get_verb_aliases(test_folder)
def main(sysargs=None): # Initialize config try: initialize_config() except RuntimeError as exc: sys.exit("Failed to initialize config: {0}".format(exc)) # Create a top level parser parser = argparse.ArgumentParser(description="catkin command", formatter_class=argparse.RawDescriptionHelpFormatter) add = parser.add_argument add('-a', '--list-aliases', action="store_true", default=False, help="lists the current verb aliases and then quits, all other arguments are ignored") add('--test-colors', action='store_true', default=False, help="prints a color test pattern to the screen and then quits, all other arguments are ignored") # Generate a list of verbs available verbs = list_verbs() # Create the subparsers for each verb and collect the argument preprocessors argument_preprocessors = create_subparsers(parser, verbs) # Get verb aliases verb_aliases = get_verb_aliases() # Setup sysargs sysargs = sys.argv[1:] if sysargs is None else sysargs cmd = os.path.basename(sys.argv[0]) # Check for --test-colors for arg in sysargs: if arg == '--test-colors': test_colors() sys.exit(0) if not arg.startswith('-'): break # Check for --list-aliases for arg in sysargs: if arg == '--list-aliases' or arg == '-a': for alias in sorted(list(verb_aliases.keys())): print("{0}: {1}".format(alias, verb_aliases[alias])) sys.exit(0) if not arg.startswith('-'): break # Do alias expansion expanding_verb_aliases = True used_aliases = [] while expanding_verb_aliases: expanding_verb_aliases = False for index, arg in enumerate(sysargs): if not arg.startswith('-'): if arg in used_aliases: print(fmt( "@!@{gf}==>@| Expanding alias '@!@{yf}" + arg + "@|' was previously expanded, ignoring this time to prevent infinite recursion." )) if arg in verb_aliases: before = [] if index == 0 else sysargs[:index - 1] after = [] if index == len(sysargs) else sysargs[index + 1:] sysargs = before + verb_aliases[arg].split() + after print(fmt( "@!@{gf}==>@| Expanding alias " "'@!@{yf}{alias}@|' " "from '@{yf}{before} @!{alias}@{boldoff}{after}@|' " "to '@{yf}{before} @!{expansion}@{boldoff}{after}@|'" ).format( alias=arg, expansion=verb_aliases[arg], before=' '.join([cmd] + before), after=(' '.join([''] + after) if after else '') )) expanding_verb_aliases = True # Prevent the alias from being used again, to prevent infinite recursion used_aliases.append(arg) del verb_aliases[arg] break # Determine the verb, splitting arguments into pre and post verb verb = None pre_verb_args = [] post_verb_args = [] for index, arg in enumerate(sysargs): # If the arg does not start with a `-` then it is a positional argument # The first positional argument must be the verb if not arg.startswith('-'): verb = arg post_verb_args = sysargs[index + 1:] break # If the `-h` or `--help` option comes before the verb, parse_args if arg in ['-h', '--help']: parser.parse_args(sysargs) # Otherwise it is a pre-verb option pre_verb_args.append(arg) # Error on no verb provided if verb is None: print(parser.format_usage()) sys.exit("Error: No verb provided.") # Error on unknown verb provided if verb not in verbs: print(parser.format_usage()) sys.exit("Error: Unknown verb '{0}' provided.".format(verb)) # First allow the verb's argument preprocessor to strip any args # and return any "extra" information it wants as a dict processed_post_verb_args, extras = argument_preprocessors[verb](post_verb_args) # Then allow argparse to process the left over post-verb arguments along # with the pre-verb arguments and the verb itself args = parser.parse_args(pre_verb_args + [verb] + processed_post_verb_args) # Extend the argparse result with the extras from the preprocessor for key, value in extras.items(): setattr(args, key, value) # Finally call the subparser's main function with the processed args # and the extras which the preprocessor may have returned sys.exit(args.main(args) or 0)