Commit dc8f83e7 authored by Jochen Sprickerhof's avatar Jochen Sprickerhof

Imported Upstream version 0.11.4

parent c3db41dd
syntax: glob
*.orig
*.swp
*.pyc
*.DS_Store
*~
*.log
.coverage
nosetests.xml
syntax: regexp
(target|build|dist)/.*
......@@ -2,8 +2,7 @@ language: python
python:
- "2.6"
- "2.7"
- "3.2"
- "3.3"
- "3.4"
# command to install dependencies
install:
# develop seems to be required by travis since 02/2013
......
0.11.4 (2015-09-25)
-------------------
- Fix bug in `pip` package detection code.
0.11.3 (2015-09-24)
-------------------
- Added an option to print out only apt and pip installable packages as commands.
- Added warning when neither the ``ROS_DISTRO`` environment variable is set nor the ``--rosdistro`` option is used.
- Fixed a bug related to group id resolution.
- Switched to using DNF instead of YUM for Fedora 22+.
- Fixed a bug where pip packages were not detected for older versions of ``pip``.
- Fixed a bug where dependencies of packages were gotten from the wrong ``package.xml`` when that package was being overlaid with local packages.
......@@ -33,7 +33,7 @@ Commands
**init**
Initialize /etc/ros/sources.list.d/ configuration. May require sudo.
Initialize /etc/ros/rosdep/sources.list.d/ configuration. May require sudo.
**install <stacks-and-packages>...**
......@@ -88,6 +88,35 @@ Options
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.
Install Options
---------------
......
__version__ = '0.11.2'
__version__ = '0.11.4'
......@@ -211,13 +211,12 @@ class InstallerContext(object):
"""
if not os_key in self.os_installers:
raise KeyError("unknown OS: %s"%(os_key))
if not installer_key in self.os_installers[os_key]:
raise KeyError("installer [%s] is not associated with OS [%s]. call add_os_installer_key() first"%(installer_key, os_key))
# validate, will throw KeyError
self.get_installer(installer_key)
if not hasattr(installer_key, '__call__'):
raise ValueError("version type should be a method")
if not installer_key(self.os_detect) in self.os_installers[os_key]:
raise KeyError("installer [%s] is not associated with OS [%s]. call add_os_installer_key() first"%(installer_key(self.os_detect), os_key))
if self.verbose:
print("set default installer [%s] for OS [%s]"%(installer_key, os_key))
print("set default installer for OS [%s]"%(os_key,))
self.default_os_installer[os_key] = installer_key
def get_default_os_installer_key(self, os_key):
......@@ -232,7 +231,12 @@ class InstallerContext(object):
if not os_key in self.os_installers:
raise KeyError("unknown OS: %s"%(os_key))
try:
return self.default_os_installer[os_key]
installer_key = self.default_os_installer[os_key](self.os_detect)
if not installer_key in self.os_installers[os_key]:
raise KeyError("installer [%s] is not associated with OS [%s]. call add_os_installer_key() first"%(installer_key, os_key))
# validate, will throw KeyError
self.get_installer(installer_key)
return installer_key
except KeyError:
return None
......@@ -410,7 +414,7 @@ class RosdepInstaller(object):
return uninstalled, errors
for installer_key, resolved in resolutions: #py3k
if verbose:
print("resolution: %s [%s]"%(installer_key, ', '.join(resolved)))
print("resolution: %s [%s]" % (installer_key, ', '.join([str(r) for r in resolved])))
try:
installer = installer_context.get_installer(installer_key)
except KeyError as e: # lookup has to be buggy to cause this
......@@ -425,7 +429,7 @@ class RosdepInstaller(object):
if packages_to_install:
uninstalled.append((installer_key, packages_to_install))
if verbose:
print("uninstalled: [%s]"%(', '.join(packages_to_install)))
print("uninstalled: [%s]"%(', '.join([str(p) for p in packages_to_install])))
return uninstalled, errors
......
......@@ -296,6 +296,13 @@ def _rosdep_main(args):
"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).")
parser.add_option("--filter-for-installers",
action="append", default=[],
help="Affects the 'db' verb. If supplied, the output of the 'db' "
"command is filtered to only list packages whose installer "
"is in the provided list. The option can be supplied "
"multiple times. A space separated list of installers can also "
"be passed as a string. Example: `--filter-for-installers \"apt pip\"`")
parser.add_option("--from-paths", dest='from_paths',
default=False, action="store_true",
help="Affects the 'check', 'keys', and 'install' verbs. "
......@@ -317,8 +324,9 @@ def _rosdep_main(args):
print(__version__)
sys.exit(0)
# flatten list of skipped keys
# flatten list of skipped keys and filter-for-installers
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(' ')]
if len(args) == 0:
parser.error("Please enter a command")
......@@ -333,9 +341,9 @@ def _rosdep_main(args):
# Convert list of keys to dictionary
options.as_root = dict((k, str_to_bool(v)) for k, v in key_list_to_dict(options.as_root).items())
if not command in ['init', 'update']:
if not command in ['init', 'update', 'fix-permissions']:
check_for_sources_list_init(options.sources_cache_dir)
else:
elif not command in ['fix-permissions']:
setup_proxy_opener()
if command in _command_rosdep_args:
return _rosdep_args_handler(command, parser, options, args)
......@@ -390,7 +398,11 @@ def _package_args_handler(command, parser, options, args):
if 'ROS_PACKAGE_PATH' not in os.environ:
os.environ['ROS_PACKAGE_PATH'] = '{0}'.format(path)
else:
os.environ['ROS_PACKAGE_PATH'] += ':{0}'.format(path)
os.environ['ROS_PACKAGE_PATH'] = '{0}{1}{2}'.format(
path,
os.pathsep,
os.environ['ROS_PACKAGE_PATH']
)
pkgs = find_catkin_packages_in(path, options.verbose)
packages.extend(pkgs)
# Make packages list unique
......@@ -617,12 +629,21 @@ def command_install(lookup, packages, options):
return 1
else:
uninstalled, errors = installer.get_uninstalled(packages, implicit=options.recursive, verbose=options.verbose)
if options.verbose:
print("uninstalled dependencies are: [%s]"%(', '.join([', '.join(pkg) for pkg in [v for k,v in uninstalled]])))
if errors:
print("ERROR: the following packages/stacks could not have their rosdep keys resolved\nto system dependencies:", file=sys.stderr)
err_msg = ("ERROR: the following packages/stacks could not have their "
"rosdep keys resolved\nto system dependencies")
if rospkg.distro.current_distro_codename() is None:
err_msg += (
" (ROS distro is not set. "
"Make sure `ROS_DISTRO` environment variable is set, or use "
"`--rosdistro` option to specify the distro, "
"e.g. `--rosdistro indigo`)"
)
print(err_msg + ":", file=sys.stderr)
for rosdep_key, error in errors.items():
print("%s: %s"%(rosdep_key, error_to_human_readable(error)), file=sys.stderr)
if options.robust:
......@@ -678,6 +699,8 @@ def command_db(options):
try:
d = view.lookup(rosdep_name)
inst_key, rule = d.get_rule_for_platform(os_name, os_version, installer_keys, default_key)
if options.filter_for_installers and inst_key not in options.filter_for_installers:
continue
resolved = installer.resolve(rule)
resolved_str = " ".join(resolved)
print ("%s -> %s"%(rosdep_name, resolved_str))
......@@ -766,7 +789,10 @@ def command_fix_permissions(options):
uid = stat_info.st_uid
gid = stat_info.st_gid
user_name = pwd.getpwuid(uid).pw_name
group_name = grp.getgrgid(gid).gr_name
try:
group_name = grp.getgrgid(gid).gr_name
except KeyError as e:
group_name = gid
ros_home = rospkg.get_ros_home()
print("Recursively changing ownership of ros home directory '{0}' "
......
......@@ -42,7 +42,7 @@ def register_installers(context):
def register_platforms(context):
context.add_os_installer_key(ARCH_OS_NAME, SOURCE_INSTALLER)
context.add_os_installer_key(ARCH_OS_NAME, PACMAN_INSTALLER)
context.set_default_os_installer_key(ARCH_OS_NAME, PACMAN_INSTALLER)
context.set_default_os_installer_key(ARCH_OS_NAME, lambda self: PACMAN_INSTALLER)
def pacman_detect_single(p):
return not subprocess.call(['pacman', '-Q', p], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
......
......@@ -45,7 +45,7 @@ def register_installers(context):
def register_platforms(context):
context.add_os_installer_key(OS_CYGWIN, SOURCE_INSTALLER)
context.add_os_installer_key(OS_CYGWIN, APT_CYG_INSTALLER)
context.set_default_os_installer_key(OS_CYGWIN, APT_CYG_INSTALLER)
context.set_default_os_installer_key(OS_CYGWIN, lambda self: APT_CYG_INSTALLER)
def cygcheck_detect_single(p):
std_out = read_stdout(['cygcheck', '-c', p])
......
......@@ -55,7 +55,7 @@ def register_debian(context):
context.add_os_installer_key(OS_DEBIAN, PIP_INSTALLER)
context.add_os_installer_key(OS_DEBIAN, GEM_INSTALLER)
context.add_os_installer_key(OS_DEBIAN, SOURCE_INSTALLER)
context.set_default_os_installer_key(OS_DEBIAN, APT_INSTALLER)
context.set_default_os_installer_key(OS_DEBIAN, lambda self: APT_INSTALLER)
context.set_os_version_type(OS_DEBIAN, OsDetect.get_codename)
def register_linaro(context):
......@@ -70,7 +70,7 @@ def register_ubuntu(context):
context.add_os_installer_key(OS_UBUNTU, PIP_INSTALLER)
context.add_os_installer_key(OS_UBUNTU, GEM_INSTALLER)
context.add_os_installer_key(OS_UBUNTU, SOURCE_INSTALLER)
context.set_default_os_installer_key(OS_UBUNTU, APT_INSTALLER)
context.set_default_os_installer_key(OS_UBUNTU, lambda self: APT_INSTALLER)
context.set_os_version_type(OS_UBUNTU, OsDetect.get_codename)
def dpkg_detect(pkgs, exec_fn=None):
......
......@@ -45,7 +45,7 @@ def register_installers(context):
def register_platforms(context):
context.add_os_installer_key(OS_FREEBSD, SOURCE_INSTALLER)
context.add_os_installer_key(OS_FREEBSD, PKG_ADD_INSTALLER)
context.set_default_os_installer_key(OS_FREEBSD, PKG_ADD_INSTALLER)
context.set_default_os_installer_key(OS_FREEBSD, lambda self: PKG_ADD_INSTALLER)
def pkg_info_detect_single(p):
if p == "builtin":
......
......@@ -56,7 +56,7 @@ def register_installers(context):
def register_platforms(context):
context.add_os_installer_key(OS_GENTOO, PORTAGE_INSTALLER)
context.add_os_installer_key(OS_GENTOO, SOURCE_INSTALLER)
context.set_default_os_installer_key(OS_GENTOO, PORTAGE_INSTALLER)
context.set_default_os_installer_key(OS_GENTOO, lambda self: PORTAGE_INSTALLER)
# Determine whether an atom is already satisfied
def portage_detect_single(atom, exec_fn = read_stdout ):
......
......@@ -43,7 +43,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, ZYPPER_INSTALLER)
context.set_default_os_installer_key(OS_OPENSUSE, ZYPPER_INSTALLER)
context.set_default_os_installer_key(OS_OPENSUSE, lambda self: ZYPPER_INSTALLER)
def rpm_detect(packages):
installed = []
......
......@@ -62,7 +62,7 @@ def register_platforms(context):
context.add_os_installer_key(OS_OSX, MACPORTS_INSTALLER)
context.add_os_installer_key(OS_OSX, PIP_INSTALLER)
context.add_os_installer_key(OS_OSX, SOURCE_INSTALLER)
context.set_default_os_installer_key(OS_OSX, BREW_INSTALLER)
context.set_default_os_installer_key(OS_OSX, lambda self: BREW_INSTALLER)
context.set_os_version_type(OS_OSX, OsDetect.get_codename)
def is_port_installed():
......@@ -269,7 +269,7 @@ class HomebrewInstaller(PackageManagerInstaller):
if len(packages) == 1 and options and not isinstance(options[0],list):
options = [options]
else:
options = map(coerce_to_list, options)
options = list(map(coerce_to_list, options))
# make sure options is a list of list of strings
try:
......
......@@ -77,7 +77,15 @@ def pip_detect(pkgs, exec_fn=None):
# https://github.com/pypa/pip/issues/1570#issuecomment-71111030
if fallback_to_pip_show:
for pkg in [p for p in pkgs if p not in ret_list]:
if subprocess.call(['pip', 'show', '-q', pkg]) == 0:
# does not see retcode but stdout for old pip to check if installed
proc = subprocess.Popen(
['pip', 'show', pkg],
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT
)
output, _ = proc.communicate()
output = output.strip()
if proc.returncode == 0 and output:
# `pip show` detected it, add it to the list.
ret_list.append(pkg)
......
......@@ -57,14 +57,14 @@ def register_fedora(context):
context.add_os_installer_key(OS_FEDORA, DNF_INSTALLER)
context.add_os_installer_key(OS_FEDORA, YUM_INSTALLER)
context.add_os_installer_key(OS_FEDORA, SOURCE_INSTALLER)
context.set_default_os_installer_key(OS_FEDORA, YUM_INSTALLER)
context.set_os_version_type(OS_FEDORA, lambda self: self.get_version() if int(self.get_version()) > 20 else self.get_codename())
context.set_default_os_installer_key(OS_FEDORA, lambda self: DNF_INSTALLER if self.get_version().isdigit() and int(self.get_version()) > 21 else YUM_INSTALLER)
context.set_os_version_type(OS_FEDORA, lambda self: self.get_version() if self.get_version().isdigit() and int(self.get_version()) > 20 else self.get_codename())
def register_rhel(context):
context.add_os_installer_key(OS_RHEL, PIP_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, YUM_INSTALLER)
context.set_default_os_installer_key(OS_RHEL, lambda self: YUM_INSTALLER)
def rpm_detect_py(packages):
ret_list = []
......@@ -142,13 +142,13 @@ class DnfInstaller(PackageManagerInstaller):
if not packages:
return []
elif not interactive and quiet:
return [['sudo', 'dnf', '--assumeyes', '--quiet', 'install'] + packages]
return [self.elevate_priv(['dnf', '--assumeyes', '--quiet', 'install']) + packages]
elif quiet:
return [['sudo', 'dnf', '--quiet', 'install'] + packages]
return [self.elevate_priv(['dnf', '--quiet', 'install']) + packages]
elif not interactive:
return [['sudo', 'dnf', '--assumeyes', 'install'] + packages]
return [self.elevate_priv(['dnf', '--assumeyes', 'install']) + packages]
else:
return [['sudo', 'dnf', 'install'] + packages]
return [self.elevate_priv(['dnf', 'install']) + packages]
class YumInstaller(PackageManagerInstaller):
......
......@@ -216,7 +216,11 @@ def test_InstallerContext_os_installers():
assert False, "should have raised"
except KeyError: pass
try:
context.set_default_os_installer_key(os_key, 'fake-key')
context.set_default_os_installer_key(os_key, 'non-method')
assert False, "should have raised"
except KeyError: pass
try:
context.set_default_os_installer_key(os_key, lambda self: 'fake-key')
assert False, "should have raised"
except KeyError: pass
try:
......@@ -241,7 +245,7 @@ def test_InstallerContext_os_installers():
# retest set_default_os_installer_key, now with installer_key not configured on os
try:
context.set_default_os_installer_key(os_key, installer_key2)
context.set_default_os_installer_key(os_key, lambda self: installer_key2)
assert False, "should have raised"
except KeyError as e:
assert 'add_os_installer' in str(e), e
......@@ -252,14 +256,14 @@ def test_InstallerContext_os_installers():
# test default
assert None == context.get_default_os_installer_key(os_key)
context.set_default_os_installer_key(os_key, installer_key1)
context.set_default_os_installer_key(os_key, lambda self: installer_key1)
assert installer_key1 == context.get_default_os_installer_key(os_key)
context.set_default_os_installer_key(os_key, installer_key2)
context.set_default_os_installer_key(os_key, lambda self: installer_key2)
assert installer_key2 == context.get_default_os_installer_key(os_key)
# retest set_default_os_installer_key, now with invalid os
try:
context.set_default_os_installer_key('bad-os', installer_key1)
context.set_default_os_installer_key('bad-os', lambda self: installer_key1)
assert False, "should have raised"
except KeyError: pass
......
......@@ -58,16 +58,16 @@ def test_DnfInstaller():
# no interactive option with YUM
mock_method.return_value = ['a', 'b']
expected = [['sudo', 'dnf', '--assumeyes', '--quiet', 'install', 'a', 'b']]
expected = [['sudo', '-H', 'dnf', '--assumeyes', '--quiet', 'install', 'a', 'b']]
val = installer.get_install_command(['whatever'], interactive=False, quiet=True)
assert val == expected, val + expected
expected = [['sudo', 'dnf', '--quiet', 'install', 'a', 'b']]
expected = [['sudo', '-H', 'dnf', '--quiet', 'install', 'a', 'b']]
val = installer.get_install_command(['whatever'], interactive=True, quiet=True)
assert val == expected, val + expected
expected = [['sudo', 'dnf', '--assumeyes', 'install', 'a', 'b']]
expected = [['sudo', '-H', 'dnf', '--assumeyes', 'install', 'a', 'b']]
val = installer.get_install_command(['whatever'], interactive=False, quiet=False)
assert val == expected, val + expected
expected = [['sudo', 'dnf', 'install', 'a', 'b']]
expected = [['sudo', '-H', 'dnf', 'install', 'a', 'b']]
val = installer.get_install_command(['whatever'], interactive=True, quiet=False)
assert val == expected, val + expected
try:
......@@ -104,3 +104,56 @@ def test_YumInstaller():
except AssertionError:
traceback.print_exc()
raise
def test_Fedora_variable_installer_key():
from rosdep2 import InstallerContext
from rosdep2.platforms import pip, redhat, source
from rosdep2.platforms.redhat import DNF_INSTALLER, YUM_INSTALLER
from rospkg.os_detect import OsDetect, OS_FEDORA
os_detect_mock = Mock(spec=OsDetect)
os_detect_mock.get_name.return_value = 'fedora'
os_detect_mock.get_codename.return_value = 'twenty'
os_detect_mock.get_version.return_value = '21'
# create our test fixture. use most of the default toolchain, but
# replace the apt installer with one that we can have more fun
# with. we will do all tests with ubuntu lucid keys -- other
# tests should cover different resolution cases.
context = InstallerContext(os_detect_mock)
pip.register_installers(context)
redhat.register_installers(context)
source.register_installers(context)
redhat.register_platforms(context)
assert YUM_INSTALLER == context.get_default_os_installer_key(OS_FEDORA)
os_detect_mock.get_version.return_value = '22'
assert DNF_INSTALLER == context.get_default_os_installer_key(OS_FEDORA)
def test_Fedora_variable_lookup_key():
from rosdep2 import InstallerContext
from rosdep2.platforms import pip, redhat, source
from rosdep2.platforms.redhat import DNF_INSTALLER, YUM_INSTALLER
from rospkg.os_detect import OsDetect, OS_FEDORA
os_detect_mock = Mock(spec=OsDetect)
os_detect_mock.get_name.return_value = 'fedora'
os_detect_mock.get_codename.return_value = 'heisenbug'
os_detect_mock.get_version.return_value = '20'
# create our test fixture. use most of the default toolchain, but
# replace the apt installer with one that we can have more fun
# with. we will do all tests with ubuntu lucid keys -- other
# tests should cover different resolution cases.
context = InstallerContext(os_detect_mock)
pip.register_installers(context)
redhat.register_installers(context)
source.register_installers(context)
redhat.register_platforms(context)
assert ('fedora', 'heisenbug') == context.get_os_name_and_version()
os_detect_mock.get_codename.return_value = 'twenty'
os_detect_mock.get_version.return_value = '21'
assert (OS_FEDORA, '21') == context.get_os_name_and_version()
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment