Skip to content

Commit

Permalink
Merge pull request #45 from Nr18/fix/execute-failures
Browse files Browse the repository at this point in the history
fix: handling of aws and git failures
  • Loading branch information
Joris Conijn authored Feb 20, 2022
2 parents b038143 + db50f33 commit 9fb20be
Show file tree
Hide file tree
Showing 5 changed files with 121 additions and 18 deletions.
17 changes: 10 additions & 7 deletions pull_request_codecommit/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,16 @@ def main(
"""
pull-request-codecommit
"""
repo = __load_repository(repository_path=repository_path, target_branch=branch)
__display_repository_information(repo)
pr = __create_pull_request(repo)

if auto_merge:
status = pr.merge()
click.echo(f"Auto merging resulted in: {status}")
try:
repo = __load_repository(repository_path=repository_path, target_branch=branch)
__display_repository_information(repo)
pr = __create_pull_request(repo)

if auto_merge:
status = pr.merge()
click.echo(f"Auto merging resulted in: {status}")
except Exception as exception:
raise click.ClickException(str(exception))


def __load_repository(
Expand Down
11 changes: 10 additions & 1 deletion pull_request_codecommit/aws/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,16 @@ def base_command(self) -> List[str]:
def __execute(self, parameters: List[str]) -> str:
command = self.base_command
command.extend(parameters)
response = subprocess.run(command, stdout=subprocess.PIPE)
response = subprocess.run(
command, stdout=subprocess.PIPE, stderr=subprocess.PIPE
)

if response.returncode != 0:
message = response.stderr.decode("utf-8").strip("\n")
last_line = message.splitlines()[-1]
raise Exception(
f"Failed to execute: `{command}`\n\n{last_line}\n\nYou can execute the command manually to troubleshoot!"
)

return response.stdout.decode("utf-8").strip("\n")

Expand Down
15 changes: 14 additions & 1 deletion pull_request_codecommit/git/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,23 @@ def __init__(self, path: str):

def __execute(self, parameters: List[str]) -> str:
parameters.insert(0, "git")
response = subprocess.run(parameters, cwd=self.__path, stdout=subprocess.PIPE)
response = subprocess.run(
parameters, cwd=self.__path, stdout=subprocess.PIPE, stderr=subprocess.PIPE
)

if response.returncode != 0:
last_line = self.__resolve_error_message(response.stderr)
command = " ".join(parameters)
raise Exception(
f"Failed to execute: `{command}`\n\n{last_line}\n\nYou can execute the command manually to troubleshoot!"
)

return response.stdout.decode("utf-8").strip("\n")

def __resolve_error_message(self, stderr: bytes) -> str:
message = stderr.decode("utf-8").strip("\n")
return message.splitlines()[-1]

def remote(self, name: str = "origin") -> str:
return self.__execute(["config", "--get", f"remote.{name}.url"])

Expand Down
42 changes: 41 additions & 1 deletion tests/test_command.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,11 @@ def edit_message(message: str) -> str:
return message


def aws_client_execute_side_effect(parameters, stdout) -> MagicMock:
def aws_client_execute_side_effect(parameters, stdout, stderr) -> MagicMock:
data: Dict[str, Any] = {}
assert -1 == stdout
mock_stdout = MagicMock()
mock_stdout.returncode = 0

if "create-pull-request" in parameters:
data = {"pullRequest": {"pullRequestId": "1"}}
Expand Down Expand Up @@ -250,3 +251,42 @@ def test_invoke_no_repository_name(
result = runner.invoke(main)
assert result.exit_code == 1
assert "Error: The repository is not compatible with this tool!" in result.output


@pytest.mark.parametrize(
"remote, region, profile, config, commits, parameters",
generate_invoke_parameters([[]]),
)
@patch("pull_request_codecommit.aws.client.subprocess.run")
@patch("pull_request_codecommit.repository.GitClient")
@patch("pull_request_codecommit.click.edit")
def test_aws_failure(
mock_edit: MagicMock,
mock_git_client: MagicMock,
mock_aws_client: MagicMock,
remote: str,
region: str,
profile: str,
config: bytes,
commits: str,
parameters: List[str],
) -> None:
mock_edit.side_effect = edit_message
mock_git_client.return_value.get_commit_messages.return_value = Commits(commits)

mock_git_client.return_value.remote.return_value = remote
mock_git_client.return_value.current_branch = "feat/my-feature"

def side_effect(parameters, stdout, stderr):
data = {}
mock_stdout = MagicMock()
mock_stdout.stderr = bytes("Some aws failure", "utf-8")
mock_stdout.returncode = 1
return mock_stdout

configparser.open = MagicMock(return_value=TextIOWrapper(BytesIO(config))) # type: ignore
mock_aws_client.side_effect = side_effect

runner = CliRunner()
result = runner.invoke(main, parameters)
assert result.exit_code == 1
54 changes: 46 additions & 8 deletions tests/test_git_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,13 @@ def test_remote(
) -> None:
mock_isdir.return_value = True

def execute(parameters, cwd, stdout):
def execute(parameters, cwd, stdout, stderr):
assert path == cwd
assert -1 == stdout
assert -1 == stderr
mock_stdout = MagicMock()
mock_stdout.stdout = bytes(f"\n\n{remote}\n\n", "utf-8")
mock_stdout.returncode = 0
return mock_stdout

mock_run.side_effect = execute
Expand Down Expand Up @@ -62,11 +64,13 @@ def test_current_branch(
) -> None:
mock_isdir.return_value = True

def execute(parameters, cwd, stdout):
def execute(parameters, cwd, stdout, stderr):
assert path == cwd
assert -1 == stdout
assert -1 == stderr
mock_stdout = MagicMock()
mock_stdout.stdout = bytes(f"\n\n{branch}\n\n", "utf-8")
mock_stdout.returncode = 0
return mock_stdout

mock_run.side_effect = execute
Expand All @@ -91,11 +95,13 @@ def test_get_commit_messages(
) -> None:
mock_isdir.return_value = True

def execute(parameters, cwd, stdout):
def execute(parameters, cwd, stdout, stderr):
assert path == cwd
assert -1 == stdout
assert -1 == stderr
mock_stdout = MagicMock()
mock_stdout.stdout = bytes(COMMITS, "utf-8")
mock_stdout.returncode = 0
return mock_stdout

mock_run.side_effect = execute
Expand All @@ -116,10 +122,12 @@ def execute(parameters, cwd, stdout):
def test_get_no_commit_messages(mock_isdir: MagicMock, mock_run: MagicMock) -> None:
mock_isdir.return_value = True

def execute(parameters, cwd, stdout):
def execute(parameters, cwd, stdout, stderr):
assert -1 == stdout
assert -1 == stderr
mock_stdout = MagicMock()
mock_stdout.stdout = bytes("", "utf-8")
mock_stdout.returncode = 0
return mock_stdout

mock_run.side_effect = execute
Expand All @@ -134,11 +142,13 @@ def execute(parameters, cwd, stdout):
def test_push(mock_isdir: MagicMock, mock_run: MagicMock) -> None:
mock_isdir.return_value = True

def execute(parameters, cwd, stdout):
def execute(parameters, cwd, stdout, stderr):
assert parameters == ["git", "push", "--set-upstream", "origin", "HEAD"]
assert -1 == stdout
assert -1 == stderr
mock_stdout = MagicMock()
mock_stdout.stdout = bytes("", "utf-8")
mock_stdout.returncode = 0
return mock_stdout

mock_run.side_effect = execute
Expand All @@ -150,11 +160,13 @@ def execute(parameters, cwd, stdout):
def test_pull(mock_isdir: MagicMock, mock_run: MagicMock) -> None:
mock_isdir.return_value = True

def execute(parameters, cwd, stdout):
def execute(parameters, cwd, stdout, stderr):
assert parameters == ["git", "pull"]
assert -1 == stdout
assert -1 == stderr
mock_stdout = MagicMock()
mock_stdout.stdout = bytes("", "utf-8")
mock_stdout.returncode = 0
return mock_stdout

mock_run.side_effect = execute
Expand All @@ -166,11 +178,13 @@ def execute(parameters, cwd, stdout):
def test_delete_branch(mock_isdir: MagicMock, mock_run: MagicMock) -> None:
mock_isdir.return_value = True

def execute(parameters, cwd, stdout):
def execute(parameters, cwd, stdout, stderr):
assert parameters == ["git", "branch", "-d", "feat/my-feature"]
assert -1 == stdout
assert -1 == stderr
mock_stdout = MagicMock()
mock_stdout.stdout = bytes("", "utf-8")
mock_stdout.returncode = 0
return mock_stdout

mock_run.side_effect = execute
Expand All @@ -182,12 +196,36 @@ def execute(parameters, cwd, stdout):
def test_checkout(mock_isdir: MagicMock, mock_run: MagicMock) -> None:
mock_isdir.return_value = True

def execute(parameters, cwd, stdout):
def execute(parameters, cwd, stdout, stderr):
assert parameters == ["git", "checkout", "master"]
assert -1 == stdout
assert -1 == stderr
mock_stdout = MagicMock()
mock_stdout.stdout = bytes("", "utf-8")
mock_stdout.returncode = 0
return mock_stdout

mock_run.side_effect = execute
Client("my-path").checkout("master")


@patch("pull_request_codecommit.git.client.subprocess.run")
@patch("pull_request_codecommit.git.client.os.path.isdir")
def test_git_failure(mock_isdir: MagicMock, mock_run: MagicMock) -> None:
mock_isdir.return_value = True

def execute(parameters, cwd, stdout, stderr):
assert parameters == ["git", "checkout", "master"]
assert -1 == stdout
assert -1 == stderr
mock_stdout = MagicMock()
mock_stdout.stderr = bytes("some git failure", "utf-8")
mock_stdout.returncode = 1
return mock_stdout

mock_run.side_effect = execute

with pytest.raises(Exception) as exception:
Client("my-path").checkout("master")

assert "some git failure" in str(exception.value)

0 comments on commit 9fb20be

Please sign in to comment.