From patchwork Thu Feb 26 20:00:11 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 1942 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=1772136114; bh=uPs+LPsHGK4zYlrMQXDnRvfr6qs85G8E1RBRitWiEt4=; 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=roXmsgcBy28SkWABx5Z8AgGnZxWYXVAXEE20e5fhZ+VTW7F6Voo3tcKy2N6Vpdh1C 7FcVPTVst8lvh7PAhfGKkxcU9ow6XOIXmUZ8ypIR7b/j33gVu3iSbMM6mW759nWV8L 0OUL/Wvzsol3JAzFl/KyrOXE3l1jNkUw1wJCs4cxPL/QrmHPWZuqiMAfcIMuw5GwX1 Kt/d1/VkI0SMJKQQv58KzLLGesMn/N1psQLpL4MNxBk2sZ4qTa8GfS6im0U0i6W3pR YuMqb+W4RkdBZFuB0xFJQzRd0Pti6BZ7uB+w/lj2Ubsz1O8tGaYZnrvx1Pgus7Hzp6 F+PaIV076p7qA== Received: from localhost (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id ABC7269E36 for ; Thu, 26 Feb 2026 13:01:54 -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 dUaesI6904aL for ; Thu, 26 Feb 2026 13:01:54 -0700 (MST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1772136114; bh=uPs+LPsHGK4zYlrMQXDnRvfr6qs85G8E1RBRitWiEt4=; 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=roXmsgcBy28SkWABx5Z8AgGnZxWYXVAXEE20e5fhZ+VTW7F6Voo3tcKy2N6Vpdh1C 7FcVPTVst8lvh7PAhfGKkxcU9ow6XOIXmUZ8ypIR7b/j33gVu3iSbMM6mW759nWV8L 0OUL/Wvzsol3JAzFl/KyrOXE3l1jNkUw1wJCs4cxPL/QrmHPWZuqiMAfcIMuw5GwX1 Kt/d1/VkI0SMJKQQv58KzLLGesMn/N1psQLpL4MNxBk2sZ4qTa8GfS6im0U0i6W3pR YuMqb+W4RkdBZFuB0xFJQzRd0Pti6BZ7uB+w/lj2Ubsz1O8tGaYZnrvx1Pgus7Hzp6 F+PaIV076p7qA== Received: from mail.u-boot.org (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id 98D3969D79 for ; Thu, 26 Feb 2026 13:01:54 -0700 (MST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1772136112; bh=fucDmVVhLTyiq+J7MoN1an4um10g6uO9lKCaIUWAD1M=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=OXJk2/Ch3AIIDzjjL9iUpeMdelbCFgKg5RhzJ7DuFnO/p08sUJPsjGcnqEn0y3o6Y zgTikTfmFMysEQPEg5Pb97m6Ne1/LrLYFIXLO/dAE2MjSAWG0c/aWTeYl44b8+TlZy oFpo2Wx1zPldIwjv4JpBxP2sMjif9n+bQ0E9OfDPfBdrghl3cJav1SW4Ke6k/6Wr1y tL7fMPMyxEFra4vIs5EnWJKzaix36mhmYByzB7tbL578UHsh17F2MZ5rrInny/rqCd rfcc6W64uvRRHwOqOV6xFp+8kUv96xG+Wgo2ZKENB2RXMfHmmZO18qynj4AWynVA2e sHs8KQUD0wo5A== Received: from localhost (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id E65EA69D79; Thu, 26 Feb 2026 13:01:52 -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 kCKqpiPhtGxC; Thu, 26 Feb 2026 13:01:52 -0700 (MST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1772136109; bh=pDhHcaJyNwinmvv+a6OjMnraUL6PUwjn7724bddMCCE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=BbBAeRcCQma/XlJIYeaFl2qI+KjzKwkndL/rsNNcZNjS6C0q6PGD9mtv9ZJdr2JeG al0gwZPQAXi5QY+oPaOVDrmYjuvyrfchugB+auZS283Nj32aHhdL62zB2WI4W2SvtV jELelQ+DjgBVTCz0v8oBcrU6dpMarytZa9K3iLr/qP+6Zb4HPJtWIqc8u+cgiY4ywr cTt0ZtOkSQwrEoECHsrTjaiUVOFOAfvZLiflnpsLqEMbH6JFtym9lsCQUy7sFYhKQA 6tSXqEb+33CTmsPr9ElnheB9A3rGibAGwg/+JRNu4fGz7CTFX37hM6RFLqst+HSJ43 4GV48VipbKqdg== Received: from u-boot.org (unknown [73.34.74.121]) by mail.u-boot.org (Postfix) with ESMTPSA id C69DB69D4A; Thu, 26 Feb 2026 13:01:48 -0700 (MST) From: Simon Glass To: U-Boot Concept Date: Thu, 26 Feb 2026 13:00:11 -0700 Message-ID: <20260226200106.1727176-6-sjg@u-boot.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260226200106.1727176-1-sjg@u-boot.org> References: <20260226200106.1727176-1-sjg@u-boot.org> MIME-Version: 1.0 Message-ID-Hash: GJOR5OT3A2NRPSDJSHRNH5GRKCNZHQQE X-Message-ID-Hash: GJOR5OT3A2NRPSDJSHRNH5GRKCNZHQQE 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 05/32] patman: Warn about series with no upstream after migration 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 When the database is upgraded from before v5, existing series will have a NULL upstream. Detect this after migration and print a warning listing the affected series, so the user knows to set an upstream for them. Add series_get_null_upstream() to query for series with NULL upstream. Have start() return the old schema version so callers can check whether a migration from a particular version occurred. Signed-off-by: Simon Glass --- tools/patman/cser_helper.py | 13 ++++++++- tools/patman/database.py | 20 +++++++++++++- tools/patman/test_cseries.py | 52 ++++++++++++++++++++++++++++++++++++ 3 files changed, 83 insertions(+), 2 deletions(-) diff --git a/tools/patman/cser_helper.py b/tools/patman/cser_helper.py index 1441904686c..0b29d52bc00 100644 --- a/tools/patman/cser_helper.py +++ b/tools/patman/cser_helper.py @@ -110,11 +110,22 @@ class CseriesHelper: # For the first instance, start it up with the expected schema self.db, is_new = Database.get_instance(fname) if is_new: - self.db.start() + old_version = self.db.start() + if old_version is not None and old_version < 5: + self._check_null_upstreams() else: # If a previous test has already checked the schema, just open it self.db.open_it() + def _check_null_upstreams(self): + """Warn about series that have no upstream set""" + names = self.db.series_get_null_upstream() + if names: + tout.warning( + f'{len(names)} series without an upstream:') + for name in names: + tout.warning(f' {name}') + def close_database(self): """Close the database""" if self.db: diff --git a/tools/patman/database.py b/tools/patman/database.py index e3df4257f8c..2bd225e4deb 100644 --- a/tools/patman/database.py +++ b/tools/patman/database.py @@ -84,7 +84,12 @@ class Database: # pylint:disable=R0904 return Database(db_path), True def start(self): - """Open the database read for use, migrate to latest schema""" + """Open the database ready for use, migrate to latest schema + + Return: + int or None: Schema version before migration, or None if no + migration was needed + """ self.open_it() old_version = self.get_schema_version() if old_version > LATEST: @@ -93,6 +98,9 @@ class Database: # pylint:disable=R0904 f'Database version {old_version} is too new (max' f' {LATEST}); please update patman') self.migrate_to(LATEST) + if old_version == LATEST: + return None + return old_version def open_it(self): """Open the database, creating it if necessary""" @@ -496,6 +504,16 @@ class Database: # pylint:disable=R0904 'UPDATE series SET upstream = ? WHERE id = ?', (ups, series_idnum)) + def series_get_null_upstream(self): + """Get a list of series names that have no upstream set + + Return: + list of str: Series names with NULL upstream + """ + res = self.execute( + 'SELECT name FROM series WHERE upstream IS NULL') + return [row[0] for row in res.fetchall()] + # ser_ver functions def ser_ver_get_link(self, series_idnum, version): diff --git a/tools/patman/test_cseries.py b/tools/patman/test_cseries.py index fc29e9a7bef..cf0d8cfdab6 100644 --- a/tools/patman/test_cseries.py +++ b/tools/patman/test_cseries.py @@ -3365,6 +3365,58 @@ Date: .* db.start() self.assertIn('is too new', err.getvalue()) + def test_migrate_upstream_warning(self): + """Test that migrating to v5 warns about series without upstream""" + db = database.Database(f'{self.tmpdir}/.patman2.db') + with terminal.capture(): + db.open_it() + + # Create a v4 database with some series + with terminal.capture() as (out, _): + db.migrate_to(4) + self.assertEqual( + 'Update database to v1\nUpdate database to v2\n' + 'Update database to v3\nUpdate database to v4', + out.getvalue().strip()) + db.execute( + "INSERT INTO series (name, desc, archived) " + "VALUES ('first', 'desc1', 0)") + db.execute( + "INSERT INTO series (name, desc, archived) " + "VALUES ('second', 'desc2', 0)") + db.execute( + "INSERT INTO series (name, desc, archived) " + "VALUES ('third', 'desc3', 0)") + db.commit() + db.close() + + # Now open via CseriesHelper which triggers migration and check + self.make_git_tree() + cser = cseries.Cseries(self.tmpdir, terminal.COLOR_NEVER) + cser.topdir = self.tmpdir + + # Point at our v4 database + database.Database.instances = {} + cser.db, _ = database.Database.get_instance( + f'{self.tmpdir}/.patman2.db') + with terminal.capture() as (_, err): + old_version = cser.db.start() + self.assertEqual(4, old_version) + + # Set upstream on one series so only two are reported + idnum = cser.db.series_find_by_name('second') + cser.db.series_set_upstream(idnum, 'us') + cser.db.commit() + + with terminal.capture() as (_, err): + cser._check_null_upstreams() + lines = err.getvalue().strip().splitlines() + self.assertEqual('2 series without an upstream:', lines[0]) + self.assertEqual(' first', lines[1]) + self.assertEqual(' third', lines[2]) + + cser.db.close() + def test_series_scan(self): """Test scanning a series for updates""" cser, _ = self.setup_second()