From: Simon Glass <simon.glass@canonical.com> When the database is upgraded to v5, try to auto-detect the upstream for each series that has a NULL upstream. This queries the git branch's remote tracking configuration and sets the upstream if a real remote (not local tracking with '.') is found. Series where auto-detection fails are still reported as a warning so the user can set them manually. Signed-off-by: Simon Glass <simon.glass@canonical.com> --- tools/patman/cser_helper.py | 35 +++++++++++++++++++++++++++++++---- tools/patman/test_cseries.py | 32 ++++++++++++++++++++++---------- 2 files changed, 53 insertions(+), 14 deletions(-) diff --git a/tools/patman/cser_helper.py b/tools/patman/cser_helper.py index 0b29d52bc00..74bccfcfbc6 100644 --- a/tools/patman/cser_helper.py +++ b/tools/patman/cser_helper.py @@ -118,12 +118,39 @@ class CseriesHelper: self.db.open_it() def _check_null_upstreams(self): - """Warn about series that have no upstream set""" + """Detect and warn about series that have no upstream set + + For each series without an upstream, try to detect it from the + git branch's remote tracking configuration. Any series that + cannot be auto-detected are reported as a warning. + """ names = self.db.series_get_null_upstream() - if names: + if not names: + return + + still_null = [] + git_dir = self.gitdir or '.git' + for name in names: + remote_name = None + if gitutil.check_branch(name, git_dir=self.gitdir): + us_ref, _ = gitutil.get_upstream(git_dir, name) + if us_ref and '/' in us_ref and not us_ref.startswith( + 'refs/'): + remote_name = us_ref.split('/')[0] + if remote_name: + idnum = self.db.series_find_by_name(name) + self.db.series_set_upstream(idnum, remote_name) + tout.progress(f"Set upstream for series '{name}' to " + f"'{remote_name}'", trailer='') + else: + still_null.append(name) + + if len(still_null) < len(names): + self.db.commit() + if still_null: tout.warning( - f'{len(names)} series without an upstream:') - for name in names: + f'{len(still_null)} series without an upstream:') + for name in still_null: tout.warning(f' {name}') def close_database(self): diff --git a/tools/patman/test_cseries.py b/tools/patman/test_cseries.py index cf0d8cfdab6..23527cfa8f0 100644 --- a/tools/patman/test_cseries.py +++ b/tools/patman/test_cseries.py @@ -3367,11 +3367,20 @@ Date: .* def test_migrate_upstream_warning(self): """Test that migrating to v5 warns about series without upstream""" + self.make_git_tree() + + # Set 'first' branch to track a remote-style upstream so that + # auto-detection can find it + self.repo.config.set_multivar('branch.first.remote', '', 'origin') + self.repo.config.set_multivar('branch.first.merge', '', + 'refs/heads/main') + db = database.Database(f'{self.tmpdir}/.patman2.db') with terminal.capture(): db.open_it() - # Create a v4 database with some series + # Create a v4 database with some series; 'first' has a matching + # branch with a detectable remote, 'second' and 'third' do not with terminal.capture() as (out, _): db.migrate_to(4) self.assertEqual( @@ -3390,10 +3399,9 @@ Date: .* 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 + cser.gitdir = self.gitdir # Point at our v4 database database.Database.instances = {} @@ -3403,18 +3411,22 @@ Date: .* 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): + # 'first' should be auto-detected, 'second' and 'third' have no + # matching branch with a remote upstream + with terminal.capture() as (out, err): cser._check_null_upstreams() + self.assertIn("Set upstream for series 'first' to 'origin'", + out.getvalue()) lines = err.getvalue().strip().splitlines() self.assertEqual('2 series without an upstream:', lines[0]) - self.assertEqual(' first', lines[1]) + self.assertEqual(' second', lines[1]) self.assertEqual(' third', lines[2]) + # Check that 'first' was actually updated in the database + slist = cser.db.series_get_dict() + self.assertEqual('origin', slist['first'].upstream) + self.assertIsNone(slist['second'].upstream) + cser.db.close() def test_series_scan(self): -- 2.43.0