Skip to content

Commit ef4ab58

Browse files
authored
feat: implement build in source for custom make (#417)
1 parent 01ab121 commit ef4ab58

File tree

5 files changed

+92
-44
lines changed

5 files changed

+92
-44
lines changed

aws_lambda_builders/workflows/custom_make/actions.py

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -25,20 +25,16 @@ class CustomMakeAction(BaseAction):
2525
def __init__(
2626
self,
2727
artifacts_dir,
28-
scratch_dir,
2928
manifest_path,
3029
osutils,
3130
subprocess_make,
3231
build_logical_id,
33-
working_directory=None,
32+
working_directory,
3433
):
3534
"""
3635
:type artifacts_dir: str
3736
:param artifacts_dir: directory where artifacts needs to be stored.
3837
39-
:type scratch_dir: str
40-
:param scratch_dir: an existing (writable) directory for temporary files
41-
4238
:type manifest_path: str
4339
:param manifest_path: path to Makefile of an Make project with the source in same folder.
4440
@@ -52,17 +48,15 @@ def __init__(
5248
:param build_logical_id: the lambda resource logical id that will be built by the custom action.
5349
5450
:type working_directory: str
55-
:param working_directory: path to the working directory where the Makefile will be executed. Use the scratch_dir
56-
as the working directory if the input working_directory is None
51+
:param working_directory: path to the working directory where the Makefile will be executed.
5752
"""
5853
super(CustomMakeAction, self).__init__()
5954
self.artifacts_dir = artifacts_dir
60-
self.scratch_dir = scratch_dir
6155
self.manifest_path = manifest_path
6256
self.osutils = osutils
6357
self.subprocess_make = subprocess_make
6458
self.build_logical_id = build_logical_id
65-
self.working_directory = working_directory if working_directory else scratch_dir
59+
self.working_directory = working_directory
6660

6761
@property
6862
def artifact_dir_path(self):

aws_lambda_builders/workflows/custom_make/workflow.py

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,10 @@ def __init__(self, source_dir, artifacts_dir, scratch_dir, manifest_path, runtim
3131

3232
self.os_utils = OSUtils()
3333

34-
# Find the logical id of the function to be built.
3534
options = kwargs.get("options") or {}
36-
build_logical_id = options.get("build_logical_id", None)
37-
working_directory = options.get("working_directory", scratch_dir)
35+
build_in_source = kwargs.get("build_in_source")
3836

37+
build_logical_id = options.get("build_logical_id", None)
3938
if not build_logical_id:
4039
raise WorkflowFailedError(
4140
workflow_name=self.NAME,
@@ -45,17 +44,37 @@ def __init__(self, source_dir, artifacts_dir, scratch_dir, manifest_path, runtim
4544

4645
subprocess_make = SubProcessMake(make_exe=self.binaries["make"].binary_path, osutils=self.os_utils)
4746

47+
# Don't build in source by default (backwards compatibility)
48+
if build_in_source is None:
49+
build_in_source = False
50+
51+
# an explicitly definied working directory should take precedence
52+
working_directory = options.get("working_directory") or self._select_working_directory(
53+
source_dir, scratch_dir, build_in_source
54+
)
55+
4856
make_action = CustomMakeAction(
4957
artifacts_dir,
50-
scratch_dir,
5158
manifest_path,
5259
osutils=self.os_utils,
5360
subprocess_make=subprocess_make,
5461
build_logical_id=build_logical_id,
5562
working_directory=working_directory,
5663
)
5764

58-
self.actions = [CopySourceAction(source_dir, scratch_dir, excludes=self.EXCLUDED_FILES), make_action]
65+
self.actions = []
66+
67+
if not self.build_in_source:
68+
# if we're building on scratch_dir, we have to first copy the source there
69+
self.actions.append(CopySourceAction(source_dir, scratch_dir, excludes=self.EXCLUDED_FILES))
70+
71+
self.actions.append(make_action)
72+
73+
def _select_working_directory(self, source_dir: str, scratch_dir: str, build_in_source: bool):
74+
"""
75+
Returns the directory where the make action should be executed
76+
"""
77+
return source_dir if build_in_source else scratch_dir
5978

6079
def get_resolvers(self):
6180
return [PathResolver(runtime="provided", binary="make", executable_search_paths=self.executable_search_paths)]

tests/integration/workflows/custom_make/test_custom_make.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,3 +109,30 @@ def test_must_build_python_project_through_makefile_unknown_target(self):
109109
runtime=self.runtime,
110110
options={"build_logical_id": "HelloWorldFunction2"},
111111
)
112+
113+
def test_must_build_python_project_through_makefile_in_source(self):
114+
self.builder.build(
115+
self.source_dir,
116+
self.artifacts_dir,
117+
self.scratch_dir,
118+
self.manifest_path_valid,
119+
runtime=self.runtime,
120+
options={"build_logical_id": "HelloWorldFunction"},
121+
build_in_source=True,
122+
)
123+
dependencies_installed = {
124+
"chardet",
125+
"urllib3",
126+
"idna",
127+
"urllib3-1.25.11.dist-info",
128+
"chardet-3.0.4.dist-info",
129+
"certifi-2020.4.5.2.dist-info",
130+
"certifi",
131+
"idna-2.10.dist-info",
132+
"requests",
133+
"requests-2.23.0.dist-info",
134+
}
135+
136+
expected_files = self.test_data_files.union(dependencies_installed)
137+
output_files = set(os.listdir(self.artifacts_dir))
138+
self.assertEqual(expected_files, output_files)

tests/unit/workflows/custom_make/test_actions.py

Lines changed: 6 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,15 @@ def tearDown(self):
2323
def test_call_makefile_target(self, OSUtilMock, SubprocessMakeMock):
2424
osutils = OSUtilMock.return_value
2525
subprocess_make = SubprocessMakeMock.return_value
26+
working_directory = "some_dir"
2627

2728
action = CustomMakeAction(
2829
"artifacts",
29-
"scratch_dir",
3030
"manifest",
3131
osutils=osutils,
3232
subprocess_make=subprocess_make,
3333
build_logical_id="logical_id",
34+
working_directory=working_directory,
3435
)
3536

3637
osutils.dirname.side_effect = lambda value: "/dir:{}".format(value)
@@ -40,48 +41,23 @@ def test_call_makefile_target(self, OSUtilMock, SubprocessMakeMock):
4041
action.execute()
4142

4243
subprocess_make.run.assert_called_with(
43-
["--makefile", "manifest", "build-logical_id"], cwd="scratch_dir", env=ANY
44-
)
45-
46-
@patch("aws_lambda_builders.workflows.custom_make.utils.OSUtils")
47-
@patch("aws_lambda_builders.workflows.custom_make.make.SubProcessMake")
48-
def test_call_makefile_target_with_working_directory(self, OSUtilMock, SubprocessMakeMock):
49-
osutils = OSUtilMock.return_value
50-
subprocess_make = SubprocessMakeMock.return_value
51-
52-
action = CustomMakeAction(
53-
"artifacts",
54-
"scratch_dir",
55-
"manifest",
56-
osutils=osutils,
57-
subprocess_make=subprocess_make,
58-
build_logical_id="logical_id",
59-
working_directory="working_dir",
60-
)
61-
62-
osutils.dirname.side_effect = lambda value: "/dir:{}".format(value)
63-
osutils.abspath.side_effect = lambda value: "/abs:{}".format(value)
64-
osutils.joinpath.side_effect = lambda a, b: "{}/{}".format(a, b)
65-
66-
action.execute()
67-
68-
subprocess_make.run.assert_called_with(
69-
["--makefile", "manifest", "build-logical_id"], cwd="working_dir", env=ANY
44+
["--makefile", "manifest", "build-logical_id"], cwd=working_directory, env=ANY
7045
)
7146

7247
@patch("aws_lambda_builders.workflows.custom_make.utils.OSUtils")
7348
@patch("aws_lambda_builders.workflows.custom_make.make.SubProcessMake")
7449
def test_makefile_target_fails(self, OSUtilMock, SubprocessMakeMock):
7550
osutils = OSUtilMock.return_value
7651
subprocess_make = SubprocessMakeMock.return_value
52+
working_directory = "some_dir"
7753

7854
action = CustomMakeAction(
7955
"artifacts",
80-
"scratch_dir",
8156
"manifest",
8257
osutils=osutils,
8358
subprocess_make=subprocess_make,
8459
build_logical_id="logical_id",
60+
working_directory=working_directory,
8561
)
8662

8763
osutils.dirname.side_effect = lambda value: "/dir:{}".format(value)
@@ -93,5 +69,5 @@ def test_makefile_target_fails(self, OSUtilMock, SubprocessMakeMock):
9369
with self.assertRaises(ActionFailedError):
9470
action.execute()
9571
subprocess_make.run.assert_called_with(
96-
["--makefile", "manifest", "build-logical_id"], cwd="scratch_dir", env=ANY
72+
["--makefile", "manifest", "build-logical_id"], cwd=working_directory, env=ANY
9773
)

tests/unit/workflows/custom_make/test_workflow.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,3 +64,35 @@ def test_use_working_directory(self):
6464
)
6565

6666
self.assertEqual(workflow.actions[1].working_directory, "working/dir/path")
67+
68+
def test_build_in_source(self):
69+
source_dir = "source"
70+
71+
workflow = CustomMakeWorkflow(
72+
source_dir,
73+
"artifacts",
74+
"scratch_dir",
75+
"manifest",
76+
options={"build_logical_id": "hello"},
77+
build_in_source=True,
78+
)
79+
80+
self.assertEqual(len(workflow.actions), 1)
81+
self.assertIsInstance(workflow.actions[0], CustomMakeAction)
82+
self.assertEqual(workflow.actions[0].working_directory, source_dir)
83+
84+
def test_build_in_source_with_custom_working_directory(self):
85+
working_dir = "working/dir/path"
86+
87+
workflow = CustomMakeWorkflow(
88+
"source",
89+
"artifacts",
90+
"scratch_dir",
91+
"manifest",
92+
options={"build_logical_id": "hello", "working_directory": working_dir},
93+
build_in_source=True,
94+
)
95+
96+
self.assertEqual(len(workflow.actions), 1)
97+
self.assertIsInstance(workflow.actions[0], CustomMakeAction)
98+
self.assertEqual(workflow.actions[0].working_directory, working_dir)

0 commit comments

Comments
 (0)