These relate to information obtained from the patchwork server, so move
their definition into the new patchwork module.

Signed-off-by: Simon Glass <s...@chromium.org>
---

 tools/patman/func_test.py |  21 +++----
 tools/patman/patchwork.py | 113 ++++++++++++++++++++++++++++++++++++
 tools/patman/status.py    | 119 ++------------------------------------
 3 files changed, 129 insertions(+), 124 deletions(-)

diff --git a/tools/patman/func_test.py b/tools/patman/func_test.py
index b3145612f9f..50fb53787d8 100644
--- a/tools/patman/func_test.py
+++ b/tools/patman/func_test.py
@@ -20,6 +20,7 @@ from patman.commit import Commit
 from patman import control
 from patman import patchstream
 from patman.patchstream import PatchStream
+from patman import patchwork
 from patman import send
 from patman.series import Series
 from patman import settings
@@ -807,7 +808,7 @@ diff --git a/lib/efi_loader/efi_memory.c 
b/lib/efi_loader/efi_memory.c
 
     def test_parse_subject(self):
         """Test parsing of the patch subject"""
-        patch = status.Patch('1')
+        patch = patchwork.Patch('1')
 
         # Simple patch not in a series
         patch.parse_subject('Testing')
@@ -876,11 +877,11 @@ diff --git a/lib/efi_loader/efi_memory.c 
b/lib/efi_loader/efi_memory.c
         commit3 = Commit('3456')
         commit3.subject = 'Subject 2'
 
-        patch1 = status.Patch('1')
+        patch1 = patchwork.Patch('1')
         patch1.subject = 'Subject 1'
-        patch2 = status.Patch('2')
+        patch2 = patchwork.Patch('2')
         patch2.subject = 'Subject 2'
-        patch3 = status.Patch('3')
+        patch3 = patchwork.Patch('3')
         patch3.subject = 'Subject 2'
 
         series = Series()
@@ -976,7 +977,7 @@ diff --git a/lib/efi_loader/efi_memory.c 
b/lib/efi_loader/efi_memory.c
         commit2 = Commit('ef12')
         commit2.subject = 'Subject 2'
 
-        patch1 = status.Patch('1')
+        patch1 = patchwork.Patch('1')
         patch1.parse_subject('[1/2] Subject 1')
         patch1.name = patch1.raw_subject
         patch1.content = 'This is my patch content'
@@ -984,7 +985,7 @@ diff --git a/lib/efi_loader/efi_memory.c 
b/lib/efi_loader/efi_memory.c
 
         patch1.comments = [comment1a]
 
-        patch2 = status.Patch('2')
+        patch2 = patchwork.Patch('2')
         patch2.parse_subject('[2/2] Subject 2')
         patch2.name = patch2.raw_subject
         patch2.content = 'Some other patch content'
@@ -1120,7 +1121,7 @@ diff --git a/lib/efi_loader/efi_memory.c 
b/lib/efi_loader/efi_memory.c
         series = patchstream.get_metadata_for_list(branch, gitdir, count)
         self.assertEqual(2, len(series.commits))
 
-        patch1 = status.Patch('1')
+        patch1 = patchwork.Patch('1')
         patch1.parse_subject('[1/2] %s' % series.commits[0].subject)
         patch1.name = patch1.raw_subject
         patch1.content = 'This is my patch content'
@@ -1128,7 +1129,7 @@ diff --git a/lib/efi_loader/efi_memory.c 
b/lib/efi_loader/efi_memory.c
 
         patch1.comments = [comment1a]
 
-        patch2 = status.Patch('2')
+        patch2 = patchwork.Patch('2')
         patch2.parse_subject('[2/2] %s' % series.commits[1].subject)
         patch2.name = patch2.raw_subject
         patch2.content = 'Some other patch content'
@@ -1291,7 +1292,7 @@ line8
         commit2 = Commit('ef12')
         commit2.subject = 'Subject 2'
 
-        patch1 = status.Patch('1')
+        patch1 = patchwork.Patch('1')
         patch1.parse_subject('[1/2] Subject 1')
         patch1.name = patch1.raw_subject
         patch1.content = 'This is my patch content'
@@ -1312,7 +1313,7 @@ Reviewed-by: %s
 
         patch1.comments = [comment1a]
 
-        patch2 = status.Patch('2')
+        patch2 = patchwork.Patch('2')
         patch2.parse_subject('[2/2] Subject 2')
         patch2.name = patch2.raw_subject
         patch2.content = 'Some other patch content'
