diff --git a/.travis.yml b/.travis.yml index b5cf62067..732ec7584 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,31 +1,38 @@ language: python matrix: include: + - os: osx + language: generic + env: PYTHON_INSTALLER=pyenv TRAVIS_PYTHON_VERSION=2.7.14 + - os: osx + language: generic + env: PYTHON_INSTALLER=pyenv TRAVIS_PYTHON_VERSION=3.6.4 + - os: osx + language: generic + env: + - PYTHON_INSTALLER=brew + - PIP_USER_FLAG="--user" - os: linux python: 2.7 - os: linux - python: 3.4 + python: 3.4 # When support for 3.4 is removed unpin the PyYAML version below. - os: linux python: 3.5 - os: linux python: 3.6 - - os: osx - language: generic - env: PYTHON_INSTALLER=brew - - os: osx - language: generic - env: PYTHON_INSTALLER=pyenv TRAVIS_PYTHON_VERSION=2.7.14 - - os: osx - language: generic - env: PYTHON_INSTALLER=pyenv TRAVIS_PYTHON_VERSION=3.6.4 + - os: linux + python: 3.7 + - os: linux + python: 3.8 # command to install dependencies install: - source .travis/install.sh - python --version - - python -m pip install PyYAML argparse rospkg vcstools catkin_pkg python-dateutil rosdistro - - python -m pip install -e . - - python -m pip install nose coverage flake8 mock codecov + - if [ $TRAVIS_PYTHON_VERSION == "3.4" ]; then python -m pip install PyYAML==5.2; fi # Forcing PyYAML 5.2 while we retain Python 3.4 support PyYAML 5.3 and higher does not support Python 3.4 + - python -m pip install $PIP_USER_FLAG PyYAML argparse rospkg vcstools catkin_pkg python-dateutil rosdistro + - python -m pip install $PIP_USER_FLAG -e . + - python -m pip install $PIP_USER_FLAG nose coverage flake8 mock codecov # command to run tests script: - python -m nose --with-coverage --cover-package=rosdep2 --with-xunit test diff --git a/.travis/install.sh b/.travis/install.sh index fab5ac6a9..71a30a69f 100755 --- a/.travis/install.sh +++ b/.travis/install.sh @@ -5,6 +5,7 @@ do_install() set -e if [[ $TRAVIS_OS_NAME == 'osx' && $PYTHON_INSTALLER == 'pyenv' ]]; then + brew update brew install pyenv-virtualenv pyenv versions eval "$(pyenv init -)" diff --git a/CHANGELOG.rst b/CHANGELOG.rst index ebcc9ae7a..d4ca37570 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,7 +1,41 @@ -0.17.1 (2019-10-22) -------------------- -- Warn about ROS_PYTHON_VERSION only when it is needed - - https://github.com/ros-infrastructure/rosdep/issues/725 +0.19.0 (2020-04-03) +------------------- +- Only release for Python3 into focal + - https://github.com/ros-infrastructure/rosdep/pull/734 +- Added --rosdistro argument to rosdep-update to scope update to one rosdistro + - https://github.com/ros-infrastructure/rosdep/pull/738 + - Fixes https://github.com/ros-infrastructure/rosdep/pull/723 +- Fix CI for Python 3.4 and run slower CI jobs first + - https://github.com/ros-infrastructure/rosdep/pull/739 +- Strip Alpine's patch version from OS codename + - https://github.com/ros-infrastructure/rosdep/pull/716 + - Fixes https://github.com/ros-infrastructure/rosdep/issues/715 +- Raise a clear and specific error message for null entries + - https://github.com/ros-infrastructure/rosdep/pull/726 +- Use DNF as the default installer on RHEL 8 and newer + - https://github.com/ros-infrastructure/rosdep/pull/713 +- Updates to YUM and DNF handling + - https://github.com/ros-infrastructure/rosdep/pull/640 +- Fix tests so they don't assume euid != 0 + - https://github.com/ros-infrastructure/rosdep/pull/703 +- Update openSUSE package query function and enable pip installer + - https://github.com/ros-infrastructure/rosdep/pull/729 +- Fix conditional dependencies when one package uses manifest.xml + - https://github.com/ros-infrastructure/rosdep/pull/737 +- Handle StopIteration when querying in debian platform + - https://github.com/ros-infrastructure/rosdep/pull/701 +- Use entry points rather than console scripts to enable usage on Windows + - https://github.com/ros-infrastructure/rosdep/pull/656 +- Depend on modules packages only to allow modules packages to be co-installable. + - https://github.com/ros-infrastructure/rosdep/pull/750 + + +0.18.0 (2019-11-20) +------------------- +- split -modules into separate Debian package + - https://github.com/ros-infrastructure/rosdep/pull/731 +- fix macOS CI + - https://github.com/ros-infrastructure/rosdep/pull/730 0.17.0 (2019-10-18) ------------------- 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/doc/rosdep_yaml_format.rst b/doc/rosdep_yaml_format.rst index eb9450c0d..08ec4e755 100644 --- a/doc/rosdep_yaml_format.rst +++ b/doc/rosdep_yaml_format.rst @@ -87,7 +87,8 @@ OS name identifiers and supported package managers * ``fedora``: Fedora Project - * ``yum`` (default) + * ``dnf`` (default) + * ``yum`` * ``source`` * ``freebsd``: FreeBSD diff --git a/scripts/rosdep b/scripts/rosdep deleted file mode 100755 index a9284a830..000000000 --- a/scripts/rosdep +++ /dev/null @@ -1,4 +0,0 @@ -#!/usr/bin/env python - -from rosdep2.main import rosdep_main -rosdep_main() diff --git a/setup.py b/setup.py index cfe9ae63d..40322f4a3 100644 --- a/setup.py +++ b/setup.py @@ -1,26 +1,40 @@ import os from setuptools import setup -exec(open(os.path.join(os.path.dirname(__file__), 'src', 'rosdep2', '_version.py')).read()) - -setup( - name='rosdep', - version=__version__, # noqa:F821 - packages=['rosdep2', 'rosdep2.ament_packages', 'rosdep2.platforms'], - package_dir={'': 'src'}, - install_requires=['catkin_pkg >= 0.4.0', 'rospkg >= 1.1.10', 'rosdistro >= 0.7.5', 'PyYAML >= 3.1'], - test_suite='nose.collector', - test_requires=['mock', 'nose >= 1.0'], - scripts=['scripts/rosdep', 'scripts/rosdep-source'], - author='Tully Foote, Ken Conley', - author_email='tfoote@osrfoundation.org', - url='http://wiki.ros.org/rosdep', - keywords=['ROS'], - classifiers=[ +kwargs = { + 'name': 'rosdep', + # same version as in: + # - src/rosdep2/__init__.py + # - stdeb.cfg + 'version': '0.19.0', + 'packages': ['rosdep2', 'rosdep2.ament_packages', 'rosdep2.platforms'], + 'package_dir': {'': 'src'}, + 'install_requires': ['catkin_pkg >= 0.4.0', 'rospkg >= 1.2.7', 'rosdistro >= 0.7.5', 'PyYAML >= 3.1'], + 'test_suite': 'nose.collector', + 'test_requires': ['mock', 'nose >= 1.0'], + 'author': 'Tully Foote, Ken Conley', + 'author_email': 'tfoote@osrfoundation.org', + 'url': 'http://wiki.ros.org/rosdep', + 'keywords': ['ROS'], + 'entry_points': { + 'console_scripts': [ + 'rosdep = rosdep2.main:rosdep_main', + 'rosdep-source = rosdep2.install:install_main' + ] + }, + 'classifiers': [ 'Programming Language :: Python', 'License :: OSI Approved :: BSD License'], - description='rosdep package manager abstraction tool for ROS', - long_description='Command-line tool for installing system ' - 'dependencies on a variety of platforms.', - license='BSD' -) + 'description': 'rosdep package manager abstraction tool for ROS', + 'long_description': 'Command-line tool for installing system ' + 'dependencies on a variety of platforms.', + 'license': 'BSD', +} +if 'SKIP_PYTHON_MODULES' in os.environ: + kwargs['packages'] = [] + kwargs['package_dir'] = {} +if 'SKIP_PYTHON_SCRIPTS' in os.environ: + kwargs['name'] += '_modules' + kwargs['entry_points'] = {} + +setup(**kwargs) diff --git a/src/rosdep2/_version.py b/src/rosdep2/_version.py index cbe8c741e..31b1f1e57 100644 --- a/src/rosdep2/_version.py +++ b/src/rosdep2/_version.py @@ -1 +1,4 @@ -__version__ = '0.17.1' +# same version as in: +# - setup.py +# - stdeb.cfg +__version__ = '0.19.0' diff --git a/scripts/rosdep-source b/src/rosdep2/install.py old mode 100755 new mode 100644 similarity index 92% rename from scripts/rosdep-source rename to src/rosdep2/install.py index 8b89e9762..b092669e1 --- a/scripts/rosdep-source +++ b/src/rosdep2/install.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python # Copyright (c) 2011, Willow Garage, Inc. # All rights reserved. # @@ -39,7 +38,7 @@ from rosdep2 import InstallFailed from rosdep2.platforms import source -NAME='rosdep-source' +NAME = 'rosdep-source' def install_main(): @@ -49,16 +48,12 @@ def install_main(): parser.error("please specify one and only one rdmanifest url") if args[0] != 'install': parser.error("currently only support the 'install' command") - rdmanifest_url= args[1] + rdmanifest_url = args[1] try: if os.path.isfile(rdmanifest_url): source.install_from_file(rdmanifest_url) else: source.install_from_url(rdmanifest_url) except InstallFailed as e: - print("ERROR: installation failed:\n%s"%e, file=sys.stderr) + print("ERROR: installation failed:\n%s" % e, file=sys.stderr) sys.exit(1) - - -if __name__ == '__main__': - install_main() diff --git a/src/rosdep2/lookup.py b/src/rosdep2/lookup.py index f61e186c6..fd89ae1a3 100644 --- a/src/rosdep2/lookup.py +++ b/src/rosdep2/lookup.py @@ -144,6 +144,9 @@ def get_rule_for_platform(self, os_name, os_version, installer_keys, default_ins return_key = installer_key break + # Check if the rule is null + if data is None: + raise ResolutionError(rosdep_key, self.data, os_name, os_version, '[%s] defined as "not available" for OS version [%s]' % (rosdep_key, os_version)) if type(data) not in (dict, list, type('str')): raise InvalidData('rosdep OS definition for [%s:%s] must be a dictionary, string, or list: %s' % (self.rosdep_key, os_name, data), origin=self.origin) @@ -171,7 +174,7 @@ def __str__(self): \trosdep key : %s \tOS name : %s \tOS version : %s -\tData: %s""" % (self.args[0], self.rosdep_key, self.os_name, self.os_version, pretty_data) +\tData:\n%s""" % (self.args[0], self.rosdep_key, self.os_name, self.os_version, pretty_data.replace('\n', '\n\t\t')) class RosdepView(object): diff --git a/src/rosdep2/main.py b/src/rosdep2/main.py index cbbf1ff91..416cacfe9 100644 --- a/src/rosdep2/main.py +++ b/src/rosdep2/main.py @@ -274,7 +274,7 @@ def setup_environment_variables(ros_distro): """ Set environment variables needed to find ROS packages and evaluate conditional dependencies. - :param rosdistro: The requested ROS distro passed on the CLI, or None + :param ros_distro: The requested ROS distro passed on the CLI, or None """ if ros_distro is not None: if 'ROS_DISTRO' in os.environ and os.environ['ROS_DISTRO'] != ros_distro: @@ -361,7 +361,9 @@ def _rosdep_main(args): parser.add_option('--rosdistro', dest='ros_distro', default=None, help='Explicitly sets the ROS distro to use, overriding ' 'the normal method of detecting the ROS distro ' - 'using the ROS_DISTRO environment variable.') + 'using the ROS_DISTRO environment variable. ' + "When used with the 'update' verb, " + 'only the specified distro will be updated.') parser.add_option('--as-root', default=[], action='append', metavar='INSTALLER_KEY:', help='Override ' 'whether sudo is used for a specific installer, ' @@ -373,10 +375,10 @@ def _rosdep_main(args): 'If specified end-of-life distros are being ' 'fetched too.') parser.add_option('-t', '--dependency-types', dest='dependency_types', - type="choice", choices=("build", "buildtool", "run", "test"), - default=[], action='append', - help='Dependency types to install, can be given multiple times. ' - 'Chose from build, buildtool, run, test. Default: all.') + 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 @@ -655,7 +657,8 @@ def update_error_handler(data_source, exc): pass update_sources_list(success_handler=update_success_handler, error_handler=update_error_handler, - skip_eol_distros=not options.include_eol_distros) + skip_eol_distros=not options.include_eol_distros, + ros_distro=options.ros_distro) print('updated cache in %s' % (sources_cache_dir)) except InvalidData as e: print('ERROR: invalid sources list file:\n\t%s' % (e), file=sys.stderr) @@ -663,6 +666,9 @@ def update_error_handler(data_source, exc): except IOError as e: print('ERROR: error loading sources list:\n\t%s' % (e), file=sys.stderr) return 1 + except ValueError as e: + print('ERROR: invalid argument value provided:\n\t%s' % (e), file=sys.stderr) + return 1 if error_occured: print('ERROR: Not all sources were able to be updated.\n[[[') for e in error_occured: diff --git a/src/rosdep2/platforms/alpine.py b/src/rosdep2/platforms/alpine.py index 2d7cc523a..4e136c2df 100644 --- a/src/rosdep2/platforms/alpine.py +++ b/src/rosdep2/platforms/alpine.py @@ -48,6 +48,7 @@ def register_platforms(context): context.add_os_installer_key(OS_ALPINE, PIP_INSTALLER) context.add_os_installer_key(OS_ALPINE, SOURCE_INSTALLER) context.set_default_os_installer_key(OS_ALPINE, lambda self: APK_INSTALLER) + context.set_os_version_type(OS_ALPINE, lambda self: ".".join(self.get_version().split('.')[:2])) def apk_detect(pkgs, exec_fn=read_stdout): diff --git a/src/rosdep2/platforms/debian.py b/src/rosdep2/platforms/debian.py index 9df098403..e5598c7c4 100644 --- a/src/rosdep2/platforms/debian.py +++ b/src/rosdep2/platforms/debian.py @@ -31,8 +31,16 @@ import subprocess import sys -from rospkg.os_detect import OS_DEBIAN, OS_LINARO, OS_UBUNTU, OS_ELEMENTARY, OS_MX, OsDetect, read_os_release - +from rospkg.os_detect import ( + OS_DEBIAN, + OS_LINARO, + OS_UBUNTU, + OS_ELEMENTARY, + OS_MX, + OS_POP, + OsDetect, + read_os_release +) from .pip import PIP_INSTALLER from .gem import GEM_INSTALLER from .source import SOURCE_INSTALLER @@ -55,6 +63,7 @@ def register_platforms(context): register_elementary(context) register_linaro(context) register_mx(context) + register_pop(context) def register_debian(context): @@ -98,6 +107,16 @@ def register_mx(context): context.set_os_override(OS_DEBIAN, version[version.find("(") + 1:version.find(")")]) +def register_pop(context): + # Pop! OS is an alias for Ubuntu. If Pop! is detected and it's + # not set as an override force ubuntu. + (os_name, os_version) = context.get_os_name_and_version() + if os_name == OS_POP and not context.os_override: + print('rosdep detected OS: [%s] aliasing it to: [%s]' % + (OS_POP, OS_UBUNTU), file=sys.stderr) + context.set_os_override(OS_UBUNTU, context.os_detect.get_codename()) + + def register_ubuntu(context): context.add_os_installer_key(OS_UBUNTU, APT_INSTALLER) context.add_os_installer_key(OS_UBUNTU, PIP_INSTALLER) @@ -140,20 +159,32 @@ def _read_apt_cache_showpkg(packages, exec_fn=None): header = 'Package: %s' % p # proceed to Package header - while next(lines) != header: + try: + while next(lines) != header: + pass + except StopIteration: pass # proceed to versions section - while next(lines) != 'Versions: ': + try: + while next(lines) != 'Versions: ': + pass + except StopIteration: pass # virtual packages don't have versions - if next(lines) != '': - yield p, False, None - continue + try: + if next(lines) != '': + yield p, False, None + continue + except StopIteration: + break # proceed to reserve provides section - while next(lines) != 'Reverse Provides: ': + try: + while next(lines) != 'Reverse Provides: ': + pass + except StopIteration: pass pr = [line.split(' ', 2)[0] for line in lines] diff --git a/src/rosdep2/platforms/opensuse.py b/src/rosdep2/platforms/opensuse.py index 27a01f08e..ab5de261f 100644 --- a/src/rosdep2/platforms/opensuse.py +++ b/src/rosdep2/platforms/opensuse.py @@ -31,6 +31,7 @@ from rospkg.os_detect import OS_OPENSUSE +from .pip import PIP_INSTALLER from .source import SOURCE_INSTALLER from ..installers import PackageManagerInstaller @@ -44,6 +45,7 @@ def register_installers(context): def register_platforms(context): context.add_os_installer_key(OS_OPENSUSE, SOURCE_INSTALLER) + context.add_os_installer_key(OS_OPENSUSE, PIP_INSTALLER) context.add_os_installer_key(OS_OPENSUSE, ZYPPER_INSTALLER) context.set_default_os_installer_key(OS_OPENSUSE, lambda self: ZYPPER_INSTALLER) @@ -51,7 +53,7 @@ def register_platforms(context): def rpm_detect(packages): installed = [] for p in packages: - if not subprocess.call(['rpm', '-q', p]): + if not subprocess.call(['rpm', '-q', '--whatprovides', p]): installed.append(p) return installed diff --git a/src/rosdep2/platforms/osx.py b/src/rosdep2/platforms/osx.py index c17e811c0..13b072377 100644 --- a/src/rosdep2/platforms/osx.py +++ b/src/rosdep2/platforms/osx.py @@ -303,7 +303,7 @@ def handle_options(options): # make sure options is a list of list of strings try: - valid = all([isinstance(x, _basestring) for l in options for x in l]) + valid = all([isinstance(x, _basestring) for option in options for x in option]) except Exception as e: raise InvalidData("Invalid list of options '%s', error: %s" % (options, e)) else: diff --git a/src/rosdep2/platforms/redhat.py b/src/rosdep2/platforms/redhat.py index 384c47fc3..dc1bbc074 100644 --- a/src/rosdep2/platforms/redhat.py +++ b/src/rosdep2/platforms/redhat.py @@ -70,9 +70,10 @@ def register_fedora(context): def register_rhel(context): context.add_os_installer_key(OS_RHEL, PIP_INSTALLER) + context.add_os_installer_key(OS_RHEL, DNF_INSTALLER) context.add_os_installer_key(OS_RHEL, YUM_INSTALLER) context.add_os_installer_key(OS_RHEL, SOURCE_INSTALLER) - context.set_default_os_installer_key(OS_RHEL, lambda self: YUM_INSTALLER) + context.set_default_os_installer_key(OS_RHEL, lambda self: DNF_INSTALLER if self.get_version().split('.', 1)[0].isdigit() and int(self.get_version().split('.', 1)[0]) >= 8 else YUM_INSTALLER) context.set_os_version_type(OS_RHEL, lambda self: self.get_version().split('.', 1)[0]) @@ -154,6 +155,24 @@ def rpm_expand(package, exec_fn=None): return rpm_expand_cmd(package, exec_fn) +def get_rpm_version_py(): + from rpm import __version__ as rpm_version + return rpm_version + + +def get_rpm_version_cmd(): + output = subprocess.check_output(['rpm', '--version']) + version = output.splitlines()[0].split(b' ')[-1].decode() + return version + + +def get_rpm_version(): + try: + return get_rpm_version_py() + except ImportError: + return get_rpm_version_cmd() + + class DnfInstaller(PackageManagerInstaller): """ This class provides the functions for installing using dnf @@ -164,6 +183,15 @@ class DnfInstaller(PackageManagerInstaller): def __init__(self): super(DnfInstaller, self).__init__(rpm_detect) + def get_version_strings(self): + dnf_output = subprocess.check_output(['dnf', '--version']) + dnf_version = dnf_output.splitlines()[0].decode() + version_strings = [ + 'dnf {}'.format(dnf_version), + 'rpm {}'.format(get_rpm_version()), + ] + return version_strings + def get_install_command(self, resolved, interactive=True, reinstall=False, quiet=False): raw_packages = self.get_packages_to_install(resolved, reinstall=reinstall) packages = [rpm_expand(package) for package in raw_packages] @@ -190,6 +218,15 @@ class YumInstaller(PackageManagerInstaller): def __init__(self): super(YumInstaller, self).__init__(rpm_detect) + def get_version_strings(self): + yum_output = subprocess.check_output(['yum', '--version']) + yum_version = yum_output.splitlines()[0].decode() + version_strings = [ + 'yum {}'.format(yum_version), + 'rpm {}'.format(get_rpm_version()), + ] + return version_strings + def get_install_command(self, resolved, interactive=True, reinstall=False, quiet=False): raw_packages = self.get_packages_to_install(resolved, reinstall=reinstall) packages = [rpm_expand(package) for package in raw_packages] diff --git a/src/rosdep2/rospack.py b/src/rosdep2/rospack.py index cefb3f3de..cefaea2e8 100644 --- a/src/rosdep2/rospack.py +++ b/src/rosdep2/rospack.py @@ -50,7 +50,15 @@ def call_pkg_config(option, pkg_name): def init_rospack_interface(): - lookup = _get_default_RosdepLookup() + class Options(object): + + 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 7def688c5..3cc9255d2 100644 --- a/src/rosdep2/rospkg_loader.py +++ b/src/rosdep2/rospkg_loader.py @@ -79,11 +79,19 @@ def __init__(self, rospack=None, rosstack=None, underlay_key=None, dependency_ty self._catkin_packages_cache = None # Dependency types to include - check_dep = lambda type_ : type_ in dependency_types or not dependency_types + 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_run_depends = check_dep('run') + 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): """ @@ -152,13 +160,23 @@ def get_rosdeps(self, resource_name, implicit=True): deps += pkg.build_depends if self.include_buildtool_depends: deps += pkg.buildtool_depends - if self.include_run_depends: - deps += pkg.run_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(): - return self._rospack.get_rosdeps(resource_name, implicit=implicit) + rosdeps = set(self._rospack.get_rosdeps(resource_name, implicit=False)) + if implicit: + # This resource is a manifest.xml, but it might depend on things with a package.xml + # Make sure they get a chance to evaluate conditions + for dep in self._rospack.get_depends(resource_name): + rosdeps = rosdeps.union(set(self.get_rosdeps(dep, implicit=True))) + return list(rosdeps) elif resource_name in self._rosstack.list(): # stacks currently do not have rosdeps of their own, implicit or otherwise return [] diff --git a/src/rosdep2/sources_list.py b/src/rosdep2/sources_list.py index 1315c83ed..70f7cb8ca 100644 --- a/src/rosdep2/sources_list.py +++ b/src/rosdep2/sources_list.py @@ -439,7 +439,7 @@ def _generate_key_from_urls(urls): def update_sources_list(sources_list_dir=None, sources_cache_dir=None, success_handler=None, error_handler=None, - skip_eol_distros=False): + skip_eol_distros=False, ros_distro=None): """ Re-downloaded data from remote sources and store in cache. Also update the cache index based on current sources. @@ -487,12 +487,21 @@ def update_sources_list(sources_list_dir=None, sources_cache_dir=None, python_versions = {} print('Query rosdistro index %s' % get_index_url()) - for dist_name in sorted(get_index().distributions.keys()): + distribution_names = get_index().distributions.keys() + if ros_distro is not None and ros_distro not in distribution_names: + raise ValueError( + 'Requested distribution "%s" is not in the index.' % ros_distro) + + for dist_name in sorted(distribution_names): distribution = get_index().distributions[dist_name] - if skip_eol_distros: - if distribution.get('distribution_status') == 'end-of-life': - print('Skip end-of-life distro "%s"' % dist_name) + if dist_name != ros_distro: + if ros_distro is not None: + print('Skip distro "%s" different from requested "%s"' % (dist_name, ros_distro)) continue + if skip_eol_distros: + if distribution.get('distribution_status') == 'end-of-life': + print('Skip end-of-life distro "%s"' % dist_name) + continue print('Add distro "%s"' % dist_name) rds = RosDistroSource(dist_name) rosdep_data = get_gbprepo_as_rosdep_data(dist_name) diff --git a/stdeb.cfg b/stdeb.cfg index 7185cf761..293b2262f 100644 --- a/stdeb.cfg +++ b/stdeb.cfg @@ -1,8 +1,29 @@ -[DEFAULT] -Depends: ca-certificates, python-rospkg (>= 1.1.10), python-yaml, python-catkin-pkg (>= 0.4.0), python-rosdistro (>= 0.7.5), sudo -Depends3: ca-certificates, python3-rospkg (>= 1.1.10), python3-yaml, python3-catkin-pkg (>= 0.4.0), python3-rosdistro (>= 0.7.5), sudo +[rosdep] +; rosdep-modules same version as in: +; - setup.py +; - src/rosdep2/_version.py +Depends: python-rosdep-modules (>= 0.19.0) +; rosdep-modules same version as in: +; - setup.py +; - src/rosdep2/_version.py +Depends3: python3-rosdep-modules (>= 0.19.0) Conflicts: python3-rosdep, python-rosdep2, python3-rosdep2 Conflicts3: python-rosdep, python-rosdep2, python3-rosdep2 Copyright-File: LICENSE Suite: xenial yakkety zesty artful bionic cosmic disco eoan jessie stretch buster +Suite3: xenial yakkety zesty artful bionic cosmic disco eoan focal jessie stretch buster X-Python3-Version: >= 3.4 +Setup-Env-Vars: SKIP_PYTHON_MODULES=1 + +[rosdep_modules] +Depends: ca-certificates, python-rospkg-modules (>= 1.2.7), python-yaml, python-catkin-pkg-modules (>= 0.4.0), python-rosdistro-modules (>= 0.7.5), sudo +Depends3: ca-certificates, python3-rospkg-modules (>= 1.2.7), python3-yaml, python3-catkin-pkg-modules (>= 0.4.0), python3-rosdistro-modules (>= 0.7.5), sudo +Conflicts: python-rosdep (<< 0.18.0), python-rosdep2 +Conflicts3: python3-rosdep (<< 0.18.0), python3-rosdep2 +Replaces: python-rosdep (<< 0.18.0) +Replaces3: python3-rosdep (<< 0.18.0) +Copyright-File: LICENSE +Suite: xenial yakkety zesty artful bionic cosmic disco eoan jessie stretch buster +Suite3: xenial yakkety zesty artful bionic cosmic disco eoan focal jessie stretch buster +X-Python3-Version: >= 3.4 +Setup-Env-Vars: SKIP_PYTHON_SCRIPTS=1 diff --git a/test/test_rosdep_alpine.py b/test/test_rosdep_alpine.py index fb4381dfa..5ab0bf433 100644 --- a/test/test_rosdep_alpine.py +++ b/test/test_rosdep_alpine.py @@ -65,27 +65,30 @@ def test_ApkInstaller(): from rosdep2.platforms.alpine import ApkInstaller @patch.object(ApkInstaller, 'get_packages_to_install') - def test(mock_method): + def test(expected_prefix, mock_method): installer = ApkInstaller() mock_method.return_value = [] assert [] == installer.get_install_command(['nonexistingfakepackage']) mock_method.return_value = ['a-dev', 'b-dev'] - expected = [['sudo', '-H', 'apk', 'add', 'a-dev', 'b-dev']] + expected = [expected_prefix + ['apk', 'add', 'a-dev', 'b-dev']] val = installer.get_install_command(['notused'], interactive=False, quiet=False) assert val == expected, 'Result was: %s' % val - expected = [['sudo', '-H', 'apk', 'add', '--interactive', 'a-dev', 'b-dev']] + expected = [expected_prefix + ['apk', 'add', '--interactive', 'a-dev', 'b-dev']] val = installer.get_install_command(['notused'], interactive=True, quiet=False) assert val == expected, 'Result was: %s' % val - expected = [['sudo', '-H', 'apk', 'add', '--quiet', 'a-dev', 'b-dev']] + expected = [expected_prefix + ['apk', 'add', '--quiet', 'a-dev', 'b-dev']] val = installer.get_install_command(['notused'], interactive=False, quiet=True) assert val == expected, 'Result was: %s' % val try: - test() + with patch('rosdep2.installers.os.geteuid', return_value=1): + test(['sudo', '-H']) + with patch('rosdep2.installers.os.geteuid', return_value=0): + test([]) except AssertionError: traceback.print_exc() raise diff --git a/test/test_rosdep_arch.py b/test/test_rosdep_arch.py index 7c6b9fd81..857aa58cb 100644 --- a/test/test_rosdep_arch.py +++ b/test/test_rosdep_arch.py @@ -41,21 +41,24 @@ def test_PacmanInstaller(): from rosdep2.platforms.arch import PacmanInstaller @patch.object(PacmanInstaller, 'get_packages_to_install') - def test(mock_method): + def test(expected_prefix, mock_method): installer = PacmanInstaller() mock_method.return_value = [] assert [] == installer.get_install_command(['fake']) # no interactive option implemented yet mock_method.return_value = ['a', 'b'] - expected = [['sudo', '-H', 'pacman', '-S', '--noconfirm', '--needed', 'a', 'b']] + expected = [expected_prefix + ['pacman', '-S', '--noconfirm', '--needed', 'a', 'b']] val = installer.get_install_command(['whatever'], interactive=False) assert val == expected, val - expected = [['sudo', '-H', 'pacman', '-S', '--needed', 'a', 'b']] + expected = [expected_prefix + ['pacman', '-S', '--needed', 'a', 'b']] val = installer.get_install_command(['whatever'], interactive=True) assert val == expected, val try: - test() + with patch('rosdep2.installers.os.geteuid', return_value=1): + test(['sudo', '-H']) + with patch('rosdep2.installers.os.geteuid', return_value=0): + test([]) except AssertionError: traceback.print_exc() raise diff --git a/test/test_rosdep_debian.py b/test/test_rosdep_debian.py index 3e098e61e..75cb60455 100644 --- a/test/test_rosdep_debian.py +++ b/test/test_rosdep_debian.py @@ -116,24 +116,27 @@ def test_AptInstaller(): @patch('rosdep2.platforms.debian.read_stdout') @patch.object(AptInstaller, 'get_packages_to_install') - def test(mock_get_packages_to_install, mock_read_stdout): + def test(expected_prefix, mock_get_packages_to_install, mock_read_stdout): installer = AptInstaller() mock_get_packages_to_install.return_value = [] mock_read_stdout.return_value = '' assert [] == installer.get_install_command(['fake']) mock_get_packages_to_install.return_value = ['a', 'b'] - expected = [['sudo', '-H', 'apt-get', 'install', '-y', 'a'], - ['sudo', '-H', 'apt-get', 'install', '-y', 'b']] + expected = [expected_prefix + ['apt-get', 'install', '-y', 'a'], + expected_prefix + ['apt-get', 'install', '-y', 'b']] val = installer.get_install_command(['whatever'], interactive=False) print('VAL', val) assert val == expected, val - expected = [['sudo', '-H', 'apt-get', 'install', 'a'], - ['sudo', '-H', 'apt-get', 'install', 'b']] + expected = [expected_prefix + ['apt-get', 'install', 'a'], + expected_prefix + ['apt-get', 'install', 'b']] val = installer.get_install_command(['whatever'], interactive=True) assert val == expected, val try: - test() + with patch('rosdep2.installers.os.geteuid', return_value=1): + test(['sudo', '-H']) + with patch('rosdep2.installers.os.geteuid', return_value=0): + test([]) except AssertionError: traceback.print_exc() raise diff --git a/test/test_rosdep_freebsd.py b/test/test_rosdep_freebsd.py index 41980e8b4..d8ee607a2 100644 --- a/test/test_rosdep_freebsd.py +++ b/test/test_rosdep_freebsd.py @@ -55,21 +55,24 @@ def test_PkgInstaller(): from rosdep2.platforms.freebsd import PkgInstaller @patch.object(PkgInstaller, 'get_packages_to_install') - def test(mock_method): + def test(expected_prefix, mock_method): installer = PkgInstaller() mock_method.return_value = [] assert [] == installer.get_install_command(['fake']) # no interactive option with YUM mock_method.return_value = ['a', 'b'] - expected = [['sudo', '-H', '/usr/sbin/pkg', 'install', '-y', 'a', 'b']] + expected = [expected_prefix + ['/usr/sbin/pkg', 'install', '-y', 'a', 'b']] val = installer.get_install_command(['whatever'], interactive=False) assert val == expected, val - expected = [['sudo', '-H', '/usr/sbin/pkg', 'install', '-y', 'a', 'b']] + expected = [expected_prefix + ['/usr/sbin/pkg', 'install', '-y', 'a', 'b']] val = installer.get_install_command(['whatever'], interactive=True) assert val == expected, val try: - test() + with patch('rosdep2.installers.os.geteuid', return_value=1): + test(['sudo', '-H']) + with patch('rosdep2.installers.os.geteuid', return_value=0): + test([]) except AssertionError: traceback.print_exc() raise diff --git a/test/test_rosdep_gem.py b/test/test_rosdep_gem.py index 8bdb4cc12..b722161e9 100644 --- a/test/test_rosdep_gem.py +++ b/test/test_rosdep_gem.py @@ -86,7 +86,7 @@ def test_no_gem(mock_method): @patch('rosdep2.platforms.gem.is_gem_installed') @patch.object(GemInstaller, 'get_packages_to_install') - def test(mock_method, mock_is_gem_installed): + def test(expected_prefix, mock_method, mock_is_gem_installed): mock_is_gem_installed.return_value = True installer = GemInstaller() mock_method.return_value = [] @@ -94,16 +94,19 @@ def test(mock_method, mock_is_gem_installed): # no interactive option with GEM mock_method.return_value = ['a', 'b'] - expected = [['sudo', '-H', 'gem', 'install', 'a'], - ['sudo', '-H', 'gem', 'install', 'b']] + expected = [expected_prefix + ['gem', 'install', 'a'], + expected_prefix + ['gem', 'install', 'b']] val = installer.get_install_command(['whatever'], interactive=False) assert val == expected, val - expected = [['sudo', '-H', 'gem', 'install', 'a'], - ['sudo', '-H', 'gem', 'install', 'b']] + expected = [expected_prefix + ['gem', 'install', 'a'], + expected_prefix + ['gem', 'install', 'b']] val = installer.get_install_command(['whatever'], interactive=True) assert val == expected, val try: - test() + with patch('rosdep2.installers.os.geteuid', return_value=1): + test(['sudo', '-H']) + with patch('rosdep2.installers.os.geteuid', return_value=0): + test([]) except AssertionError: traceback.print_exc() raise diff --git a/test/test_rosdep_installers.py b/test/test_rosdep_installers.py index 0d71e8f45..1d3186638 100644 --- a/test/test_rosdep_installers.py +++ b/test/test_rosdep_installers.py @@ -28,6 +28,7 @@ from __future__ import print_function from contextlib import contextmanager +from mock import patch import os import sys try: @@ -583,7 +584,8 @@ def fakeout(): sys.stderr = realstderr -def test_RosdepInstaller_install_resolved(): +@patch('rosdep2.installers.os.geteuid', return_value=1) +def test_RosdepInstaller_install_resolved(mock_geteuid): from rosdep2 import create_default_installer_context from rosdep2.lookup import RosdepLookup from rosdep2.installers import RosdepInstaller diff --git a/test/test_rosdep_lookup.py b/test/test_rosdep_lookup.py index 30f26877a..8efce1019 100644 --- a/test/test_rosdep_lookup.py +++ b/test/test_rosdep_lookup.py @@ -58,14 +58,14 @@ def create_test_SourcesListLoader(): def get_cache_raw(): cache_rosdep_path = os.path.join(get_cache_dir(), '0a12d6e7b0d47be9b76e7726720e4cb79528cbaa') with open(cache_rosdep_path) as f: - cache_raw = yaml.load(f.read()) + cache_raw = yaml.safe_load(f.read()) return cache_raw def get_cache_raw_python(): cache_rosdep_path = os.path.join(get_cache_dir(), 'f6f4ef95664e373cd4754501337fa217f5b55d91') with open(cache_rosdep_path) as f: - cache_raw = yaml.load(f.read()) + cache_raw = yaml.safe_load(f.read()) return cache_raw @@ -125,7 +125,7 @@ def test_RosdepDefinition(): pass # - test w/valid data - d2 = yaml.load(FAKE_TINYXML_RULE)['testtinyxml'] + d2 = yaml.safe_load(FAKE_TINYXML_RULE)['testtinyxml'] definition = RosdepDefinition('d2', d2, 'file2.txt') # - tripwire str(definition) @@ -182,6 +182,26 @@ def test_RosdepDefinition(): val = definition.get_rule_for_platform('ubuntu', 'trusty', ['apt', 'source', 'pip'], 'apt') assert val == ('apt', ['libtinyxml2-dev']), val + definition = RosdepDefinition('trusty_only_key', {'ubuntu': {'*': None, 'trusty': ['trusty_only_pkg']}, 'debian': None}, 'wildcard.txt') + try: + val = definition.get_rule_for_platform('ubuntu', 'lucid', ['apt', 'source', 'pip'], 'apt') + assert False, 'should have raised: %s' % (str(val)) + except ResolutionError as e: + assert e.rosdep_key == 'trusty_only_key' + assert e.os_name == 'ubuntu' + assert e.os_version == '*' + # tripwire + str(e) + try: + val = definition.get_rule_for_platform('debian', 'stretch', ['apt', 'source', 'pip'], 'apt') + assert False, 'should have raised: %s' % (str(val)) + except ResolutionError as e: + assert e.rosdep_key == 'trusty_only_key' + assert e.os_name == 'debian' + assert e.os_version == 'stretch' + # tripwire + str(e) + # test reverse merging OS things (first is default) definition = RosdepDefinition('test', {'debian': 'libtest-dev'}, 'fake-1.txt') # rule should work as expected before reverse-merge @@ -309,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 0ecd1b3bd..9eaa4b8ad 100644 --- a/test/test_rosdep_main.py +++ b/test/test_rosdep_main.py @@ -162,7 +162,8 @@ def test_check(self): pass @patch('rosdep2.platforms.debian.read_stdout') - def test_install(self, mock_read_stdout): + @patch('rosdep2.installers.os.geteuid', return_value=1) + def test_install(self, mock_geteuid, mock_read_stdout): sources_cache = get_cache_dir() cmd_extras = ['-c', sources_cache] catkin_tree = get_test_catkin_tree_dir() @@ -268,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/test_rosdep_opensuse.py b/test/test_rosdep_opensuse.py index bad50ccc4..608474c4c 100644 --- a/test/test_rosdep_opensuse.py +++ b/test/test_rosdep_opensuse.py @@ -41,21 +41,24 @@ def test_ZypperInstaller(): from rosdep2.platforms.opensuse import ZypperInstaller @patch.object(ZypperInstaller, 'get_packages_to_install') - def test(mock_method): + def test(expected_prefix, mock_method): installer = ZypperInstaller() mock_method.return_value = [] assert [] == installer.get_install_command(['fake']) + mock_method.return_value = ['a', 'b'] # no interactive option with YUM - mock_method.return_value = ['a', 'b'] - expected = [['sudo', '-H', 'zypper', 'install', '-yl', 'a', 'b']] + expected = [expected_prefix + ['zypper', 'install', '-yl', 'a', 'b']] val = installer.get_install_command(['whatever'], interactive=False) assert val == expected, val - expected = [['sudo', '-H', 'zypper', 'install', 'a', 'b']] + expected = [expected_prefix + ['zypper', 'install', 'a', 'b']] val = installer.get_install_command(['whatever'], interactive=True) assert val == expected, val try: - test() + with patch('rosdep2.installers.os.geteuid', return_value=1): + test(['sudo', '-H']) + with patch('rosdep2.installers.os.geteuid', return_value=0): + test([]) except AssertionError: traceback.print_exc() raise diff --git a/test/test_rosdep_pip.py b/test/test_rosdep_pip.py index ad86aae0f..628481b48 100644 --- a/test/test_rosdep_pip.py +++ b/test/test_rosdep_pip.py @@ -85,7 +85,7 @@ def test_no_pip(mock_method): @patch('rosdep2.platforms.pip.get_pip_command') @patch.object(PipInstaller, 'get_packages_to_install') - def test(mock_method, mock_get_pip_command): + def test(expected_prefix, mock_method, mock_get_pip_command): mock_get_pip_command.return_value = ['mock-pip'] installer = PipInstaller() mock_method.return_value = [] @@ -93,16 +93,19 @@ def test(mock_method, mock_get_pip_command): # no interactive option with PIP mock_method.return_value = ['a', 'b'] - expected = [['sudo', '-H', 'mock-pip', 'install', '-U', 'a'], - ['sudo', '-H', 'mock-pip', 'install', '-U', 'b']] + expected = [expected_prefix + ['mock-pip', 'install', '-U', 'a'], + expected_prefix + ['mock-pip', 'install', '-U', 'b']] val = installer.get_install_command(['whatever'], interactive=False) assert val == expected, val - expected = [['sudo', '-H', 'mock-pip', 'install', '-U', 'a'], - ['sudo', '-H', 'mock-pip', 'install', '-U', 'b']] + expected = [expected_prefix + ['mock-pip', 'install', '-U', 'a'], + expected_prefix + ['mock-pip', 'install', '-U', 'b']] val = installer.get_install_command(['whatever'], interactive=True) assert val == expected, val try: - test() + with patch('rosdep2.installers.os.geteuid', return_value=1): + test(['sudo', '-H']) + with patch('rosdep2.installers.os.geteuid', return_value=0): + test([]) except AssertionError: traceback.print_exc() raise diff --git a/test/test_rosdep_redhat.py b/test/test_rosdep_redhat.py index 581910355..e9dab6cdd 100644 --- a/test/test_rosdep_redhat.py +++ b/test/test_rosdep_redhat.py @@ -80,27 +80,30 @@ def test_DnfInstaller(): from rosdep2.platforms.redhat import DnfInstaller @patch.object(DnfInstaller, 'get_packages_to_install') - def test(mock_method): + def test(expected_prefix, mock_method): installer = DnfInstaller() mock_method.return_value = [] assert [] == installer.get_install_command(['fake']) # no interactive option with YUM mock_method.return_value = ['a', 'b'] - expected = [['sudo', '-H', 'dnf', '--assumeyes', '--quiet', '--setopt=strict=0', 'install', 'a', 'b']] + expected = [expected_prefix + ['dnf', '--assumeyes', '--quiet', '--setopt=strict=0', 'install', 'a', 'b']] val = installer.get_install_command(['whatever'], interactive=False, quiet=True) assert val == expected, val + expected - expected = [['sudo', '-H', 'dnf', '--quiet', '--setopt=strict=0', 'install', 'a', 'b']] + expected = [expected_prefix + ['dnf', '--quiet', '--setopt=strict=0', 'install', 'a', 'b']] val = installer.get_install_command(['whatever'], interactive=True, quiet=True) assert val == expected, val + expected - expected = [['sudo', '-H', 'dnf', '--assumeyes', '--setopt=strict=0', 'install', 'a', 'b']] + expected = [expected_prefix + ['dnf', '--assumeyes', '--setopt=strict=0', 'install', 'a', 'b']] val = installer.get_install_command(['whatever'], interactive=False, quiet=False) assert val == expected, val + expected - expected = [['sudo', '-H', 'dnf', '--setopt=strict=0', 'install', 'a', 'b']] + expected = [expected_prefix + ['dnf', '--setopt=strict=0', 'install', 'a', 'b']] val = installer.get_install_command(['whatever'], interactive=True, quiet=False) assert val == expected, val + expected try: - test() + with patch('rosdep2.installers.os.geteuid', return_value=1): + test(['sudo', '-H']) + with patch('rosdep2.installers.os.geteuid', return_value=0): + test([]) except AssertionError: traceback.print_exc() raise @@ -110,27 +113,30 @@ def test_YumInstaller(): from rosdep2.platforms.redhat import YumInstaller @patch.object(YumInstaller, 'get_packages_to_install') - def test(mock_method): + def test(expected_prefix, mock_method): installer = YumInstaller() mock_method.return_value = [] assert [] == installer.get_install_command(['fake']) # no interactive option with YUM mock_method.return_value = ['a', 'b'] - expected = [['sudo', '-H', 'yum', '--assumeyes', '--quiet', '--skip-broken', 'install', 'a', 'b']] + expected = [expected_prefix + ['yum', '--assumeyes', '--quiet', '--skip-broken', 'install', 'a', 'b']] val = installer.get_install_command(['whatever'], interactive=False, quiet=True) assert val == expected, val + expected - expected = [['sudo', '-H', 'yum', '--quiet', '--skip-broken', 'install', 'a', 'b']] + expected = [expected_prefix + ['yum', '--quiet', '--skip-broken', 'install', 'a', 'b']] val = installer.get_install_command(['whatever'], interactive=True, quiet=True) assert val == expected, val + expected - expected = [['sudo', '-H', 'yum', '--assumeyes', '--skip-broken', 'install', 'a', 'b']] + expected = [expected_prefix + ['yum', '--assumeyes', '--skip-broken', 'install', 'a', 'b']] val = installer.get_install_command(['whatever'], interactive=False, quiet=False) assert val == expected, val + expected - expected = [['sudo', '-H', 'yum', '--skip-broken', 'install', 'a', 'b']] + expected = [expected_prefix + ['yum', '--skip-broken', 'install', 'a', 'b']] val = installer.get_install_command(['whatever'], interactive=True, quiet=False) assert val == expected, val + expected try: - test() + with patch('rosdep2.installers.os.geteuid', return_value=1): + test(['sudo', '-H']) + with patch('rosdep2.installers.os.geteuid', return_value=0): + test([]) except AssertionError: traceback.print_exc() raise diff --git a/test/test_rosdep_slackware.py b/test/test_rosdep_slackware.py index 73288654e..8f6857c72 100644 --- a/test/test_rosdep_slackware.py +++ b/test/test_rosdep_slackware.py @@ -89,25 +89,28 @@ def test_SbotoolsInstaller(): from rosdep2.platforms.slackware import SbotoolsInstaller @patch.object(SbotoolsInstaller, 'get_packages_to_install') - def test(mock_method): + def test(expected_prefix, mock_method): installer = SbotoolsInstaller() mock_method.return_value = [] assert [] == installer.get_install_command(['fake']) mock_method.return_value = ['a', 'b'] - expected = [['sudo', '-H', 'sboinstall', '-r', 'a'], - ['sudo', '-H', 'sboinstall', '-r', 'b']] + expected = [expected_prefix + ['sboinstall', '-r', 'a'], + expected_prefix + ['sboinstall', '-r', 'b']] val = installer.get_install_command(['whatever'], interactive=False) assert val == expected, val - expected = [['sudo', '-H', 'sboinstall', 'a'], - ['sudo', '-H', 'sboinstall', 'b']] + expected = [expected_prefix + ['sboinstall', 'a'], + expected_prefix + ['sboinstall', 'b']] val = installer.get_install_command(['whatever'], interactive=True) assert val == expected, val try: - test() + with patch('rosdep2.installers.os.geteuid', return_value=1): + test(['sudo', '-H']) + with patch('rosdep2.installers.os.geteuid', return_value=0): + test([]) except AssertionError: traceback.print_exc() raise @@ -159,25 +162,28 @@ def test_SlackpkgInstaller(): from rosdep2.platforms.slackware import SlackpkgInstaller @patch.object(SlackpkgInstaller, 'get_packages_to_install') - def test(mock_method): + def test(expected_prefix, mock_method): installer = SlackpkgInstaller() mock_method.return_value = [] assert [] == installer.get_install_command(['fake']) mock_method.return_value = ['a', 'b'] - expected = [['sudo', '-H', 'slackpkg', 'install', 'a'], - ['sudo', '-H', 'slackpkg', 'install', 'b']] + expected = [expected_prefix + ['slackpkg', 'install', 'a'], + expected_prefix + ['slackpkg', 'install', 'b']] val = installer.get_install_command(['whatever'], interactive=False) assert val == expected, val - expected = [['sudo', '-H', 'slackpkg', 'install', 'a'], - ['sudo', '-H', 'slackpkg', 'install', 'b']] + expected = [expected_prefix + ['slackpkg', 'install', 'a'], + expected_prefix + ['slackpkg', 'install', 'b']] val = installer.get_install_command(['whatever'], interactive=True) assert val == expected, val try: - test() + with patch('rosdep2.installers.os.geteuid', return_value=1): + test(['sudo', '-H']) + with patch('rosdep2.installers.os.geteuid', return_value=0): + test([]) except AssertionError: traceback.print_exc() raise 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 + +