Exemplo n.º 1
0
    def create_prefix_script(self, prefix_path, merge_install):  # noqa: D102
        prefix_env_path = prefix_path / 'local_setup.sh'
        logger.info("Creating prefix script '%s'" % prefix_env_path)
        expand_template(
            Path(__file__).parent / 'template' / 'prefix.sh.em',
            prefix_env_path,
            {
                'prefix_path': prefix_path,
                'python_executable': sys.executable,
                'merge_install': merge_install,
                'package_script_no_ext': 'package',
            })
        shutil.copy(
            str(self._get_prefix_util_path()),
            str(prefix_path / '_local_setup_util.py'))

        prefix_chain_env_path = prefix_path / 'setup.sh'
        logger.info(
            "Creating prefix chain script '%s'" % prefix_chain_env_path)
        expand_template(
            Path(__file__).parent / 'template' / 'prefix_chain.sh.em',
            prefix_chain_env_path,
            {
                'prefix_path': prefix_path,
                'chained_prefix_path': get_chained_prefix_path(
                    skip=prefix_path),
                'prefix_script_no_ext': 'local_setup',
            })
Exemplo n.º 2
0
    def create_prefix_script(self, prefix_path, merge_install):  # noqa: D102
        prefix_env_path = prefix_path / 'local_setup.bat'
        logger.info("Creating prefix script '%s'" % prefix_env_path)
        expand_template(
            Path(__file__).parent / 'template' / 'prefix.bat.em',
            prefix_env_path, {
                'python_executable': sys.executable,
                'merge_install': merge_install,
                'package_script_no_ext': 'package',
            })

        prefix_util_path = prefix_path / '_local_setup_util_bat.py'
        logger.info("Creating prefix util module '%s'" % prefix_util_path)
        expand_template(self._get_prefix_util_template_path(),
                        prefix_util_path, {'shell_extension': self})

        prefix_chain_env_path = prefix_path / 'setup.bat'
        logger.info("Creating prefix chain script '%s'" %
                    prefix_chain_env_path)
        expand_template(
            Path(__file__).parent / 'template' / 'prefix_chain.bat.em',
            prefix_chain_env_path, {
                'chained_prefix_path':
                get_chained_prefix_path(skip=prefix_path),
                'prefix_script_no_ext': 'local_setup',
            })
Exemplo n.º 3
0
    def create_prefix_script(self, prefix_path, merge_install):  # noqa: D102
        prefix_env_path = prefix_path / 'local_setup.bash'
        logger.info(
            "Creating prefix script '{prefix_env_path}'".format_map(locals()))
        expand_template(
            Path(__file__).parent / 'template' / 'prefix.bash.em',
            prefix_env_path,
            {
                'python_executable': sys.executable,
                'merge_install': merge_install,
                'package_script_no_ext': 'package',
            })
        # no need to copy prefix_util.py explicitly since bash relies on sh

        prefix_chain_env_path = prefix_path / 'setup.bash'
        logger.info(
            "Creating prefix chain script '{prefix_chain_env_path}'"
            .format_map(locals()))
        expand_template(
            Path(__file__).parent / 'template' / 'prefix_chain.bash.em',
            prefix_chain_env_path,
            {
                'chained_prefix_path': get_chained_prefix_path(
                    skip=prefix_path),
                'prefix_script_no_ext': 'local_setup',
            })
Exemplo n.º 4
0
def find_installed_packages_in_environment():
    """
    Find packages under the COLCON_PREFIX_PATH.

    For each prefix path the package index is being read and the first time a
    package is being found its install prefix is being added to the result.

    :returns: The mapping from a package name to the prefix path
    :rtype: OrderedDict
    """
    packages = OrderedDict()
    for prefix_path in get_chained_prefix_path():
        prefix_path = Path(prefix_path)
        pkgs = find_installed_packages(prefix_path)
        if pkgs is None:
            logger.debug("Ignoring prefix path '{prefix_path}'".format_map(
                locals()))
            continue
        for pkg_name in sorted(pkgs.keys()):
            # ignore packages with the same name in "lower" prefix path
            if pkg_name in packages:
                continue
            packages[pkg_name] = pkgs[pkg_name]
    return packages
