def main(opts): # Context-aware args if opts.build_this or opts.start_with_this: # Determine the enclosing package try: this_package = find_enclosing_package() except InvalidPackage: pass # Handle context-based package building if opts.build_this: if this_package: opts.packages += [this_package] else: sys.exit( "catkin build: --this was specified, but this directory is not in a catkin package." ) # If --start--with was used without any packages and --this was specified, start with this package if opts.start_with_this: if this_package: opts.start_with = this_package else: sys.exit( "catkin build: --this was specified, but this directory is not in a catkin package." ) if opts.no_deps and not opts.packages: sys.exit("With --no-deps, you must specify packages to build.") if not opts.force_color and not is_tty(sys.stdout): set_color(False) # Load the context ctx = Context.Load(opts.workspace, opts.profile, opts) # Load the environment of the workspace to extend if ctx.extend_path is not None: try: load_resultspace_environment(ctx.extend_path) except IOError as exc: log( clr("@!@{rf}Error:@| Unable to extend workspace from \"%s\": %s" % (ctx.extend_path, exc.message))) return 1 # Display list and leave the filesystem untouched if opts.dry_run: dry_run(ctx, opts.packages, opts.no_deps, opts.start_with) return # Check if the context is valid before writing any metadata if not ctx.source_space_exists(): print("catkin build: error: Unable to find source space `%s`" % ctx.source_space_abs) return 1 # Always save the last context under the build verb update_metadata(ctx.workspace, ctx.profile, 'build', ctx.get_stored_dict()) build_metadata = get_metadata(ctx.workspace, ctx.profile, 'build') if build_metadata.get('needs_force', False): opts.force_cmake = True update_metadata(ctx.workspace, ctx.profile, 'build', {'needs_force': False}) # Save the context as the configuration if opts.save_config: Context.Save(ctx) start = time.time() try: return build_isolated_workspace( ctx, packages=opts.packages, start_with=opts.start_with, no_deps=opts.no_deps, jobs=opts.parallel_jobs, force_cmake=opts.force_cmake, force_color=opts.force_color, quiet=not opts.verbose, interleave_output=opts.interleave_output, no_status=opts.no_status, limit_status_rate=opts.limit_status_rate, lock_install=not opts.no_install_lock, no_notify=opts.no_notify) finally: log("[build] Runtime: {0}".format( format_time_delta(time.time() - start)))
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 main(opts): # Context-aware args if opts.build_this or opts.start_with_this: # Determine the enclosing package try: this_package = find_enclosing_package() except InvalidPackage: pass # Handle context-based package building if opts.build_this: if this_package: opts.packages += [this_package] else: sys.exit("catkin build: --this was specified, but this directory is not contained by a catkin package.") # If --start--with was used without any packages and --this was specified, start with this package if opts.start_with_this: if this_package: opts.start_with = this_package else: sys.exit("catkin build: --this was specified, but this directory is not contained by a catkin package.") if opts.no_deps and not opts.packages: sys.exit("With --no-deps, you must specify packages to build.") if not opts.force_color and not is_tty(sys.stdout): set_color(False) # Load the context ctx = Context.Load(opts.workspace, opts.profile, opts) # Load the environment of the workspace to extend if ctx.extend_path is not None: try: load_resultspace_environment(ctx.extend_path) except IOError as exc: log(clr("@!@{rf}Error:@| Unable to extend workspace from \"%s\": %s" % (ctx.extend_path, exc.message))) return 1 # Display list and leave the filesystem untouched if opts.dry_run: dry_run(ctx, opts.packages, opts.no_deps, opts.start_with) return # Check if the context is valid before writing any metadata if not ctx.source_space_exists(): print("catkin build: error: Unable to find source space `%s`" % ctx.source_space_abs) return 1 # Always save the last context under the build verb update_metadata(ctx.workspace, ctx.profile, 'build', ctx.get_stored_dict()) build_metadata = get_metadata(ctx.workspace, ctx.profile, 'build') if build_metadata.get('needs_force', False): opts.force_cmake = True update_metadata(ctx.workspace, ctx.profile, 'build', {'needs_force': False}) # Save the context as the configuration if opts.save_config: Context.Save(ctx) start = time.time() try: return build_isolated_workspace( ctx, packages=opts.packages, start_with=opts.start_with, no_deps=opts.no_deps, jobs=opts.parallel_jobs, force_cmake=opts.force_cmake, force_color=opts.force_color, quiet=not opts.verbose, interleave_output=opts.interleave_output, no_status=opts.no_status, lock_install=not opts.no_install_lock, no_notify=opts.no_notify ) finally: log("[build] Runtime: {0}".format(format_time_delta(time.time() - start)))
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(opts): # Check for develdebug mode if opts.develdebug is not None: os.environ['TROLLIUSDEBUG'] = opts.develdebug.lower() logging.basicConfig(level=opts.develdebug.upper()) # Set color options if (opts.force_color or is_tty(sys.stdout)) and not opts.no_color: set_color(True) else: set_color(False) # Context-aware args if opts.build_this or opts.start_with_this: # Determine the enclosing package try: ws_path = find_enclosing_workspace(getcwd()) # Suppress warnings since this won't necessaraly find all packages # in the workspace (it stops when it finds one package), and # relying on it for warnings could mislead people. this_package = find_enclosing_package( search_start_path=getcwd(), ws_path=ws_path, warnings=[]) except (InvalidPackage, RuntimeError): this_package = None # Handle context-based package building if opts.build_this: if this_package: opts.packages += [this_package] else: sys.exit( "[build] Error: In order to use --this, the current directory must be part of a catkin package.") # If --start--with was used without any packages and --this was specified, start with this package if opts.start_with_this: if this_package: opts.start_with = this_package else: sys.exit( "[build] Error: In order to use --this, the current directory must be part of a catkin package.") if opts.no_deps and not opts.packages and not opts.unbuilt: sys.exit(clr("[build] @!@{rf}Error:@| With --no-deps, you must specify packages to build.")) # Load the context ctx = Context.load(opts.workspace, opts.profile, opts, append=True) # Initialize the build configuration make_args, makeflags, cli_flags, jobserver = configure_make_args( ctx.make_args, ctx.jobs_args, ctx.use_internal_make_jobserver) # Set the jobserver memory limit if jobserver and opts.mem_limit: log(clr("@!@{pf}EXPERIMENTAL: limit memory to '%s'@|" % str(opts.mem_limit))) # At this point psuitl will be required, check for it and bail out if not set try: import psutil # noqa except ImportError as exc: log("Could not import psutil, but psutil is required when using --mem-limit.") log("Please either install psutil or avoid using --mem-limit.") sys.exit("Exception: {0}".format(exc)) job_server.set_max_mem(opts.mem_limit) ctx.make_args = make_args # Load the environment of the workspace to extend if ctx.extend_path is not None: try: load_resultspace_environment(ctx.extend_path) except IOError as exc: sys.exit(clr("[build] @!@{rf}Error:@| Unable to extend workspace from \"%s\": %s" % (ctx.extend_path, exc.message))) # Check if the context is valid before writing any metadata if not ctx.source_space_exists(): sys.exit(clr("[build] @!@{rf}Error:@| Unable to find source space `%s`") % ctx.source_space_abs) # ensure the build space was previously built by catkin_tools previous_tool = get_previous_tool_used_on_the_space(ctx.build_space_abs) if previous_tool is not None and previous_tool != 'catkin build': if opts.override_build_tool_check: log(clr( "@{yf}Warning: build space at '%s' was previously built by '%s', " "but --override-build-tool-check was passed so continuing anyways." % (ctx.build_space_abs, previous_tool))) else: sys.exit(clr( "@{rf}The build space at '%s' was previously built by '%s'. " "Please remove the build space or pick a different build space." % (ctx.build_space_abs, previous_tool))) # the build space will be marked as catkin build's if dry run doesn't return # ensure the devel space was previously built by catkin_tools previous_tool = get_previous_tool_used_on_the_space(ctx.devel_space_abs) if previous_tool is not None and previous_tool != 'catkin build': if opts.override_build_tool_check: log(clr( "@{yf}Warning: devel space at '%s' was previously built by '%s', " "but --override-build-tool-check was passed so continuing anyways." % (ctx.devel_space_abs, previous_tool))) else: sys.exit(clr( "@{rf}The devel space at '%s' was previously built by '%s'. " "Please remove the devel space or pick a different devel space." % (ctx.devel_space_abs, previous_tool))) # the devel space will be marked as catkin build's if dry run doesn't return # Display list and leave the file system untouched if opts.dry_run: # TODO: Add unbuilt dry_run(ctx, opts.packages, opts.no_deps, opts.start_with) return # Print the build environment for a given package and leave the filesystem untouched if opts.get_env: return print_build_env(ctx, opts.get_env[0]) # Now mark the build and devel spaces as catkin build's since dry run didn't return. mark_space_as_built_by(ctx.build_space_abs, 'catkin build') mark_space_as_built_by(ctx.devel_space_abs, 'catkin build') # Get the last build context build_metadata = get_metadata(ctx.workspace, ctx.profile, 'build') if build_metadata.get('cmake_args') != ctx.cmake_args or build_metadata.get('cmake_args') != opts.cmake_args: opts.force_cmake = True if build_metadata.get('needs_force', False): opts.force_cmake = True update_metadata(ctx.workspace, ctx.profile, 'build', {'needs_force': False}) # Always save the last context under the build verb update_metadata(ctx.workspace, ctx.profile, 'build', ctx.get_stored_dict()) # Save the context as the configuration if opts.save_config: Context.save(ctx) # Get parallel toplevel jobs try: parallel_jobs = int(opts.parallel_jobs) except TypeError: parallel_jobs = None # Set VERBOSE environment variable if opts.verbose: os.environ['VERBOSE'] = '1' return build_isolated_workspace( ctx, packages=opts.packages, start_with=opts.start_with, no_deps=opts.no_deps, unbuilt=opts.unbuilt, n_jobs=parallel_jobs, force_cmake=opts.force_cmake, pre_clean=opts.pre_clean, force_color=opts.force_color, quiet=not opts.verbose, interleave_output=opts.interleave_output, no_status=opts.no_status, limit_status_rate=opts.limit_status_rate, lock_install=not opts.no_install_lock, no_notify=opts.no_notify, continue_on_failure=opts.continue_on_failure, summarize_build=opts.summarize # Can be True, False, or None )
def main(opts): # Check for develdebug mode if opts.develdebug is not None: os.environ['TROLLIUSDEBUG'] = opts.develdebug.lower() logging.basicConfig(level=opts.develdebug.upper()) # Set color options opts.force_color = os.environ.get('CATKIN_TOOLS_FORCE_COLOR', opts.force_color) if (opts.force_color or is_tty(sys.stdout)) and not opts.no_color: set_color(True) else: set_color(False) # Context-aware args if opts.build_this or opts.start_with_this: # Determine the enclosing package try: ws_path = find_enclosing_workspace(getcwd()) # Suppress warnings since this won't necessaraly find all packages # in the workspace (it stops when it finds one package), and # relying on it for warnings could mislead people. this_package = find_enclosing_package(search_start_path=getcwd(), ws_path=ws_path, warnings=[]) except (InvalidPackage, RuntimeError): this_package = None # Handle context-based package building if opts.build_this: if this_package: opts.packages += [this_package] else: sys.exit( "[build] Error: In order to use --this, the current directory must be part of a catkin package." ) # If --start--with was used without any packages and --this was specified, start with this package if opts.start_with_this: if this_package: opts.start_with = this_package else: sys.exit( "[build] Error: In order to use --this, the current directory must be part of a catkin package." ) if opts.no_deps and not opts.packages and not opts.unbuilt: sys.exit( clr("[build] @!@{rf}Error:@| With --no-deps, you must specify packages to build." )) # Load the context ctx = Context.load(opts.workspace, opts.profile, opts, append=True) # Initialize the build configuration make_args, makeflags, cli_flags, jobserver = configure_make_args( ctx.make_args, ctx.jobs_args, ctx.use_internal_make_jobserver) # Set the jobserver memory limit if jobserver and opts.mem_limit: log( clr("@!@{pf}EXPERIMENTAL: limit memory to '%s'@|" % str(opts.mem_limit))) # At this point psuitl will be required, check for it and bail out if not set try: import psutil # noqa except ImportError as exc: log("Could not import psutil, but psutil is required when using --mem-limit." ) log("Please either install psutil or avoid using --mem-limit.") sys.exit("Exception: {0}".format(exc)) job_server.set_max_mem(opts.mem_limit) ctx.make_args = make_args # Load the environment of the workspace to extend if ctx.extend_path is not None: try: load_resultspace_environment(ctx.extend_path) except IOError as exc: sys.exit( clr("[build] @!@{rf}Error:@| Unable to extend workspace from \"%s\": %s" % (ctx.extend_path, exc.message))) # Check if the context is valid before writing any metadata if not ctx.source_space_exists(): sys.exit( clr("[build] @!@{rf}Error:@| Unable to find source space `%s`") % ctx.source_space_abs) # ensure the build space was previously built by catkin_tools previous_tool = get_previous_tool_used_on_the_space(ctx.build_space_abs) if previous_tool is not None and previous_tool != 'catkin build': if opts.override_build_tool_check: log( clr("@{yf}Warning: build space at '%s' was previously built by '%s', " "but --override-build-tool-check was passed so continuing anyways." % (ctx.build_space_abs, previous_tool))) else: sys.exit( clr("@{rf}The build space at '%s' was previously built by '%s'. " "Please remove the build space or pick a different build space." % (ctx.build_space_abs, previous_tool))) # the build space will be marked as catkin build's if dry run doesn't return # ensure the devel space was previously built by catkin_tools previous_tool = get_previous_tool_used_on_the_space(ctx.devel_space_abs) if previous_tool is not None and previous_tool != 'catkin build': if opts.override_build_tool_check: log( clr("@{yf}Warning: devel space at '%s' was previously built by '%s', " "but --override-build-tool-check was passed so continuing anyways." % (ctx.devel_space_abs, previous_tool))) else: sys.exit( clr("@{rf}The devel space at '%s' was previously built by '%s'. " "Please remove the devel space or pick a different devel space." % (ctx.devel_space_abs, previous_tool))) # the devel space will be marked as catkin build's if dry run doesn't return # Display list and leave the file system untouched if opts.dry_run: # TODO: Add unbuilt dry_run(ctx, opts.packages, opts.no_deps, opts.start_with) return # Print the build environment for a given package and leave the filesystem untouched if opts.get_env: return print_build_env(ctx, opts.get_env[0]) # Now mark the build and devel spaces as catkin build's since dry run didn't return. mark_space_as_built_by(ctx.build_space_abs, 'catkin build') mark_space_as_built_by(ctx.devel_space_abs, 'catkin build') # Get the last build context build_metadata = get_metadata(ctx.workspace, ctx.profile, 'build') # Force cmake if the CMake arguments have changed if build_metadata.get('cmake_args') != ctx.cmake_args: opts.force_cmake = True # Check the devel layout compatibility last_devel_layout = build_metadata.get('devel_layout', ctx.devel_layout) if last_devel_layout != ctx.devel_layout: sys.exit( clr("@{rf}@!Error:@|@{rf} The current devel space layout, `{}`," "is incompatible with the configured layout, `{}`.@|").format( last_devel_layout, ctx.devel_layout)) # Check if some other verb has changed the workspace in such a way that it needs to be forced if build_metadata.get('needs_force', False): opts.force_cmake = True update_metadata(ctx.workspace, ctx.profile, 'build', {'needs_force': False}) # Always save the last context under the build verb update_metadata(ctx.workspace, ctx.profile, 'build', ctx.get_stored_dict()) # Save the context as the configuration if opts.save_config: Context.save(ctx) # Get parallel toplevel jobs try: parallel_jobs = int(opts.parallel_jobs) except TypeError: parallel_jobs = None # Set VERBOSE environment variable if opts.verbose: os.environ['VERBOSE'] = '1' return build_isolated_workspace( ctx, packages=opts.packages, start_with=opts.start_with, no_deps=opts.no_deps, unbuilt=opts.unbuilt, n_jobs=parallel_jobs, force_cmake=opts.force_cmake, pre_clean=opts.pre_clean, force_color=opts.force_color, quiet=not opts.verbose, interleave_output=opts.interleave_output, no_status=opts.no_status, limit_status_rate=opts.limit_status_rate, lock_install=not opts.no_install_lock, no_notify=opts.no_notify, continue_on_failure=opts.continue_on_failure, summarize_build=opts.summarize # Can be True, False, or None )
def main(opts): # Set color options opts.force_color = os.environ.get('CATKIN_TOOLS_FORCE_COLOR', opts.force_color) if (opts.force_color or is_tty(sys.stdout)) and not opts.no_color: set_color(True) else: set_color(False) # Context-aware args if opts.build_this: # Determine the enclosing package try: ws_path = find_enclosing_workspace(getcwd()) # Suppress warnings since this won't necessarily find all packages # in the workspace (it stops when it finds one package), and # relying on it for warnings could mislead people. this_package = find_enclosing_package(search_start_path=getcwd(), ws_path=ws_path, warnings=[]) except InvalidPackage as ex: sys.exit( clr("[test] @!@{rf}Error:@| The file {} is an invalid package.xml file." " See below for details:\n\n{}").format( ex.package_path, ex.msg)) # Handle context-based package building if this_package: opts.packages += [this_package] else: sys.exit( clr("[test] @!@{rf}Error:@| In order to use --this, " "the current directory must be part of a catkin package.")) # Load the context ctx = Context.load(opts.workspace, opts.profile, opts, append=True) # Load the environment of the workspace to extend if ctx.extend_path is not None: try: load_resultspace_environment(ctx.extend_path) except IOError as exc: sys.exit( clr("[test] @!@{rf}Error:@| Unable to extend workspace from \"{}\": {}" ).format(ctx.extend_path, str(exc))) # Check if the context is valid before writing any metadata if not ctx.source_space_exists(): sys.exit( clr("[test] @!@{rf}Error:@| Unable to find source space `{}`"). format(ctx.source_space_abs)) # Extract make arguments make_args, _, _, _ = configure_make_args(ctx.make_args, ctx.jobs_args, ctx.use_internal_make_jobserver) ctx.make_args = make_args # Get parallel toplevel jobs try: parallel_jobs = int(opts.parallel_jobs) except TypeError: parallel_jobs = None # Set VERBOSE environment variable if opts.verbose and 'VERBOSE' not in os.environ: os.environ['VERBOSE'] = '1' # Get test targets catkin_test_target = 'run_tests' cmake_test_target = 'test' if opts.test_target: catkin_test_target = opts.test_target cmake_test_target = opts.test_target if opts.catkin_test_target: catkin_test_target = opts.catkin_test_target return test_workspace( ctx, packages=opts.packages, n_jobs=parallel_jobs, quiet=not opts.verbose, interleave_output=opts.interleave_output, no_status=opts.no_status, limit_status_rate=opts.limit_status_rate, no_notify=opts.no_notify, continue_on_failure=opts.continue_on_failure, summarize_build=opts.summarize, catkin_test_target=catkin_test_target, cmake_test_target=cmake_test_target, )
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" ) 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.' ) # 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]) # 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 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 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") 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.') # 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]) # 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 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)