diff --git a/Makefile b/Makefile index de0456317..4a1082d77 100644 --- a/Makefile +++ b/Makefile @@ -27,4 +27,4 @@ testsetup: echo "running rosdep tests" test: testsetup - nosetests --with-coverage --cover-package=rosdep2 --with-xunit test + nosetests3 --with-coverage --cover-package=rosdep2 --with-xunit test diff --git a/src/rosdep2/lookup.py b/src/rosdep2/lookup.py index 1d8d979b3..fd89ae1a3 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=[]): """ 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", "run", "test" """ # initialize the loader if rospack is None: @@ -358,7 +360,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..416cacfe9 100644 --- a/src/rosdep2/main.py +++ b/src/rosdep2/main.py @@ -123,16 +123,21 @@ class UsageError(Exception): """ -def _get_default_RosdepLookup(options): +_global_options = None + +def _get_default_RosdepLookup(options=None): """ Helper routine for converting command-line options into appropriate RosdepLookup instance. """ + global _global_options + if options is None: + options = _global_options os_override = convert_os_override_option(options.os_override) 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 @@ -295,6 +300,7 @@ def setup_environment_variables(ros_distro): def _rosdep_main(args): # sources cache dir is our local database. + global _global_options default_sources_cache = get_sources_cache_dir() parser = OptionParser(usage=_usage, prog='rosdep') @@ -368,8 +374,14 @@ 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=("build", "buildtool", "build_export", "exec", "run", "test", "doc"), + default=[], action='append', + help='Dependency types to install, can be given multiple times. ' + 'Chose from build, buildtool, build_export, exec, run, test, doc. Default: all except doc.') options, args = parser.parse_args(args) + _global_options = options if options.print_version or options.print_all_versions: # First print the rosdep version. print('{}'.format(__version__)) diff --git a/src/rosdep2/rospack.py b/src/rosdep2/rospack.py index c5b13f04c..cefaea2e8 100644 --- a/src/rosdep2/rospack.py +++ b/src/rosdep2/rospack.py @@ -56,7 +56,9 @@ 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..3cc9255d2 100644 --- a/src/rosdep2/rospkg_loader.py +++ b/src/rosdep2/rospkg_loader.py @@ -59,7 +59,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 +78,21 @@ def __init__(self, rospack=None, rosstack=None, underlay_key=None): self._loadable_resource_cache = None self._catkin_packages_cache = None + # Dependency types to include + def check_dep(dep_type): + if dependency_types: + return dep_type in dependency_types + else: + return dep_type in ['buildtool', 'build', 'build_export', 'exec', 'test'] + + self.include_build_depends = check_dep('build') + self.include_buildtool_depends = check_dep('buildtool') + self.include_build_export_depends = check_dep('build_export') or check_dep('run') + self.include_exec_depends = check_dep('exec') or check_dep('run') + self.include_test_depends = check_dep('test') + self.include_doc_depends = check_dep('doc') + + def load_view(self, view_name, rosdep_db, verbose=False): """ Load view data into *rosdep_db*. If the view has already @@ -140,7 +155,19 @@ 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 = [] + if self.include_build_depends: + deps += pkg.build_depends + if self.include_buildtool_depends: + deps += pkg.buildtool_depends + if self.include_build_export_depends: + deps += pkg.build_export_depends + if self.include_exec_depends: + deps += pkg.exec_depends + if self.include_test_depends: + deps += pkg.test_depends + if self.include_doc_depends: + deps += pkg.doc_depends 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..8efce1019 100644 --- a/test/test_rosdep_lookup.py +++ b/test/test_rosdep_lookup.py @@ -329,6 +329,51 @@ 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']) + run_lookup = RosdepLookup.create_from_rospkg(rospack=rospack, rosstack=rosstack, + sources_loader=sources_loader, dependency_types=['run']) + 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'] + run_deps = ['eigen', 'testlibtool', 'testtinyxml'] # build_export + exec + 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(run_lookup.get_rosdeps('multi_dep_type_catkin_package')) == set(run_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..9eaa4b8ad 100644 --- a/test/test_rosdep_main.py +++ b/test/test_rosdep_main.py @@ -269,6 +269,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 + +