Exemplo n.º 5
0
def test_get_chained_prefix_path():
    # empty environment variable
    with EnvironmentContext(COLCON_PREFIX_PATH=''):
        prefix_path = get_chained_prefix_path()
        assert prefix_path == []

    # extra path separator
    with EnvironmentContext(COLCON_PREFIX_PATH=os.pathsep):
        prefix_path = get_chained_prefix_path(skip='/path/to/skip')
        assert prefix_path == []

    ColconPrefixPath.PREFIX_PATH_NAME = 'colcon'
    with patch('colcon_core.prefix_path.get_prefix_path_extensions',
               return_value={
                   100: {
                       'colcon': ColconPrefixPath()
                   },
               }):
        with TemporaryDirectory(prefix='test_colcon_') as basepath:
            basepath = Path(basepath)
            with EnvironmentContext(COLCON_PREFIX_PATH=os.pathsep.join(
                [str(basepath), str(basepath)])):
                # multiple results, duplicates being skipped
                prefix_path = get_chained_prefix_path(skip='/path/to/skip')
                assert prefix_path == [str(basepath)]

                # skipping results
                prefix_path = get_chained_prefix_path(skip=str(basepath))
                assert prefix_path == []

            # skipping non-existing results
            with EnvironmentContext(COLCON_PREFIX_PATH=os.pathsep.join(
                [str(basepath),
                 str(basepath / 'non-existing-sub')])):
                with patch('colcon_core.prefix_path.colcon.logger.warning'
                           ) as warn:
                    prefix_path = get_chained_prefix_path()
                assert prefix_path == [str(basepath)]
                assert warn.call_count == 1
                assert len(warn.call_args[0]) == 1
                assert warn.call_args[0][0].endswith(
                    "non-existing-sub' in the environment variable "
                    "COLCON_PREFIX_PATH doesn't exist")
                # suppress duplicate warning
                with patch('colcon_core.prefix_path.colcon.logger.warning'
                           ) as warn:
                    prefix_path = get_chained_prefix_path()
                assert prefix_path == [str(basepath)]
                assert warn.call_count == 0

    with EntryPointContext(extension1=Extension1, extension2=Extension2):
        extensions = get_prefix_path_extensions()

        # one invalid return value, one not implemented
        extensions[100]['extension2'].extend_prefix_path = Mock(
            return_value=False)
        extensions[90]['extension1'].extend_prefix_path = Mock(
            return_value=None)
        with patch('colcon_core.prefix_path.logger.error') as error:
            get_chained_prefix_path()
        # the raised exception is catched and results in an error message
        assert error.call_count == 1
        assert len(error.call_args_list[0][0]) == 1
        assert error.call_args_list[0][0][0].startswith(
            "Exception in prefix path extension 'extension2': "
            'extend_prefix_path() should return None\n')
Exemplo n.º 6
0
    def main(self, *, context):  # noqa: D102
        check_and_mark_build_tool(context.args.build_base)
        check_and_mark_install_layout(context.args.install_base,
                                      merge_install=context.args.merge_install)

        self._create_paths(context.args)

        decorators = get_packages(
            context.args,
            additional_argument_names=self.task_argument_destinations,
            recursive_categories=('run', ))

        install_base = os.path.abspath(
            os.path.join(os.getcwd(), context.args.install_base))
        jobs, unselected_packages = self._get_jobs(context.args, decorators,
                                                   install_base)

        underlay_packages = {}
        for prefix_path in get_chained_prefix_path():
            packages = find_installed_packages(Path(prefix_path))
            if packages:
                for pkg, path in packages.items():
                    if pkg not in underlay_packages:
                        underlay_packages[pkg] = []
                    underlay_packages[pkg].append(str(path))

        override_messages = {}
        for overlay_package in jobs.keys():
            if overlay_package in underlay_packages:
                if overlay_package not in context.args.allow_overriding:
                    override_messages[overlay_package] = (
                        "'{overlay_package}'".format_map(locals()) +
                        ' is in: ' +
                        ', '.join(underlay_packages[overlay_package]))

        if override_messages:
            override_msg = (
                'Some selected packages are already built in one or more'
                ' underlay workspaces:'
                '\n\t' + '\n\t'.join(override_messages.values()) +
                '\nIf a package in a merged underlay workspace is overridden'
                ' and it installs headers, then all packages in the overlay'
                ' must sort their include directories by workspace order.'
                ' Failure to do so may result in build failures or undefined'
                ' behavior at run time.'
                '\nIf the overridden package is used by another package'
                ' in any underlay, then the overriding package in the'
                ' overlay must be API and ABI compatible or undefined'
                ' behavior at run time may occur.'
                '\n\nIf you understand the risks and want to override a'
                ' package anyways, add the following to the command'
                ' line:'
                '\n\t--allow-overriding ' +
                ' '.join(sorted(override_messages.keys())))

            logger.warn(override_msg +
                        '\n\nThis may be promoted to an error in a'
                        ' future release of colcon-core.')

        on_error = OnError.interrupt \
            if not context.args.continue_on_error else OnError.skip_downstream

        def post_unselected_packages(*, event_queue):
            nonlocal unselected_packages
            names = [pkg.name for pkg in unselected_packages]
            for name in sorted(names):
                event_queue.put((JobUnselected(name), None))

        rc = execute_jobs(context,
                          jobs,
                          on_error=on_error,
                          pre_execution_callback=post_unselected_packages)

        self._create_prefix_scripts(install_base, context.args.merge_install)

        return rc