def __enter__(self) -> "BuildContext": self._stacks = SamLocalStackProvider.get_stacks( self._template_file, parameter_overrides=self._parameter_overrides ) self._template_dict = SamLocalStackProvider.find_root_stack(self.stacks).template_dict self._function_provider = SamFunctionProvider(self.stacks) self._layer_provider = SamLayerProvider(self.stacks) if not self._base_dir: # Base directory, if not provided, is the directory containing the template self._base_dir = str(pathlib.Path(self._template_file).resolve().parent) self._build_dir = self._setup_build_dir(self._build_dir, self._clean) if self._cached: cache_path = pathlib.Path(self._cache_dir) cache_path.mkdir(mode=self._BUILD_DIR_PERMISSIONS, parents=True, exist_ok=True) self._cache_dir = str(cache_path.resolve()) if self._use_container: self._container_manager = ContainerManager( docker_network_id=self._docker_network, skip_pull_image=self._skip_pull_image ) return self
def __enter__(self): """ Performs some basic checks and returns itself when everything is ready to invoke a Lambda function. :returns InvokeContext: Returns this object """ stacks = self._get_stacks() self._template_dict = SamLocalStackProvider.find_root_stack( stacks).template_dict self._function_provider = SamFunctionProvider(stacks) self._env_vars_value = self._get_env_vars_value(self._env_vars_file) self._container_env_vars_value = self._get_env_vars_value( self._container_env_vars_file) self._log_file_handle = self._setup_log_file(self._log_file) # in case of warm containers && debugging is enabled && if debug-function property is not provided, so # if the provided template only contains one lambda function, so debug-function will be set to this function # if the template contains multiple functions, a warning message "that the debugging option will be ignored" # will be printed if self._containers_mode == ContainersMode.WARM and self._debug_ports and not self._debug_function: if len(self._function_provider.functions) == 1: self._debug_function = list( self._function_provider.functions.keys())[0] else: LOG.info( "Warning: you supplied debugging options but you did not specify the --debug-function option." " To specify which function you want to debug, please use the --debug-function <function-name>" ) # skipp the debugging self._debug_ports = None self._debug_context = self._get_debug_context( self._debug_ports, self._debug_args, self._debugger_path, self._container_env_vars_value, self._debug_function, ) self._container_manager = self._get_container_manager( self._docker_network, self._skip_pull_image, self._shutdown) if not self._container_manager.is_docker_reachable: raise InvokeContextException( "Running AWS SAM projects locally requires Docker. Have you got it installed and running?" ) # initialize all lambda function containers upfront if self._containers_initializing_mode == ContainersInitializationMode.EAGER: self._initialize_all_functions_containers() return self
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