def create_prefix_script(self, prefix_path, merge_install): # noqa: D102 prefix_env_path = prefix_path / 'local_setup.sh' logger.info("Creating prefix script '%s'" % prefix_env_path) expand_template( Path(__file__).parent / 'template' / 'prefix.sh.em', prefix_env_path, { 'prefix_path': prefix_path, 'python_executable': sys.executable, 'merge_install': merge_install, 'package_script_no_ext': 'package', }) shutil.copy( str(self._get_prefix_util_path()), str(prefix_path / '_local_setup_util.py')) prefix_chain_env_path = prefix_path / 'setup.sh' logger.info( "Creating prefix chain script '%s'" % prefix_chain_env_path) expand_template( Path(__file__).parent / 'template' / 'prefix_chain.sh.em', prefix_chain_env_path, { 'prefix_path': prefix_path, 'chained_prefix_path': get_chained_prefix_path( skip=prefix_path), 'prefix_script_no_ext': 'local_setup', })
def create_prefix_script(self, prefix_path, merge_install): # noqa: D102 prefix_env_path = prefix_path / 'local_setup.bat' logger.info("Creating prefix script '%s'" % prefix_env_path) expand_template( Path(__file__).parent / 'template' / 'prefix.bat.em', prefix_env_path, { 'python_executable': sys.executable, 'merge_install': merge_install, 'package_script_no_ext': 'package', }) prefix_util_path = prefix_path / '_local_setup_util_bat.py' logger.info("Creating prefix util module '%s'" % prefix_util_path) expand_template(self._get_prefix_util_template_path(), prefix_util_path, {'shell_extension': self}) prefix_chain_env_path = prefix_path / 'setup.bat' logger.info("Creating prefix chain script '%s'" % prefix_chain_env_path) expand_template( Path(__file__).parent / 'template' / 'prefix_chain.bat.em', prefix_chain_env_path, { 'chained_prefix_path': get_chained_prefix_path(skip=prefix_path), 'prefix_script_no_ext': 'local_setup', })
def create_prefix_script(self, prefix_path, merge_install): # noqa: D102 prefix_env_path = prefix_path / 'local_setup.bash' logger.info( "Creating prefix script '{prefix_env_path}'".format_map(locals())) expand_template( Path(__file__).parent / 'template' / 'prefix.bash.em', prefix_env_path, { 'python_executable': sys.executable, 'merge_install': merge_install, 'package_script_no_ext': 'package', }) # no need to copy prefix_util.py explicitly since bash relies on sh prefix_chain_env_path = prefix_path / 'setup.bash' logger.info( "Creating prefix chain script '{prefix_chain_env_path}'" .format_map(locals())) expand_template( Path(__file__).parent / 'template' / 'prefix_chain.bash.em', prefix_chain_env_path, { 'chained_prefix_path': get_chained_prefix_path( skip=prefix_path), 'prefix_script_no_ext': 'local_setup', })
def find_installed_packages_in_environment(): """ Find packages under the COLCON_PREFIX_PATH. For each prefix path the package index is being read and the first time a package is being found its install prefix is being added to the result. :returns: The mapping from a package name to the prefix path :rtype: OrderedDict """ packages = OrderedDict() for prefix_path in get_chained_prefix_path(): prefix_path = Path(prefix_path) pkgs = find_installed_packages(prefix_path) if pkgs is None: logger.debug("Ignoring prefix path '{prefix_path}'".format_map( locals())) continue for pkg_name in sorted(pkgs.keys()): # ignore packages with the same name in "lower" prefix path if pkg_name in packages: continue packages[pkg_name] = pkgs[pkg_name] return packages
def test_get_chained_prefix_path(): # empty environment variable with EnvironmentContext(COLCON_PREFIX_PATH=''): prefix_path = get_chained_prefix_path() assert prefix_path == [] # extra path separator with EnvironmentContext(COLCON_PREFIX_PATH=os.pathsep): prefix_path = get_chained_prefix_path(skip='/path/to/skip') assert prefix_path == [] ColconPrefixPath.PREFIX_PATH_NAME = 'colcon' with patch('colcon_core.prefix_path.get_prefix_path_extensions', return_value={ 100: { 'colcon': ColconPrefixPath() }, }): with TemporaryDirectory(prefix='test_colcon_') as basepath: basepath = Path(basepath) with EnvironmentContext(COLCON_PREFIX_PATH=os.pathsep.join( [str(basepath), str(basepath)])): # multiple results, duplicates being skipped prefix_path = get_chained_prefix_path(skip='/path/to/skip') assert prefix_path == [str(basepath)] # skipping results prefix_path = get_chained_prefix_path(skip=str(basepath)) assert prefix_path == [] # skipping non-existing results with EnvironmentContext(COLCON_PREFIX_PATH=os.pathsep.join( [str(basepath), str(basepath / 'non-existing-sub')])): with patch('colcon_core.prefix_path.colcon.logger.warning' ) as warn: prefix_path = get_chained_prefix_path() assert prefix_path == [str(basepath)] assert warn.call_count == 1 assert len(warn.call_args[0]) == 1 assert warn.call_args[0][0].endswith( "non-existing-sub' in the environment variable " "COLCON_PREFIX_PATH doesn't exist") # suppress duplicate warning with patch('colcon_core.prefix_path.colcon.logger.warning' ) as warn: prefix_path = get_chained_prefix_path() assert prefix_path == [str(basepath)] assert warn.call_count == 0 with EntryPointContext(extension1=Extension1, extension2=Extension2): extensions = get_prefix_path_extensions() # one invalid return value, one not implemented extensions[100]['extension2'].extend_prefix_path = Mock( return_value=False) extensions[90]['extension1'].extend_prefix_path = Mock( return_value=None) with patch('colcon_core.prefix_path.logger.error') as error: get_chained_prefix_path() # the raised exception is catched and results in an error message assert error.call_count == 1 assert len(error.call_args_list[0][0]) == 1 assert error.call_args_list[0][0][0].startswith( "Exception in prefix path extension 'extension2': " 'extend_prefix_path() should return None\n')
def main(self, *, context): # noqa: D102 check_and_mark_build_tool(context.args.build_base) check_and_mark_install_layout(context.args.install_base, merge_install=context.args.merge_install) self._create_paths(context.args) decorators = get_packages( context.args, additional_argument_names=self.task_argument_destinations, recursive_categories=('run', )) install_base = os.path.abspath( os.path.join(os.getcwd(), context.args.install_base)) jobs, unselected_packages = self._get_jobs(context.args, decorators, install_base) underlay_packages = {} for prefix_path in get_chained_prefix_path(): packages = find_installed_packages(Path(prefix_path)) if packages: for pkg, path in packages.items(): if pkg not in underlay_packages: underlay_packages[pkg] = [] underlay_packages[pkg].append(str(path)) override_messages = {} for overlay_package in jobs.keys(): if overlay_package in underlay_packages: if overlay_package not in context.args.allow_overriding: override_messages[overlay_package] = ( "'{overlay_package}'".format_map(locals()) + ' is in: ' + ', '.join(underlay_packages[overlay_package])) if override_messages: override_msg = ( 'Some selected packages are already built in one or more' ' underlay workspaces:' '\n\t' + '\n\t'.join(override_messages.values()) + '\nIf a package in a merged underlay workspace is overridden' ' and it installs headers, then all packages in the overlay' ' must sort their include directories by workspace order.' ' Failure to do so may result in build failures or undefined' ' behavior at run time.' '\nIf the overridden package is used by another package' ' in any underlay, then the overriding package in the' ' overlay must be API and ABI compatible or undefined' ' behavior at run time may occur.' '\n\nIf you understand the risks and want to override a' ' package anyways, add the following to the command' ' line:' '\n\t--allow-overriding ' + ' '.join(sorted(override_messages.keys()))) logger.warn(override_msg + '\n\nThis may be promoted to an error in a' ' future release of colcon-core.') on_error = OnError.interrupt \ if not context.args.continue_on_error else OnError.skip_downstream def post_unselected_packages(*, event_queue): nonlocal unselected_packages names = [pkg.name for pkg in unselected_packages] for name in sorted(names): event_queue.put((JobUnselected(name), None)) rc = execute_jobs(context, jobs, on_error=on_error, pre_execution_callback=post_unselected_packages) self._create_prefix_scripts(install_base, context.args.merge_install) return rc