From patchwork Wed Dec 24 21:30:32 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 1072 Return-Path: X-Original-To: u-boot-concept@u-boot.org Delivered-To: u-boot-concept@u-boot.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1766611865; bh=Z3YxxdgHhZOIpWUNTNAbD7iJW/Sa0rKcuAsxNDAJI8M=; h=From:To:Date:In-Reply-To:References:CC:Subject:List-Id: List-Archive:List-Help:List-Owner:List-Post:List-Subscribe: List-Unsubscribe:From; b=FyQTH8aZprLa9kI9buz1k8++ILxvS9tRt4kO1RHkvaZsXP2zQ4RvW0vY2x+7k3f8H WyhUT+/1pkDpvJcK9AdAswnh/U4T1nePKkS6CqZ1oRc4HcbimOPO0QPZsdwACx7UvL qBXhbZKHKjxA9yylEU26PVXAKn4b8+TgbELiRCxAwPLlJLCKbfzL0IijrY9VQjd/A9 kyhhJYisiu03B3cBNOaDiS9VDmDVt+hrd6e8pPftURwWbt0nabEkjGS2gyuBVSQwXJ tjESHw0dBCnwLcFPvZz4LFHxXMwUGJWabdpwIuogEnY9H+yAdy6MoEcHShA6wTrKOJ nkk9QlNGClmjg== Received: from localhost (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id D54E364E31 for ; Wed, 24 Dec 2025 14:31:05 -0700 (MST) X-Virus-Scanned: Debian amavis at Received: from mail.u-boot.org ([127.0.0.1]) by localhost (mail.u-boot.org [127.0.0.1]) (amavis, port 10024) with ESMTP id 1iIpdU2OI13l for ; Wed, 24 Dec 2025 14:31:05 -0700 (MST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1766611865; bh=Z3YxxdgHhZOIpWUNTNAbD7iJW/Sa0rKcuAsxNDAJI8M=; h=From:To:Date:In-Reply-To:References:CC:Subject:List-Id: List-Archive:List-Help:List-Owner:List-Post:List-Subscribe: List-Unsubscribe:From; b=FyQTH8aZprLa9kI9buz1k8++ILxvS9tRt4kO1RHkvaZsXP2zQ4RvW0vY2x+7k3f8H WyhUT+/1pkDpvJcK9AdAswnh/U4T1nePKkS6CqZ1oRc4HcbimOPO0QPZsdwACx7UvL qBXhbZKHKjxA9yylEU26PVXAKn4b8+TgbELiRCxAwPLlJLCKbfzL0IijrY9VQjd/A9 kyhhJYisiu03B3cBNOaDiS9VDmDVt+hrd6e8pPftURwWbt0nabEkjGS2gyuBVSQwXJ tjESHw0dBCnwLcFPvZz4LFHxXMwUGJWabdpwIuogEnY9H+yAdy6MoEcHShA6wTrKOJ nkk9QlNGClmjg== Received: from mail.u-boot.org (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id C520C64E2C for ; Wed, 24 Dec 2025 14:31:05 -0700 (MST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1766611863; bh=cdlh7f5vrMCpmyVbbvwJ1GXuof2G2nBAyOmvMeVfDtg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=uJRNL4ysbLk2ns1rv6tVgZhwcoadYucsNjqokKcjAixhqflvp/6B9wgGMRdeMuft6 ADbWduUq0O9BKVncbEfUZKEeDEdfMVRRCZ/XBfeVp2yqYItK/fnU4pIOBY1N+I2spJ pISaSSxFyVZLd6crPime4YhGVCJlKbF+L+yU2s5gyWDO7CmaCR3o1MHQPber4a6trt 12w/0kHjPN9+QTrJQBVPuorzrMv2acj4HjBW1czpa+c35X8IPROe7G4jNnL/nRZ+lv NnRcLhY5fBVJ+9PT4P12dLP3PAOK6b1NatKBaXLEgZ9LYqmkTdZUNkgm6kwurOStIC 4xPmC8PskDvjQ== Received: from localhost (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id A262E64E3C; Wed, 24 Dec 2025 14:31:03 -0700 (MST) X-Virus-Scanned: Debian amavis at Received: from mail.u-boot.org ([127.0.0.1]) by localhost (mail.u-boot.org [127.0.0.1]) (amavis, port 10026) with ESMTP id ZXIpl1gs2qw2; Wed, 24 Dec 2025 14:31:03 -0700 (MST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1766611857; bh=R2/Ei4Dd483riJX1tXZtV1mNHmVPI779NSlNk168rmI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=sBV8EfmYAA0DAIPf1Tdu1C/asm4P73nMtMKTd5jHtrNEqLm8XRzwj6X7uP1YbIqSO 0fctg4kv45szRZfSQUfa+aoHZip4dv8VaTOob8Y7sZGsEGqdpJGKEHtmlrQoWiLDvu eqLvt179NVcGLsZM8ggkpffefOGQQpncuhvgH1bmpQ6JFTAHjgx6PuRjW8flNIUp2r wA5pk3tN6ZZC9niqMnVa+3NCs2+sTVODxQSgQ0xDkYSiqoyhTivhKrvMovJ1ZL4wXm 4TdwfyMH4LUy1Www0eCJo6n7hQsl6aZn65dGSO9oQjc7hfqqExsTcIg8QYSa3MrPrW 4N85CN8sBIYbQ== Received: from u-boot.org (unknown [73.34.74.121]) by mail.u-boot.org (Postfix) with ESMTPSA id 5BDE964CCC; Wed, 24 Dec 2025 14:30:57 -0700 (MST) From: Simon Glass To: U-Boot Concept Date: Wed, 24 Dec 2025 14:30:32 -0700 Message-ID: <20251224213045.3010514-2-sjg@u-boot.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20251224213045.3010514-1-sjg@u-boot.org> References: <20251224213045.3010514-1-sjg@u-boot.org> MIME-Version: 1.0 Message-ID-Hash: KOG3JA3BWSFKB4KU6CGWUB6MFDU4A74P X-Message-ID-Hash: KOG3JA3BWSFKB4KU6CGWUB6MFDU4A74P X-MailFrom: sjg@u-boot.org X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header CC: Simon Glass , Claude X-Mailman-Version: 3.3.10 Precedence: list Subject: [Concept] [PATCH 1/9] pickman: Fix 80-column line length compliance List-Id: Discussion and patches related to U-Boot Concept Archived-At: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: From: Simon Glass Break long lines to comply with 80-character limit and remove trailing whitespace across agent.py, control.py, database.py, gitlab_api.py, and __main__.py Co-developed-by: Claude Signed-off-by: Simon Glass --- tools/pickman/__main__.py | 22 ++++++++++++---------- tools/pickman/agent.py | 13 ++++++++----- tools/pickman/control.py | 12 ++++++++---- tools/pickman/database.py | 11 +++++++---- tools/pickman/gitlab_api.py | 15 ++++++++++----- 5 files changed, 45 insertions(+), 28 deletions(-) diff --git a/tools/pickman/__main__.py b/tools/pickman/__main__.py index 05e0f7fb6bb..d11734f1f25 100755 --- a/tools/pickman/__main__.py +++ b/tools/pickman/__main__.py @@ -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, diff --git a/tools/pickman/agent.py b/tools/pickman/agent.py index 4570312a97c..9b37428af3e 100644 --- a/tools/pickman/agent.py +++ b/tools/pickman/agent.py @@ -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 - For merge commits (identified by "Merge" in subject): git cherry-pick -x -m 1 --allow-empty @@ -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} diff --git a/tools/pickman/control.py b/tools/pickman/control.py index b14c830f1d4..7a52b99a9ed 100644 --- a/tools/pickman/control.py +++ b/tools/pickman/control.py @@ -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) diff --git a/tools/pickman/database.py b/tools/pickman/database.py index b8da21caf58..f584fe14c21 100644 --- a/tools/pickman/database.py +++ b/tools/pickman/database.py @@ -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 diff --git a/tools/pickman/gitlab_api.py b/tools/pickman/gitlab_api.py index 0ccdf8defb2..94af6880b7c 100644 --- a/tools/pickman/gitlab_api.py +++ b/tools/pickman/gitlab_api.py @@ -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,