diff --git a/src/rosdep2/catkin_packages.py b/src/rosdep2/catkin_packages.py index 76cd8ffb6..3d8b72c60 100644 --- a/src/rosdep2/catkin_packages.py +++ b/src/rosdep2/catkin_packages.py @@ -13,6 +13,8 @@ _catkin_workspace_packages = [] _catkin_packages_cache = {} +VALID_DEPENDENCY_TYPES = {'build', 'buildtool', 'build_export', 'buildtool_export', 'exec', 'test', 'doc'} + def find_catkin_packages_in(path, verbose=False): """ diff --git a/src/rosdep2/lookup.py b/src/rosdep2/lookup.py index 1d8d979b3..0926dbeb6 100644 --- a/src/rosdep2/lookup.py +++ b/src/rosdep2/lookup.py @@ -328,7 +328,7 @@ def get_resources_that_need(self, rosdep_name): @staticmethod def create_from_rospkg(rospack=None, rosstack=None, sources_loader=None, - verbose=False): + verbose=False, dependency_types=None): """ Create :class:`RosdepLookup` based on current ROS package environment. @@ -339,6 +339,8 @@ def create_from_rospkg(rospack=None, rosstack=None, instance used to crawl ROS stacks. :param sources_loader: (optional) Override SourcesLoader used for managing sources.list data sources. + :param dependency_types: (optional) List of dependency types. + Allowed: {'build', 'buildtool', 'build_export', 'buildtool_export', 'exec', 'test', 'doc'} """ # initialize the loader if rospack is None: @@ -347,6 +349,8 @@ def create_from_rospkg(rospack=None, rosstack=None, rosstack = RosStack() if sources_loader is None: sources_loader = SourcesListLoader.create_default(verbose=verbose) + if dependency_types is None: + dependency_types = [] rosdep_db = RosdepDatabase() @@ -358,7 +362,7 @@ def create_from_rospkg(rospack=None, rosstack=None, # Create the rospkg loader on top of the underlay loader = RosPkgLoader(rospack=rospack, rosstack=rosstack, - underlay_key=underlay_key) + underlay_key=underlay_key, dependency_types=dependency_types) # create our actual instance lookup = RosdepLookup(rosdep_db, loader) diff --git a/src/rosdep2/main.py b/src/rosdep2/main.py index 268fcbdc1..db74ec638 100644 --- a/src/rosdep2/main.py +++ b/src/rosdep2/main.py @@ -76,6 +76,7 @@ from .catkin_packages import find_catkin_packages_in from .catkin_packages import set_workspace_packages from .catkin_packages import get_workspace_packages +from .catkin_packages import VALID_DEPENDENCY_TYPES from catkin_pkg.package import InvalidPackage @@ -132,7 +133,7 @@ def _get_default_RosdepLookup(options): sources_loader = SourcesListLoader.create_default(sources_cache_dir=options.sources_cache_dir, os_override=os_override, verbose=options.verbose) - lookup = RosdepLookup.create_from_rospkg(sources_loader=sources_loader) + lookup = RosdepLookup.create_from_rospkg(sources_loader=sources_loader, dependency_types=options.dependency_types) lookup.verbose = options.verbose return lookup @@ -368,6 +369,11 @@ def _rosdep_main(args): help="Affects the 'update' verb. " 'If specified end-of-life distros are being ' 'fetched too.') + parser.add_option('-t', '--dependency-types', dest='dependency_types', + type="choice", choices=list(VALID_DEPENDENCY_TYPES), + default=[], action='append', + help='Dependency types to install, can be given multiple times. ' + 'Choose from {}. Default: all except doc.'.format(VALID_DEPENDENCY_TYPES)) options, args = parser.parse_args(args) if options.print_version or options.print_all_versions: @@ -401,9 +407,10 @@ def _rosdep_main(args): print('No installers with versions available found.') sys.exit(0) - # flatten list of skipped keys and filter-for-installers + # flatten list of skipped keys, filter-for-installers, and dependency types options.skip_keys = [key for s in options.skip_keys for key in s.split(' ')] options.filter_for_installers = [inst for s in options.filter_for_installers for inst in s.split(' ')] + options.dependency_types = [dep for s in options.dependency_types for dep in s.split(' ')] if len(args) == 0: parser.error('Please enter a command') diff --git a/src/rosdep2/rospack.py b/src/rosdep2/rospack.py index c5b13f04c..c51044994 100644 --- a/src/rosdep2/rospack.py +++ b/src/rosdep2/rospack.py @@ -56,6 +56,7 @@ def __init__(self): self.os_override = None self.sources_cache_dir = get_sources_cache_dir() self.verbose = False + self.dependency_types = [] lookup = _get_default_RosdepLookup(Options()) return lookup.get_rosdep_view(DEFAULT_VIEW_KEY) diff --git a/src/rosdep2/rospkg_loader.py b/src/rosdep2/rospkg_loader.py index 95a10c5d4..789305879 100644 --- a/src/rosdep2/rospkg_loader.py +++ b/src/rosdep2/rospkg_loader.py @@ -39,6 +39,7 @@ import catkin_pkg.package import rospkg +from .catkin_packages import VALID_DEPENDENCY_TYPES from .loader import RosdepLoader # Default view key is the view that packages that are not in stacks @@ -59,7 +60,7 @@ class RosPkgLoader(RosdepLoader): - def __init__(self, rospack=None, rosstack=None, underlay_key=None): + def __init__(self, rospack=None, rosstack=None, underlay_key=None, dependency_types=[]): """ :param underlay_key: If set, all views loaded by this loader will depend on this key. @@ -78,6 +79,9 @@ def __init__(self, rospack=None, rosstack=None, underlay_key=None): self._loadable_resource_cache = None self._catkin_packages_cache = None + default_dep_types = VALID_DEPENDENCY_TYPES - {'doc'} + self.include_dep_types = VALID_DEPENDENCY_TYPES.intersection(set(dependency_types)) if dependency_types else default_dep_types + def load_view(self, view_name, rosdep_db, verbose=False): """ Load view data into *rosdep_db*. If the view has already @@ -140,7 +144,7 @@ def get_rosdeps(self, resource_name, implicit=True): if resource_name in self.get_catkin_paths(): pkg = catkin_pkg.package.parse_package(self.get_catkin_paths()[resource_name]) pkg.evaluate_conditions(os.environ) - deps = pkg.build_depends + pkg.buildtool_depends + pkg.run_depends + pkg.test_depends + pkg.buildtool_export_depends + deps = sum((getattr(pkg, '{}_depends'.format(d)) for d in self.include_dep_types), []) return [d.name for d in deps if d.evaluated_condition] elif resource_name in self.get_loadable_resources(): rosdeps = set(self._rospack.get_rosdeps(resource_name, implicit=False)) diff --git a/test/test_rosdep_lookup.py b/test/test_rosdep_lookup.py index 0bc4f2db5..97389690a 100644 --- a/test/test_rosdep_lookup.py +++ b/test/test_rosdep_lookup.py @@ -329,6 +329,47 @@ def test_RosdepLookup_get_rosdeps(): assert set(lookup.get_rosdeps('metapackage_with_deps', implicit=False)) == set(['catkin', 'simple_catkin_package', 'another_catkin_package']) +def test_RosdepLookup_dependency_types(): + from rosdep2.loader import RosdepLoader + from rosdep2.lookup import RosdepLookup + rospack, rosstack = get_test_rospkgs() + + sources_loader = create_test_SourcesListLoader() + default_lookup = RosdepLookup.create_from_rospkg(rospack=rospack, rosstack=rosstack, + sources_loader=sources_loader) + buildtool_lookup = RosdepLookup.create_from_rospkg(rospack=rospack, rosstack=rosstack, + sources_loader=sources_loader, dependency_types=['buildtool']) + build_lookup = RosdepLookup.create_from_rospkg(rospack=rospack, rosstack=rosstack, + sources_loader=sources_loader, dependency_types=['build']) + build_export_lookup = RosdepLookup.create_from_rospkg(rospack=rospack, rosstack=rosstack, + sources_loader=sources_loader, dependency_types=['build_export']) + exec_lookup = RosdepLookup.create_from_rospkg(rospack=rospack, rosstack=rosstack, + sources_loader=sources_loader, dependency_types=['exec']) + test_lookup = RosdepLookup.create_from_rospkg(rospack=rospack, rosstack=rosstack, + sources_loader=sources_loader, dependency_types=['test']) + doc_lookup = RosdepLookup.create_from_rospkg(rospack=rospack, rosstack=rosstack, + sources_loader=sources_loader, dependency_types=['doc']) + mix_lookup = RosdepLookup.create_from_rospkg(rospack=rospack, rosstack=rosstack, + sources_loader=sources_loader, dependency_types=['build', 'build_export']) + + buildtool_deps = ['catkin'] + build_deps = ['testboost', 'eigen'] + build_export_deps = ['eigen', 'testtinyxml'] + exec_deps = ['eigen', 'testlibtool'] + test_deps = ['curl'] + doc_deps = ['epydoc'] + default_deps = buildtool_deps + build_deps + build_export_deps + exec_deps + test_deps + + assert set(buildtool_lookup.get_rosdeps('multi_dep_type_catkin_package')) == set(buildtool_deps) + assert set(build_lookup.get_rosdeps('multi_dep_type_catkin_package')) == set(build_deps) + assert set(build_export_lookup.get_rosdeps('multi_dep_type_catkin_package')) == set(build_export_deps) + assert set(exec_lookup.get_rosdeps('multi_dep_type_catkin_package')) == set(exec_deps) + assert set(test_lookup.get_rosdeps('multi_dep_type_catkin_package')) == set(test_deps) + assert set(mix_lookup.get_rosdeps('multi_dep_type_catkin_package')) == set(build_deps + build_export_deps) + assert set(default_lookup.get_rosdeps('multi_dep_type_catkin_package')) == set(default_deps) + assert set(doc_lookup.get_rosdeps('multi_dep_type_catkin_package')) == set(doc_deps) + + def test_RosdepLookup_get_resources_that_need(): from rosdep2.lookup import RosdepLookup rospack, rosstack = get_test_rospkgs() diff --git a/test/test_rosdep_main.py b/test/test_rosdep_main.py index 9d9d315de..a0809e403 100644 --- a/test/test_rosdep_main.py +++ b/test/test_rosdep_main.py @@ -205,7 +205,12 @@ def read_stdout(cmd, capture_stderr=False): expected = [ '#[apt] Installation commands:', ' sudo -H apt-get install ros-fuerte-catkin', - ' sudo -H apt-get install libboost1.40-all-dev' + ' sudo -H apt-get install libboost1.40-all-dev', + ' sudo -H apt-get install libeigen3-dev', + ' sudo -H apt-get install libtinyxml-dev', + ' sudo -H apt-get install libltdl-dev', + ' sudo -H apt-get install libtool', + ' sudo -H apt-get install libcurl4-openssl-dev', ] lines = stdout.getvalue().splitlines() assert set(lines) == set(expected), lines @@ -269,6 +274,12 @@ def test_keys(self): rosdep_main(['keys', 'another_catkin_package'] + cmd_extras + ['-i']) stdout, stderr = b assert stdout.getvalue().strip() == 'catkin', stdout.getvalue() + with fakeout() as b: + rosdep_main(['keys', 'multi_dep_type_catkin_package', '-t', 'test', '-t', 'doc'] + cmd_extras) + stdout, stderr = b + output_keys = set(stdout.getvalue().split()) + expected_keys = set(['curl', 'epydoc']) + assert output_keys == expected_keys, stdout.getvalue() except SystemExit: assert False, 'system exit occurred' try: diff --git a/test/tree/catkin/multi_dep_type_catkin_package/package.xml b/test/tree/catkin/multi_dep_type_catkin_package/package.xml new file mode 100644 index 000000000..470c21121 --- /dev/null +++ b/test/tree/catkin/multi_dep_type_catkin_package/package.xml @@ -0,0 +1,19 @@ + + multi_dep_type_catkin_package + 0.0.0 + + This is a package with depencencies of multiple types + + Nobody + BSD + + catkin + + eigen + testboost + testtinyxml + testlibtool + curl + epydoc + +