aws_lambda_builders/workflows/custom_make/actions.py (57 lines of code) (raw):
"""
Action to build a specific Makefile target
"""
import logging
from pathlib import Path
from aws_lambda_builders.actions import ActionFailedError, BaseAction, Purpose
from .exceptions import MakeFileNotFoundError
from .make import MakeExecutionError
LOG = logging.getLogger(__name__)
class CustomMakeAction(BaseAction):
"""
A Lambda Builder Action that builds and packages a provided runtime project using Make.
"""
NAME = "MakeBuild"
DESCRIPTION = "Running build target on Makefile"
PURPOSE = Purpose.COMPILE_SOURCE
def __init__(
self,
artifacts_dir,
manifest_path,
osutils,
subprocess_make,
build_logical_id,
working_directory,
):
"""
:type artifacts_dir: str
:param artifacts_dir: directory where artifacts needs to be stored.
:type manifest_path: str
:param manifest_path: path to Makefile of an Make project with the source in same folder.
:type osutils: aws_lambda_builders.workflows.custom_make.utils.OSUtils
:param osutils: An instance of OS Utilities for file manipulation
:type subprocess_make aws_lambda_builders.workflows.custom_make.make.SubprocessMake
:param subprocess_make: An instance of the Make process wrapper
:type build_logical_id: str
:param build_logical_id: the lambda resource logical id that will be built by the custom action.
:type working_directory: str
:param working_directory: path to the working directory where the Makefile will be executed.
"""
super(CustomMakeAction, self).__init__()
self.artifacts_dir = artifacts_dir
self.manifest_path = manifest_path
self.osutils = osutils
self.subprocess_make = subprocess_make
self.build_logical_id = build_logical_id
self.working_directory = working_directory
@property
def artifact_dir_path(self):
# This is required when running on windows to determine if we are running in linux
# subsystem or on native cmd or powershell.
if self.osutils.is_windows():
return Path(self.artifacts_dir).as_posix() if self.osutils.which("sh") else self.artifacts_dir
else:
return self.artifacts_dir
def manifest_check(self):
# Check for manifest file presence and if not present raise MakefileNotFoundError
if not self.osutils.exists(self.manifest_path):
raise MakeFileNotFoundError("Makefile not found at {}".format(self.manifest_path))
def execute(self):
"""
Runs the action.
:raises lambda_builders.actions.ActionFailedError: when Make Build fails.
"""
# Check for manifest file
try:
self.manifest_check()
except MakeFileNotFoundError as ex:
raise ActionFailedError(str(ex))
# Create the Artifacts Directory if it doesnt exist.
if not self.osutils.exists(self.artifacts_dir):
self.osutils.makedirs(self.artifacts_dir)
try:
current_env = self.osutils.environ()
LOG.info("%s: Current Artifacts Directory : %s", self.build_logical_id, self.artifact_dir_path)
current_env.update({"ARTIFACTS_DIR": self.artifact_dir_path})
# Export environmental variables that might be needed by other binaries used
# within the Makefile and also specify the makefile to be used as well.
self.subprocess_make.run(
[
"--makefile",
"{}".format(self.manifest_path),
"build-{logical_id}".format(logical_id=self.build_logical_id),
],
env=current_env,
cwd=self.working_directory,
)
except MakeExecutionError as ex:
raise ActionFailedError(str(ex))