pax_global_header00006660000000000000000000000064124746574460014535gustar00rootroot0000000000000052 comment=28ff3224ff36301b70359f12d26c89df2515b4e6 ros-rosinstall-generator-0.1.11/000077500000000000000000000000001247465744600165745ustar00rootroot00000000000000ros-rosinstall-generator-0.1.11/.gitignore000066400000000000000000000000701247465744600205610ustar00rootroot00000000000000build deb_dist dist *.pyc rosinstall_generator.egg-info ros-rosinstall-generator-0.1.11/.travis.yml000066400000000000000000000004641247465744600207110ustar00rootroot00000000000000language: python python: - "2.6" - "2.7" - "3.3" # command to install dependencies install: - pip install argparse catkin-pkg distribute rosdistro rospkg PyYAML # command to run tests script: # This package doesn't have tests yet. - true # - nosetests -s --tests test notifications: email: false ros-rosinstall-generator-0.1.11/LICENSE.txt000066400000000000000000000030611247465744600204170ustar00rootroot00000000000000Software License Agreement (BSD License) Copyright (c) 2013, Open Source Robotics Foundation, 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 notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Open Source Robotics Foundation, 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 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ros-rosinstall-generator-0.1.11/Makefile000077500000000000000000000006571247465744600202470ustar00rootroot00000000000000.PHONY: all setup clean_dist distro clean install NAME=rosinstall_generator VERSION=`./setup.py --version` all: echo "noop for debbuild" setup: echo "building version ${VERSION}" clean_dist: -rm -f MANIFEST -rm -rf deb_dist -rm -rf dist -rm -rf src/rosinstall_generator.egg-info distro: setup clean_dist python setup.py sdist clean: clean_dist echo "clean" install: distro sudo checkinstall python setup.py install ros-rosinstall-generator-0.1.11/README.rst000066400000000000000000000010261247465744600202620ustar00rootroot00000000000000rosinstall_generator ==================== Code & tickets -------------- +----------------------+------------------------------------------------------------------+ | rosinstall_generator | http://github.com/ros-infrastructure/rosinstall_generator | +----------------------+------------------------------------------------------------------+ | Issues | http://github.com/ros-infrastructure/rosinstall_generator/issues | +----------------------+------------------------------------------------------------------+ ros-rosinstall-generator-0.1.11/bin/000077500000000000000000000000001247465744600173445ustar00rootroot00000000000000ros-rosinstall-generator-0.1.11/bin/rosinstall_generator000077500000000000000000000170711247465744600235400ustar00rootroot00000000000000#!/usr/bin/env python from __future__ import print_function import argparse import logging import os import sys import yaml from rosinstall_generator.generator import ARG_ALL_PACKAGES, ARG_CURRENT_ENVIRONMENT, generate_rosinstall, sort_rosinstall def _existing_directory(path): if not os.path.isdir(path): raise argparse.ArgumentTypeError("'%s' is not an existing directory" % path) return path def main(argv=sys.argv[1:]): distro_name = os.environ['ROS_DISTRO'] if 'ROS_DISTRO' in os.environ else None parser = argparse.ArgumentParser( description='Generate a .rosinstall file for a set of packages.') parser.add_argument('--debug', action='store_true', default=False, help='Print debug information about fetching the ROS distribution files to stderr') parser.add_argument('--verbose', action='store_true', default=False, help='Print verbose information to stderr') parser.add_argument('--rosdistro', required=distro_name is None, default=distro_name, help='The ROS distro (default: environment variable ROS_DISTRO if defined)') parser.add_argument('package_names', nargs='*', metavar='pkgname', help="catkin package names, rosbuild stack names or variant names. Use '%s' to specify all packages available in the current environment. Use '%s' to specify all release packages (only usable as a single argument)." % (ARG_CURRENT_ENVIRONMENT, ARG_ALL_PACKAGES)) parser.add_argument('--from-path', type=_existing_directory, nargs='*', help="Add a set of catkin packages found recursively under the given path as if they would have been passed as 'package_names'.") parser.add_argument('--repos', nargs='*', metavar='reponame', help='Repository names containing catkin packages.') group = parser.add_mutually_exclusive_group() group.add_argument('--upstream', action='store_true', default=False, help='Fetch the release tag of catkin packages from the upstream repo instead of the gbp. Note that this implies always fetching the whole repository which might contain additional (unreleased) packages.') group.add_argument('--upstream-development', action='store_true', default=False, help='Fetch the development version of catkin packages from the upstream repo instead of the gbp. Be aware that the development version might not even be intended to build between releases. Note that this implies always fetching the whole repository which might contain additional (unreleased) packages.') group = parser.add_mutually_exclusive_group() group.add_argument('--deps', action='store_true', default=False, help='Include recursive dependencies') group.add_argument('--deps-up-to', nargs='*', help="A set of packages which will limit the recursive dependencies to packages which (in-)directly depend on a package in this set. Use '%s' to specify all packages available in the current environment." % ARG_CURRENT_ENVIRONMENT) # implies either --deps or --deps-up-to parser.add_argument('--deps-depth', type=int, metavar='N', help='Limit recursive dependencies to a specific level (not supported on Groovy).') parser.add_argument('--deps-only', action='store_true', default=False, help='Include only the recursive dependencies but not the specified packages') group = parser.add_mutually_exclusive_group() group.add_argument('--wet-only', action='store_true', default=False, help='Only include catkin packages') group.add_argument('--dry-only', action='store_true', default=False, help='Only include rosbuild stacks') group.add_argument('--catkin-only', action='store_true', default=False, help="Only wet packages with build type 'catkin'") group.add_argument('--non-catkin-only', action='store_true', default=False, help="Only wet packages with build type other than 'catkin'") parser.add_argument('--exclude', nargs='*', help="Exclude a set of packages (also skips further recursive dependencies). Use '%s' to specify all packages available in the current environment." % ARG_CURRENT_ENVIRONMENT) parser.add_argument('--exclude-path', type=_existing_directory, nargs='*', help='Exclude a set of catkin packages found recursively under the given path (also skips further recursive dependencies).') parser.add_argument('--flat', action='store_true', default=False, help='Use a flat folder structure without a parent folder names after the repository containing the catkin packages') parser.add_argument('--tar', action='store_true', default=False, help='Use tarballs instead of repositories for catkin packages (rosbuild stacks are always tarballs)') args = parser.parse_args(argv) # check for invalid combinations if args.rosdistro == 'groovy' and args.deps_depth: parser.error("Option '--deps-depth N' is not available for the ROS distro 'groovy'") if args.rosdistro != 'groovy': if args.dry_only: parser.error("For the ROS distro '%s' there are no rosbuild released packages so '--dry-only' is not a valid option" % args.rosdistro) args.wet_only = True if not args.package_names and not args.from_path and not args.repos: parser.error('Either some package names must be specified, some --from-path or some repository names using --repos') if ARG_ALL_PACKAGES in args.package_names and (len(args.package_names) > 1 or args.repos): parser.error("When using '%s' as a package name no other names can be specified" % ARG_ALL_PACKAGES) if not args.deps and not args.deps_up_to: if args.deps_depth: parser.error("Option '--deps-depth N' can only be used together with either '--deps' or '--deps-up-to'") if args.deps_only: parser.error("Option '--deps-only' can only be used together with either '--deps' or '--deps-up-to'") if args.deps_depth is not None and args.deps_depth < 1: parser.error("The argument 'N' to the option '--deps-depth ' must be a positive integer") if args.catkin_only or args.non_catkin_only: args.wet_only = True # pass all logging output to stderr logger = logging.getLogger('rosinstall_generator') logger.addHandler(logging.StreamHandler(sys.stderr)) verbose_level = logging.DEBUG if args.verbose else logging.INFO logger.setLevel(verbose_level) debug_level = logging.DEBUG if args.debug else logging.INFO logger = logging.getLogger('rosinstall_generator.dry') logger.setLevel(debug_level) logger = logging.getLogger('rosinstall_generator.wet') logger.setLevel(debug_level) if '--rosdistro' not in argv: print('Using ROS_DISTRO: %s' % args.rosdistro, file=sys.stderr) try: rosinstall_data = generate_rosinstall(args.rosdistro, args.package_names, from_paths=args.from_path, repo_names=args.repos, deps=args.deps, deps_up_to=args.deps_up_to, deps_depth=args.deps_depth, deps_only=args.deps_only, wet_only=args.wet_only, dry_only=args.dry_only, catkin_only=args.catkin_only, non_catkin_only=args.non_catkin_only, excludes=args.exclude, exclude_paths=args.exclude_path, flat=args.flat, tar=args.tar, upstream_version_tag=args.upstream, upstream_source_version=args.upstream_development) except RuntimeError as e: if args.debug: raise print(str(e), file=sys.stderr) return 1 rosinstall_data = sort_rosinstall(rosinstall_data) print(yaml.safe_dump(rosinstall_data, default_flow_style=False)) return 0 if __name__ == '__main__': rc = main() sys.exit(rc) ros-rosinstall-generator-0.1.11/setup.py000077500000000000000000000020731247465744600203130ustar00rootroot00000000000000#!/usr/bin/env python import os from setuptools import setup, find_packages exec(open(os.path.join(os.path.dirname(__file__), 'src', 'rosinstall_generator', '__init__.py')).read()) setup( name='rosinstall_generator', version=__version__, install_requires=['argparse', 'catkin_pkg >= 0.1.28', 'distribute', 'rosdistro >= 0.3.4', 'rospkg', 'PyYAML'], packages=find_packages('src'), package_dir={'': 'src'}, scripts=['bin/rosinstall_generator'], author='Dirk Thomas', author_email='dthomas@osrfoundation.org', maintainer='Dirk Thomas', maintainer_email='dthomas@osrfoundation.org', url='http://wiki.ros.org/rosinstall_generator', download_url='http://download.ros.org/downloads/rosinstall_generator/', keywords=['ROS'], classifiers=['Programming Language :: Python', 'License :: OSI Approved :: BSD License', 'License :: OSI Approved :: MIT License'], description="A tool to generator rosinstall files", long_description="""A tool to generator rosinstall files""", license='BSD' ) ros-rosinstall-generator-0.1.11/setup.sh000066400000000000000000000001041247465744600202630ustar00rootroot00000000000000export PATH=`pwd`/bin:$PATH export PYTHONPATH=`pwd`/src:$PYTHONPATH ros-rosinstall-generator-0.1.11/src/000077500000000000000000000000001247465744600173635ustar00rootroot00000000000000ros-rosinstall-generator-0.1.11/src/rosinstall_generator/000077500000000000000000000000001247465744600236235ustar00rootroot00000000000000ros-rosinstall-generator-0.1.11/src/rosinstall_generator/__init__.py000066400000000000000000000033161247465744600257370ustar00rootroot00000000000000# Software License Agreement (BSD License) # # Copyright (c) 2013, Open Source Robotics Foundation, 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 notice, this list of conditions and the following # disclaimer in the documentation and/or other materials provided # with the distribution. # * Neither the name of Open Source Robotics Foundation, 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 ARE DISCLAIMED. IN NO EVENT SHALL THE # COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. """ Library to generate rosinstall file for set of packages/stacks. """ __version__ = '0.1.11' ros-rosinstall-generator-0.1.11/src/rosinstall_generator/distro.py000066400000000000000000000136651247465744600255140ustar00rootroot00000000000000# Software License Agreement (BSD License) # # Copyright (c) 2013, Open Source Robotics Foundation, 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 notice, this list of conditions and the following # disclaimer in the documentation and/or other materials provided # with the distribution. # * Neither the name of Open Source Robotics Foundation, 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 ARE DISCLAIMED. IN NO EVENT SHALL THE # COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. import logging import os import sys from rosdistro import get_cached_distribution, get_index, get_index_url from rosdistro.dependency_walker import DependencyWalker from rosdistro.manifest_provider import get_release_tag def get_distro(distro_name): index = get_index(get_index_url()) return get_cached_distribution(index, distro_name) def get_package_names(distro): released_names = [] unreleased_names = [] for pkg_name, pkg in distro.release_packages.items(): repo = distro.repositories[pkg.repository_name].release_repository if repo: if repo.version is not None: released_names.append(pkg_name) else: unreleased_names.append(pkg_name) return released_names, unreleased_names # redirect all output to logger class CustomLogger(object): def __init__(self): self.logger = logging.getLogger('rosinstall_generator.wet') self.linebuf = '' def write(self, buf): for line in buf.rstrip().splitlines(): self.logger.log(logging.DEBUG, line.rstrip()) def get_recursive_dependencies(distro, package_names, excludes=None, limit_depth=None): excludes = set(excludes or []) dependencies = set([]) walker = DependencyWalker(distro) # redirect all stderr output to logger stderr = sys.stderr sys.stderr = CustomLogger() try: for pkg_name in package_names: try: dependencies |= walker.get_recursive_depends(pkg_name, ['buildtool', 'build', 'run', 'test'], ros_packages_only=True, ignore_pkgs=dependencies | excludes, limit_depth=limit_depth) except AssertionError as e: raise RuntimeError("Failed to fetch recursive dependencies of package '%s': %s" % (pkg_name, e)) finally: sys.stderr = stderr dependencies -= set(package_names) return dependencies def get_recursive_dependencies_on(distro, package_names, excludes=None, limit=None): excludes = set(excludes or []) limit = set(limit or []) # to improve performance limit search space if possible if limit: released_names, _ = get_package_names(distro) excludes.update(set(released_names) - limit - set(package_names)) dependencies = set([]) walker = DependencyWalker(distro) # redirect all stderr output to logger stderr = sys.stderr sys.stderr = CustomLogger() try: for pkg_name in package_names: dependencies |= walker.get_recursive_depends_on(pkg_name, ['buildtool', 'build', 'run', 'test'], ignore_pkgs=dependencies | excludes) finally: sys.stderr = stderr dependencies -= set(package_names) return dependencies def generate_rosinstall(distro, package_names, flat=False, tar=False): rosinstall_data = [] for pkg_name in package_names: rosinstall_data.extend(_generate_rosinstall_for_package(distro, pkg_name, flat=flat, tar=tar)) return rosinstall_data def _generate_rosinstall_for_package(distro, pkg_name, flat=False, tar=False): pkg = distro.release_packages[pkg_name] repo = distro.repositories[pkg.repository_name].release_repository assert repo is not None and repo.version is not None, 'Package "%s" does not have a version"' % pkg_name local_name = pkg_name if not flat and repo.package_names != [pkg_name]: local_name = '%s/%s' % (repo.name, local_name) release_tag = get_release_tag(repo, pkg_name) return _generate_rosinstall(local_name, repo.url, release_tag, tar=tar) def _generate_rosinstall(local_name, url, release_tag, tar=False): if tar: # the repository name might be different than repo.name coming from rosdistro repo_name = os.path.basename(url[:-4]) suffix = '.git' if not url.endswith(suffix): raise RuntimeError("The repository '%s' must end with '%s': %s" % (repo_name, suffix, url)) url = url[:-len(suffix)] + '/archive/{0}.tar.gz'.format(release_tag) data = [{ 'tar': { 'local-name': local_name, 'uri': url, 'version': '{0}-{1}'.format(repo_name, release_tag.replace('/', '-')) } }] else: data = [{ 'git': { 'local-name': local_name, 'uri': url, 'version': release_tag } }] return data ros-rosinstall-generator-0.1.11/src/rosinstall_generator/dry_distro.py000066400000000000000000000121461247465744600263630ustar00rootroot00000000000000# Software License Agreement (BSD License) # # Copyright (c) 2013, Open Source Robotics Foundation, 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 notice, this list of conditions and the following # disclaimer in the documentation and/or other materials provided # with the distribution. # * Neither the name of Open Source Robotics Foundation, 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 ARE DISCLAIMED. IN NO EVENT SHALL THE # COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. import logging import rospkg.distro as rosdistro try: from urllib.error import URLError except ImportError: from urllib2 import URLError import yaml from rosdistro.loader import load_url logger = logging.getLogger('rosinstall_generator.dry') def get_distro(distro_name): return rosdistro.load_distro(rosdistro.distro_uri(distro_name)) def get_stack_names(distro): released_names = [] unreleased_names = [] for stack_name, stack in distro.stacks.items(): if stack.version: released_names.append(stack_name) else: unreleased_names.append(stack_name) return released_names, unreleased_names def get_recursive_dependencies(distro, stack_names, excludes=None): excludes = set(excludes or []) dry_dependencies = set(stack_names) wet_dependencies = set([]) traverse_stacks = set(stack_names) while traverse_stacks: stack_name = traverse_stacks.pop() info = _get_stack_info(distro, stack_name) if 'depends' in info: for depend in info['depends']: if depend in excludes: continue if depend in distro.stacks: if depend not in dry_dependencies: dry_dependencies.add(depend) traverse_stacks.add(depend) else: wet_dependencies.add(depend) return dry_dependencies, wet_dependencies def get_recursive_dependencies_on(distro, stack_names, excludes=None, limit=None): excludes = set(excludes or []) limit = set(limit or []) # to improve performance limit search space if possible if limit: released_names, _ = get_stack_names(distro) excludes.update(set(released_names) - limit - set(stack_names)) depends_on = set([]) stacks_to_check = set(stack_names) while stacks_to_check: next_stack_to_check = stacks_to_check.pop() deps = _get_dependencies_on(distro, next_stack_to_check, ignore_stacks=excludes) new_deps = deps - depends_on stacks_to_check |= new_deps depends_on |= new_deps return depends_on def _get_dependencies_on(distro, stack_name, ignore_stacks=None): ignore_stacks = ignore_stacks or [] depends_on = set([]) for name, stack in distro.stacks.items(): if name in ignore_stacks or not stack.version: continue info = _get_stack_info(distro, name) if 'depends' in info: if stack_name in info['depends']: depends_on.add(name) return depends_on _stack_info = {} def _get_stack_info(distro, stack_name): global _stack_info if stack_name not in _stack_info: stack = distro.stacks[stack_name] version = stack.version url = 'http://ros-dry-releases.googlecode.com/svn/download/stacks/%(stack_name)s/%(stack_name)s-%(version)s/%(stack_name)s-%(version)s.yaml' % locals() logger.debug('Load dry package info from "%s"' % url) try: data = load_url(url) except URLError as e: raise RuntimeError("Could not fetch information for stack '%s' with version '%s': %s" % (stack_name, version, e)) _stack_info[stack_name] = yaml.load(data) return _stack_info[stack_name] def generate_rosinstall(distro, stack_names): rosinstall_data = [] for stack_name in stack_names: rosinstall_data.extend(distro.stacks[stack_name].vcs_config.to_rosinstall(stack_name, branch='release-tar', anonymous=True)) return rosinstall_data ros-rosinstall-generator-0.1.11/src/rosinstall_generator/generator.py000066400000000000000000000526561247465744600262010ustar00rootroot00000000000000# Software License Agreement (BSD License) # # Copyright (c) 2013, Open Source Robotics Foundation, 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 notice, this list of conditions and the following # disclaimer in the documentation and/or other materials provided # with the distribution. # * Neither the name of Open Source Robotics Foundation, 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 ARE DISCLAIMED. IN NO EVENT SHALL THE # COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. from __future__ import print_function import copy import logging import os from catkin_pkg.package import InvalidPackage, parse_package_string from catkin_pkg.packages import find_packages_allowing_duplicates from rospkg import RosPack, RosStack from rospkg.environment import ROS_PACKAGE_PATH from rosinstall_generator.distro import get_distro as _get_wet_distro from rosinstall_generator.distro import generate_rosinstall as generate_wet_rosinstall from rosinstall_generator.distro import get_recursive_dependencies as get_recursive_dependencies_of_wet from rosinstall_generator.distro import get_recursive_dependencies_on as get_recursive_dependencies_on_of_wet from rosinstall_generator.distro import get_package_names from rosinstall_generator.distro import _generate_rosinstall from rosinstall_generator.dry_distro import get_distro as _get_dry_distro from rosinstall_generator.dry_distro import generate_rosinstall as generate_dry_rosinstall from rosinstall_generator.dry_distro import get_recursive_dependencies as get_recursive_dependencies_of_dry from rosinstall_generator.dry_distro import get_recursive_dependencies_on as get_recursive_dependencies_on_of_dry from rosinstall_generator.dry_distro import get_stack_names logger = logging.getLogger('rosinstall_generator') ARG_ALL_PACKAGES = 'ALL' ARG_CURRENT_ENVIRONMENT = 'RPP' def _split_special_keywords(names): non_keyword_names = set(names) keywords = set([]) if ARG_ALL_PACKAGES in names: non_keyword_names.remove(ARG_ALL_PACKAGES) keywords.add(ARG_ALL_PACKAGES) if ARG_CURRENT_ENVIRONMENT in names: non_keyword_names.remove(ARG_CURRENT_ENVIRONMENT) keywords.add(ARG_CURRENT_ENVIRONMENT) return non_keyword_names, keywords def _classify_repo_names(distro_name, repo_names): names = set([]) unknown_names = set([]) if repo_names: wet_distro = get_wet_distro(distro_name) for repo_name in repo_names: if repo_name in wet_distro.repositories: names.add(repo_name) else: unknown_names.add(repo_name) return names, unknown_names def _get_packages_for_repos(distro_name, repo_names): package_names = set([]) unreleased_repo_names = set([]) wet_distro = get_wet_distro(distro_name) for repo_name in repo_names: release_repo = wet_distro.repositories[repo_name].release_repository if release_repo: package_names.update(release_repo.package_names) else: unreleased_repo_names.add(repo_name) return package_names, unreleased_repo_names def _classify_names(distro_name, names): unknown_names = set(names or []) wet_package_names = set([]) dry_stack_names = set([]) variant_names = set([]) # identify wet packages if unknown_names: wet_distro = get_wet_distro(distro_name) for name in unknown_names: if name in wet_distro.release_packages: wet_package_names.add(name) unknown_names -= wet_package_names if distro_name == 'groovy': # identify dry stacks/variants if unknown_names: dry_distro = get_dry_distro(distro_name) for name in unknown_names: if name in dry_distro.get_stacks(released=True): dry_stack_names.add(name) if name in dry_distro.variants: variant_names.add(name) unknown_names -= dry_stack_names unknown_names -= variant_names # resolve variant names into wet package names or dry stack names if variant_names: wet_distro = get_wet_distro(distro_name) for variant_name in variant_names: variant_depends = dry_distro.variants[variant_name].get_stack_names() for depend in variant_depends: if depend in wet_distro.release_packages: wet_package_names.add(depend) elif depend in dry_distro.stacks: dry_stack_names.add(depend) else: raise RuntimeError("The following dependency of variant '%s' could not be found: %s" % (variant_name, depend)) return Names(wet_package_names, dry_stack_names), unknown_names def generate_rosinstall_for_repos(repos, version_tag=True, tar=False): rosinstall_data = [] for repo in repos.values(): if version_tag: version = repo.release_repository.version.split('-')[0] else: version = repo.source_repository.version rosinstall_data += _generate_rosinstall(repo.name, repo.source_repository.url, version, tar=tar) return rosinstall_data class Names(object): ''' Stores wet package names and dry stack names. ''' def __init__(self, wet_package_names, dry_stack_names): self.wet_package_names = set(wet_package_names) self.dry_stack_names = set(dry_stack_names) def update(self, other): self.wet_package_names.update(other.wet_package_names) self.dry_stack_names.update(other.dry_stack_names) def _expand_keywords(distro_name, keywords): names = set([]) if ARG_ALL_PACKAGES in keywords: wet_distro = get_wet_distro(distro_name) released_package_names, _ = get_package_names(wet_distro) names.update(released_package_names) if distro_name == 'groovy': dry_distro = get_dry_distro(distro_name) released_stack_names, _ = get_stack_names(dry_distro) names.update(released_stack_names) if ARG_CURRENT_ENVIRONMENT in keywords: names.update(_get_packages_in_environment()) return names _packages_in_environment = None def _get_packages_in_environment(): global _packages_in_environment if _packages_in_environment is None: if ROS_PACKAGE_PATH not in os.environ or not os.environ[ROS_PACKAGE_PATH]: raise RuntimeError("The environment variable '%s' must be set when using '%s'" % (ROS_PACKAGE_PATH, ARG_CURRENT_ENVIRONMENT)) _packages_in_environment = set([]) rs = RosStack() _packages_in_environment.update(set(rs.list())) rp = RosPack() _packages_in_environment.update(set(rp.list())) return _packages_in_environment def _get_package_names(path): return set([pkg.name for _, pkg in find_packages_allowing_duplicates(path).items()]) _wet_distro = None _dry_distro = None def get_wet_distro(distro_name): global _wet_distro if _wet_distro is None: _wet_distro = _get_wet_distro(distro_name) return _wet_distro def get_dry_distro(distro_name): global _dry_distro if _dry_distro is None and distro_name == 'groovy': _dry_distro = _get_dry_distro(distro_name) return _dry_distro def generate_rosinstall(distro_name, names, from_paths=None, repo_names=None, deps=False, deps_up_to=None, deps_depth=None, deps_only=False, wet_only=False, dry_only=False, catkin_only=False, non_catkin_only=False, excludes=None, exclude_paths=None, flat=False, tar=False, upstream_version_tag=False, upstream_source_version=False): # classify package/stack names names, keywords = _split_special_keywords(names) # find packages recursively in include paths if from_paths: include_names_from_path = set([]) [include_names_from_path.update(_get_package_names(from_path)) for from_path in from_paths] logger.debug("The following wet packages found in '--from-path' will be considered: %s" % ', '.join(sorted(include_names_from_path))) names.update(include_names_from_path) # expand repository names into package names repo_names, unknown_repo_names = _classify_repo_names(distro_name, repo_names) if unknown_repo_names: logger.warn('The following unknown repositories will be ignored: %s' % (', '.join(sorted(unknown_repo_names)))) wet_package_names, unreleased_repo_names = _get_packages_for_repos(distro_name, repo_names) names.update(wet_package_names) if unreleased_repo_names and not upstream_version_tag and not upstream_source_version: logger.warn('The following unreleased repositories will be ignored: %s' % ', '.join(sorted(unreleased_repo_names))) if unreleased_repo_names and (deps or deps_up_to) and (upstream_version_tag or upstream_source_version): logger.warn('The dependencies of the following unreleased repositories are unknown and will be ignored: %s' % ', '.join(sorted(unreleased_repo_names))) has_repos = ((repo_names - unreleased_repo_names) and (upstream_version_tag or upstream_source_version)) or (unreleased_repo_names and upstream_source_version) names, unknown_names = _classify_names(distro_name, names) if unknown_names: logger.warn('The following not released packages/stacks will be ignored: %s' % (', '.join(sorted(unknown_names)))) if keywords: expanded_names, unknown_names = _classify_names(distro_name, _expand_keywords(distro_name, keywords)) if unknown_names: logger.warn('The following not released packages/stacks from the %s will be ignored: %s' % (ROS_PACKAGE_PATH, ', '.join(sorted(unknown_names)))) names.update(expanded_names) if not names.wet_package_names and not names.dry_stack_names and not has_repos: raise RuntimeError('No packages/stacks left after ignoring not released') if names.wet_package_names or names.dry_stack_names: logger.debug('Packages/stacks: %s' % ', '.join(sorted(names.wet_package_names | names.dry_stack_names))) if unreleased_repo_names: logger.debug('Unreleased repositories: %s' % ', '.join(sorted(unreleased_repo_names))) # classify deps-up-to deps_up_to_names, keywords = _split_special_keywords(deps_up_to or []) deps_up_to_names, unknown_names = _classify_names(distro_name, deps_up_to_names) if unknown_names: logger.warn("The following not released '--deps-up-to' packages/stacks will be ignored: %s" % (', '.join(sorted(unknown_names)))) if keywords: expanded_names, unknown_names = _classify_names(distro_name, _expand_keywords(distro_name, keywords)) if unknown_names: logger.warn("The following not released '--deps-up-to' packages/stacks from the %s will be ignored: %s" % (ROS_PACKAGE_PATH, ', '.join(sorted(unknown_names)))) deps_up_to_names.update(expanded_names) if deps_up_to: logger.debug('Dependencies up to: %s' % ', '.join(sorted(deps_up_to_names.wet_package_names | deps_up_to_names.dry_stack_names))) # classify excludes exclude_names, keywords = _split_special_keywords(excludes or []) if exclude_paths: exclude_names_from_path = set([]) [exclude_names_from_path.update(_get_package_names(exclude_path)) for exclude_path in exclude_paths] logger.debug("The following wet packages found in '--exclude-path' will be excluded: %s" % ', '.join(sorted(exclude_names_from_path))) exclude_names.update(exclude_names_from_path) exclude_names, unknown_names = _classify_names(distro_name, exclude_names) if unknown_names: logger.warn("The following not released '--exclude' packages/stacks will be ignored: %s" % (', '.join(sorted(unknown_names)))) if keywords: expanded_names, unknown_names = _classify_names(distro_name, _expand_keywords(distro_name, keywords)) exclude_names.update(expanded_names) if excludes: logger.debug('Excluded packages/stacks: %s' % ', '.join(sorted(exclude_names.wet_package_names | exclude_names.dry_stack_names))) result = copy.deepcopy(names) # clear wet packages if not requested if dry_only: result.wet_package_names.clear() # clear dry packages if not requested and no dependencies if wet_only and not deps and not deps_up_to: result.dry_stack_names.clear() # remove excluded names from the list of wet and dry names result.wet_package_names -= exclude_names.wet_package_names result.dry_stack_names -= exclude_names.dry_stack_names if not result.wet_package_names and not result.dry_stack_names and not has_repos: raise RuntimeError('No packages/stacks left after applying the exclusions') if result.wet_package_names: logger.debug('Wet packages: %s' % ', '.join(sorted(result.wet_package_names))) if result.dry_stack_names: logger.debug('Dry stacks: %s' % ', '.join(sorted(result.dry_stack_names))) # extend the names with recursive dependencies if deps or deps_up_to: # add dry dependencies if result.dry_stack_names: dry_distro = get_dry_distro(distro_name) _, unreleased_stack_names = get_stack_names(dry_distro) excludes = exclude_names.dry_stack_names | deps_up_to_names.dry_stack_names | set(unreleased_stack_names) dry_dependencies, wet_dependencies = get_recursive_dependencies_of_dry(dry_distro, result.dry_stack_names, excludes=excludes) logger.debug('Dry stacks including dependencies: %s' % ', '.join(sorted(dry_dependencies))) result.dry_stack_names |= dry_dependencies if not dry_only: # add wet dependencies of dry stuff logger.debug('Wet dependencies of dry stacks: %s' % ', '.join(sorted(wet_dependencies))) for depend in wet_dependencies: if depend in exclude_names.wet_package_names or depend in deps_up_to_names.wet_package_names: continue wet_distro = get_wet_distro(distro_name) assert depend in wet_distro.release_packages, "Package '%s' does not have a version" % depend result.wet_package_names.add(depend) # add wet dependencies if result.wet_package_names: wet_distro = get_wet_distro(distro_name) _, unreleased_package_names = get_package_names(wet_distro) excludes = exclude_names.wet_package_names | deps_up_to_names.wet_package_names | set(unreleased_package_names) result.wet_package_names |= get_recursive_dependencies_of_wet(wet_distro, result.wet_package_names, excludes=excludes, limit_depth=deps_depth) logger.debug('Wet packages including dependencies: %s' % ', '.join(sorted(result.wet_package_names))) # intersect result with recursive dependencies on if deps_up_to: # intersect with wet dependencies on if deps_up_to_names.wet_package_names: wet_distro = get_wet_distro(distro_name) # wet depends on do not include the names since they are excluded to stop recursion asap wet_package_names = get_recursive_dependencies_on_of_wet(wet_distro, deps_up_to_names.wet_package_names, excludes=names.wet_package_names, limit=result.wet_package_names) # keep all names which are already in the result set wet_package_names |= result.wet_package_names & names.wet_package_names result.wet_package_names = wet_package_names else: result.wet_package_names.clear() logger.debug('Wet packages after intersection: %s' % ', '.join(sorted(result.wet_package_names))) # intersect with dry dependencies on dry_dependency_names = result.wet_package_names | deps_up_to_names.dry_stack_names if dry_dependency_names and not wet_only: dry_distro = get_dry_distro(distro_name) # dry depends on do not include the names since they are excluded to stop recursion asap dry_stack_names = get_recursive_dependencies_on_of_dry(dry_distro, dry_dependency_names, excludes=names.dry_stack_names, limit=result.dry_stack_names) # keep all names which are already in the result set dry_stack_names |= result.dry_stack_names & names.dry_stack_names result.dry_stack_names = dry_stack_names else: result.dry_stack_names.clear() logger.debug('Dry stacks after intersection: %s' % ', '.join(sorted(result.dry_stack_names))) # exclude passed in names if deps_only: result.wet_package_names -= set(names.wet_package_names) result.dry_stack_names -= set(names.dry_stack_names) # exclude wet packages based on build type if catkin_only or non_catkin_only: wet_distro = get_wet_distro(distro_name) for pkg_name in list(result.wet_package_names): pkg_xml = wet_distro.get_release_package_xml(pkg_name) try: pkg = parse_package_string(pkg_xml) except InvalidPackage as e: logger.warn("The package '%s' has an invalid manifest and will be ignored: %s" % (pkg_name, e)) result.wet_package_names.remove(pkg_name) continue build_type = ([e.content for e in pkg.exports if e.tagname == 'build_type'][0]) if 'build_type' in [e.tagname for e in pkg.exports] else 'catkin' if catkin_only ^ (build_type == 'catkin'): result.wet_package_names.remove(pkg_name) # get wet and/or dry rosinstall data rosinstall_data = [] if not dry_only and (result.wet_package_names or has_repos): wet_distro = get_wet_distro(distro_name) if upstream_version_tag or upstream_source_version: # determine repositories based on package names and passed in repository names repos = {} for pkg_name in result.wet_package_names: pkg = wet_distro.release_packages[pkg_name] if pkg.repository_name not in repos: repo = wet_distro.repositories[pkg.repository_name] release_repo = repo.release_repository assert not upstream_version_tag or release_repo.version is not None, "Package '%s' in repository '%s' does not have a release version" % (pkg_name, pkg.repository_name) repos[pkg.repository_name] = repo for repo_name in repo_names: if repo_name not in repos: repos[repo_name] = wet_distro.repositories[repo_name] # ignore repos which lack information repos_without_source = [repo_name for repo_name, repo in repos.items() if not repo.source_repository] if repos_without_source: logger.warn('The following repositories with an unknown upstream will be ignored: %s' % ', '.join(sorted(repos_without_source))) [repos.pop(repo_name) for repo_name in repos_without_source] if upstream_version_tag: repos_without_release = [repo_name for repo_name, repo in repos.items() if not repo.release_repository or not repo.release_repository.version] if repos_without_release: logger.warn('The following repositories without a release will be ignored: %s' % ', '.join(sorted(repos_without_release))) [repos.pop(repo_name) for repo_name in repos_without_release] logger.debug('Generate rosinstall entries for wet repositories: %s' % ', '.join(sorted(repos.keys()))) wet_rosinstall_data = generate_rosinstall_for_repos(repos, version_tag=upstream_version_tag, tar=tar) rosinstall_data += wet_rosinstall_data else: logger.debug('Generate rosinstall entries for wet packages: %s' % ', '.join(sorted(result.wet_package_names))) wet_rosinstall_data = generate_wet_rosinstall(wet_distro, result.wet_package_names, flat=flat, tar=tar) rosinstall_data += wet_rosinstall_data if not wet_only and result.dry_stack_names: logger.debug('Generate rosinstall entries for dry stacks: %s' % ', '.join(sorted(result.dry_stack_names))) dry_distro = get_dry_distro(distro_name) dry_rosinstall_data = generate_dry_rosinstall(dry_distro, result.dry_stack_names) rosinstall_data += dry_rosinstall_data return rosinstall_data def sort_rosinstall(rosinstall_data): def _rosinstall_key(item): key = list(item.keys())[0] return item[key]['local-name'] return sorted(rosinstall_data, key=_rosinstall_key) ros-rosinstall-generator-0.1.11/stdeb.cfg000077500000000000000000000006301247465744600203600ustar00rootroot00000000000000[DEFAULT] Depends: python-argparse, python-catkin-pkg (>= 0.1.28), python-rosdistro (>= 0.3.4), python-rospkg, python-yaml Depends3: python3-catkin-pkg (>= 0.1.28), python3-rosdistro (>= 0.3.4), python3-rospkg, python3-yaml Conflicts: python3-rosinstall-generator Conflicts3: python-rosinstall-generator Suite: oneiric precise quantal raring saucy trusty utopic vivid wheezy jessie X-Python3-Version: >= 3.2