Commit 91254782 authored by Jochen Sprickerhof's avatar Jochen Sprickerhof

New upstream version 0.11.7

parent dc8f83e7
......@@ -12,3 +12,4 @@ deb_dist
dist
src/rosdep.egg-info
nose*
_build
......@@ -6,7 +6,7 @@ python:
# command to install dependencies
install:
# develop seems to be required by travis since 02/2013
- pip install PyYAML argparse rospkg vcstools catkin_pkg python-dateutil distribute rosdistro
- pip install PyYAML argparse rospkg vcstools catkin_pkg python-dateutil rosdistro
- python setup.py build develop
- pip install nose coverage
# command to run tests
......
0.11.6 (2017-08-01)
-------------------
- Changed the way virtual packages are checked in apt to use ``apt-cache``
- https://github.com/ros-infrastructure/rosdep/pull/533
- Fixed a bug where the dependencies of metapackages were not being installed
- https://github.com/ros-infrastructure/rosdep/pull/531
- Improved error handling of failed downloads or invalid source files
- https://github.com/ros-infrastructure/rosdep/pull/523
0.11.6 (2017-07-27)
-------------------
- Added resinstall option for ``pip`` installer
- https://github.com/ros-infrastructure/rosdep/pull/450
- Fixed detection and handling of virtual packages in ``apt`` (more changes to follow)
- https://github.com/ros-infrastructure/rosdep/pull/468
- https://github.com/ros-infrastructure/rosdep/pull/515
- Added support for Slackware
- https://github.com/ros-infrastructure/rosdep/pull/469
- Fixed flags being passed to pacman on Arch Linux
- https://github.com/ros-infrastructure/rosdep/pull/472
- https://github.com/ros-infrastructure/rosdep/pull/476
- No longer uses ``sudo`` when already root
- https://github.com/ros-infrastructure/rosdep/pull/474
- Added more information to ``rosdep --version``
- https://github.com/ros-infrastructure/rosdep/pull/481
- https://github.com/ros-infrastructure/rosdep/pull/499
- Fixed bug when using ``--verbose`` with ``rosdep install`` on macOS with Homebrew
- https://github.com/ros-infrastructure/rosdep/pull/525
- Fixed bug with the ``depends:`` part of a stanze not being used to ordered installations correctly
- https://github.com/ros-infrastructure/rosdep/pull/529
- Fixed Python3 bug on macOS
- https://github.com/ros-infrastructure/rosdep/pull/441
0.11.5 (2016-05-23)
-------------------
- add ca-certificates as a dependency to support https urls
- add quiet option for ``pip``
- Documentation updates
- Elementary support improvements
0.11.4 (2015-09-25)
-------------------
......
......@@ -23,6 +23,7 @@
<li>Red Hat Enterprise Linux (rpm/experimental)</li>
<li>Arch (pacman/experimental)</li>
<li>Gentoo (equery/experimental)</li>
<li>Slackware (sbotools/experimental)</li>
<li>Cygwin (experimental)</li>
</ul>
......
......@@ -19,124 +19,18 @@ necessary package(s).
Run ``rosdep -h`` or ``rosdep <command> -h`` to access the built-in tool
documentation.
Commands
--------
**check <stacks-and-packages>...**
Check if the dependencies of ROS package(s) have been met.
**db**
Display the local rosdep database.
**init**
Initialize /etc/ros/rosdep/sources.list.d/ configuration. May require sudo.
**install <stacks-and-packages>...**
Install dependencies for specified ROS packages.
**keys <stacks-and-packages>...**
List the rosdep keys that the ROS packages depend on.
**resolve <rosdeps>...**
Resolve <rosdeps> to system dependencies
**update**
Update the local rosdep database based on the rosdep sources.
**what-needs <rosdeps>...**
Print a list of packages that declare a rosdep on (at least
one of) <rosdeps>
**where-defined <rosdeps>...**
Print a list of YAML files that declare a rosdep on (at least
one of) <rosdeps>
.. rosdep_cli_help:: commands
Options
-------
**--os=OS_NAME:OS_VERSION**
Override OS name and version (colon-separated), e.g. ubuntu:lucid
**-c SOURCES_CACHE_DIR, --sources-cache-dir=SOURCES_CACHE_DIR**
Override default sources cache directory (local rosdep database).
**-a, --all**
Select all ROS packages. Only valid for commands that take <stacks-and-packages> as arguments.
**-h, --help**
Show usage information
**-v, --verbose**
Enable verbose output
**--version**
Print version and exit.
**-q**
Suppress output except for errors
**-n**
Do not consider implicit/recursive dependencies. Only valid with ``keys``, ``check``, and ``install`` commands.
**-i, --ignore-packages-from-source, --ignore-src**
Affects the ``check`` and ``install`` verbs. If specified then rosdep will not install keys that are found to be catkin packages anywhere in the ROS_PACKAGE_PATH or in any of the directories given by the ``--from-paths`` option.
**--skip-keys=SKIP_KEYS**
Affects the ``check`` and ``install`` verbs. The specified rosdep keys will be ignored, i.e. not resolved and not installed. The option can be supplied multiple times. A space separated list of rosdep keys can also be passed as a string. A more permanent solution to locally ignore a rosdep key is creating a local rosdep rule with an empty list of packages (include it in ``/etc/ros/rosdep/sources.list.d/`` before the defaults).
**--from-paths**
Affects the ``check``, ``keys``, and ``install`` verbs. If specified the arugments to those verbs will be considered paths to be searched, acting on all catkin packages found there in.
**--rosdistro=ROS_DISTRO**
Explicitly sets the ROS distro to use, overriding the normal method of detecting the ROS distro using the ROS_DISTRO environment variable.
**--as-root=INSTALLER_KEY:<bool>**
Override whether sudo is used for a specific installer, e.g. ``--as-root pip:false`` or ``--as-root "pip:no homebrew:yes"``. Can be specified multiple times.
.. rosdep_cli_help:: options
Install Options
---------------
**--reinstall**
(re)install all dependencies, even if already installed
**-y, --default-yes**
Tell the package manager to default to y or fail when installing
**-s, --simulate**
Simulate install
**-r**
Continue installing despite errors.
**-R**
Install implicit/recursive dependencies.
.. rosdep_cli_help:: install
......@@ -11,13 +11,14 @@
# All configuration values have a default; values that are commented out
# serve to show the default.
import sys, os
import os
import sys
sys.path.insert(0, './')
sys.path.insert(0, '../src')
import catkin_sphinx
from rosdep2 import __version__
import catkin_sphinx # noqa
from rosdep2 import __version__ # noqa
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
......@@ -31,7 +32,13 @@ from rosdep2 import __version__
# Add any Sphinx extension module names here, as strings. They can be extensions
# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
extensions = ['sphinx.ext.autodoc', 'sphinx.ext.intersphinx', 'sphinx.ext.coverage', 'sphinx.ext.viewcode']
extensions = [
'sphinx.ext.autodoc',
'sphinx.ext.intersphinx',
'sphinx.ext.coverage',
'sphinx.ext.viewcode',
'rosdep_doc_utils',
]
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
......
......@@ -41,7 +41,7 @@ The default sources list for rosdep uses the following files::
yaml https://github.com/ros/rosdistro/raw/master/rosdep/base.yaml
yaml https://github.com/ros/rosdistro/raw/master/rosdep/python.yaml
yaml https://github.com/ros/rosdistro/raw/master/rosdep/osx-homebrew.yaml osx
Create a new file in ``/etc/ros/rosdep/sources.list.d/`` that points
at your forked repository instead. The filename should use a lower
number so it is processed first.
......@@ -61,8 +61,9 @@ The repository contains the following files:
Edit the appropriate file(s) for your change, i.e., if you are
contributing a Homebrew rule, only edit ``osx-homebrew.yaml``, if you
are contributing a rule for a Python library, only edit
``python.yaml``, and, otherwise, put your rule in ``base.yaml``.
``python.yaml``, and, otherwise, put your rule in ``base.yaml``.
To edit, change the ``https://`` url to a local path using the format
``file:///abs/path``.
Make sure that your rules work
------------------------------
......@@ -86,5 +87,8 @@ Submit a pull request with your updated rules
Use GitHub's pull request mechanism to request that your updates get
included in the main databases.
There are guidelines for submitting pull requests at: https://github.com/ros/rosdistro/blob/master/CONTRIBUTING.md
And include instructions how to prevalidate your changes using the unit tests.
After your request has been accepted, you can undo your changes to
``/etc/ros/rosdep/sources.list.d``.
......@@ -12,12 +12,12 @@ REP 114: rospkg standalone library
----------------------------------
The rosdep library is being developed using the ROS REP process. It
is necessary to be familiar with these REPs in order to make sure
is necessary to be familiar with these REPs in order to make sure
that rosdep continues to follow the relevant specifications.
- `REP 111: Multiple Package Manager Support for Rosdep <http://ros.org/reps/rep-0111.html>`_.
- `REP 112: Source Package Manager for Rosdep <http://ros.org/reps/rep-0112.html>`_.
- `REP 125: rosdep 2 <http://ros.org/reps/rep-0125.html>`_.
- `REP 111: Multiple Package Manager Support for Rosdep <http://ros.org/reps/rep-0111.html>`_.
- `REP 112: Source Package Manager for Rosdep <http://ros.org/reps/rep-0112.html>`_.
- `REP 125: rosdep 2 <http://ros.org/reps/rep-0125.html>`_.
Bug reports and feature requests
--------------------------------
......@@ -45,7 +45,7 @@ Declaring a new OS
''''''''''''''''''
Adding support for a new OS is fairly straightforward: you just
have to provide rosdep2 the keys that are associated with your OS and the
have to provide rosdep2 the keys that are associated with your OS and the
keys of the installers that your OS supports.
Implementations must provide a ``register_platforms(context)`` call
......@@ -97,7 +97,7 @@ of the ``PipInstaller``::
return []
else:
return [['sudo', 'pip', 'install', '-U', p] for p in packages]
The pattern is fairly simple to implement for other package managers.
You must provide a ``detect_function(package_names)``
......@@ -125,7 +125,7 @@ Setup
pip install mock
rosdep2 uses `Python nose <http://readthedocs.org/docs/nose/en/latest/>`_
rosdep2 uses `Python nose <http://readthedocs.org/docs/nose/en/latest/>`_
for testing, which is a fairly simple and straightfoward test
framework. You just have to write a function start with the name
``test`` and use normal ``assert`` statements for your tests.
......@@ -138,7 +138,7 @@ You can run the tests, including coverage, as follows:
::
cd rosdep2/test
nosetests
nosetests
Documentation
......
......@@ -17,95 +17,20 @@ in order to get the OpenGL headers on Ubuntu? How about OS X? Fedora?
rosdep can answer this question for your platform and install the
necessary package(s).
For more information on rosdep, see http://ros.org/wiki/rosdep.
Run "rosdep -h" or "rosdep <command> -h" to access the built-in tool
Run ``rosdep -h`` or ``rosdep <command> -h`` to access the built-in tool
documentation.
Commands
--------
**check <stacks-and-packages>...**
Check if the dependencies of ROS package(s) have been met.
**db**
Display the local rosdep database.
**init**
Initialize /etc/ros/sources.list.d/ configuration. May require sudo.
**install <stacks-and-packages>...**
Install dependencies for specified ROS packages.
**keys <stacks-and-packages>...**
List the rosdep keys that the ROS packages depend on.
**resolve <rosdeps>...**
Resolve <rosdeps> to system dependencies
**update**
Update the local rosdep database based on the rosdep sources.
**what-needs <rosdeps>...**
Print a list of packages that declare a rosdep on (at least
one of) <rosdeps>
**where-defined <rosdeps>...**
Print a list of YAML files that declare a rosdep on (at least
one of) <rosdeps>
.. rosdep_cli_help:: commands
Options
-------
**--os=OS_NAME:OS_VERSION**
Override OS name and version (colon-separated), e.g. ubuntu:lucid
**-c SOURCES_CACHE_DIR, --sources-cache-dir=SOURCES_CACHE_DIR**
Override default sources cache directory (local rosdep database).
**-a, --all**
Select all ROS packages. Only valid for commands that take <stacks-and-packages> as arguments.
**-h, --help**
Show usage information
**-v, --verbose**
Enable verbose output
.. rosdep_cli_help:: options
Install Options
---------------
**--reinstall**
(re)install all dependencies, even if already installed
**-y, --default-yes**
Tell the package manager to default to y or fail when installing
**-s, --simulate**
Simulate install
**-r**
Continue installing despite errors.
**-R**
Install implicit/recursive dependencies.
.. rosdep_cli_help:: install
......@@ -67,7 +67,7 @@ Example::
sudo apt-get install python-numpy
sudo apt-get install python-paramiko
sudo apt-get install python-yaml
You can also query rosdep to find out more information about specific
dependencies::
......
# Copyright 2016 Open Source Robotics Foundation, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from docutils import nodes
from docutils.parsers.rst import Directive
import re
import subprocess
import sys
from rosdep2.main import _usage
class RosdepCLIDirective(Directive):
required_arguments = 1
def run(self):
if 'commands' in self.arguments:
return [nodes.literal_block(text=_usage)]
capitalized_usage = _usage[0].upper() + _usage[1:] + '\n'
escaped_capitalized_usage = re.escape(capitalized_usage)
py = sys.executable
if 'options' in self.arguments:
out = subprocess.check_output(
[py, '-c', "from rosdep2.main import rosdep_main;rosdep_main(['-h'])"]
)
return [
nodes.literal_block(text=re.sub(escaped_capitalized_usage, '', out))
]
if 'install' in self.arguments:
out = subprocess.check_output(
[py, '-c', "from rosdep2.main import rosdep_main;rosdep_main(['install', '-h'])"]
)
return [
nodes.literal_block(text=re.sub(escaped_capitalized_usage, '', out))
]
def setup(app):
app.add_directive('rosdep_cli_help', RosdepCLIDirective)
......@@ -40,7 +40,7 @@ The names above resolve as follows:
* ``ROSDEP_NAME`` is the name referred to by manifest files. Examples: ``log4cxx`` or ``gtest``.
* ``OS_NAME`` is the name of an OS. Examples: ``ubuntu``, ``osx``, ``fedora``, ``debian``, or ``windows``.
* ``OS_VERSION`` (*optional*) is the name of specific versions in the OS. Examples: ``lucid`` or ``squeeze``. If no ``OS_VERSION`` is specified, the rule is assumed to apply to all versions.
* ``PACKAGE_MANAGER`` (*optional in ROS Electric, required in ROS Fuerte*) is a key to select which package manager to use for this rosdep. Examples: ``apt``, ``easy_install``, ``macports``.
* ``PACKAGE_MANAGER`` (*optional in ROS Electric, required in ROS Fuerte*) is a key to select which package manager to use for this rosdep. Examples: ``apt``, ``pip``, ``macports``.
* ``PACKAGE_ARGUMENT`` is free-form YAML that is be passed to the handler for the specified ``PACKAGE_MANAGER``.
......@@ -94,6 +94,11 @@ OS name identifiers and supported package managers
* ``pkg_add`` (default)
* ``source``
* ``gentoo``: Gentoo Linux
* ``portage`` (default)
* ``source``
* ``osx`` : Apple OS X
......
......@@ -44,7 +44,7 @@ source first. The general format is::
``yaml``
``rosdep.yaml`` file
``rosdep.yaml`` file
``gbpdistro``
......@@ -53,7 +53,7 @@ source first. The general format is::
``type``
Type must be ``yaml`` or ``gbpdistro``. In the future, more types may be supported.
``url``
URL should point to the HTTP location of a rosdep YAML file. URL
......@@ -91,4 +91,4 @@ currently in use for building catkin-based ROS stacks. End users are
not expected to write their own ``gbpdistro`` files and the
specification is unstable.
......@@ -8,10 +8,9 @@ setup(
version=__version__,
packages=['rosdep2', 'rosdep2.platforms'],
package_dir={'': 'src'},
install_requires=['catkin_pkg', 'rospkg >= 1.0.34', 'rosdistro >= 0.4.0', 'PyYAML >= 3.1'],
setup_requires=['nose >= 1.0'],
install_requires=['catkin_pkg', 'rospkg >= 1.0.37', 'rosdistro >= 0.4.0', 'PyYAML >= 3.1'],
test_suite='nose.collector',
test_requires=['mock'],
test_requires=['mock', 'nose >= 1.0'],
scripts=['scripts/rosdep', 'scripts/rosdep-source'],
author="Tully Foote, Ken Conley",
author_email="tfoote@osrfoundation.org",
......
......@@ -64,9 +64,10 @@ def create_default_installer_context(verbose=False):
from .platforms import pip
from .platforms import gem
from .platforms import redhat
from .platforms import slackware
from .platforms import source
platform_mods = [arch, cygwin, debian, gentoo, opensuse, osx, redhat]
platform_mods = [arch, cygwin, debian, gentoo, opensuse, osx, redhat, slackware]
installer_mods = [source, pip, gem] + platform_mods
context = InstallerContext()
......
__version__ = '0.11.4'
__version__ = '0.11.7'
# Copyright (c) 2012, Willow Garage, Inc.
# All rights reserved.
#
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright
......@@ -12,7 +12,7 @@
# * Neither the name of the Willow Garage, Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
......@@ -29,6 +29,7 @@
from collections import defaultdict
class Resolution(dict):
"""A default dictionary for use in the :class:`DependencyGraph`."""
def __init__(self):
......@@ -38,12 +39,14 @@ class Resolution(dict):
self['dependencies'] = []
self['is_root'] = True
class DependencyGraph(defaultdict):
"""
Provides a mechanism for generating a list of resolutions which preserves the dependency order.
The :class:`DependencyGraph` inherits from a *defaultdict*, so it can be used as such to load the dependency graph data into it.
Example::
The :class:`DependencyGraph` inherits from a *defaultdict*, so it can be used as such to load
the dependency graph data into it.
Example::
# Dependency graph:: A-B-C
dg = DependencyGraph()
......@@ -61,7 +64,7 @@ class DependencyGraph(defaultdict):
"""
def __init__(self):
defaultdict.__init__(self, Resolution)
def detect_cycles(self, rosdep_key, traveled_keys):
"""
Recursive function to detect cycles in the dependency graph.
......@@ -71,14 +74,14 @@ class DependencyGraph(defaultdict):
:raises: :exc:`AssertionError` if the rosdep_key is in the traveled keys, indicating a cycle has occurred.
"""
assert rosdep_key not in traveled_keys, "A cycle in the dependency graph occurred with key `%s`."%rosdep_key
assert rosdep_key not in traveled_keys, "A cycle in the dependency graph occurred with key `%s`." % rosdep_key
traveled_keys.append(rosdep_key)
for dependency in self[rosdep_key]['dependencies']:
self.detect_cycles(dependency, traveled_keys)
def validate(self):
"""
Performs validations on the dependency graph, like cycle detection and invalid rosdep key detection.
Performs validations on the dependency graph, like cycle detection and invalid rosdep key detection.
:raises: :exc:`AssertionError` if a cycle is detected.
:raises: :exc:`KeyError` if an invalid rosdep_key is found in the dependency graph.
......@@ -88,7 +91,9 @@ class DependencyGraph(defaultdict):
# i.e.: Ensure we aren't pointing to invalid rosdep keys
for dependency in self[rosdep_key]['dependencies']:
if dependency not in self:
raise KeyError("Invalid Graph Structure: rosdep key `%s` does not exist in the dictionary of resolutions."%dependency)
raise KeyError(
"Invalid Graph Structure: rosdep key `%s` does not exist in the dictionary of resolutions."
% dependency)
self[dependency]['is_root'] = False
# Check each entry for cyclical dependencies
for rosdep_key in self:
......@@ -99,7 +104,7 @@ class DependencyGraph(defaultdict):
Generates an ordered list of dependencies using the dependency graph.
:returns: *[(installer_key, [install_keys])]*, ``[(str, [str])]``. *installer_key* is the key
that denotes which installed the accompanying *install_keys* are for. *installer_key* are something
that denotes which installed the accompanying *install_keys* are for. *installer_key* are something
like ``apt`` or ``homebrew``. *install_keys* are something like ``boost`` or ``ros-fuerte-ros_comm``.
:raises: :exc:`AssertionError` if a cycle is detected.
......
......@@ -29,6 +29,7 @@
from __future__ import print_function
import os
import subprocess
import traceback
......@@ -293,7 +294,7 @@ class Installer(object):
resolved2 = installer.resolve(args2)
resolved = installer.unique(resolved1, resolved2)
:param *resolved_rules: resolved arguments. Resolved
:param resolved_rules: resolved arguments. Resolved
arguments must all be from this :class:`Installer` instance.
"""
raise NotImplementedError("Base class unique", resolved_rules)
......@@ -314,11 +315,13 @@ class PackageManagerInstaller(Installer):
def __init__(self, detect_fn, supports_depends=False):
"""
:param supports_depends: package manager supports dependency key
:param detect_fn: function that for a given list of packages determines
the list of installed packages.
"""
self.detect_fn = detect_fn
self.supports_depends = supports_depends
self.as_root = True
self.sudo_command = 'sudo -H'
self.sudo_command = 'sudo -H' if os.geteuid() != 0 else ""
def elevate_priv(self, cmd):
"""
......@@ -356,6 +359,10 @@ class PackageManagerInstaller(Installer):
return sorted(list(s))
def get_packages_to_install(self, resolved, reinstall=False):
'''
Return a list of packages (out of *resolved*) that still need to get
installed.
'''
if reinstall:
return resolved
if not resolved:
......@@ -364,8 +371,20 @@ class PackageManagerInstaller(Installer):
return list(set(resolved) - set(self.detect_fn(resolved)))
def is_installed(self, resolved_item):
'''
Check if a given package was installed.
'''
return not self.get_packages_to_install([resolved_item])
def get_version_strings(self):
'''
Return a list of version information strings.
Where each string is of the form "<installer> <version string>".
For example, ["apt-get x.y.z"] or ["pip x.y.z", "setuptools x.y.z"].
'''
raise NotImplementedError('subclasses must implement get_version_strings method')
def get_install_command(self, resolved, interactive=True, reinstall=False, quiet=False):
raise NotImplementedError('subclasses must implement', resolved, interactive, reinstall, quiet)
......@@ -379,6 +398,18 @@ class PackageManagerInstaller(Installer):
return rosdep_args.get('depends', [])
return [] # Default return empty list
def normalize_uninstalled_to_list(uninstalled):
uninstalled_dependencies = []
for pkg_or_list in [v for k, v in uninstalled]:
if isinstance(pkg_or_list, list):
for pkg in pkg_or_list:
uninstalled_dependencies.append(str(pkg))
else:
uninstalled_dependencies.append(str(pkg))
return uninstalled_dependencies
class RosdepInstaller(object):
def __init__(self, installer_context, lookup):
......@@ -465,8 +496,12 @@ class RosdepInstaller(object):
installer.install(uninstalled)
"""
if verbose:
print("install options: reinstall[%s] simulate[%s] interactive[%s]"%(reinstall, simulate, interactive))
print("install: uninstalled keys are %s"%(', '.join([', '.join(pkg) for pkg in [v for k,v in uninstalled]])))
print(
"install options: reinstall[%s] simulate[%s] interactive[%s]" %
(reinstall, simulate, interactive)
)
uninstalled_list = normalize_uninstalled_to_list(uninstalled)
print("install: uninstalled keys are %s" % ', '.join(uninstalled_list))
# Squash uninstalled again, in case some dependencies were already installed
squashed_uninstalled = []
......
......@@ -478,10 +478,11 @@ class RosdepLookup(object):
except KeyError:
raise ResolutionError(rosdep_key, definition.data, os_name, os_version, "Unsupported installer [%s]"%(installer_key))
resolution = installer.resolve(rosdep_args_dict)
dependencies = installer.get_depends(rosdep_args_dict)
dependencies = installer.get_depends(rosdep_args_dict)
# cache value
self._resolve_cache[rosdep_key] = os_name, os_version, view.name, installer_key, resolution, dependencies
# the dependencies list is copied to prevent mutation before next cache hit
self._resolve_cache[rosdep_key] = os_name, os_version, view.name, installer_key, resolution, list(dependencies)
return installer_key, resolution, dependencies
......
......@@ -59,7 +59,8 @@ import rospkg
from . import create_default_installer_context, get_default_installer
from . import __version__
from .core import RosdepInternalError, InstallFailed, UnsupportedOs, InvalidData, CachePermissionError
from .core import RosdepInternalError, InstallFailed, UnsupportedOs, InvalidData, CachePermissionError, DownloadFailure
from .installers import normalize_uninstalled_to_list
from .installers import RosdepInstaller