Skip to content

Commit 47cc2e7

Browse files
authored
fix: Makefile workflow to stream output (#399)
1 parent d8c7a19 commit 47cc2e7

File tree

2 files changed

+35
-14
lines changed

2 files changed

+35
-14
lines changed

aws_lambda_builders/workflows/custom_make/make.py

Lines changed: 27 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
"""
22
Wrapper around calling make through a subprocess.
33
"""
4-
4+
import io
55
import logging
6+
import subprocess
7+
import shutil
8+
import threading
69

710
LOG = logging.getLogger(__name__)
811

@@ -82,14 +85,26 @@ def run(self, args, env=None, cwd=None):
8285

8386
p = self.osutils.popen(invoke_make, stdout=self.osutils.pipe, stderr=self.osutils.pipe, cwd=cwd, env=env)
8487

85-
out, err = p.communicate()
86-
87-
# Typically this type of information is logged to DEBUG, however, since the Make builder
88-
# can be different per customer's use case, it is helpful to always log the output so
89-
# developers can diagnose any issues.
90-
LOG.info(out.decode("utf8").strip())
91-
92-
if p.returncode != 0:
93-
raise MakeExecutionError(message=err.decode("utf8").strip())
94-
95-
return out.decode("utf8").strip()
88+
# Create a stdout variable that will contain the final stitched stdout result
89+
stdout = ""
90+
# Create a buffer and use a thread to gather the stderr stream into the buffer
91+
stderr_buf = io.BytesIO()
92+
stderr_thread = threading.Thread(target=shutil.copyfileobj, args=(p.stderr, stderr_buf), daemon=True)
93+
stderr_thread.start()
94+
95+
# Log every stdout line by iterating
96+
for line in p.stdout:
97+
decoded_line = line.decode("utf-8").strip()
98+
LOG.info(decoded_line)
99+
# Gather total stdout
100+
stdout += decoded_line
101+
102+
# Wait for the process to exit and stderr thread to end.
103+
return_code = p.wait()
104+
stderr_thread.join()
105+
106+
if return_code != 0:
107+
# Raise an Error with the appropriate value from the stderr buffer.
108+
raise MakeExecutionError(message=stderr_buf.getvalue().decode("utf8").strip())
109+
110+
return stdout

tests/unit/workflows/custom_make/test_make.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import io
12
from unittest import TestCase
23
from mock import patch
34

@@ -8,11 +9,16 @@ class FakePopen:
89
def __init__(self, out=b"out", err=b"err", retcode=0):
910
self.out = out
1011
self.err = err
12+
self.stderr = io.BytesIO(err)
13+
self.stdout = [out]
1114
self.returncode = retcode
1215

1316
def communicate(self):
1417
return self.out, self.err
1518

19+
def wait(self):
20+
return self.returncode
21+
1622

1723
class TestSubprocessMake(TestCase):
1824
@patch("aws_lambda_builders.workflows.custom_make.utils.OSUtils")
@@ -67,15 +73,15 @@ def test_uses_env_and_cwd_if_supplied(self):
6773
)
6874

6975
def test_returns_popen_out_decoded_if_retcode_is_0(self):
70-
self.popen.out = b"some encoded text\n\n"
76+
self.popen.stdout = [b"some encoded text\n\n"]
7177

7278
result = self.under_test.run(["build_logical_id"])
7379

7480
self.assertEqual(result, "some encoded text")
7581

7682
def test_raises_MakeExecutionError_with_err_text_if_retcode_is_not_0(self):
7783
self.popen.returncode = 1
78-
self.popen.err = b"some error text\n\n"
84+
self.popen.stderr = io.BytesIO(b"some error text\n\n")
7985

8086
with self.assertRaises(MakeExecutionError) as raised:
8187
self.under_test.run(["build-logical_id"])

0 commit comments

Comments
 (0)