Skip to content

Commit

Permalink
Linting and formatting (#30)
Browse files Browse the repository at this point in the history
---
fel-version: 0.3.2
fel-stack: devel
fel-stack-index: 2
fel-branch: fel/devel/2
fel-amended-from: 33bbd6c
fel-pr: 30
  • Loading branch information
Zabot committed Jun 10, 2021
1 parent 25c0f82 commit 9fc8cf6
Show file tree
Hide file tree
Showing 20 changed files with 483 additions and 328 deletions.
3 changes: 2 additions & 1 deletion .github/workflows/python-package.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,13 @@ jobs:
run: |
python -m pip install poetry
poetry install
- name: Lint with flake8
- name: Lint
run: |
# stop the build if there are Python syntax errors or undefined names
poetry run flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
# exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide
poetry run flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
poetry run black --check fel test
- name: Configure git
run: |
git config --global user.email "[email protected]"
Expand Down
149 changes: 87 additions & 62 deletions fel/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,20 @@

from . import __version__
from .config import load_config
from .submit import submit, submit_stack
from .submit import submit_stack
from .land import land
from .stack import Stack, StackProgress
from .pr import update_prs
from .meta import parse_meta
from .mergeability import is_mergeable
from .style import *
from .stack_spinner import Spinner, ThreadGroup
import time

from . import style


def _submit(repo, gh_repo, _, config):
stack = Stack(repo, repo.head.commit, repo.heads[config['upstream']])
with Spinner('') as spinner:
stack = Stack(repo, repo.head.commit, repo.heads[config["upstream"]])
with Spinner("") as spinner:
sp = StackProgress(stack, spinner.print)
spinner.label = sp

Expand All @@ -40,109 +41,128 @@ def _submit(repo, gh_repo, _, config):
# Rewrite the PRs to include the fel stack
update_prs(gh_repo, stack, sp)


def _land(repo, gh_repo, args, config):
land(repo,
repo.head.commit,
gh_repo,
repo.heads[config['upstream']],
config['branch_prefix'],
admin_merge=args.admin,
)
land(
repo,
repo.head.commit,
gh_repo,
repo.heads[config["upstream"]],
config["branch_prefix"],
admin_merge=args.admin,
)

repo.remote().fetch(prune=True)


def _stack(repo, gh_repo, args, config):
s = Stack(repo, repo.head.commit, repo.heads[config['upstream']])
s = Stack(repo, repo.head.commit, repo.heads[config["upstream"]])
s.annotate()
s.push()


def _status(repo, gh_repo, __, config):
stack = Stack(repo, repo.head.commit, repo.heads[config['upstream']])
stack = Stack(repo, repo.head.commit, repo.heads[config["upstream"]])

with Spinner('') as spinner:
with Spinner("") as spinner:
sp = StackProgress(stack, spinner.print)
spinner.label = sp

with sp.start('Fetching PR Info'):
with sp.start("Fetching PR Info"):

def get_status(commit, pr_num):
"""Retrieve the status of a pull request"""
pr = gh_repo.get_pull(pr_num)

mergeable, message, temp = is_mergeable(gh_repo, pr, config['upstream'])
mergeable, message, temp = is_mergeable(gh_repo, pr, config["upstream"])

icon = ""
if mergeable:
icon = ok + '✓'
icon = style.ok + "✓"
elif temp:
icon = warn + '• '
icon = style.warn + "• "
else:
icon = fail + '✖ '
icon = style.fail + "✖ "

status = f"{icon}{message}{default}"
status = f"{icon}{message}{style.default}"

sp[commit] = f"{context}#{pr_num}{default} {status} {commit.summary} {dull}{pr_link}{default}"
sp[
commit
] = f"{style.context}#{pr_num}{style.default} {status} {commit.summary} {style.dull}{pr_link}{style.default}"

with ThreadGroup() as tasks:
for commit in stack.commits():
_, meta = parse_meta(commit.message)
try:
pr_num = meta['fel-pr']
pr_num = meta["fel-pr"]
pr_link = f"{gh_repo.html_url}/pull/{pr_num}"

tasks.do(get_status, commit, pr_num)
sp[commit] = f"{context}#{pr_num}{default} {info}{{spinner}} Fetching PR info{default} {commit.summary} {dull}{pr_link}{default}"
sp[
commit
] = f"{style.context}#{pr_num}{style.default} {style.info}{{spinner}} Fetching PR info{style.default} {commit.summary} {style.dull}{pr_link}{style.default}"

except KeyError:
try:
branch = meta['fel-branch']
sp[commit] = f"{context}{branch}{default} {commit.summary}"
branch = meta["fel-branch"]
sp[
commit
] = f"{style.context}{branch}{style.default} {commit.summary}"

except KeyError:
sp[commit] = f"{context}{commit.hexsha[:8]}{default} {commit.summary}"
sp[
commit
] = f"{style.context}{commit.hexsha[:8]}{style.default} {commit.summary}"


def main():
parser = argparse.ArgumentParser()
parser.add_argument('-C',
metavar='path',
type=Path,
help='change directory to path before running fel',
)
parser.add_argument('-f', '--config',
metavar='config',
type=Path,
help='fel config file',
default=Path.home().joinpath('.fel.yml'),
)
parser.add_argument('--verbose',
action='store_true',
help='display verbose logging information',
)
parser.add_argument('--version',
action='store_true',
help='display version information',
)
parser.add_argument(
"-C",
metavar="path",
type=Path,
help="change directory to path before running fel",
)
parser.add_argument(
"-f",
"--config",
metavar="config",
type=Path,
help="fel config file",
default=Path.home().joinpath(".fel.yml"),
)
parser.add_argument(
"--verbose",
action="store_true",
help="display verbose logging information",
)
parser.add_argument(
"--version",
action="store_true",
help="display version information",
)

subparsers = parser.add_subparsers()

submit_parser = subparsers.add_parser('submit')
submit_parser = subparsers.add_parser("submit")
submit_parser.set_defaults(func=_submit)

land_parser = subparsers.add_parser('land')
land_parser.add_argument('--admin',
action='store_true',
help='admin merge all PRs',
)
land_parser = subparsers.add_parser("land")
land_parser.add_argument(
"--admin",
action="store_true",
help="admin merge all PRs",
)
land_parser.set_defaults(func=_land)

status_parser = subparsers.add_parser('status')
status_parser = subparsers.add_parser("status")
status_parser.set_defaults(func=_status)

stack_parser = subparsers.add_parser('stack')
stack_parser = subparsers.add_parser("stack")
stack_parser.set_defaults(func=_stack)

args = parser.parse_args()


try:
config = load_config(args.config)
except IOError as ex:
Expand All @@ -152,10 +172,14 @@ def main():
logging.error("Missing required config field: %s", ex)
return 2

if config['check_for_updates']:
latest = requests.get('https://pypi.org/pypi/fel/json').json()['info']['version']
if config["check_for_updates"]:
latest = requests.get("https://pypi.org/pypi/fel/json").json()["info"][
"version"
]
if latest != __version__:
print("You are running fel {}, the latest is {}".format(__version__, latest))
print(
"You are running fel {}, the latest is {}".format(__version__, latest)
)

if args.verbose:
logging.basicConfig(level=logging.INFO)
Expand All @@ -172,18 +196,18 @@ def main():
repo = git.Repo(repo_root)

# Login to github and find the repo
gh_client = Github(config['gh_token'])
gh_client = Github(config["gh_token"])

# Get the fel branch prefix
username = gh_client.get_user().login.lower()
config['branch_prefix'] = "fel/{}".format(username)
config["branch_prefix"] = "fel/{}".format(username)

# Find the github repo associated with the local repo's remote
try:
remote_url = next(repo.remote().urls)
match = re.match(r"(?:git@|https://)github.com[:/](.*/.*)", remote_url)
gh_slug = match.group(1)
if gh_slug.endswith('.git'):
if gh_slug.endswith(".git"):
gh_slug = gh_slug[:-4]
gh_repo = gh_client.get_repo(gh_slug)

Expand All @@ -202,5 +226,6 @@ def main():

return 0

if __name__ == '__main__':

if __name__ == "__main__":
main()
9 changes: 5 additions & 4 deletions fel/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,14 @@

# These configs are populated by default
default_config = {
'upstream': 'master',
'check_for_updates': True,
'gh_token': None,
"upstream": "master",
"check_for_updates": True,
"gh_token": None,
}

# These fields are required to be non-null
required_fields = ['gh_token']
required_fields = ["gh_token"]


def load_config(filepath):
config = default_config
Expand Down
30 changes: 22 additions & 8 deletions fel/land.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,16 @@
from .submit import submit
from .mergeability import is_mergeable, wait_for_checks

def land(repo, commit, gh_repo, upstream, branch_prefix, admin_merge=False, wait_for_merge=True):

def land(
repo,
commit,
gh_repo,
upstream,
branch_prefix,
admin_merge=False,
wait_for_merge=True,
):
logging.info("landing %s on %s", commit, upstream)

# We can't handle merge commits
Expand All @@ -19,33 +28,36 @@ def land(repo, commit, gh_repo, upstream, branch_prefix, admin_merge=False, wait
return {}

# Make sure that our parent is already landed
rebased = land(repo, commit.parents[0], gh_repo, upstream, branch_prefix, admin_merge)
rebased = land(
repo, commit.parents[0], gh_repo, upstream, branch_prefix, admin_merge
)

# If landing commit's parent rebased commit, update commit to what it was rebased to
commit = rebased.get(commit, commit)

# Tell github to merge the PR
_, meta = parse_meta(commit.message)
try:
pr_num = meta['fel-pr']
diff_branch = repo.heads[meta['fel-branch']]
pr_num = meta["fel-pr"]
diff_branch = repo.heads[meta["fel-branch"]]

# Land the PR
logging.info("merging %s", commit)
pr = gh_repo.get_pull(pr_num)


mergeable, status, wait = is_mergeable(gh_repo, pr, upstream.name)

if wait and wait_for_merge:
mergeable, status = wait_for_checks(gh_repo, pr, upstream.name)

if not mergeable and not admin_merge:
logging.error("Merge is blocked, run with --admin to force merge: %s", status)
logging.error(
"Merge is blocked, run with --admin to force merge: %s", status
)
raise SystemExit()

try:
status = pr.merge(merge_method='squash')
status = pr.merge(merge_method="squash")
if not status.merged:
logging.error("Failed to merge pr %s", status.message)
raise SystemExit()
Expand All @@ -66,7 +78,9 @@ def land(repo, commit, gh_repo, upstream, branch_prefix, admin_merge=False, wait
# Get the remote ref of upstream
remote_ref = repo.remote().refs[pr.base.ref]

print("Landed PR #{} on {} as {}".format(pr_num, pr.base.ref, remote_ref.commit))
print(
"Landed PR #{} on {} as {}".format(pr_num, pr.base.ref, remote_ref.commit)
)

# rebase all children onto the pr base branch
rebased_commits = subtree_graft(repo, commit, remote_ref.commit, True)
Expand Down
Loading

0 comments on commit 9fc8cf6

Please sign in to comment.