async def generate_command_environment( self, task_name, build_base, dependencies, ): # noqa: D102 if sys.platform != 'win32': raise SkipExtensionException('Not usable on non-Windows systems') # check if all dependencies are available # removes dependencies available in the environment from the parameter check_dependency_availability( dependencies, script_filename='package.bat') hook_path = build_base / ('colcon_command_prefix_%s.bat' % task_name) expand_template( Path(__file__).parent / 'template' / 'command_prefix.bat.em', hook_path, {'dependencies': dependencies}) cmd = [str(hook_path), '&&', 'set'] env = await get_environment_variables(cmd, cwd=str(build_base)) # write environment variables to file for debugging env_path = build_base / ( 'colcon_command_prefix_%s.bat.env' % task_name) with env_path.open('w') as h: for key in sorted(env.keys()): value = env[key] h.write('{key}={value}\n'.format_map(locals())) return env
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', })
def create_package_script( # noqa: D102 self, prefix_path, pkg_name, hooks): pkg_env_path = prefix_path / 'share' / pkg_name / 'package.dsv' logger.info("Creating package descriptor '%s'" % pkg_env_path) expand_template( Path(__file__).parent / 'template' / 'package.dsv.em', pkg_env_path, { 'hooks': hooks, })
def create_hook_set_value( self, env_hook_name, prefix_path, pkg_name, name, value, ): # noqa: D102 hook_path = prefix_path / 'share' / pkg_name / 'hook' / \ ('%s.bat' % env_hook_name) logger.info("Creating environment hook '%s'" % hook_path) expand_template( Path(__file__).parent / 'template' / 'hook_set_value.bat.em', hook_path, {'name': name, 'value': value}) return hook_path
def create_package_script(self, prefix_path, pkg_name, hooks): # noqa: D102 pkg_env_path = prefix_path / 'share' / pkg_name / 'package.bat' logger.info("Creating package script '%s'" % pkg_env_path) expand_template( Path(__file__).parent / 'template' / 'package.bat.em', pkg_env_path, { 'hooks': list(filter(lambda hook: str(hook[0]).endswith('.bat'), hooks)), })
def create_prefix_script(self, prefix_path, merge_install): # Use parent of prefix_path to display a pretty workspace name workspace_name = 'unknown' if len(prefix_path.parts) >= 2: workspace_name = prefix_path.parts[-2] output_path = prefix_path / 'spawn_shell.bash' logger.info("Creating '{output_path}'".format_map(locals())) expand_template( Path(__file__).parent / 'template' / 'spawn_shell.bash.em', output_path, {'workspace_name': workspace_name})
def create_hook_prepend_value( self, env_hook_name, prefix_path, pkg_name, name, subdirectory, ): # noqa: D102 hook_path = prefix_path / 'share' / pkg_name / 'hook' / \ ('%s.sh' % env_hook_name) logger.info("Creating environment hook '%s'" % hook_path) expand_template( Path(__file__).parent / 'template' / 'hook_prepend_value.sh.em', hook_path, { 'name': name, 'subdirectory': subdirectory, }) return hook_path
def create_package_script(self, prefix_path, pkg_name, hooks): # noqa: D102 pkg_env_path = prefix_path / 'share' / pkg_name / 'package.ps1' logger.info("Creating package script '{pkg_env_path}'".format_map( locals())) expand_template( Path(__file__).parent / 'template' / 'package.ps1.em', pkg_env_path, { 'pkg_name': pkg_name, 'hooks': list(filter(lambda hook: str(hook[0]).endswith('.ps1'), hooks)), })
def create_hook_prepend_value( self, env_hook_name, prefix_path, pkg_name, name, subdirectory, ): # noqa: D102 hook_path = prefix_path / 'share' / pkg_name / 'hook' / \ ('%s.dsv' % env_hook_name) logger.info("Creating environment descriptor '%s'" % hook_path) expand_template( Path(__file__).parent / 'template' / 'hook_prepend_value.dsv.em', hook_path, { 'type_': 'prepend-non-duplicate', 'name': name, 'value': subdirectory, }) return hook_path
async def generate_command_environment( self, task_name, build_base, dependencies, ): # noqa: D102 global powershell_executable_name if not self._is_primary: raise SkipExtensionException('Not usable outside of PowerShell') # check if all dependencies are available # removes dependencies available in the environment from the parameter check_dependency_availability( dependencies, script_filename='package.ps1') hook_path = build_base / ('colcon_command_prefix_%s.ps1' % task_name) expand_template( Path(__file__).parent / 'template' / 'command_prefix.ps1.em', hook_path, {'dependencies': dependencies}) cmd = [ '.', str(hook_path), ';', '(Get-Item Env:).GetEnumerator()', '|', 'ForEach-Object', '{ "$($_.Key)=$($_.Value)" }' ] if POWERSHELL_EXECUTABLE is None: raise RuntimeError( "Could not find '{powershell_executable_name}' executable" .format(powershell_executable_name=powershell_executable_name)) cmd = [POWERSHELL_EXECUTABLE, '-Command', ' '.join(cmd)] env = await get_environment_variables( cmd, cwd=str(build_base), shell=False) # write environment variables to file for debugging env_path = build_base / \ ('colcon_command_prefix_%s.ps1.env' % task_name) with env_path.open('w') as h: for key in sorted(env.keys()): value = env[key] h.write('{key}={value}\n'.format_map(locals())) return env
def create_hook_set_value( # noqa: D102 self, env_hook_name, prefix_path, pkg_name, name, value, ): hook_path = prefix_path / 'share' / pkg_name / 'hook' / \ ('%s.sh' % env_hook_name) logger.info("Creating environment hook '%s'" % hook_path) if value == '': value = '$COLCON_PREFIX_PATH' expand_template( Path(__file__).parent / 'template' / 'hook_set_value.sh.em', hook_path, { 'name': name, 'value': value }) return hook_path
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', })
async def generate_command_environment( self, task_name, build_base, dependencies, ): # noqa: D102 if sys.platform != 'win32': raise SkipExtensionException('Not usable on non-Windows systems') hook_path = build_base / ('colcon_command_prefix_%s.bat' % task_name) expand_template( Path(__file__).parent / 'template' / 'command_prefix.bat.em', hook_path, {'dependencies': dependencies}) # ensure that the referenced scripts exist missing = OrderedDict() for pkg_name, pkg_install_base in dependencies.items(): pkg_script = Path( pkg_install_base) / 'share' / pkg_name / 'package.bat' if not pkg_script.exists(): missing[pkg_name] = str(pkg_script) if missing: raise RuntimeError( 'Failed to find the following files:' + ''.join('\n- %s' % path for path in missing.values()) + '\nCheck that the following packages have been built:' + ''.join('\n- %s' % name for name in missing.keys())) cmd = [str(hook_path), '&&', 'set'] env = await get_environment_variables(cmd, cwd=str(build_base)) # write environment variables to file for debugging env_path = build_base / ('colcon_command_prefix_%s.bat.env' % task_name) with env_path.open('w') as h: for key in sorted(env.keys()): value = env[key] h.write('{key}={value}\n'.format_map(locals())) return env
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', }) shutil.copy(str(self._get_prefix_util_path()), str(prefix_path / '_local_setup_util.py')) 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, { 'colcon_prefix_path': get_colcon_prefix_path(skip=prefix_path), 'prefix_script_no_ext': 'local_setup', })
def test_expand_template(): with TemporaryDirectory(prefix='test_colcon_') as destination_path: template_path = Path(destination_path) / 'invalid_template.em' template_path.write_text('@[if True]') with pytest.raises(TransientParseError): with patch('colcon_core.shell.template.logger.error') as error: expand_template(template_path, destination_path, {}) # the raised exception is catched and results in an error message assert error.call_count == 1 assert len(error.call_args[0]) == 1 assert error.call_args[0][0].endswith( " processing template '{template_path}'".format_map(locals())) template_path.write_text('@(var)') with pytest.raises(NameError): with patch('colcon_core.shell.template.logger.error') as error: expand_template(template_path, destination_path, {}) # the raised exception is catched and results in an error message assert error.call_count == 1 assert len(error.call_args[0]) == 1 assert error.call_args[0][0].endswith( " processing template '{template_path}'".format_map(locals()))
def test_expand_template(): with TemporaryDirectory(prefix='test_colcon_') as base_path: template_path = Path(base_path) / 'template.em' destination_path = Path(base_path) / 'expanded_template' # invalid template, missing @[end if] template_path.write_text('@[if True]') with pytest.raises(TransientParseError): with patch('colcon_core.shell.template.logger.error') as error: expand_template(template_path, destination_path, {}) # the raised exception is catched and results in an error message assert error.call_count == 1 assert len(error.call_args[0]) == 1 assert error.call_args[0][0].endswith( " processing template '{template_path}'".format_map(locals())) assert not destination_path.exists() # missing variable template_path.write_text('@(var)') with pytest.raises(NameError): with patch('colcon_core.shell.template.logger.error') as error: expand_template(template_path, destination_path, {}) # the raised exception is catched and results in an error message assert error.call_count == 1 assert len(error.call_args[0]) == 1 assert error.call_args[0][0].endswith( " processing template '{template_path}'".format_map(locals())) assert not destination_path.exists() # skip all symlink tests on Windows for now if sys.platform == 'win32': # pragma: no cover return # remove destination if it is a symlink destination_path.symlink_to(template_path) assert destination_path.is_symlink() expand_template(template_path, destination_path, {'var': 'value'}) assert not destination_path.is_symlink() assert destination_path.exists()