From patchwork Sat Apr 4 21:29:04 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 2143 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=1775338385; bh=cVzLG2EG1Bu2VkCAc+J/e5SgjTfu6wUvqc8yLyFTwBQ=; 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=qwQEd/b9RM8dNzK7MHtuPSa4IRsaV3hAg2Hq/6IpVPYLDe32L0GlzSjl46+FJ8Ou5 VPArGaxY/dBnAQ1Ue6xFel1bRtZZMR17NAULykoOCTI7Ebwy/1qAZnkN9ksgUXMNkU dnZB9JEP5waqXcQkcpzWA8xHiruibqSxtY7OughomoMVLz9L/pMbVmGXkepRrD8RBy Y3Tq/9eQDRnq0g+O72A61ul5ctXrcZVMC4Nw7KzchAkRL2wWn0XqCc7ZwRiK4tQJgH 9RL7JzXo6iGHVA057u3r9uC3qbjdY+RzFzowzyBfrOvgAexI3qsyJv/DQMs4kuy/YR QJHfH5YOLkJSQ== Received: from localhost (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id 2B43A5FC8F for ; Sat, 4 Apr 2026 15:33:05 -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 Qjy_EU64dSKI for ; Sat, 4 Apr 2026 15:33:05 -0600 (MDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1775338385; bh=cVzLG2EG1Bu2VkCAc+J/e5SgjTfu6wUvqc8yLyFTwBQ=; 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=qwQEd/b9RM8dNzK7MHtuPSa4IRsaV3hAg2Hq/6IpVPYLDe32L0GlzSjl46+FJ8Ou5 VPArGaxY/dBnAQ1Ue6xFel1bRtZZMR17NAULykoOCTI7Ebwy/1qAZnkN9ksgUXMNkU dnZB9JEP5waqXcQkcpzWA8xHiruibqSxtY7OughomoMVLz9L/pMbVmGXkepRrD8RBy Y3Tq/9eQDRnq0g+O72A61ul5ctXrcZVMC4Nw7KzchAkRL2wWn0XqCc7ZwRiK4tQJgH 9RL7JzXo6iGHVA057u3r9uC3qbjdY+RzFzowzyBfrOvgAexI3qsyJv/DQMs4kuy/YR QJHfH5YOLkJSQ== Received: from mail.u-boot.org (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id 19B446833B for ; Sat, 4 Apr 2026 15:33:05 -0600 (MDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1775338383; bh=q+7UeSKEn0FDtRpivHOwVzEIxaCrDo37fZzs3P67chM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=F8fByOKOup3NQE+bFxRWEjlP9qOPxSQT0OLHbaca3s3bdgIjKR7KYtgeHuMX8+hrm 3nptrfEDFrKazInOyj3+em00a9m7MJ8OUdNmqnSM9/SqQQ7Fx7MTfEQ9evU1JAZrEP aZYTV0l0XMNiNnbZGd+fPZS+35bdwiSNI9akMev02H+Yj4YGEiXhunoBqlHUF/z+Z+ qcfJoOGpOq7+WGCxBNdUbF4XEhtnnOGz+xh3U08MWjRMY05Jd+xVp3zqDuPRTOg4fB pW4ZQh87EmPhLoFXz1ET23e6QSlqR8WLe4eUcAxDyQ5qN+tvo12des7XF4NoJcMLFJ RZdgZVC2nAPsw== Received: from localhost (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id 1057E6833B; Sat, 4 Apr 2026 15:33:03 -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 XFz_HiWKzBTV; Sat, 4 Apr 2026 15:33:03 -0600 (MDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1775338378; bh=7FsehO4bxwavjCe9pw/Kb6KZwhhctHKtn1S61wrGFLM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=GD/H4Lmh+rWBoPoMt7nVWn5FFYfCR7Ch8GPDtr8yu2UsMMKC14nreLSJnDXkJnWKK mM6frs68p3f6keGW/TixoA2lm03D3duUgDXvTdO2IGs0fgH6G4A4DzAiVwRe2ILxYt gsxs6+qgu7Vordf3O+fbaFnR1oWf+fKbRxWqdNpp2eSYLJ6S8/ynwEmbk0z1lhj7Sy k7+u0XUaVBfNwqqXSpj4t2EgpGswXG6QsOl95BSMBeTc2Ho3mU28xjeQMzQMJvlkfo 8alK4+xmoSYiidma5LuGv869r5cvnizGwcXzFXbAxF0YqXQ7rQmkVQHWhNSYJN/6ot QENoN79rIAvSQ== Received: from u-boot.org (unknown [73.34.74.121]) by mail.u-boot.org (Postfix) with ESMTPSA id A406D5E7B4; Sat, 4 Apr 2026 15:32:58 -0600 (MDT) From: Simon Glass To: U-Boot Concept Date: Sat, 4 Apr 2026 15:29:04 -0600 Message-ID: <20260404213020.372253-29-sjg@u-boot.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260404213020.372253-1-sjg@u-boot.org> References: <20260404213020.372253-1-sjg@u-boot.org> MIME-Version: 1.0 Message-ID-Hash: WSITVR4SVFO6FPVZ7IHKXWEZJVMYRHAT X-Message-ID-Hash: WSITVR4SVFO6FPVZ7IHKXWEZJVMYRHAT 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 28/37] patman: Add 'series info' command to show version details 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 Add a 'patman series info' command that displays detailed information about a series including description, upstream, and for each version: the patchwork link, per-version description, cover letter name, patch list with state, archive tag and review notes. This helps diagnose autolink issues by showing what description each version has stored, which is what patchwork searches use. Signed-off-by: Simon Glass --- tools/patman/cmdline.py | 1 + tools/patman/control.py | 2 ++ tools/patman/cseries.py | 47 ++++++++++++++++++++++++++++++++++++ tools/patman/test_cseries.py | 42 ++++++++++++++++++++++++++++++++ 4 files changed, 92 insertions(+) diff --git a/tools/patman/cmdline.py b/tools/patman/cmdline.py index edefa778446..bee9fd21483 100644 --- a/tools/patman/cmdline.py +++ b/tools/patman/cmdline.py @@ -294,6 +294,7 @@ def add_series_subparser(subparsers): series_subparsers.add_parser('get-link') series_subparsers.add_parser('inc') + series_subparsers.add_parser('info') ls = series_subparsers.add_parser('ls', aliases=['list']) _add_archived(ls) diff --git a/tools/patman/control.py b/tools/patman/control.py index 3ce9736d6ba..9ba9b6e0b8e 100644 --- a/tools/patman/control.py +++ b/tools/patman/control.py @@ -199,6 +199,8 @@ def do_series(args, test_db=None, pwork=None, cser=None): dry_run=args.dry_run, show_summary=True) elif args.subcmd == 'dec': cser.decrement(args.series, args.dry_run) + elif args.subcmd == 'info': + cser.show_info(args.series) elif args.subcmd == 'gather': cser.gather(pwork, args.series, args.version, args.show_comments, args.show_cover_comments, args.gather_tags, diff --git a/tools/patman/cseries.py b/tools/patman/cseries.py index 1dd1550f367..e272a5839fc 100644 --- a/tools/patman/cseries.py +++ b/tools/patman/cseries.py @@ -861,6 +861,53 @@ class Cseries(cser_helper.CseriesHelper): if dry_run: tout.info('Dry run completed') + def show_info(self, series): + """Show detailed information about a series and all its versions + + Args: + series (str): Series name, or None for current branch + """ + ser, _ = self._parse_series_and_version(series, None) + if not ser.idnum: + raise ValueError(f"Series '{ser.name}' not found in database") + + print(f"Series: {ser.name}") + print(f" Description: {ser.desc}") + print(f" Upstream: {ser.upstream or '(none)'}") + + versions = self.db.ser_ver_get_for_series(ser.idnum) + if not isinstance(versions, list): + versions = [versions] + + for sv in versions: + link_str = sv.link or '(none)' + print(f"\n Version {sv.version}:") + print(f" Link: {link_str}") + print(f" Description: {sv.desc or '(none)'}") + if sv.name: + print(f" Cover: {sv.name}") + if sv.archive_tag: + print(f" Archive tag: {sv.archive_tag}") + + # Show patches + try: + pclist = self.db.pcommit_get_list(sv.idnum) + print(f" Patches: {len(pclist)}") + for pc in pclist: + state = f' [{pc.state}]' if pc.state else '' + print(f" {pc.seq + 1}: {pc.subject}{state}") + except (ValueError, AttributeError): + pass + + # Show notes if any + if sv.notes: + lines = sv.notes.strip().splitlines() + print(f" Notes: {lines[0]}") + for line in lines[1:3]: + print(f" {line}") + if len(lines) > 3: + print(f" ... ({len(lines)} lines)") + def set_upstream(self, series, ups, dry_run=False): """Set the upstream for a series diff --git a/tools/patman/test_cseries.py b/tools/patman/test_cseries.py index e207e8bc173..5974c69253a 100644 --- a/tools/patman/test_cseries.py +++ b/tools/patman/test_cseries.py @@ -4438,3 +4438,45 @@ Date: .* # Future 3 weeks when = datetime(2025, 3, 31, 10, 0, 0) self.assertEqual('in 3w', wf.friendly_time(now, when)) + + def test_series_info(self): + """Test the series info command""" + cser = self.get_database() + + # Create a series with upstream and two versions + cser.db.upstream_add('us', 'https://us.example.com') + series_id = cser.db.series_add('test-info', 'My test series', ups='us') + svid1 = cser.db.ser_ver_add(series_id, 1, link='12345', + desc='First version desc') + svid2 = cser.db.ser_ver_add(series_id, 2, desc='Second version desc') + + # Add patches to v1 + from patman.database import Pcommit + cser.db.pcommit_add_list(svid1, [ + Pcommit(idnum=None, seq=0, subject='Fix the widget', + svid=svid1, change_id=None, state=None, + patch_id=None, num_comments=0), + Pcommit(idnum=None, seq=1, subject='Add widget tests', + svid=svid1, change_id=None, state=None, + patch_id=None, num_comments=0)]) + + # Add notes to v2 + cser.db.ser_ver_set_notes(svid2, 'Fixed review feedback') + cser.commit() + + with terminal.capture() as (out, _): + cser.show_info('test-info') + + output = out.getvalue() + self.assertIn('Series: test-info', output) + self.assertIn('Description: My test series', output) + self.assertIn('Upstream: us', output) + self.assertIn('Version 1:', output) + self.assertIn('Link: 12345', output) + self.assertIn('First version desc', output) + self.assertIn('Patches: 2', output) + self.assertIn('Fix the widget', output) + self.assertIn('Add widget tests', output) + self.assertIn('Version 2:', output) + self.assertIn('Second version desc', output) + self.assertIn('Notes: Fixed review feedback', output)