예제 #1
0
    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")
예제 #2
0
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))
예제 #3
0
    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()
예제 #4
0
    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
예제 #5
0
    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)
예제 #6
0
    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()
예제 #7
0
    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
예제 #8
0
    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)
예제 #9
0
파일: command.py 프로젝트: uu64/aws-sam-cli
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
예제 #10
0
    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()
예제 #11
0
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)
예제 #12
0
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))