From patchwork Sun Mar 29 15:01:33 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 2082 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=1774796540; bh=uY2Xq2CJUGKLs3XuF7zQMp4J6xoAP6WiTwE+8WgrQPg=; 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=cc/yF6uHOfh73FFJzDyk+RuGIA5RnOkzFM7AD06lJjrZ1O++AKmY3dccEmd0PGpSB ajVavWdyd1MI+2D0G/h6bEr2I+Pe4y/9l3Xtr4Nk7BRVcwvZD0UIe24OUw8YDpDNhC NTQ24eBZKzFBS2cWv8n5+vHg8Hvq6EwVDhi0Qh551n117JBTgr2PEvorGjBCl+iRnq aLzn9leqrHx4pQjSZEu46qw3Px6TRPgP/eHTl1X9RurHphed/fGRVaxJmCvnB7SwDn MWp6GnDfaJQr0FpzNe9J6kgSG7B7D+o8DRnlMyaRmoNgqeW0y5Zd9UjXCBlz/NczwA fxFggWfOK71vA== Received: from localhost (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id AF6F56A2D1 for ; Sun, 29 Mar 2026 09:02:20 -0600 (MDT) 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 nvnQDgnh0Idl for ; Sun, 29 Mar 2026 09:02:20 -0600 (MDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1774796540; bh=uY2Xq2CJUGKLs3XuF7zQMp4J6xoAP6WiTwE+8WgrQPg=; 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=cc/yF6uHOfh73FFJzDyk+RuGIA5RnOkzFM7AD06lJjrZ1O++AKmY3dccEmd0PGpSB ajVavWdyd1MI+2D0G/h6bEr2I+Pe4y/9l3Xtr4Nk7BRVcwvZD0UIe24OUw8YDpDNhC NTQ24eBZKzFBS2cWv8n5+vHg8Hvq6EwVDhi0Qh551n117JBTgr2PEvorGjBCl+iRnq aLzn9leqrHx4pQjSZEu46qw3Px6TRPgP/eHTl1X9RurHphed/fGRVaxJmCvnB7SwDn MWp6GnDfaJQr0FpzNe9J6kgSG7B7D+o8DRnlMyaRmoNgqeW0y5Zd9UjXCBlz/NczwA fxFggWfOK71vA== Received: from mail.u-boot.org (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id 9EDF46A2AB for ; Sun, 29 Mar 2026 09:02:20 -0600 (MDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1774796538; bh=YM5luIkKe4ctAkGcKjSAe+36+ulFh6WFgWZxB4c5a7Y=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Uan8tJ2zi975haNucV8MpwGiFWRhqyGb95UHfwrcqHVE3dIYyLEfoB2k8YQtu+nc0 Tvfh+jNttteMUpZlwHYxbPrWQD8goWDCbKqtKp0i2UZaGZpoBxuXbunTehIub9ml/i BZC5sTIL5YK9FuCi+uf7N/k4b+9O4zODmPdobsOQ34oodDQAKBk8cDszWPHTFtQUcm T7xkUy1JzjkusruejBWCTxfZJzcJ9frhE2wOgS5ewNlXI9DtavEUS5lIBMwCuXPTyp 81npoXY5wmt2x/HTXTExlQlQFAgbQ3BXXaiJ0JyX/x+8R7obhhl8fHmd6GJlLGsWOz pllv4BH9wM1eA== Received: from localhost (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id A9DCD6A02E; Sun, 29 Mar 2026 09:02:18 -0600 (MDT) 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 zaBCiQtyWYXb; Sun, 29 Mar 2026 09:02:18 -0600 (MDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1774796532; bh=rQCMEigTSz96J/D8r1PJw78SjG/ply5+dGyKMi4pZCM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ontNVA29+NXtyKGG1nURaauY4ojPqST8WktH7PYwopkk+S6LDwhSTOQePjOac5K2C LHCf2HJ5JXv582UW9yDXhpiDqleXcV3KKOQ8eKkHHwRxptVUCfoNwIWYQNmv9OGbPC v96X5QVeRsvrOMXPumuYp71Wvx26joqayfbOnIIcNW1Nano8jAj1HGjcc1RpSJCjZU oLxr+pNvQJm5My7ZvFdbI/2IfJGfuHkkpozQRlu96KALyyHNGoFio9DqO8Sk2secx9 C/VbEBvPEK7u7GihVjSEdyYE11nEYqeB0wOEqRWFGi6nIHx9UEYuH+HSM1Q7pvMX28 7PXA+LCSqwgHA== Received: from u-boot.org (unknown [73.34.74.121]) by mail.u-boot.org (Postfix) with ESMTPSA id 8B2E56A2D3; Sun, 29 Mar 2026 09:02:12 -0600 (MDT) From: Simon Glass To: U-Boot Concept Date: Sun, 29 Mar 2026 09:01:33 -0600 Message-ID: <20260329150140.4095446-9-sjg@u-boot.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260329150140.4095446-1-sjg@u-boot.org> References: <20260329150140.4095446-1-sjg@u-boot.org> MIME-Version: 1.0 Message-ID-Hash: ZZBITPOTIGFPHUD6PFAJE6EBTFMCCD6F X-Message-ID-Hash: ZZBITPOTIGFPHUD6PFAJE6EBTFMCCD6F 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 X-Mailman-Version: 3.3.10 Precedence: list Subject: [Concept] [PATCH 08/11] patman: Add 'workflow' command with todo subcommands 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 Wire the workflow todo feature into the command line with a new 'workflow' (alias 'wf') top-level command. Subcommands: patman wf todo [-s SERIES] [DAYS] - mark series for todo patman wf todo [-s SERIES] --clear - clear the todo marker patman wf todo-list [--all] - list due (or all) todos Signed-off-by: Simon Glass --- tools/patman/cmdline.py | 32 +++++++++++++++++++++++++++++++- tools/patman/control.py | 29 +++++++++++++++++++++++++++++ tools/patman/test_cseries.py | 20 ++++++++++++++++++++ 3 files changed, 80 insertions(+), 1 deletion(-) diff --git a/tools/patman/cmdline.py b/tools/patman/cmdline.py index 5bf917e4712..3628c12459c 100644 --- a/tools/patman/cmdline.py +++ b/tools/patman/cmdline.py @@ -26,6 +26,7 @@ ALIASES = { 'status': ['st'], 'patchwork': ['pw'], 'upstream': ['us'], + 'workflow': ['wf'], # Subcommand aliases 'archive': ['ar'], @@ -35,6 +36,7 @@ ALIASES = { 'open': ['o'], 'progress': ['p', 'pr', 'prog'], 'rm-version': ['rmv'], + 'todo-list': ['tl'], 'unarchive': ['unar'], } @@ -476,6 +478,32 @@ def add_upstream_subparser(subparsers): return upstream +def add_workflow_subparser(subparsers): + """Add the 'workflow' subparser + + Args: + subparsers (argparse action): Subparser parent + + Return: + ArgumentParser: workflow subparser + """ + workflow = subparsers.add_parser('workflow', aliases=ALIASES['workflow'], + help='Manage workflow items') + workflow_subparsers = workflow.add_subparsers(dest='subcmd') + todo = workflow_subparsers.add_parser('todo') + todo.add_argument('-s', '--series', help='Name of series') + todo.add_argument('days', nargs='?', type=int, default=14, + help='Number of days until due (default: 14)') + todo.add_argument('--clear', action='store_true', + help='Clear the todo marker instead of setting it') + + tlist = workflow_subparsers.add_parser('todo-list', + aliases=ALIASES['todo-list']) + tlist.add_argument('--all', action='store_true', dest='show_all', + help='Show all scheduled todos, not just due ones') + return workflow + + def setup_parser(): """Set up command-line parser @@ -518,6 +546,7 @@ def setup_parser(): series = add_series_subparser(subparsers) add_status_subparser(subparsers) upstream = add_upstream_subparser(subparsers) + workflow = add_workflow_subparser(subparsers) # Only add the 'test' action if the test data files are available. if HAS_TESTS: @@ -530,6 +559,7 @@ def setup_parser(): 'series': series, 'patchwork': patchwork, 'upstream': upstream, + 'workflow': workflow, } return parsers @@ -578,7 +608,7 @@ def parse_args(argv=None, config_fname=None, parsers=None): args.cmd = full if 'subcmd' in args and args.subcmd in aliases: args.subcmd = full - if args.cmd in ['series', 'upstream', 'patchwork'] and not args.subcmd: + if args.cmd in ['series', 'upstream', 'patchwork', 'workflow'] and not args.subcmd: parser.parse_args([args.cmd, '--help']) return args diff --git a/tools/patman/control.py b/tools/patman/control.py index cabd2138bb3..fe012f1a21b 100644 --- a/tools/patman/control.py +++ b/tools/patman/control.py @@ -344,6 +344,33 @@ def patchwork(args, test_db=None, pwork=None): finally: cser.close_database() +def do_workflow(args, test_db=None): + """Process a 'workflow' subcommand + + Args: + args (Namespace): Arguments to process + test_db (str or None): Directory containing the test database, None to + use the normal one + """ + from patman import cseries + from patman import workflow + + cser = cseries.Cseries(test_db) + try: + cser.open_database() + if args.subcmd == 'todo': + if args.clear: + workflow.todo_clear(cser, args.series) + else: + workflow.todo(cser, args.series, args.days) + elif args.subcmd == 'todo-list': + workflow.todo_list(cser, args.show_all) + else: + raise ValueError(f"Unknown workflow subcommand '{args.subcmd}'") + finally: + cser.close_database() + + def do_patman(args, test_db=None, pwork=None, cser=None): """Process a patman command @@ -392,6 +419,8 @@ def do_patman(args, test_db=None, pwork=None, cser=None): upstream(args, test_db) elif args.cmd == 'patchwork': patchwork(args, test_db, pwork) + elif args.cmd == 'workflow': + do_workflow(args, test_db) except Exception as exc: terminal.tprint(f'patman: {type(exc).__name__}: {exc}', colour=terminal.Color.RED) diff --git a/tools/patman/test_cseries.py b/tools/patman/test_cseries.py index b4dce4cb853..8fcdbd340fb 100644 --- a/tools/patman/test_cseries.py +++ b/tools/patman/test_cseries.py @@ -4273,3 +4273,23 @@ Date: .* with terminal.capture() as (out, _): cser.summary(None) self.assertNotIn('[todo]', out.getvalue()) + + def test_workflow_todo_cmdline(self): + """Test todo via the command line""" + cser = self.get_cser() + with terminal.capture(): + cser.add('first', 'my description', allow_unmarked=True) + + # Test via command line + self.db_close() + with terminal.capture() as (out, _): + self.run_args('workflow', 'todo', '-s', 'first', '7') + self.assertIn('marked for todo', out.getvalue()) + + with terminal.capture() as (out, _): + self.run_args('workflow', 'todo', '-s', 'first', '--clear') + self.assertIn('Todo cleared', out.getvalue()) + + with terminal.capture() as (out, _): + self.run_args('wf', 'todo-list') + self.assertIn('No todos due', out.getvalue())