@@ -60,24 +60,24 @@ def parse_args(argv):
subparsers.add_parser('compare', help='Compare branches')
- count_merges = subparsers.add_parser('count-merges',
- help='Count remaining merges to process')
+ count_merges = subparsers.add_parser(
+ 'count-merges', help='Count remaining merges to process')
count_merges.add_argument('source', help='Source branch name')
subparsers.add_parser('list-sources', help='List tracked source branches')
- next_merges = subparsers.add_parser('next-merges',
- help='Show next N merges to be applied')
+ next_merges = subparsers.add_parser(
+ 'next-merges', help='Show next N merges to be applied')
next_merges.add_argument('source', help='Source branch name')
next_merges.add_argument('-c', '--count', type=int, default=10,
help='Number of merges to show (default: 10)')
- next_set = subparsers.add_parser('next-set',
- help='Show next set of commits to cherry-pick')
+ next_set = subparsers.add_parser(
+ 'next-set', help='Show next set of commits to cherry-pick')
next_set.add_argument('source', help='Source branch name')
- review_cmd = subparsers.add_parser('review',
- help='Check open MRs and handle comments')
+ review_cmd = subparsers.add_parser(
+ 'review', help='Check open MRs and handle comments')
review_cmd.add_argument('-r', '--remote', default='ci',
help='Git remote (default: ci)')
@@ -95,7 +95,8 @@ def parse_args(argv):
help='Run step repeatedly until stopped')
poll_cmd.add_argument('source', help='Source branch name')
poll_cmd.add_argument('-i', '--interval', type=int, default=300,
- help='Interval between steps in seconds (default: 300)')
+ help='Interval between steps in seconds '
+ '(default: 300)')
poll_cmd.add_argument('-m', '--max-mrs', type=int, default=5,
help='Max open MRs allowed (default: 5)')
poll_cmd.add_argument('-r', '--remote', default='ci',
@@ -115,7 +116,8 @@ def parse_args(argv):
test_cmd = subparsers.add_parser('test', help='Run tests')
test_cmd.add_argument('-P', '--processes', type=int,
- help='Number of processes to run tests (default: all)')
+ help='Number of processes to run tests '
+ '(default: all)')
test_cmd.add_argument('-T', '--test-coverage', action='store_true',
help='Run tests and check for 100%% coverage')
test_cmd.add_argument('-v', '--verbosity', type=int, default=1,
@@ -83,7 +83,8 @@ async def run(commits, source, branch_name, repo_path=None):
Steps to follow:
1. First run 'git status' to check the repository state is clean
-2. Create and checkout a new branch based on ci/master: git checkout -b {branch_name} ci/master
+2. Create and checkout a new branch based on ci/master:
+ git checkout -b {branch_name} ci/master
3. Cherry-pick each commit in order:
- For regular commits: git cherry-pick -x <hash>
- For merge commits (identified by "Merge" in subject): git cherry-pick -x -m 1 --allow-empty <hash>
@@ -94,9 +95,10 @@ Steps to follow:
- Show the conflicting files
- Try to resolve simple conflicts automatically
- For complex conflicts, describe what needs manual resolution and abort
- - When fix-ups are needed, amend the commit to add a one-line note at the end
- of the commit message describing the changes made
-5. After ALL cherry-picks complete, verify with 'git log --oneline -n {len(commits) + 2}'
+ - When fix-ups are needed, amend the commit to add a one-line note at the
+ end of the commit message describing the changes made
+5. After ALL cherry-picks complete, verify with
+ 'git log --oneline -n {len(commits) + 2}'
Ensure all {len(commits)} commits are present.
6. Run 'buildman -L --board sandbox -w -o /tmp/pickman' to verify the build
7. Report the final status including:
@@ -287,7 +289,8 @@ def build_review_prompt(mr_iid, branch_name, task_desc, context_section,
comment_steps = """ - Make the requested changes to the code
- Amend the relevant commit or create a fixup commit"""
- return f"""Task for merge request !{mr_iid} (branch: {branch_name}): {task_desc}
+ return f"""Task for merge request !{mr_iid} (branch: {branch_name}):
+{task_desc}
{context_section}{comment_section}{rebase_section}
Steps to follow:
1. Checkout the branch: git checkout {branch_name}
@@ -601,7 +601,8 @@ def get_history(fname, source, commits, branch_name, conv_log):
fhandle.write(content)
# Generate commit message
- commit_msg = f'pickman: Record cherry-pick of {len(commits)} commits from {source}\n\n'
+ commit_msg = (f'pickman: Record cherry-pick of {len(commits)} commits '
+ f'from {source}\n\n')
commit_msg += '\n'.join(f'- {c.short_hash} {c.subject}' for c in commits)
return content, commit_msg
@@ -806,7 +807,8 @@ def execute_apply(dbs, source, commits, branch_name, args): # pylint: disable=t
target = args.target
# Use merge commit subject as title (last commit is the merge)
title = f'[pickman] {commits[-1].subject}'
- # Description matches .pickman-history entry (summary + conversation)
+ # Description matches .pickman-history entry
+ # (summary + conversation)
summary = format_history_summary(source, commits, branch_name)
description = f'{summary}\n\n### Conversation log\n{conv_log}'
@@ -1083,7 +1085,8 @@ Comments addressed:
# Commit the history file
run_git(['add', '-f', HISTORY_FILE])
- run_git(['commit', '-m', f'pickman: Record review handling for {branch_name}'])
+ run_git(['commit', '-m',
+ f'pickman: Record review handling for {branch_name}'])
def do_review(args, dbs):
@@ -1126,7 +1129,8 @@ def parse_mr_description(desc):
desc (str): MR description text
Returns:
- tuple: (source_branch, last_commit_hash) or (None, None) if not parseable
+ tuple: (source_branch, last_commit_hash) or (None, None)
+ if not parseable
"""
# Extract source branch from "## date: source_branch" line
source_match = re.search(r'^## [^:]+: (.+)$', desc, re.MULTILINE)
@@ -292,8 +292,9 @@ class Database: # pylint: disable=too-many-public-methods
cherry_hash) or None if not found
"""
res = self.execute(
- 'SELECT id, chash, source_id, mergereq_id, subject, author, status, '
- 'cherry_hash FROM pcommit WHERE chash = ?', (chash,))
+ 'SELECT id, chash, source_id, mergereq_id, subject, author, '
+ 'status, cherry_hash FROM pcommit WHERE chash = ?',
+ (chash,))
return res.fetchone()
def commit_get_by_source(self, source_id, status=None):
@@ -344,11 +345,13 @@ class Database: # pylint: disable=too-many-public-methods
"""
if cherry_hash:
self.execute(
- 'UPDATE pcommit SET status = ?, cherry_hash = ? WHERE chash = ?',
+ 'UPDATE pcommit SET status = ?, cherry_hash = ? '
+ 'WHERE chash = ?',
(status, cherry_hash, chash))
else:
self.execute(
- 'UPDATE pcommit SET status = ? WHERE chash = ?', (status, chash))
+ 'UPDATE pcommit SET status = ? WHERE chash = ?',
+ (status, chash))
def commit_set_mergereq(self, chash, mergereq_id):
"""Set the merge request for a commit
@@ -132,7 +132,8 @@ def parse_url(url):
Examples:
- git@gitlab.com:group/project.git -> ('gitlab.com', 'group/project')
- - https://gitlab.com/group/project.git -> ('gitlab.com', 'group/project')
+ - https://gitlab.com/group/project.git ->
+ ('gitlab.com', 'group/project')
"""
# SSH format: git@gitlab.com:group/project.git
ssh_match = re.match(r'git@([^:]+):(.+?)(?:\.git)?$', url)
@@ -211,7 +212,8 @@ def push_branch(remote, branch, force=False, skip_ci=True):
args.extend(['-o', 'ci.skip'])
if force:
if have_remote_ref:
- args.append(f'--force-with-lease=refs/remotes/{remote}/{branch}')
+ args.append(
+ f'--force-with-lease=refs/remotes/{remote}/{branch}')
else:
args.append('--force')
args.extend([push_target, f'HEAD:{branch}'])
@@ -349,7 +351,8 @@ def get_open_pickman_mrs(remote):
remote (str): Remote name
Returns:
- list: List of dicts with 'iid', 'title', 'web_url', 'source_branch' keys,
+ list: List of dicts with 'iid', 'title', 'web_url', 'source_branch'
+ keys,
or None on failure
"""
return get_pickman_mrs(remote, state='opened')
@@ -594,7 +597,8 @@ def check_permissions(remote): # pylint: disable=too-many-return-statements
token = get_token()
if not token:
tout.error('No GitLab token configured')
- tout.error('Set token in ~/.config/pickman.conf or GITLAB_TOKEN env var')
+ tout.error('Set token in ~/.config/pickman.conf or '
+ 'GITLAB_TOKEN env var')
return None
remote_url = get_remote_url(remote)
@@ -625,7 +629,8 @@ def check_permissions(remote): # pylint: disable=too-many-return-statements
except gitlab.exceptions.GitlabGetError:
pass
- access_name = ACCESS_LEVELS.get(access_level, f'Unknown ({access_level})')
+ access_name = ACCESS_LEVELS.get(access_level,
+ f'Unknown ({access_level})')
return PermissionInfo(
user=user.username,