def test_identify(): path = '/some/path' context = EntryPointContext(extension1=Extension1, extension2=Extension2, extension3=Extension3, extension4=Extension4) with context: # no identification desc = identify({}, path) assert desc is None # no complete identification extensions = get_package_identification_extensions() extensions[80]['extension1'].identify = Mock(side_effect=identify_name) desc = identify(extensions, path) assert desc is None # valid result combined across priority groups extensions = get_package_identification_extensions() extensions[100]['extension4'].identify = Mock( side_effect=identify_type) desc = identify(extensions, path) assert isinstance(desc, PackageDescriptor) assert str(desc.path) == '/some/path'.replace('/', os.sep) assert desc.name == 'name' assert desc.type == 'type' # skip location extensions = get_package_identification_extensions() extensions[90]['extension3'].identify = Mock( side_effect=IgnoreLocationException()) with pytest.raises(IgnoreLocationException): identify(extensions, path) # valid result from first priority group # lower priority groups are not even invoked extensions = get_package_identification_extensions() extensions[100]['extension4'].identify.side_effect = \ identify_name_and_type desc = identify(extensions, path) assert isinstance(desc, PackageDescriptor) assert str(desc.path) == '/some/path'.replace('/', os.sep) assert desc.name == 'name' assert desc.type == 'type' with context: # multiple different results result in skipping the location extensions = get_package_identification_extensions() extensions[100]['extension2'].identify = Mock( side_effect=identify_name) extensions[100]['extension4'].identify = Mock( side_effect=identify_type) with pytest.raises(IgnoreLocationException): identify(extensions, path)
def get_package_descriptors(args, *, additional_argument_names=None): """ Get the package descriptors. The overview of the process: * Discover the package descriptors using the package discovery and identification extensions * Check is the passed package selection arguments have valid values * Augment the package descriptors :param additional_argument_names: A list of additional arguments to consider :returns: set of :py:class:`colcon_core.package_descriptor.PackageDescriptor` :rtype: set """ extensions = get_package_identification_extensions() descriptors = discover_packages(args, extensions) pkg_names = {d.name for d in descriptors} _check_package_selection_parameters(args, pkg_names) augment_packages(descriptors, additional_argument_names=additional_argument_names) return descriptors
def package_name_completer(prefix, **kwargs): """Callable returning a list of packages names.""" from colcon_core.package_discovery import discover_packages from colcon_core.package_identification \ import get_package_identification_extensions # discover packages extensions = get_package_identification_extensions() pkgs = discover_packages(kwargs.get('parsed_args'), extensions) # return package names starting with the given prefix pkg_names = [pkg.name for pkg in pkgs] return (name for name in pkg_names if name.startswith(prefix))
def test_get_package_identification_extensions(): with EntryPointContext( extension1=Extension1, extension2=Extension2, extension3=Extension3, extension4=Extension4, ): extensions = get_package_identification_extensions() assert list(extensions.keys()) == [100, 90, 80] assert list(extensions[100].keys()) == ['extension2', 'extension4'] assert list(extensions[90].keys()) == ['extension3'] assert list(extensions[80].keys()) == ['extension1']
def get_package_path(package_name, args): """ Get the relative package path. Use the `package_discovery` extension to find package path. :param str package_name: The name of the package to find path :param args: The positional arguments to `add_argument()` :returns: The package path or None """ extensions = get_package_identification_extensions() descriptors = discover_packages(args, extensions) package_path = '' for pkg in descriptors: if (pkg.name == args.package_name): package_path = pkg.path return package_path
def test__identify(): desc_path_only = PackageDescriptor('/some/path') with EntryPointContext( extension1=Extension1, extension2=Extension2, extension3=Extension3, extension4=Extension4, ): # valid result extensions = get_package_identification_extensions()[100] extensions['extension2'].identify = Mock() extensions['extension4'].identify = identify_name_and_type desc = _identify(extensions, desc_path_only) assert isinstance(desc, PackageDescriptor) assert str(desc.path) == '/some/path'.replace('/', os.sep) assert desc.name == 'name' assert desc.type == 'type' # no results extensions = get_package_identification_extensions()[100] extensions['extension2'].identify = Mock() extensions['extension4'].identify = Mock() desc = _identify(extensions, desc_path_only) assert desc is None # multiple different results extensions = get_package_identification_extensions()[100] extensions['extension2'].identify = identify_name extensions['extension4'].identify = identify_type with patch( 'colcon_core.package_identification.logger.warning') as warn: desc = _identify(extensions, desc_path_only) assert desc is False # the raised exception is catched and results in a warn message assert warn.call_count == 1 assert len(warn.call_args[0]) == 1 assert 'multiple matches' in warn.call_args[0][0] # invalid return value extensions = get_package_identification_extensions()[90] extensions['extension3'].identify = Mock(return_value=True) with patch('colcon_core.package_identification.logger.error') as error: desc = _identify(extensions, desc_path_only) assert desc is None # the raised exception is catched and results in an error message assert error.call_count == 1 assert len(error.call_args[0]) == 1 assert error.call_args[0][0].startswith( "Exception in package identification extension 'extension3' " "in '/some/path': identify() should return None\n".replace( '/', os.sep)) # skip location extensions = get_package_identification_extensions()[90] extensions['extension3'].identify = Mock( side_effect=IgnoreLocationException()) with pytest.raises(IgnoreLocationException): _identify(extensions, desc_path_only) # raise exception extensions = get_package_identification_extensions()[90] extensions['extension3'].identify = Mock( side_effect=RuntimeError('custom exception')) with patch('colcon_core.package_identification.logger.error') as error: desc = _identify(extensions, desc_path_only) assert desc is None # the raised exception is catched and results in an error message assert error.call_count == 1 assert len(error.call_args[0]) == 1 assert error.call_args[0][0].startswith( "Exception in package identification extension 'extension3' " "in '/some/path': custom exception\n".replace('/', os.sep))