diff --git a/tools/patman/patchwork.py b/tools/patman/patchwork.py
index 0456f98e83c..bb3645455fe 100644
--- a/tools/patman/patchwork.py
+++ b/tools/patman/patchwork.py
@@ -6,6 +6,7 @@
 """
 
 import asyncio
+import re
 
 import aiohttp
 
@@ -15,6 +16,118 @@ RETRIES = 3
 # Max concurrent request
 MAX_CONCURRENT = 50
 
+# Patches which are part of a multi-patch series are shown with a prefix like
+# [prefix, version, sequence], for example '[RFC, v2, 3/5]'. All but the last
+# part is optional. This decodes the string into groups. For single patches
+# the [] part is not present:
+# Groups: (ignore, ignore, ignore, prefix, version, sequence, subject)
+RE_PATCH = re.compile(r'(\[(((.*),)?(.*),)?(.*)\]\s)?(.*)$')
+
+# This decodes the sequence string into a patch number and patch count
+RE_SEQ = re.compile(r'(\d+)/(\d+)')
+
+
+class Patch(dict):
+    """Models a patch in patchwork
+
+    This class records information obtained from patchwork
+
+    Some of this information comes from the 'Patch' column:
+
+        [RFC,v2,1/3] dm: Driver and uclass changes for tiny-dm
+
+    This shows the prefix, version, seq, count and subject.
+
+    The other properties come from other columns in the display.
+
+    Properties:
+        pid (str): ID of the patch (typically an integer)
+        seq (int): Sequence number within series (1=first) parsed from sequence
+            string
+        count (int): Number of patches in series, parsed from sequence string
+        raw_subject (str): Entire subject line, e.g.
+            "[1/2,v2] efi_loader: Sort header file ordering"
+        prefix (str): Prefix string or None (e.g. 'RFC')
+        version (str): Version string or None (e.g. 'v2')
+        raw_subject (str): Raw patch subject
+        subject (str): Patch subject with [..] part removed (same as commit
+            subject)
+    """
+    def __init__(self, pid):
+        super().__init__()
+        self.id = pid  # Use 'id' to match what the Rest API provides
+        self.seq = None
+        self.count = None
+        self.prefix = None
+        self.version = None
+        self.raw_subject = None
+        self.subject = None
+
+    # These make us more like a dictionary
+    def __setattr__(self, name, value):
+        self[name] = value
+
+    def __getattr__(self, name):
+        return self[name]
+
+    def __hash__(self):
+        return hash(frozenset(self.items()))
+
+    def __str__(self):
+        return self.raw_subject
+
+    def parse_subject(self, raw_subject):
+        """Parse the subject of a patch into its component parts
+
+        See RE_PATCH for details. The parsed info is placed into seq, count,
+        prefix, version, subject
+
+        Args:
+            raw_subject (str): Subject string to parse
+
+        Raises:
+            ValueError: the subject cannot be parsed
+        """
+        self.raw_subject = raw_subject.strip()
+        mat = RE_PATCH.search(raw_subject.strip())
+        if not mat:
+            raise ValueError(f"Cannot parse subject '{raw_subject}'")
+        self.prefix, self.version, seq_info, self.subject = mat.groups()[3:]
+        mat_seq = RE_SEQ.match(seq_info) if seq_info else False
+        if mat_seq is None:
+            self.version = seq_info
+            seq_info = None
+        if self.version and not self.version.startswith('v'):
+            self.prefix = self.version
+            self.version = None
+        if seq_info:
+            if mat_seq:
+                self.seq = int(mat_seq.group(1))
+                self.count = int(mat_seq.group(2))
+        else:
+            self.seq = 1
+            self.count = 1
+
+
+class Review:
+    """Represents a single review email collected in Patchwork
+
+    Patches can attract multiple reviews. Each consists of an author/date and
+    a variable number of 'snippets', which are groups of quoted and unquoted
+    text.
+    """
+    def __init__(self, meta, snippets):
+        """Create new Review object
+
+        Args:
+            meta (str): Text containing review author and date
+            snippets (list): List of snippets in th review, each a list of text
+                lines
+        """
+        self.meta = ' : '.join([line for line in meta.splitlines() if line])
+        self.snippets = snippets
+
+
 class Patchwork:
     """Class to handle communication with patchwork
     """
diff --git a/tools/patman/status.py b/tools/patman/status.py
index 5fb436e08ff..8edb4ced449 100644
--- a/tools/patman/status.py
+++ b/tools/patman/status.py
@@ -11,25 +11,16 @@ collected from patchwork.
 import collections
 import concurrent.futures
 from itertools import repeat
-import re
 
 import pygit2
 import requests
 
-from patman import patchstream
-from patman.patchstream import PatchStream
 from u_boot_pylib import terminal
 from u_boot_pylib import tout
+from patman import patchstream
+from patman import patchwork
+from patman.patchstream import PatchStream
 
-# Patches which are part of a multi-patch series are shown with a prefix like
-# [prefix, version, sequence], for example '[RFC, v2, 3/5]'. All but the last
-# part is optional. This decodes the string into groups. For single patches
-# the [] part is not present:
-# Groups: (ignore, ignore, ignore, prefix, version, sequence, subject)
-RE_PATCH = re.compile(r'(\[(((.*),)?(.*),)?(.*)\]\s)?(.*)$')
-
-# This decodes the sequence string into a patch number and patch count
-RE_SEQ = re.compile(r'(\d+)/(\d+)')
 
 def to_int(vals):
     """Convert a list of strings into integers, using 0 if not an integer
