diff --git a/README.md b/README.md index 71c1664..562b416 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,12 @@ # colcon-bundle [![GitHub Action Status][action-badge]][action-workflow] -**NOTE:** `colcon-bundle` only supports Ubuntu Xenial and Ubuntu Bionic operating systems and x86, ARMHF, and ARM64 architectures. All other operating systems and architectures are currently not supported. +**NOTE:** `colcon-bundle` only supports Ubuntu Xenial, Ubuntu Bionic, and Ubuntu Focla operating systems and x86, ARMHF, and ARM64 architectures. All other operating systems and architectures are currently not supported. This package is a plugin to [colcon-core](https://github.com/colcon/colcon-core.git). It provides functionality to bundle a built workspace. A bundle is a portable environment which can be moved to a different linux system and executed as if the contents of the bundle were installed locally. -Currently, ROS Kinetic is supported by installing the `colcon-ros-bundle` package. +Currently, ROS Kinetic, Noetic, and Foxy is supported by installing the `colcon-ros-bundle` package. # Installation @@ -26,7 +26,6 @@ sudo pip3 install colcon-ros-bundle 1. Add dependencies to the install list for each installer. 1. Run installs in the following order: 1. `apt` - 1. `pip` 1. `pip3` 1. Run the following transforms: 1. Update the shebangs of scripts to use `#!/usr/bin/env`. diff --git a/colcon_bundle/installer/pip.py b/colcon_bundle/installer/pip.py deleted file mode 100644 index 946b59c..0000000 --- a/colcon_bundle/installer/pip.py +++ /dev/null @@ -1,30 +0,0 @@ -# Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. -# SPDX-License-Identifier: Apache-2.0 - -import os - -from colcon_bundle.installer.base_pip_installer import \ - BasePipInstallerExtensionPoint - - -class PipBundleInstallerExtensionPoint(BasePipInstallerExtensionPoint): - """Python 2 pip installer.""" - - def add_arguments(self, *, parser): # noqa: D102 - parser.add_argument( - '--pip-args', - nargs='*', metavar='*', type=str.lstrip, - help='Pass arguments to CMake projects. ' - 'Arguments matching other options in colcon must be prefixed ' - 'by a space,\ne.g. --pip-args " --help"') - parser.add_argument( - '--pip-requirements', type=str, default=None, - help='Path to a requirements.txt. All packages in the file' - 'will be installed into Python2 in the bundle') - - def initialize(self, context): # noqa: D102 - super().initialize(context) - self._python_path = os.path.join( - self.context.prefix_path, 'usr', 'bin', 'python2') - self._pip_args = self.context.args.pip_args - self.additional_requirements = self.context.args.pip_requirements diff --git a/setup.cfg b/setup.cfg index 1107074..2f7158b 100644 --- a/setup.cfg +++ b/setup.cfg @@ -60,8 +60,7 @@ colcon_core.verb = bundle = colcon_bundle.verb.bundle:BundleVerb colcon_bundle.installer = apt = colcon_bundle.installer.apt:AptBundleInstallerExtension - pip = colcon_bundle.installer.pip:PipBundleInstallerExtensionPoint - pip3 = colcon_bundle.installer.pip3:Pip3BundleInstallerExtensionPoint + pip = colcon_bundle.installer.pip3:Pip3BundleInstallerExtensionPoint colcon_bundle.task.bundle = python = colcon_bundle.task.python.bundle:PythonBundleTask diff --git a/test/installer/test_pip_installer.py b/test/installer/test_pip_installer.py deleted file mode 100644 index c711a78..0000000 --- a/test/installer/test_pip_installer.py +++ /dev/null @@ -1,192 +0,0 @@ -from unittest.mock import patch, Mock, mock_open -from tempfile import mkdtemp -import shutil -import os - -from colcon_bundle.installer import BundleInstallerContext -from colcon_bundle.installer.pip import PipBundleInstallerExtensionPoint - - -def test_install_nothing(): - installer = PipBundleInstallerExtensionPoint() - cache_dir = mkdtemp() - prefix = mkdtemp() - context_args = Mock() - context_args.pip_requirements = None - context = BundleInstallerContext( - args=context_args, cache_path=cache_dir, prefix_path=prefix) - installer.initialize(context) - result = installer.install() - assert result == {'installed_packages': []} - - -@patch('subprocess.check_call') -@patch('subprocess.check_output') -def test_install(check_output, check_call): - installer = PipBundleInstallerExtensionPoint() - cache_dir = mkdtemp() - prefix = mkdtemp() - python_path = os.path.join(prefix, 'usr', 'bin', 'python2') - context_args = Mock() - context_args.pip_args = [] - context_args.pip_requirements = None - context = BundleInstallerContext( - args=context_args, cache_path=cache_dir, prefix_path=prefix) - check_output.return_value = 'pkg1==3.4.5\npkg2==3.1.2\n' - try: - installer.initialize(context) - installer.add_to_install_list('pkg1==3.4.5') - installer.add_to_install_list('pkg2>=3.1.2') - installer.add_to_install_list('remove_me') - installer.remove_from_install_list('remove_me') - result = installer.install() - - assert result == { - 'installed_packages': [ - { - 'name': 'pkg1', - 'version': '3.4.5' - }, - { - 'name': 'pkg2', - 'version': '3.1.2' - } - ] - } - finally: - shutil.rmtree(cache_dir) - shutil.rmtree(prefix) - - -@patch('subprocess.check_call') -@patch('subprocess.check_output') -def test_install_with_additional_arguments(check_output, check_call): - installer = PipBundleInstallerExtensionPoint() - cache_dir = mkdtemp() - prefix = mkdtemp() - python_path = os.path.join(prefix, 'usr', 'bin', 'python2') - context_args = Mock() - context_args.pip_args = [' --test-arg-1', '--test-arg-2'] - context_args.pip_requirements = None - context = BundleInstallerContext( - args=context_args, cache_path=cache_dir, prefix_path=prefix) - check_output.return_value = 'pkg1==3.4.5\npkg2==3.1.2\n' - try: - installer.initialize(context) - installer.add_to_install_list('pkg1==3.4.5') - installer.add_to_install_list('pkg2>=3.1.2') - installer.add_to_install_list('remove_me') - installer.remove_from_install_list('remove_me') - result = installer.install() - - assert result == { - 'installed_packages': [ - { - 'name': 'pkg1', - 'version': '3.4.5' - }, - { - 'name': 'pkg2', - 'version': '3.1.2' - } - ] - } - finally: - shutil.rmtree(cache_dir) - shutil.rmtree(prefix) - -@patch('subprocess.check_call') -@patch('subprocess.check_output') -def test_install_not_required(check_output, check_call): - installer = PipBundleInstallerExtensionPoint() - cache_dir = mkdtemp() - - prefix = mkdtemp() - python_path = os.path.join(prefix, 'usr', 'bin', 'python2') - context_args = Mock() - context_args.pip_args = [] - context_args.pip_requirements = None - context = BundleInstallerContext( - args=context_args, cache_path=cache_dir, prefix_path=prefix) - check_output.return_value = 'pkg1==3.4.5\npkg2==3.1.2\n' - try: - installer.initialize(context) - installer.add_to_install_list('pkg1==3.4.5') - installer.add_to_install_list('pkg2>=3.1.2') - installer.add_to_install_list('remove_me') - installer.remove_from_install_list('remove_me') - result = installer.install() - - assert result == { - 'installed_packages': [ - { - 'name': 'pkg1', - 'version': '3.4.5' - }, - { - 'name': 'pkg2', - 'version': '3.1.2' - } - ] - } - - result_2 = installer.install() - assert result == result_2 - # Verify we haven't called pip - assert check_call.call_count == 4 - # Verify we haven't called pip freeze - assert check_output.call_count == 1 - finally: - shutil.rmtree(cache_dir) - shutil.rmtree(prefix) - - -@patch('subprocess.check_call') -@patch('subprocess.check_output') -@patch('builtins.open', mock_open(read_data='rpkg==1.2.3')) -def test_install_addtional_requirements(check_output, check_call): - """ - This test should be mocking the read and write to the file - and then reading the requirements file. Instead I am just - checking the packages array after the install to verify - the "requrements.txt" was read and added to the list. - """ - installer = PipBundleInstallerExtensionPoint() - cache_dir = mkdtemp() - prefix = mkdtemp() - python_path = os.path.join(prefix, 'usr', 'bin', 'python2') - context_args = Mock() - context_args.pip_args = [] - context_args.pip_requirements = 'requirements.txt' - context = BundleInstallerContext( - args=context_args, cache_path=cache_dir, prefix_path=prefix) - check_output.return_value = 'pkg1==3.4.5\npkg2==3.1.2\nrpkg==1.2.3\n' - try: - installer.initialize(context) - installer.add_to_install_list('pkg1==3.4.5') - installer.add_to_install_list('pkg2==3.1.2') - - result = installer.install() - assert installer._packages == [ - 'pkg1==3.4.5', 'pkg2==3.1.2', 'rpkg==1.2.3' - ] - - assert result == { - 'installed_packages': [ - { - 'name': 'pkg1', - 'version': '3.4.5' - }, - { - 'name': 'pkg2', - 'version': '3.1.2' - }, - { - 'name': 'rpkg', - 'version': '1.2.3' - } - ] - } - finally: - shutil.rmtree(cache_dir) - shutil.rmtree(prefix)