def test_find_installed_packages(): with EntryPointContext(colcon_isolated=IsolatedInstalledPackageFinder, colcon_merged=MergedInstalledPackageFinder): with TemporaryDirectory(prefix='test_colcon_') as install_base: install_base = Path(install_base) # install base doesn't exist assert find_installed_packages(install_base) is None # unknown install layout marker_file = install_base / '.colcon_install_layout' marker_file.write_text('unknown') assert find_installed_packages(install_base) is None # package index directory doesn't exist marker_file.write_text('merged') packages = find_installed_packages(install_base) assert len(packages) == 0 with patch( 'colcon_core.shell.installed_packages' '.get_relative_package_index_path', return_value=Path('relative/package/index')) as rel_path: # setup for isolated case (install_base / 'dummy_file').write_text('') (install_base / '.hidden_dir').mkdir() (install_base / 'dummy_dir' / rel_path() / 'dummy_dir').mkdir(parents=True) (install_base / 'pkgA' / rel_path()).mkdir(parents=True) (install_base / 'pkgA' / rel_path() / 'pkgA').write_text('') # setup for merged case (install_base / rel_path() / 'dummy_dir').mkdir(parents=True) (install_base / rel_path() / '.dummy').write_text('') (install_base / rel_path() / 'pkgB').write_text('') (install_base / rel_path() / 'pkgC').write_text('') marker_file.write_text('isolated') packages = find_installed_packages(install_base) assert len(packages) == 1 assert 'pkgA' in packages.keys() assert packages['pkgA'] == install_base / 'pkgA' marker_file.write_text('merged') packages = find_installed_packages(install_base) assert len(packages) == 2 assert 'pkgB' in packages.keys() assert packages['pkgC'] == install_base assert 'pkgC' in packages.keys() assert packages['pkgB'] == install_base
def test_inconsistent_package_finding_extensions(): with EntryPointContext(dne=FIExtensionPathNotExist): with TemporaryDirectory(prefix='test_colcon_') as install_base: install_base = Path(install_base) with patch('colcon_core.shell.logger.warning') as mock_warn: assert {} == find_installed_packages(install_base) dne_path = Path('/does/not/exist') mock_warn.assert_called_once_with( "Ignoring 'pkgA' found at '{0}'" ' because the path does not exist.'.format(dne_path))
def test_find_package_two_locations(): with TemporaryDirectory(prefix='test_colcon_') as base: base = Path(base) location1 = base / 'pkgA' location2 = base / 'pkgB' location1.mkdir() location2.mkdir() class PackageLocation1(FindInstalledPackagesExtensionPoint): def find_installed_packages(self, base: Path): return {'pkgA': location1} class PackageLocation2(FindInstalledPackagesExtensionPoint): def find_installed_packages(self, base: Path): return {'pkgA': location2} with EntryPointContext(loc1=PackageLocation1, loc2=PackageLocation2): with patch('colcon_core.shell.logger.warning') as mock_warn: assert {'pkgA': location1} == find_installed_packages(base) mock_warn.assert_called_once_with( "The package 'pkgA' previously found at" " '{location1}' was found again at '{location2}'." " Ignoring '{location2}'".format_map(locals()))
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