@@ -659,7 +659,7 @@ class Cseries(cser_helper.CseriesHelper):
tout.detail(f'Name match: ID {proj_id}')
if not proj_id:
raise ValueError(f"Unknown project name '{name}'")
- self.db.settings_update(name, proj_id, link_name)
+ self.db.patchwork_update(name, proj_id, link_name)
self.commit()
if not quiet:
tout.notice(f"Project '{name}' patchwork-ID {proj_id} "
@@ -674,7 +674,7 @@ class Cseries(cser_helper.CseriesHelper):
proj_id (int): Patchworks project ID for this project
link_name (str): Patchwork's link-name for the project
"""
- return self.db.settings_get()
+ return self.db.patchwork_get()
def remove(self, name, dry_run=False):
"""Remove a series from the database
@@ -165,12 +165,12 @@ class Database: # pylint:disable=R0904
self.cur.execute('ALTER TABLE ser_ver ADD COLUMN archive_tag')
def _migrate_to_v5(self):
- """Add upstream support to series, settings and upstream tables
+ """Add upstream support to series, patchwork and upstream tables
- Add upstream column to series table
- - Recreate settings table without UNIQUE constraint on name, adding
- an upstream column (since the same project can have multiple
- remotes)
+ - Rename and recreate patchwork table (formerly 'settings') without
+ UNIQUE constraint on name, adding an upstream column (since the
+ same project can have multiple remotes)
- Add patchwork_url, identity, series_to, no_maintainers and
no_tags columns to upstream table
- Add desc column to ser_ver table
@@ -178,17 +178,17 @@ class Database: # pylint:disable=R0904
self.cur.execute('ALTER TABLE series ADD COLUMN upstream')
self.cur.execute(
- 'CREATE TABLE settings_new '
+ 'CREATE TABLE patchwork_new '
'(name, proj_id INT, link_name, upstream)')
self.cur.execute(
- 'INSERT INTO settings_new SELECT name, proj_id, link_name, NULL '
+ 'INSERT INTO patchwork_new SELECT name, proj_id, link_name, NULL '
'FROM settings')
self.cur.execute('DROP TABLE settings')
- self.cur.execute('ALTER TABLE settings_new RENAME TO settings')
+ self.cur.execute('ALTER TABLE patchwork_new RENAME TO patchwork')
default_ups = self.upstream_get_default()
if default_ups:
self.cur.execute(
- 'UPDATE settings SET upstream = ?', (default_ups,))
+ 'UPDATE patchwork SET upstream = ?', (default_ups,))
self.cur.execute('ALTER TABLE upstream ADD COLUMN patchwork_url')
self.cur.execute('ALTER TABLE upstream ADD COLUMN identity')
@@ -867,32 +867,43 @@ class Database: # pylint:disable=R0904
udict[name] = url, is_default
return udict
- # settings functions
+ # patchwork functions
- def settings_update(self, name, proj_id, link_name):
- """Set the patchwork settings of the project
+ def patchwork_update(self, name, proj_id, link_name, ups=None):
+ """Set the patchwork project details for an upstream
Args:
name (str): Name of the project to use in patchwork
proj_id (int): Project ID for the project
link_name (str): Link name for the project
+ ups (str or None): Upstream name to associate with, or None
"""
- self.execute('DELETE FROM settings')
self.execute(
- 'INSERT INTO settings (name, proj_id, link_name) '
- 'VALUES (?, ?, ?)', (name, proj_id, link_name))
+ 'DELETE FROM patchwork WHERE upstream IS ?', (ups,))
+ self.execute(
+ 'INSERT INTO patchwork (name, proj_id, link_name, upstream) '
+ 'VALUES (?, ?, ?, ?)', (name, proj_id, link_name, ups))
+
+ def patchwork_get(self, ups=None):
+ """Get the patchwork project details for an upstream
- def settings_get(self):
- """Get the patchwork settings of the project
+ Args:
+ ups (str or None): Upstream name to look up, or None for any
Returns:
- tuple or None if there are no settings:
+ tuple or None if there is no project set:
name (str): Project name, e.g. 'U-Boot'
proj_id (int): Patchworks project ID for this project
link_name (str): Patchwork's link-name for the project
"""
- res = self.execute("SELECT name, proj_id, link_name FROM settings")
+ if ups is not None:
+ res = self.execute(
+ 'SELECT name, proj_id, link_name FROM patchwork '
+ 'WHERE upstream = ?', (ups,))
+ else:
+ res = self.execute(
+ 'SELECT name, proj_id, link_name FROM patchwork')
recs = res.fetchall()
- if len(recs) != 1:
+ if not recs:
return None
return recs[0]
@@ -2502,6 +2502,66 @@ Tested-by: Mary Smith <msmith@wibble.com> # yak
f"Project 'U-Boot' patchwork-ID {self.PROJ_ID} link-name 'uboot'",
out.getvalue().strip())
+ def test_patchwork_upstream(self):
+ """Test patchwork project with upstream association"""
+ cser = self.get_cser()
+
+ # Add two upstreams
+ cser.db.upstream_add('us', 'https://us.example.com')
+ cser.db.upstream_add('ci', 'https://ci.example.com')
+ cser.db.commit()
+
+ # Set project for a specific upstream
+ cser.db.patchwork_update('U-Boot', 6, 'uboot', 'us')
+ cser.db.commit()
+
+ # Look up by upstream
+ info = cser.db.patchwork_get('us')
+ self.assertEqual(('U-Boot', 6, 'uboot'), info)
+
+ # Different upstream has no project
+ self.assertIsNone(cser.db.patchwork_get('ci'))
+
+ # No upstream arg returns any match
+ info = cser.db.patchwork_get()
+ self.assertEqual(('U-Boot', 6, 'uboot'), info)
+
+ # Set a different project for ci
+ cser.db.patchwork_update('Linux', 10, 'linux', 'ci')
+ cser.db.commit()
+
+ self.assertEqual(('Linux', 10, 'linux'), cser.db.patchwork_get('ci'))
+ self.assertEqual(('U-Boot', 6, 'uboot'), cser.db.patchwork_get('us'))
+
+ def test_migrate_patchwork_upstream(self):
+ """Test that migrating to v5 renames settings to patchwork"""
+ db = database.Database(f'{self.tmpdir}/.patman3.db')
+ with terminal.capture():
+ db.open_it()
+
+ # Create a v4 database with an upstream and a patchwork row
+ with terminal.capture():
+ db.migrate_to(4)
+ db.execute(
+ "INSERT INTO upstream (name, url, is_default) "
+ "VALUES ('us', 'https://us.example.com', 1)")
+ db.execute(
+ "INSERT INTO settings (name, proj_id, link_name) "
+ "VALUES ('U-Boot', 6, 'uboot')")
+ db.commit()
+
+ # Migrate to v5
+ with terminal.capture():
+ db.migrate_to(5)
+
+ # The existing row should now be in 'patchwork' with the default upstream
+ res = db.execute(
+ 'SELECT name, proj_id, link_name, upstream FROM patchwork')
+ recs = res.fetchall()
+ self.assertEqual(1, len(recs))
+ self.assertEqual(('U-Boot', 6, 'uboot', 'us'), recs[0])
+ db.close()
+
def check_series_list_patches(self):
"""Test listing the patches for a series"""
cser = self.get_cser()