[Concept,26/32] patman: Add header and tidy columns in upstream list

Message ID 20260226200106.1727176-27-sjg@u-boot.org
State New
Headers
Series patman: Add multi-upstream support |

Commit Message

Simon Glass Feb. 26, 2026, 8 p.m. UTC
  From: Simon Glass <simon.glass@canonical.com>

Add a header row and separator to 'upstream list' output, matching
the style used by 'series ls'. Use narrower columns and show the
default upstream with '*' instead of 'default'. Collect optional
fields (patchwork URL, identity, series-to, flags) into an Options
column.

Signed-off-by: Simon Glass <simon.glass@canonical.com>
---

 tools/patman/cseries.py      | 21 +++++++++++++--------
 tools/patman/test_cseries.py | 35 ++++++++++++++---------------------
 2 files changed, 27 insertions(+), 29 deletions(-)
  

Patch

diff --git a/tools/patman/cseries.py b/tools/patman/cseries.py
index 588e83298bd..47da57acc0f 100644
--- a/tools/patman/cseries.py
+++ b/tools/patman/cseries.py
@@ -1218,24 +1218,29 @@  class Cseries(cser_helper.CseriesHelper):
         """
         udict = self.get_upstream_dict()
 
+        print(f"{'Name':6} {'Def':3} {'Project':10} {'URL':40} Options")
+        border = (f"{'-' * 6} {'-' * 3} {'-' * 10} {'-' * 40} "
+                  f"{'-' * 20}")
+        print(border)
         for name, items in udict.items():
             (url, is_default, patchwork_url, identity, series_to,
              no_maintainers, no_tags) = items
-            default = 'default' if is_default else ''
+            default = '*' if is_default else ''
             proj = self.db.patchwork_get(name)
             proj_name = proj[0] if proj else ''
-            line = f'{name:10.10} {default:8} {proj_name:20} {url}'
+            opts = []
             if patchwork_url:
-                line += f'  pw:{patchwork_url}'
+                opts.append(f'pw:{patchwork_url}')
             if identity:
-                line += f'  id:{identity}'
+                opts.append(f'id:{identity}')
             if series_to:
-                line += f'  to:{series_to}'
+                opts.append(f'to:{series_to}')
             if no_maintainers:
-                line += '  no-maintainers'
+                opts.append('no-maintainers')
             if no_tags:
-                line += '  no-tags'
-            print(line)
+                opts.append('no-tags')
+            print(f'{name:6} {default:3} {proj_name:10} {url:40} '
+                  f'{" ".join(opts)}')
 
     def upstream_set(self, name, **kwargs):
         """Update settings on an existing upstream
diff --git a/tools/patman/test_cseries.py b/tools/patman/test_cseries.py
index fcfe6610321..3d475956ff9 100644
--- a/tools/patman/test_cseries.py
+++ b/tools/patman/test_cseries.py
@@ -1764,13 +1764,10 @@  Tested-by: Mary Smith <msmith@wibble.com>   # yak
         with terminal.capture() as (out, _):
             cser.upstream_list()
         lines = out.getvalue().splitlines()
-        self.assertEqual(2, len(lines))
-        self.assertEqual(
-            'us                                       https://one',
-            lines[0])
-        self.assertEqual(
-            'ci                                       git@two',
-            lines[1])
+        self.assertEqual(4, len(lines))
+        self.assertIn('Name', lines[0])
+        self.assertIn('https://one', lines[2])
+        self.assertIn('git@two', lines[3])
 
     def test_upstream_add_patchwork_url(self):
         """Test adding an upstream with a patchwork URL"""
@@ -1789,8 +1786,8 @@  Tested-by: Mary Smith <msmith@wibble.com>   # yak
         with terminal.capture() as (out, _):
             cser.upstream_list()
         lines = out.getvalue().splitlines()
-        self.assertEqual(1, len(lines))
-        self.assertIn('pw:https://pw.example.com', lines[0])
+        self.assertEqual(3, len(lines))
+        self.assertIn('pw:https://pw.example.com', lines[2])
 
         # Check database lookup
         pw_url = cser.db.upstream_get_patchwork_url('us')
@@ -1808,10 +1805,9 @@  Tested-by: Mary Smith <msmith@wibble.com>   # yak
         with terminal.capture() as (out, _):
             self.run_args('upstream', 'list')
         lines = out.getvalue().splitlines()
-        self.assertEqual(1, len(lines))
-        self.assertEqual(
-            'us                                       https://one',
-            lines[0])
+        self.assertEqual(3, len(lines))
+        self.assertIn('us', lines[2])
+        self.assertIn('https://one', lines[2])
 
     def test_upstream_set(self):
         """Test updating settings on an existing upstream"""
@@ -1891,13 +1887,9 @@  Tested-by: Mary Smith <msmith@wibble.com>   # yak
         with terminal.capture() as (out, _):
             cser.upstream_list()
         lines = out.getvalue().splitlines()
-        self.assertEqual(2, len(lines))
-        self.assertEqual(
-            'us                                       https://one',
-            lines[0])
-        self.assertEqual(
-            'ci         default                       git@two',
-            lines[1])
+        self.assertEqual(4, len(lines))
+        self.assertNotIn('*', lines[2])
+        self.assertIn('*', lines[3])
 
         cser.upstream_set_default(None)
         self.assertIsNone(cser.upstream_get_default())
@@ -1982,7 +1974,8 @@  Tested-by: Mary Smith <msmith@wibble.com>   # yak
             self.run_args('upstream', 'delete', 'ci')
         with terminal.capture() as (out, _):
             self.run_args('upstream', 'list')
-        self.assertFalse(out.getvalue().strip())
+        lines = out.getvalue().splitlines()
+        self.assertEqual(2, len(lines))
 
     def test_series_upstream(self):
         """Test upstream field in the series table"""