Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 33 additions & 2 deletions aws_lambda_builders/workflows/go_modules/builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
Build a Go project using standard Go tooling
"""
import logging
from pathlib import Path

from aws_lambda_builders.workflow import BuildMode
from aws_lambda_builders.architecture import X86_64, ARM64
Expand All @@ -21,7 +22,7 @@ class GoModulesBuilder(object):

LANGUAGE = "go"

def __init__(self, osutils, binaries, mode=BuildMode.RELEASE, architecture=X86_64, trim_go_path=False):
def __init__(self, osutils, binaries, handler, mode=BuildMode.RELEASE, architecture=X86_64, trim_go_path=False):
"""Initialize a GoModulesBuilder.

:type osutils: :class:`lambda_builders.utils.OSUtils`
Expand All @@ -42,6 +43,7 @@ def __init__(self, osutils, binaries, mode=BuildMode.RELEASE, architecture=X86_6
self.mode = mode
self.goarch = get_goarch(architecture)
self.trim_go_path = trim_go_path
self.handler = handler

def build(self, source_dir_path, output_path):
"""Builds a go project onto an output path.
Expand Down Expand Up @@ -69,6 +71,35 @@ def build(self, source_dir_path, output_path):
out, err = p.communicate()

if p.returncode != 0:
raise BuilderError(message=err.decode("utf8").strip())
LOG.debug(err.decode("utf8").strip())
LOG.debug("Go files not found. Attempting to build for Go files in a different directory")
process, p_out, p_err = self._attempt_to_build_from_handler(cmd, source_dir_path, env)
if process.returncode != 0:
raise BuilderError(message=p_err.decode("utf8").strip())
return p_out.decode("utf8").strip()

return out.decode("utf8").strip()

def _attempt_to_build_from_handler(self, cmd: list, source_dir_path: str, env: dict):
"""Builds Go files when package/source file in different directory

:type cmd: list
:param cmd: list of commands.

:type source_dir_path: str
:param source_dir_path: path to the source file/package.

:type env: dict
:param env: dictionary with environment variables.
"""

# Path to the source directory for Go files in a diff directory
cmd[-1] = str(Path(source_dir_path, self.handler))
LOG.debug(
"Go files not found at CodeUri %s . Descending into sub-directories to find the handler: %s",
source_dir_path,
cmd[-1],
)
p = self.osutils.popen(cmd, cwd=source_dir_path, env=env, stdout=self.osutils.pipe, stderr=self.osutils.pipe)
out, err = p.communicate()
return p, out, err
8 changes: 7 additions & 1 deletion aws_lambda_builders/workflows/go_modules/workflow.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,14 @@ def __init__(
output_path = osutils.joinpath(artifacts_dir, handler)

builder = GoModulesBuilder(
osutils, binaries=self.binaries, mode=mode, architecture=self.architecture, trim_go_path=trim_go_path
osutils,
binaries=self.binaries,
handler=handler,
mode=mode,
architecture=self.architecture,
trim_go_path=trim_go_path,
)

self.actions = [GoModulesBuildAction(source_dir, output_path, builder)]

def get_validators(self):
Expand Down
15 changes: 15 additions & 0 deletions tests/integration/workflows/go_modules/test_go.py
Original file line number Diff line number Diff line change
Expand Up @@ -181,3 +181,18 @@ def test_builds_with_trimpath_are_equal(self):
pathname = Path(self.artifacts_dir, "no-deps-main")
pathnameOfCopy = Path(self.artifacts_dir, "no-deps-main-copy")
self.assertEqual(get_md5_hexdigest(pathname), get_md5_hexdigest(pathnameOfCopy))

def test_builds_project_with_nested_dir(self):
source_dir = os.path.join(self.TEST_DATA_FOLDER, "nested_build_folder")
package_dir = os.path.join(source_dir, "cmd/helloWorld")
self.builder.build(
package_dir,
self.artifacts_dir,
self.scratch_dir,
os.path.join(source_dir, "go.mod"),
runtime=self.runtime,
options={"artifact_executable_name": "helloWorld"},
)
expected_files = {"helloWorld"}
output_files = set(os.listdir(self.artifacts_dir))
self.assertEqual(expected_files, output_files)
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package main

func main() {

}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module github.com/awslabs/aws-lambda-builders
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/aws/aws-lambda-go v1.8.0 h1:YMCzi9FP7MNVVj9AkGpYyaqh/mvFOjhqiDtnNlWtKTg=
github.com/aws/aws-lambda-go v1.8.0/go.mod h1:zUsUQhAUjYzR8AuduJPCfhBuKWUaDbQiPOG+ouzmE1A=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/urfave/cli.v1 v1.20.0/go.mod h1:vuBzUtMdQeixQj8LVd+/98pzhxNGQoyuPBlsXHOQNO0=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
34 changes: 27 additions & 7 deletions tests/unit/workflows/go_modules/test_builder.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from unittest import TestCase

from mock import patch, Mock
from pathlib import Path

from aws_lambda_builders.binary_path import BinaryPath
from aws_lambda_builders.workflows.go_modules.builder import GoModulesBuilder, BuilderError
Expand All @@ -21,14 +22,16 @@ class TestGoBuilder(TestCase):
def setUp(self, OSUtilMock):
self.osutils = OSUtilMock.return_value
self.osutils.pipe = "PIPE"
self.handler = "cmd/helloWorld"
self.popen = FakePopen()
self.osutils.popen.side_effect = [self.popen]
self.popen_go_case = FakePopen()
self.osutils.popen.side_effect = [self.popen, self.popen_go_case]
self.binaries = {"go": BinaryPath(resolver=Mock(), validator=Mock(), binary="go", binary_path="/path/to/go")}
self.under_test = GoModulesBuilder(self.osutils, self.binaries)
self.under_test = GoModulesBuilder(self.osutils, self.binaries, self.handler)

def test_run_executes_bundler_on_nixes(self):
self.osutils.is_windows.side_effect = [False]
self.under_test = GoModulesBuilder(self.osutils, self.binaries)
self.under_test = GoModulesBuilder(self.osutils, self.binaries, self.handler)
self.under_test.build("source_dir", "output_path")
self.osutils.popen.assert_called_with(
["/path/to/go", "build", "-o", "output_path", "source_dir"],
Expand All @@ -38,20 +41,37 @@ def test_run_executes_bundler_on_nixes(self):
stdout="PIPE",
)

def test_build_gofiles_in_different_directory(self):
self.popen.returncode = 1
self.popen_go_case.returncode = 0
self.osutils.is_windows.side_effect = [False]
self.under_test = GoModulesBuilder(self.osutils, self.binaries, self.handler)
self.under_test.build("source_dir_path", "output_path")

self.osutils.popen.assert_called_with(
["/path/to/go", "build", "-o", "output_path", str(Path("source_dir_path/cmd/helloWorld"))],
cwd="source_dir_path",
env={"GOOS": "linux", "GOARCH": "amd64"},
stderr="PIPE",
stdout="PIPE",
)

def test_returns_popen_out_decoded_if_retcode_is_0(self):
self.popen.out = b"some encoded text\n\n"
result = self.under_test.build("source_dir", "output_path")
self.assertEqual(result, "some encoded text")

def test_raises_BuilderError_with_err_text_if_retcode_is_not_0(self):
@patch("aws_lambda_builders.workflows.go_modules.builder.GoModulesBuilder._attempt_to_build_from_handler")
def test_raises_BuilderError_with_err_text_if_retcode_is_not_0(self, patched_helper):
patched_helper.return_value = self.popen, "", b"some error text\n\n"
self.popen.returncode = 1
self.popen.err = b"some error text\n\n"
with self.assertRaises(BuilderError) as raised:
self.under_test.build("source_dir", "output_path")
self.assertEqual(raised.exception.args[0], "Builder Failed: some error text")

def test_debug_configuration_set(self):
self.under_test = GoModulesBuilder(self.osutils, self.binaries, "Debug")
self.under_test = GoModulesBuilder(self.osutils, self.binaries, self.handler, "Debug")
self.under_test.build("source_dir", "output_path")
self.osutils.popen.assert_called_with(
["/path/to/go", "build", "-gcflags", "all=-N -l", "-o", "output_path", "source_dir"],
Expand All @@ -62,7 +82,7 @@ def test_debug_configuration_set(self):
)

def test_trimpath_configuration_set(self):
self.under_test = GoModulesBuilder(self.osutils, self.binaries, "release", "x86_64", True)
self.under_test = GoModulesBuilder(self.osutils, self.binaries, self.handler, "release", "x86_64", True)
self.under_test.build("source_dir", "output_path")
self.osutils.popen.assert_called_with(
["/path/to/go", "build", "-trimpath", "-o", "output_path", "source_dir"],
Expand All @@ -73,7 +93,7 @@ def test_trimpath_configuration_set(self):
)

def test_debug_configuration_set_with_arm_architecture(self):
self.under_test = GoModulesBuilder(self.osutils, self.binaries, "Debug", "arm64")
self.under_test = GoModulesBuilder(self.osutils, self.binaries, self.handler, "Debug", "arm64")
self.under_test.build("source_dir", "output_path")
self.osutils.popen.assert_called_with(
["/path/to/go", "build", "-gcflags", "all=-N -l", "-o", "output_path", "source_dir"],
Expand Down