@@ -44,106 +35,6 @@ def to_int(vals):
     return out
 
 
-class Patch(dict):
-    """Models a patch in patchwork
-
-    This class records information obtained from patchwork
-
-    Some of this information comes from the 'Patch' column:
-
-        [RFC,v2,1/3] dm: Driver and uclass changes for tiny-dm
-
-    This shows the prefix, version, seq, count and subject.
-
-    The other properties come from other columns in the display.
-
-    Properties:
-        pid (str): ID of the patch (typically an integer)
-        seq (int): Sequence number within series (1=first) parsed from sequence
-            string
-        count (int): Number of patches in series, parsed from sequence string
-        raw_subject (str): Entire subject line, e.g.
-            "[1/2,v2] efi_loader: Sort header file ordering"
-        prefix (str): Prefix string or None (e.g. 'RFC')
-        version (str): Version string or None (e.g. 'v2')
-        raw_subject (str): Raw patch subject
-        subject (str): Patch subject with [..] part removed (same as commit
-            subject)
-    """
-    def __init__(self, pid):
-        super().__init__()
-        self.id = pid  # Use 'id' to match what the Rest API provides
-        self.seq = None
-        self.count = None
-        self.prefix = None
-        self.version = None
-        self.raw_subject = None
-        self.subject = None
-
-    # These make us more like a dictionary
-    def __setattr__(self, name, value):
-        self[name] = value
-
-    def __getattr__(self, name):
-        return self[name]
-
-    def __hash__(self):
-        return hash(frozenset(self.items()))
-
-    def __str__(self):
-        return self.raw_subject
-
-    def parse_subject(self, raw_subject):
-        """Parse the subject of a patch into its component parts
-
-        See RE_PATCH for details. The parsed info is placed into seq, count,
-        prefix, version, subject
-
-        Args:
-            raw_subject (str): Subject string to parse
-
-        Raises:
-            ValueError: the subject cannot be parsed
-        """
-        self.raw_subject = raw_subject.strip()
-        mat = RE_PATCH.search(raw_subject.strip())
-        if not mat:
-            raise ValueError("Cannot parse subject '%s'" % raw_subject)
-        self.prefix, self.version, seq_info, self.subject = mat.groups()[3:]
-        mat_seq = RE_SEQ.match(seq_info) if seq_info else False
-        if mat_seq is None:
-            self.version = seq_info
-            seq_info = None
-        if self.version and not self.version.startswith('v'):
-            self.prefix = self.version
-            self.version = None
-        if seq_info:
-            if mat_seq:
-                self.seq = int(mat_seq.group(1))
-                self.count = int(mat_seq.group(2))
-        else:
-            self.seq = 1
-            self.count = 1
-
-
-class Review:
-    """Represents a single review email collected in Patchwork
-
-    Patches can attract multiple reviews. Each consists of an author/date and
-    a variable number of 'snippets', which are groups of quoted and unquoted
-    text.
-    """
-    def __init__(self, meta, snippets):
-        """Create new Review object
-
-        Args:
-            meta (str): Text containing review author and date
-            snippets (list): List of snippets in th review, each a list of text
-                lines
-        """
-        self.meta = ' : '.join([line for line in meta.splitlines() if line])
-        self.snippets = snippets
-
 def compare_with_series(series, patches):
     """Compare a list of patches with a series it came from
 
@@ -253,7 +144,7 @@ def collect_patches(series, series_id, url, 
rest_api=call_rest_api):
     # Work through each row (patch) one at a time, collecting the information
     warn_count = 0
     for pw_patch in patch_dict:
-        patch = Patch(pw_patch['id'])
+        patch = patchwork.Patch(pw_patch['id'])
         patch.parse_subject(pw_patch['name'])
         patches.append(patch)
     if warn_count > 1:
@@ -304,7 +195,7 @@ def find_new_responses(new_rtag_list, review_list, seq, 
cmt, patch, url,
         if pstrm.snippets:
             submitter = comment['submitter']
             person = '%s <%s>' % (submitter['name'], submitter['email'])
-            reviews.append(Review(person, pstrm.snippets))
+            reviews.append(patchwork.Review(person, pstrm.snippets))
         for response, people in pstrm.commit.rtags.items():
             rtags[response].update(people)
 
-- 
2.43.0

Reply via email to