def test_must_setup_context( self, ContainerManagerMock, pathlib_mock, SamLayerProviderMock, SamFunctionProviderMock, get_template_data_mock ): template_dict = get_template_data_mock.return_value = "template dict" layer1 = DummyLayer("layer1", "buildmethod") layer2 = DummyLayer("layer1", None) layer_provider_mock = Mock() layer_provider_mock.get.return_value = layer1 layerprovider = SamLayerProviderMock.return_value = layer_provider_mock function1 = DummyFunction("func1") func_provider_mock = Mock() func_provider_mock.get.return_value = function1 funcprovider = SamFunctionProviderMock.return_value = func_provider_mock base_dir = pathlib_mock.Path.return_value.resolve.return_value.parent = "basedir" container_mgr_mock = ContainerManagerMock.return_value = Mock() context = BuildContext( "function_identifier", "template_file", None, # No base dir is provided "build_dir", manifest_path="manifest_path", clean=True, use_container=True, docker_network="network", parameter_overrides="overrides", skip_pull_image=True, mode="buildmode", ) setup_build_dir_mock = Mock() build_dir_result = setup_build_dir_mock.return_value = "my/new/build/dir" context._setup_build_dir = setup_build_dir_mock # call the enter method result = context.__enter__() self.assertEqual(result, context) # __enter__ must return self self.assertEqual(context.template_dict, template_dict) self.assertEqual(context.function_provider, funcprovider) self.assertEqual(context.layer_provider, layerprovider) self.assertEqual(context.base_dir, base_dir) self.assertEqual(context.container_manager, container_mgr_mock) self.assertEqual(context.build_dir, build_dir_result) self.assertEqual(context.use_container, True) self.assertEqual(context.output_template_path, os.path.join(build_dir_result, "template.yaml")) self.assertEqual(context.manifest_path_override, os.path.abspath("manifest_path")) self.assertEqual(context.mode, "buildmode") resources_to_build = context.resources_to_build self.assertTrue(function1 in resources_to_build.functions) self.assertTrue(layer1 in resources_to_build.layers) get_template_data_mock.assert_called_once_with("template_file") SamFunctionProviderMock.assert_called_once_with(template_dict, "overrides") pathlib_mock.Path.assert_called_once_with("template_file") setup_build_dir_mock.assert_called_with("build_dir", True) ContainerManagerMock.assert_called_once_with(docker_network_id="network", skip_pull_image=True) func_provider_mock.get.assert_called_once_with("function_identifier")
def test_must_return_many_functions_to_build(self, ContainerManagerMock, pathlib_mock, SamFunctionProviderMock, get_template_data_mock): template_dict = get_template_data_mock.return_value = "template dict" func_provider_mock = Mock() func_provider_mock.get_all.return_value = [ "function to build", "and another function" ] funcprovider = SamFunctionProviderMock.return_value = func_provider_mock base_dir = pathlib_mock.Path.return_value.resolve.return_value.parent = "basedir" container_mgr_mock = ContainerManagerMock.return_value = Mock() context = BuildContext( None, "template_file", None, # No base dir is provided "build_dir", manifest_path="manifest_path", clean=True, use_container=True, docker_network="network", parameter_overrides="overrides", skip_pull_image=True, mode="buildmode", ) setup_build_dir_mock = Mock() build_dir_result = setup_build_dir_mock.return_value = "my/new/build/dir" context._setup_build_dir = setup_build_dir_mock # call the enter method result = context.__enter__() self.assertEqual(result, context) # __enter__ must return self self.assertEqual(context.template_dict, template_dict) self.assertEqual(context.function_provider, funcprovider) self.assertEqual(context.base_dir, base_dir) self.assertEqual(context.container_manager, container_mgr_mock) self.assertEqual(context.build_dir, build_dir_result) self.assertEqual(context.use_container, True) self.assertEqual(context.output_template_path, os.path.join(build_dir_result, "template.yaml")) self.assertEqual(context.manifest_path_override, os.path.abspath("manifest_path")) self.assertEqual(context.mode, "buildmode") self.assertEqual(context.functions_to_build, ["function to build", "and another function"]) get_template_data_mock.assert_called_once_with("template_file") SamFunctionProviderMock.assert_called_once_with( template_dict, "overrides") pathlib_mock.Path.assert_called_once_with("template_file") setup_build_dir_mock.assert_called_with("build_dir", True) ContainerManagerMock.assert_called_once_with( docker_network_id="network", skip_pull_image=True) func_provider_mock.get_all.assert_called_once()
def test_must_fail_with_illegal_identifier( self, ContainerManagerMock, pathlib_mock, SamLayerProviderMock, SamFunctionProviderMock, get_buildable_stacks_mock, ): template_dict = "template dict" stack = Mock() stack.template_dict = template_dict get_buildable_stacks_mock.return_value = ([stack], []) func_provider_mock = Mock() func_provider_mock.get.return_value = None func_provider_mock.get_all.return_value = [ DummyFunction("func1"), DummyFunction("func2") ] funcprovider = SamFunctionProviderMock.return_value = func_provider_mock layer_provider_mock = Mock() layer_provider_mock.get.return_value = None layer_provider_mock.get_all.return_value = [ DummyLayer("layer1", None), DummyLayer("layer2", None) ] layerprovider = SamLayerProviderMock.return_value = layer_provider_mock base_dir = pathlib_mock.Path.return_value.resolve.return_value.parent = "basedir" container_mgr_mock = ContainerManagerMock.return_value = Mock() context = BuildContext( "illegal", "template_file", None, # No base dir is provided "build_dir", manifest_path="manifest_path", clean=True, use_container=True, docker_network="network", parameter_overrides={"overrides": "value"}, skip_pull_image=True, mode="buildmode", cached=False, cache_dir="cache_dir", ) setup_build_dir_mock = Mock() build_dir_result = setup_build_dir_mock.return_value = "my/new/build/dir" context._setup_build_dir = setup_build_dir_mock # call the enter method result = context.__enter__() with self.assertRaises(ResourceNotFound): context.resources_to_build
def test_must_return_buildable_dependent_layer_when_function_is_build( self, ContainerManagerMock, pathlib_mock, SamLayerProviderMock, SamFunctionProviderMock, get_buildable_stacks_mock, ): template_dict = "template dict" stack = Mock() stack.template_dict = template_dict get_buildable_stacks_mock.return_value = ([stack], []) layer1 = DummyLayer("layer1", "python3.8") layer2 = DummyLayer("layer2", None) layer_provider_mock = Mock() layer_provider_mock.get.return_value = layer1 layerprovider = SamLayerProviderMock.return_value = layer_provider_mock func1 = DummyFunction("func1", [layer1, layer2]) func_provider_mock = Mock() func_provider_mock.get.return_value = func1 funcprovider = SamFunctionProviderMock.return_value = func_provider_mock base_dir = pathlib_mock.Path.return_value.resolve.return_value.parent = "basedir" container_mgr_mock = ContainerManagerMock.return_value = Mock() context = BuildContext( "func1", "template_file", None, # No base dir is provided "build_dir", manifest_path="manifest_path", clean=True, use_container=True, docker_network="network", parameter_overrides={"overrides": "value"}, skip_pull_image=True, mode="buildmode", cached=False, cache_dir="cache_dir", ) setup_build_dir_mock = Mock() build_dir_result = setup_build_dir_mock.return_value = "my/new/build/dir" context._setup_build_dir = setup_build_dir_mock # call the enter method context.__enter__() self.assertTrue(func1 in context.resources_to_build.functions) self.assertTrue(layer1 in context.resources_to_build.layers) self.assertTrue(layer2 not in context.resources_to_build.layers) self.assertTrue(context.is_building_specific_resource)
def test_when_build_dir_is_cwd_raises_exception(self, pathlib_patch, os_patch, shutil_patch): path_mock = Mock() pathlib_patch.Path.return_value = path_mock os_patch.path.abspath.side_effect = ["/somepath", "/somepath"] path_mock.cwd.return_value = "/somepath" build_dir = "/somepath" with self.assertRaises(InvalidBuildDirException): BuildContext._setup_build_dir(build_dir, True) self.assertEqual(os_patch.path.abspath.call_count, 2) os_patch.listdir.assert_not_called() path_mock.exists.assert_not_called() path_mock.mkdir.assert_not_called() pathlib_patch.Path.assert_called_once_with(build_dir) shutil_patch.rmtree.assert_not_called() pathlib_patch.Path.cwd.assert_called_once()
def do_cli( template, # pylint: disable=too-many-locals base_dir, build_dir, clean, use_container, manifest_path, docker_network, skip_pull_image, parameter_overrides): """ Implementation of the ``cli`` method """ LOG.debug("'build' command is called") if use_container: LOG.info("Starting Build inside a container") with BuildContext(template, base_dir, build_dir, clean=clean, manifest_path=manifest_path, use_container=use_container, parameter_overrides=parameter_overrides, docker_network=docker_network, skip_pull_image=skip_pull_image) as ctx: builder = ApplicationBuilder( ctx.function_provider, ctx.build_dir, ctx.base_dir, manifest_path_override=ctx.manifest_path_override, container_manager=ctx.container_manager) try: artifacts = builder.build() modified_template = builder.update_template( ctx.template_dict, ctx.original_template_path, artifacts) move_template(ctx.original_template_path, ctx.output_template_path, modified_template) click.secho("\nBuild Succeeded", fg="green") msg = gen_success_msg( os.path.relpath(ctx.build_dir), os.path.relpath(ctx.output_template_path), os.path.abspath( ctx.build_dir) == os.path.abspath(DEFAULT_BUILD_DIR)) click.secho(msg, fg="yellow") except (UnsupportedRuntimeException, BuildError, UnsupportedBuilderLibraryVersionError) as ex: click.secho("Build Failed", fg="red") raise UserException(str(ex))
def test_must_setup_context(self, ContainerManagerMock, pathlib_mock, SamFunctionProviderMock, get_template_data_mock): template_dict = get_template_data_mock.return_value = "template dict" funcprovider = SamFunctionProviderMock.return_value = "funcprovider" base_dir = pathlib_mock.Path.return_value.resolve.return_value.parent = "basedir" container_mgr_mock = ContainerManagerMock.return_value = Mock() context = BuildContext("template_file", None, # No base dir is provided "build_dir", manifest_path="manifest_path", clean=True, use_container=True, docker_network="network", parameter_overrides="overrides", skip_pull_image=True) setup_build_dir_mock = Mock() build_dir_result = setup_build_dir_mock.return_value = "my/new/build/dir" context._setup_build_dir = setup_build_dir_mock # call the enter method result = context.__enter__() self.assertEquals(result, context) # __enter__ must return self self.assertEquals(context.template_dict, template_dict) self.assertEquals(context.function_provider, funcprovider) self.assertEquals(context.base_dir, base_dir) self.assertEquals(context.container_manager, container_mgr_mock) self.assertEquals(context.build_dir, build_dir_result) self.assertEquals(context.use_container, True) self.assertEquals(context.output_template_path, os.path.join(build_dir_result, "template.yaml")) self.assertEquals(context.manifest_path_override, os.path.abspath("manifest_path")) get_template_data_mock.assert_called_once_with("template_file") SamFunctionProviderMock.assert_called_once_with(template_dict, "overrides") pathlib_mock.Path.assert_called_once_with("template_file") setup_build_dir_mock.assert_called_with("build_dir", True) ContainerManagerMock.assert_called_once_with(docker_network_id="network", skip_pull_image=True)
def test_must_print_remote_url_warning( self, remote_stack_full_paths, print_warning, ContainerManagerMock, pathlib_mock, SamLayerProviderMock, SamFunctionProviderMock, get_buildable_stacks_mock, log_mock, ): get_buildable_stacks_mock.return_value = ([], remote_stack_full_paths) context = BuildContext( "function_identifier", "template_file", None, # No base dir is provided "build_dir", manifest_path="manifest_path", clean=True, use_container=True, docker_network="network", parameter_overrides={"overrides": "value"}, skip_pull_image=True, mode="buildmode", cached=False, cache_dir="cache_dir", ) context._setup_build_dir = Mock() # call the enter method context.__enter__() if print_warning: log_mock.warning.assert_called_once_with( ANY, "\n".join([ f"- {full_path}" for full_path in remote_stack_full_paths ])) else: log_mock.warning.assert_not_called()
def test_must_fail_when_layer_is_build_without_buildmethod( self, ContainerManagerMock, pathlib_mock, SamLayerProviderMock, SamFunctionProviderMock, get_template_data_mock ): template_dict = get_template_data_mock.return_value = "template dict" func_provider_mock = Mock() func_provider_mock.get.return_value = None funcprovider = SamFunctionProviderMock.return_value = func_provider_mock layer1 = DummyLayer("layer1", None) layer_provider_mock = Mock() layer_provider_mock.get.return_value = layer1 layerprovider = SamLayerProviderMock.return_value = layer_provider_mock base_dir = pathlib_mock.Path.return_value.resolve.return_value.parent = "basedir" container_mgr_mock = ContainerManagerMock.return_value = Mock() context = BuildContext( "layer1", "template_file", None, # No base dir is provided "build_dir", manifest_path="manifest_path", clean=True, use_container=True, docker_network="network", parameter_overrides={"overrides": "value"}, skip_pull_image=True, mode="buildmode", cached=False, cache_dir="cache_dir", ) setup_build_dir_mock = Mock() build_dir_result = setup_build_dir_mock.return_value = "my/new/build/dir" context._setup_build_dir = setup_build_dir_mock # call the enter method result = context.__enter__() with self.assertRaises(MissingBuildMethodException): context.resources_to_build
def test_must_return_only_layer_when_layer_is_build( self, ContainerManagerMock, pathlib_mock, SamLayerProviderMock, SamFunctionProviderMock, get_template_data_mock ): template_dict = get_template_data_mock.return_value = "template dict" func_provider_mock = Mock() func_provider_mock.get.return_value = None funcprovider = SamFunctionProviderMock.return_value = func_provider_mock layer1 = DummyLayer("layer1", "python3.8") layer_provider_mock = Mock() layer_provider_mock.get.return_value = layer1 layerprovider = SamLayerProviderMock.return_value = layer_provider_mock base_dir = pathlib_mock.Path.return_value.resolve.return_value.parent = "basedir" container_mgr_mock = ContainerManagerMock.return_value = Mock() context = BuildContext( "layer1", "template_file", None, # No base dir is provided "build_dir", manifest_path="manifest_path", clean=True, use_container=True, docker_network="network", parameter_overrides="overrides", skip_pull_image=True, mode="buildmode", ) setup_build_dir_mock = Mock() build_dir_result = setup_build_dir_mock.return_value = "my/new/build/dir" context._setup_build_dir = setup_build_dir_mock # call the enter method context.__enter__() self.assertTrue(layer1 in context.resources_to_build.layers)
def test_build_dir_does_not_exist(self, pathlib_patch, os_patch, shutil_patch): path_mock = Mock() pathlib_patch.Path.return_value = path_mock path_mock.resolve.return_value = "long/full/path" path_mock.exists.return_value = False build_dir = "/somepath" full_build_path = BuildContext._setup_build_dir(build_dir, True) self.assertEquals(full_build_path, "long/full/path") os_patch.listdir.assert_not_called() path_mock.exists.assert_called_once() path_mock.mkdir.assert_called_once_with(mode=0o755, parents=True, exist_ok=True) pathlib_patch.Path.assert_called_once_with(build_dir) shutil_patch.rmtree.assert_not_called()
def test_non_clean_build_when_dir_exists_with_non_empty_dir(self, pathlib_patch, os_patch, shutil_patch): path_mock = Mock() pathlib_patch.Path.return_value = path_mock os_patch.path.abspath.side_effect = ["/somepath", "/cwd/path"] path_mock.cwd.return_value = "/cwd/path" os_patch.listdir.return_value = True path_mock.resolve.return_value = "long/full/path" path_mock.exists.return_value = True build_dir = "/somepath" full_build_path = BuildContext._setup_build_dir(build_dir, False) self.assertEqual(full_build_path, "long/full/path") self.assertEqual(os_patch.path.abspath.call_count, 2) os_patch.listdir.assert_called_once() path_mock.exists.assert_called_once() path_mock.mkdir.assert_called_once_with(mode=0o755, parents=True, exist_ok=True) pathlib_patch.Path.assert_called_once_with(build_dir) shutil_patch.rmtree.assert_not_called() pathlib_patch.Path.cwd.assert_called_once()
def do_cli( # pylint: disable=too-many-locals, too-many-statements function_identifier: Optional[str], template: str, base_dir: Optional[str], build_dir: str, cache_dir: str, clean: bool, use_container: bool, cached: bool, parallel: bool, manifest_path: Optional[str], docker_network: Optional[str], skip_pull_image: bool, parameter_overrides: Dict, mode: Optional[str], container_env_var: Optional[Tuple[str]], container_env_var_file: Optional[str], build_image: Optional[Tuple[str]], ) -> None: """ Implementation of the ``cli`` method """ from samcli.commands.exceptions import UserException from samcli.commands.build.build_context import BuildContext from samcli.lib.build.app_builder import ( ApplicationBuilder, BuildError, UnsupportedBuilderLibraryVersionError, ContainerBuildNotSupported, ) from samcli.lib.build.workflow_config import UnsupportedRuntimeException from samcli.local.lambdafn.exceptions import FunctionNotFound from samcli.commands._utils.template import move_template from samcli.lib.build.build_graph import InvalidBuildGraphException LOG.debug("'build' command is called") if cached: LOG.info("Starting Build use cache") if use_container: LOG.info("Starting Build inside a container") processed_env_vars = _process_env_var(container_env_var) processed_build_images = _process_image_options(build_image) with BuildContext( function_identifier, template, base_dir, build_dir, cache_dir, cached, clean=clean, manifest_path=manifest_path, use_container=use_container, parameter_overrides=parameter_overrides, docker_network=docker_network, skip_pull_image=skip_pull_image, mode=mode, container_env_var=processed_env_vars, container_env_var_file=container_env_var_file, build_images=processed_build_images, ) as ctx: try: builder = ApplicationBuilder( ctx.resources_to_build, ctx.build_dir, ctx.base_dir, ctx.cache_dir, ctx.cached, ctx.is_building_specific_resource, manifest_path_override=ctx.manifest_path_override, container_manager=ctx.container_manager, mode=ctx.mode, parallel=parallel, container_env_var=processed_env_vars, container_env_var_file=container_env_var_file, build_images=processed_build_images, ) except FunctionNotFound as ex: raise UserException(str(ex), wrapped_from=ex.__class__.__name__) from ex try: artifacts = builder.build() stack_output_template_path_by_stack_path = { stack.stack_path: stack.get_output_template_path(ctx.build_dir) for stack in ctx.stacks } for stack in ctx.stacks: modified_template = builder.update_template( stack, artifacts, stack_output_template_path_by_stack_path, ) move_template(stack.location, stack.get_output_template_path(ctx.build_dir), modified_template) click.secho("\nBuild Succeeded", fg="green") # try to use relpath so the command is easier to understand, however, # under Windows, when SAM and (build_dir or output_template_path) are # on different drive, relpath() fails. root_stack = SamLocalStackProvider.find_root_stack(ctx.stacks) out_template_path = root_stack.get_output_template_path( ctx.build_dir) try: build_dir_in_success_message = os.path.relpath(ctx.build_dir) output_template_path_in_success_message = os.path.relpath( out_template_path) except ValueError: LOG.debug( "Failed to retrieve relpath - using the specified path as-is instead" ) build_dir_in_success_message = ctx.build_dir output_template_path_in_success_message = out_template_path msg = gen_success_msg( build_dir_in_success_message, output_template_path_in_success_message, os.path.abspath( ctx.build_dir) == os.path.abspath(DEFAULT_BUILD_DIR), ) click.secho(msg, fg="yellow") except ( UnsupportedRuntimeException, BuildError, BuildInsideContainerError, UnsupportedBuilderLibraryVersionError, ContainerBuildNotSupported, InvalidBuildGraphException, ) as ex: click.secho("\nBuild Failed", fg="red") # Some Exceptions have a deeper wrapped exception that needs to be surfaced # from deeper than just one level down. deep_wrap = getattr(ex, "wrapped_from", None) wrapped_from = deep_wrap if deep_wrap else ex.__class__.__name__ raise UserException(str(ex), wrapped_from=wrapped_from) from ex
def test_must_return_many_functions_to_build( self, ContainerManagerMock, pathlib_mock, SamLayerProviderMock, SamFunctionProviderMock, get_buildable_stacks_mock, ): template_dict = "template dict" stack = Mock() stack.template_dict = template_dict get_buildable_stacks_mock.return_value = ([stack], []) func1 = DummyFunction("func1") func2 = DummyFunction("func2") func_provider_mock = Mock() func_provider_mock.get_all.return_value = [func1, func2] funcprovider = SamFunctionProviderMock.return_value = func_provider_mock layer1 = DummyLayer("layer1", "buildMethod") layer2 = DummyLayer("layer1", None) layer_provider_mock = Mock() layer_provider_mock.get_all.return_value = [layer1, layer2] layerprovider = SamLayerProviderMock.return_value = layer_provider_mock base_dir = pathlib_mock.Path.return_value.resolve.return_value.parent = "basedir" container_mgr_mock = ContainerManagerMock.return_value = Mock() context = BuildContext( None, "template_file", None, # No base dir is provided "build_dir", manifest_path="manifest_path", clean=True, use_container=True, docker_network="network", parameter_overrides={"overrides": "value"}, skip_pull_image=True, mode="buildmode", cached=False, cache_dir="cache_dir", ) setup_build_dir_mock = Mock() build_dir_result = setup_build_dir_mock.return_value = "my/new/build/dir" context._setup_build_dir = setup_build_dir_mock # call the enter method result = context.__enter__() self.assertEqual(result, context) # __enter__ must return self self.assertEqual(context.function_provider, funcprovider) self.assertEqual(context.layer_provider, layerprovider) self.assertEqual(context.base_dir, base_dir) self.assertEqual(context.container_manager, container_mgr_mock) self.assertEqual(context.build_dir, build_dir_result) self.assertEqual(context.use_container, True) self.assertEqual(context.stacks, [stack]) self.assertEqual(context.manifest_path_override, os.path.abspath("manifest_path")) self.assertEqual(context.mode, "buildmode") self.assertFalse(context.is_building_specific_resource) resources_to_build = context.resources_to_build self.assertEqual(resources_to_build.functions, [func1, func2]) self.assertEqual(resources_to_build.layers, [layer1]) get_buildable_stacks_mock.assert_called_once_with( "template_file", parameter_overrides={"overrides": "value"}) SamFunctionProviderMock.assert_called_once_with([stack], False) pathlib_mock.Path.assert_called_once_with("template_file") setup_build_dir_mock.assert_called_with("build_dir", True) ContainerManagerMock.assert_called_once_with( docker_network_id="network", skip_pull_image=True) func_provider_mock.get_all.assert_called_once()
def do_cli( # pylint: disable=too-many-locals, too-many-statements function_identifier, template, base_dir, build_dir, clean, use_container, manifest_path, docker_network, skip_pull_image, parameter_overrides, mode, ): """ Implementation of the ``cli`` method """ from samcli.commands.exceptions import UserException from samcli.commands.build.build_context import BuildContext from samcli.lib.build.app_builder import ( ApplicationBuilder, BuildError, UnsupportedBuilderLibraryVersionError, ContainerBuildNotSupported, ) from samcli.lib.build.workflow_config import UnsupportedRuntimeException from samcli.local.lambdafn.exceptions import FunctionNotFound from samcli.commands._utils.template import move_template LOG.debug("'build' command is called") if use_container: LOG.info("Starting Build inside a container") with BuildContext( function_identifier, template, base_dir, build_dir, clean=clean, manifest_path=manifest_path, use_container=use_container, parameter_overrides=parameter_overrides, docker_network=docker_network, skip_pull_image=skip_pull_image, mode=mode, ) as ctx: try: builder = ApplicationBuilder( ctx.resources_to_build, ctx.build_dir, ctx.base_dir, manifest_path_override=ctx.manifest_path_override, container_manager=ctx.container_manager, mode=ctx.mode, ) except FunctionNotFound as ex: raise UserException(str(ex), wrapped_from=ex.__class__.__name__) try: artifacts = builder.build() modified_template = builder.update_template( ctx.template_dict, ctx.original_template_path, artifacts) move_template(ctx.original_template_path, ctx.output_template_path, modified_template) click.secho("\nBuild Succeeded", fg="green") # try to use relpath so the command is easier to understand, however, # under Windows, when SAM and (build_dir or output_template_path) are # on different drive, relpath() fails. try: build_dir_in_success_message = os.path.relpath(ctx.build_dir) output_template_path_in_success_message = os.path.relpath( ctx.output_template_path) except ValueError: LOG.debug( "Failed to retrieve relpath - using the specified path as-is instead" ) build_dir_in_success_message = ctx.build_dir output_template_path_in_success_message = ctx.output_template_path msg = gen_success_msg( build_dir_in_success_message, output_template_path_in_success_message, os.path.abspath( ctx.build_dir) == os.path.abspath(DEFAULT_BUILD_DIR), ) click.secho(msg, fg="yellow") except ( UnsupportedRuntimeException, BuildError, BuildInsideContainerError, UnsupportedBuilderLibraryVersionError, ContainerBuildNotSupported, ) as ex: click.secho("\nBuild Failed", fg="red") # Some Exceptions have a deeper wrapped exception that needs to be surfaced # from deeper than just one level down. deep_wrap = getattr(ex, "wrapped_from", None) wrapped_from = deep_wrap if deep_wrap else ex.__class__.__name__ raise UserException(str(ex), wrapped_from=wrapped_from)
def do_cli( function_identifier, # pylint: disable=too-many-locals template, base_dir, build_dir, clean, use_container, manifest_path, docker_network, skip_pull_image, parameter_overrides, mode): """ Implementation of the ``cli`` method """ LOG.debug("'build' command is called") if use_container: LOG.info("Starting Build inside a container") with BuildContext(function_identifier, template, base_dir, build_dir, clean=clean, manifest_path=manifest_path, use_container=use_container, parameter_overrides=parameter_overrides, docker_network=docker_network, skip_pull_image=skip_pull_image, mode=mode) as ctx: try: builder = ApplicationBuilder( ctx.functions_to_build, ctx.build_dir, ctx.base_dir, manifest_path_override=ctx.manifest_path_override, container_manager=ctx.container_manager, mode=ctx.mode) except FunctionNotFound as ex: raise UserException(str(ex)) try: artifacts = builder.build() modified_template = builder.update_template( ctx.template_dict, ctx.original_template_path, artifacts) move_template(ctx.original_template_path, ctx.output_template_path, modified_template) click.secho("\nBuild Succeeded", fg="green") # try to use relpath so the command is easier to understand, however, # under Windows, when SAM and (build_dir or output_template_path) are # on different drive, relpath() fails. try: build_dir_in_success_message = os.path.relpath(ctx.build_dir) output_template_path_in_success_message = os.path.relpath( ctx.output_template_path) except ValueError: LOG.debug( "Failed to retrieve relpath - using the specified path as-is instead" ) build_dir_in_success_message = ctx.build_dir output_template_path_in_success_message = ctx.output_template_path msg = gen_success_msg( build_dir_in_success_message, output_template_path_in_success_message, os.path.abspath( ctx.build_dir) == os.path.abspath(DEFAULT_BUILD_DIR)) click.secho(msg, fg="yellow") except (UnsupportedRuntimeException, BuildError, UnsupportedBuilderLibraryVersionError, ContainerBuildNotSupported) as ex: click.secho("\nBuild Failed", fg="red") raise UserException(str(ex))