Skip to content

Commit

Permalink
Merge pull request #6 from Nr18/develop
Browse files Browse the repository at this point in the history
chore: create release
  • Loading branch information
Joris Conijn authored Jan 24, 2022
2 parents 2f91eb0 + 9059558 commit 1286343
Show file tree
Hide file tree
Showing 17 changed files with 734 additions and 36 deletions.
4 changes: 1 addition & 3 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,4 @@ __pycache__
*.egg-info
dist
.coverage
sample-reports/*.xml
rules
tests/rules/
/my-repo
33 changes: 20 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,13 @@
[![Maintenance](https://img.shields.io/badge/Maintained-yes-green.svg)](https://github.com/Nr18/pull-request-codecommit/graphs/commit-activity)
[![GitHub release](https://img.shields.io/github/release/Nr18/pull-request-codecommit.svg)](https://github.com/Nr18/pull-request-codecommit/releases/)
[![Continuous Integration](https://github.com/Nr18/pull-request-codecommit/actions/workflows/ci.yml/badge.svg)](https://github.com/Nr18/pull-request-codecommit/actions/workflows/ci.yml)
[![codecov](https://codecov.io/gh/Nr18/pull-request-codecommit/branch/main/graph/badge.svg?token=RMPJ8DBMKZ)](https://codecov.io/gh/Nr18/pull-request-codecommit)
[![codecov](https://codecov.io/gh/Nr18/pull-request-codecommit/branch/main/graph/badge.svg?token=H6zsiLbNjP)](https://codecov.io/gh/Nr18/pull-request-codecommit)

TODO
> Note, this project is still under development and is not functional yet!
This tool makes it easy to create pull requests for [AWS CodeCommit](https://aws.amazon.com/codecommit/). It relies on the
[Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) standard. It looks at the git commits between the
current and the destination branch. Then it tries to create a pull request with this information as input.

## Installation

Expand All @@ -27,20 +31,17 @@ source .venv/bin/activate
pip install pull_request_codecommit
```

## Alternative installation: Docker

Build the docker image

```bash
docker build -t pull-request-codecommit-docker .
```
## Configuration

#### Docker usage
The tool uses the following file `~/.aws/pull-request-codecommit`. It will first load the `default` profile and then, if
provided the profile specific settings.

Run the `pull-request-codecommit` command as follows
```ini
[profile default]
branch=main

```bash
docker run --rm -it -v `pwd`:/tests pull-request-codecommit-docker pull-request-codecommit
[profile acme-profile]
branch=develop
```

## Usage
Expand All @@ -50,3 +51,9 @@ To use `pull-request-codecommit` you just execute the following command:
```bash
pull-request-codecommit
```

## Testing locally

```bash
./create_repo.sh
```
52 changes: 52 additions & 0 deletions create_repo.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
#!/usr/bin/env bash

REPOSITORY=my-repo

set -e

rm -rf "${REPOSITORY}"
mkdir "${REPOSITORY}"
pushd "${REPOSITORY}"
touch README.md
git init
git remote add origin codecommit::eu-west-1://my-profile@repository
git add README.md
git commit -m "feat: initial commit"

git checkout -b documentation-update

echo "# ${REPOSITORY}" >> README.md
echo "" >> README.md
echo "This is a test repository with multiple commits. These commits can be used to test the pull-request-codecommit tool." >> README.md
git add README.md
git commit -m "feat: initial README setup
Because it is a good practice to describe what a repository is doing we add it to the README.md.
Issue: #1"

echo "" >> README.md
echo "We want to support multiple commits" >> README.md

git add README.md
git commit -m "docs: describe multiple commits
Issue: #1"

echo "" >> README.md
echo "Even more and different issue number" >> README.md

git add README.md
git commit -m "chore: other issue number
Issue: #2"

echo "" >> README.md
echo "Even more and different style issue number" >> README.md

git add README.md
git commit -m "refactor: use jira style issue number
fixes issue JIRA-1234"

poetry run pull-request-codecommit
18 changes: 2 additions & 16 deletions poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

32 changes: 30 additions & 2 deletions pull_request_codecommit/__init__.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,41 @@
from typing import Optional

import click

from pull_request_codecommit.repository import Repository


@click.command()
def main() -> None:
@click.option("-r", "--repository-path", default=None)
def main(repository_path: Optional[str]) -> None:
"""
pull-request-codecommit
"""
click.echo("TODO: Implement me!")
repo = Repository(repository_path)

if not repo.supported:
raise click.ClickException("The repository is not compatible with this tool!")

click.echo(f"Remote: {repo.remote}")
click.echo(f"Region: {repo.aws_region}")
click.echo(f"Profile: {repo.aws_profile}")
click.echo(f"Repo: {repo.repository_name}")
click.echo(f"Branch: {repo.branch}")
click.echo()
title, description = repo.pull_request_information()

message = click.edit(f"{title}\n\n{description}")

if message is None:
raise click.ClickException("Pull request was not created")

title = message.splitlines()[0]
description = "\n".join(message.splitlines()[1:])
link = repo.create_pull_request(title, description)
click.echo(f"Please review/approve: {link}")
click.echo()
click.echo(click.style(title, bold=True))
click.echo(description)


if __name__ == "__main__":
Expand Down
1 change: 1 addition & 0 deletions pull_request_codecommit/aws/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from .client import Client
46 changes: 46 additions & 0 deletions pull_request_codecommit/aws/client.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
from __future__ import annotations

import json
from typing import List
import subprocess


class Client:
"""
Understands aws operations
We use the AWS CLI for these operations so that we can use tha MFA toke cache from the cli.
"""

def __init__(self, profile: str, region: str) -> None:
self.__profile = profile
self.__region = region

def __execute(self, parameters: List[str]) -> str:
command = ["aws", "--profile", self.__profile, "--region", self.__region]
command.extend(parameters)
response = subprocess.run(command, stdout=subprocess.PIPE)

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

def create_pull_request(
self,
title: str,
description: str,
repository: str,
source: str,
destination: str,
) -> dict:
command = [
"codecommit",
"create-pull-request",
"--title",
title,
"--description",
description,
"--targets",
f"repositoryName={repository}, sourceReference={source}, destinationReference={destination}",
]
response = self.__execute(command)
data = json.loads(response)
return data.get("pullRequest")
50 changes: 50 additions & 0 deletions pull_request_codecommit/config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
from typing import Dict, Optional

import configparser
from pathlib import Path


class Config:
"""
Understands the configuration of the pull-request-codecommit tool.
"""

__cached_config: Dict[str, Dict[str, str]] = {}
__config_file: Optional[configparser.ConfigParser] = None

@classmethod
def __default_config(cls) -> Dict[str, str]:
return cls.__load_config("default")

@classmethod
def __get_config_value(cls, profile: str, key: str) -> str:
if profile not in cls.__cached_config:
cls.__cached_config[profile] = cls.__default_config()
cls.__cached_config[profile].update(cls.__load_config(profile))

return cls.__cached_config[profile].get(key, "")

@classmethod
def __user_config(cls) -> configparser.ConfigParser:
if not cls.__config_file:
cls.__config_file = configparser.ConfigParser()
cls.__config_file.read(f"{Path.home()}/.aws/pull-request-codecommit")

return cls.__config_file

@classmethod
def __load_config(cls, profile: str) -> Dict[str, str]:
config = {}

if profile != "default":
profile = f"profile {profile}"

if profile in cls.__user_config().sections():
for key, value in list(cls.__user_config().items(profile)):
config[key] = value

return config

@classmethod
def destination_branch(cls, profile: str) -> str:
return cls.__get_config_value(profile, "branch")
4 changes: 4 additions & 0 deletions pull_request_codecommit/git/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
from .commits import Commits
from .commit import Commit
from .message import Message
from .client import Client
37 changes: 37 additions & 0 deletions pull_request_codecommit/git/client.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
from __future__ import annotations
from typing import List
import os.path
import subprocess
from .commits import Commits


class Client:
"""
Understands git operations
"""

def __init__(self, path: str):
if not os.path.isdir(path):
raise NotADirectoryError(f"The {path} is not a directory.")

self.__path: str = path

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

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

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

@property
def current_branch(self) -> str:
return self.__execute(["branch", "--show-current"])

def get_commit_messages(self, destination_branch: str) -> Commits:
messages = self.__execute(
["log", f"{destination_branch}..{self.current_branch}"]
)

return Commits(messages)
17 changes: 17 additions & 0 deletions pull_request_codecommit/git/commit.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
from .message import Message


class Commit:
"""
Understands git commit
"""

def __init__(self, commit: str, author: str, date: str, message: Message) -> None:
self.__commit: str = commit
self.__author: str = author
self.__date: str = date
self.__message: Message = message

@property
def message(self) -> Message:
return self.__message
Loading

0 comments on commit 1286343

Please sign in to comment.