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
19 changes: 7 additions & 12 deletions samcli/commands/build/build_context.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,21 +73,16 @@ def __exit__(self, *args):

@staticmethod
def _setup_build_dir(build_dir, clean):
build_path = pathlib.Path(build_dir)

# Get absolute path
build_dir = str(pathlib.Path(build_dir).resolve())

if not pathlib.Path(build_dir).exists():
# Build directory does not exist. Create the directory and all intermediate paths
os.makedirs(build_dir, BuildContext._BUILD_DIR_PERMISSIONS)

if os.listdir(build_dir) and clean:
# Build folder contains something inside. Clear everything.
if build_path.exists() and os.listdir(build_dir) and clean:
# build folder contains something inside. Clear everything.
shutil.rmtree(build_dir)
# this would have cleared the parent folder as well. So recreate it.
os.mkdir(build_dir, BuildContext._BUILD_DIR_PERMISSIONS)

return build_dir
build_path.mkdir(mode=BuildContext._BUILD_DIR_PERMISSIONS, parents=True, exist_ok=True)

# ensure path resolving is done after creation: https://bugs.python.org/issue32434
return str(build_path.resolve())

@property
def container_manager(self):
Expand Down
87 changes: 86 additions & 1 deletion tests/unit/commands/buildcmd/test_build_context.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import os

from unittest import TestCase
from mock import patch, Mock

Expand Down Expand Up @@ -52,3 +51,89 @@ def test_must_setup_context(self, ContainerManagerMock, pathlib_mock, SamFunctio
setup_build_dir_mock.assert_called_with("build_dir", True)
ContainerManagerMock.assert_called_once_with(docker_network_id="network",
skip_pull_image=True)


class TestBuildContext_setup_build_dir(TestCase):

@patch("samcli.commands.build.build_context.shutil")
@patch("samcli.commands.build.build_context.os")
@patch("samcli.commands.build.build_context.pathlib")
def test_build_dir_exists_with_non_empty_dir(self, pathlib_patch, os_patch, shutil_patch):
path_mock = Mock()
pathlib_patch.Path.return_value = path_mock
os_patch.listdir.return_value = True
path_mock.resolve.return_value = "long/full/path"
path_mock.exists.return_value = True
build_dir = "/somepath"

full_build_path = BuildContext._setup_build_dir(build_dir, True)

self.assertEquals(full_build_path, "long/full/path")

os_patch.listdir.assert_called_once()
path_mock.exists.assert_called_once()
path_mock.mkdir.assert_called_once_with(mode=0o755, parents=True, exist_ok=True)
Copy link
Contributor

@sriram-mv sriram-mv Apr 9, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: can we use BuildContext._BUILD_DIR_PERMISSIONS here instead of 755 explicitly.

edit: thought about it, it would be like accessing protected member, so never mind.

pathlib_patch.Path.assert_called_once_with(build_dir)
shutil_patch.rmtree.assert_called_once_with(build_dir)

@patch("samcli.commands.build.build_context.shutil")
@patch("samcli.commands.build.build_context.os")
@patch("samcli.commands.build.build_context.pathlib")
def test_build_dir_exists_with_empty_dir(self, pathlib_patch, os_patch, shutil_patch):
path_mock = Mock()
pathlib_patch.Path.return_value = path_mock
os_patch.listdir.return_value = False
path_mock.resolve.return_value = "long/full/path"
path_mock.exists.return_value = True
build_dir = "/somepath"

full_build_path = BuildContext._setup_build_dir(build_dir, True)

self.assertEquals(full_build_path, "long/full/path")

os_patch.listdir.assert_called_once()
path_mock.exists.assert_called_once()
path_mock.mkdir.assert_called_once_with(mode=0o755, parents=True, exist_ok=True)
pathlib_patch.Path.assert_called_once_with(build_dir)
shutil_patch.rmtree.assert_not_called()

@patch("samcli.commands.build.build_context.shutil")
@patch("samcli.commands.build.build_context.os")
@patch("samcli.commands.build.build_context.pathlib")
def test_build_dir_does_not_exist(self, pathlib_patch, os_patch, shutil_patch):
path_mock = Mock()
pathlib_patch.Path.return_value = path_mock
path_mock.resolve.return_value = "long/full/path"
path_mock.exists.return_value = False
build_dir = "/somepath"

full_build_path = BuildContext._setup_build_dir(build_dir, True)

self.assertEquals(full_build_path, "long/full/path")

os_patch.listdir.assert_not_called()
path_mock.exists.assert_called_once()
path_mock.mkdir.assert_called_once_with(mode=0o755, parents=True, exist_ok=True)
pathlib_patch.Path.assert_called_once_with(build_dir)
shutil_patch.rmtree.assert_not_called()

@patch("samcli.commands.build.build_context.shutil")
@patch("samcli.commands.build.build_context.os")
@patch("samcli.commands.build.build_context.pathlib")
def test_non_clean_build_when_dir_exists_with_non_empty_dir(self, pathlib_patch, os_patch, shutil_patch):
path_mock = Mock()
pathlib_patch.Path.return_value = path_mock
os_patch.listdir.return_value = True
path_mock.resolve.return_value = "long/full/path"
path_mock.exists.return_value = True
build_dir = "/somepath"

full_build_path = BuildContext._setup_build_dir(build_dir, False)

self.assertEquals(full_build_path, "long/full/path")

os_patch.listdir.assert_called_once()
path_mock.exists.assert_called_once()
path_mock.mkdir.assert_called_once_with(mode=0o755, parents=True, exist_ok=True)
pathlib_patch.Path.assert_called_once_with(build_dir)
shutil_patch.rmtree.assert_not_called()