collected from patchwork.
"""
+import asyncio
from collections import defaultdict
import concurrent.futures
from itertools import repeat
+import aiohttp
import pygit2
-import requests
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
def to_int(vals):
[parent.target])
return num_added
-def check_status(series, series_id, pwork):
+def _check_status(series, series_id, pwork):
"""Check the status of a series on Patchwork
This finds review tags and comments for a series in Patchwork, displaying
f'series has {num_commits}')
-def do_show_status(series, patch_for_commit, show_comments, new_rtag_list,
+def do_show_status(patches, series, branch, show_comments, col,
+ warnings_on_stderr=True):
+ """Check the status of a series on Patchwork
+
+ This finds review tags and comments for a series in Patchwork, displaying
+ them to show what is new compared to the local series.
+
+ Args:
+ patches (list of Patch): Patch objects in the series
+ series (Series): Series object for the existing branch
+ branch (str): Existing branch to update, or None
+ show_comments (bool): True to show the comments on each patch
+ col (terminal.Colour): Colour object
+
+ Return: tuple:
+ int: Number of new review tags to add
+ list: List of review tags to add, one item for each commit, each a
+ dict:
+ key: Response tag (e.g. 'Reviewed-by')
+ value: Set of people who gave that response, each a name/email
+ string
+ list of PATCH objects
+ """
+ compare = []
+ for pw_patch in patches:
+ patch = patchwork.Patch(pw_patch.id)
+ patch.parse_subject(pw_patch.series_data['name'])
+ compare.append(patch)
+
+ count = len(series.commits)
+ new_rtag_list = [None] * count
+ review_list = [None] * count
+
+ patch_for_commit, _, warnings = compare_with_series(series, compare)
+ for warn in warnings:
+ tout.do_output(tout.WARNING if warnings_on_stderr else tout.INFO, warn)
+
+ for seq, pw_patch in enumerate(patches):
+ compare[seq].patch = pw_patch
+
+ for i in range(count):
+ pat = patch_for_commit.get(i)
+ if pat:
+ patch_data = pat.patch.data
+ comment_data = pat.patch.comments
+ new_rtag_list[i], review_list[i] = process_reviews(
+ patch_data['content'], comment_data, series.commits[i].rtags)
+ num_to_add = _do_show_status(series, patch_for_commit, show_comments, new_rtag_list,
+ review_list, col)
+ return num_to_add, new_rtag_list, patches
+
+
+def _do_show_status(series, patch_for_commit, show_comments, new_rtag_list,
review_list, col):
num_to_add = 0
for seq, cmt in enumerate(series.commits):
num_to_add += show_responses(col, new_rtags, indent, True)
if show_comments:
for review in review_list[seq]:
- terminal.tprint('Review: %s' % review.meta, colour=col.RED)
+ terminal.tprint('Review: %s' % review.meta, colour=col.RED,
+ col=col)
for snippet in review.snippets:
for line in snippet:
quoted = line.startswith('>')
- terminal.tprint(' %s' % line,
- colour=col.MAGENTA if quoted else None)
+ terminal.tprint(
+ f' {line}',
+ colour=col.MAGENTA if quoted else None, col=col)
terminal.tprint()
return num_to_add
-def show_status(series, branch, dest_branch, force, patches, patch_for_commit,
- show_comments, new_rtag_list, review_list, test_repo=None):
- """Show status to the user and allow a branch to be written
+def show_status(series, branch, dest_branch, force, patches, show_comments,
+ test_repo=None):
+ """Check the status of a series on Patchwork
+
+ This finds review tags and comments for a series in Patchwork, displaying
+ them to show what is new compared to the local series.
Args:
series (Series): Series object for the existing branch
dest_branch (str): Name of new branch to create, or None
force (bool): True to force overwriting dest_branch if it exists
patches (list of Patch): Patches sorted by sequence number
- patch_for_commit (dict): Patches for commit
- key: Commit number (0...n-1)
- value: Patch object for that commit
- show_comments (bool): True to show patch comments
- new_rtag_list (list of dict) review tags for each patch:
- key: Response tag (e.g. 'Reviewed-by')
- value: Set of people who gave that response, each a name/email
- string
- review_list (list of list): list for each patch, each a:
- list of Review objects for the patch
+ show_comments (bool): True to show the comments on each patch
test_repo (pygit2.Repository): Repo to use (use None unless testing)
"""
col = terminal.Color()
check_patch_count(len(series.commits), len(patches))
- num_to_add = do_show_status(series, patch_for_commit, show_comments,
- new_rtag_list, review_list, col)
+ num_to_add, new_rtag_list, _ = do_show_status(
+ patches, series, branch, show_comments, col)
- terminal.tprint("%d new response%s available in patchwork%s" %
- (num_to_add, 's' if num_to_add != 1 else '',
- '' if dest_branch
- else ' (use -d to write them to a new branch)'))
+ if not dest_branch and num_to_add:
+ msg = ' (use -d to write them to a new branch)'
+ else:
+ msg = ''
+ terminal.tprint(
+ f"{num_to_add} new response{'s' if num_to_add != 1 else ''} "
+ f'available in patchwork{msg}')
if dest_branch:
- num_added = create_branch(series, new_rtag_list, branch, dest_branch,
- force, test_repo)
+ num_added = create_branch(series, new_rtag_list, branch,
+ dest_branch, force, test_repo)
terminal.tprint(
- "%d response%s added from patchwork into new branch '%s'" %
- (num_added, 's' if num_added != 1 else '', dest_branch))
+ f"{num_added} response{'s' if num_added != 1 else ''} added "
+ f"from patchwork into new branch '{dest_branch}'")
+
+
+async def check_status(link, pwork, read_comments=False):
+ """Set up an HTTP session and get the required state
+
+ Args:
+ link (str): Patch series ID number
+ pwork (Patchwork): Patchwork object to use for reading
+ read_comments (bool): True to read comments and state for each patch
+
+ Return: tuple:
+ list of Patch objects
+ """
+ async with aiohttp.ClientSession() as client:
+ patches = await pwork.series_get_state(client, link, read_comments)
+ return patches
def check_and_show_status(series, link, branch, dest_branch, force,
branch (str): Existing branch to update, or None
dest_branch (str): Name of new branch to create, or None
force (bool): True to force overwriting dest_branch if it exists
- show_comments (bool): True to show patch comments
+ show_comments (bool): True to show the comments on each patch
pwork (Patchwork): Patchwork object to use for reading
test_repo (pygit2.Repository): Repo to use (use None unless testing)
"""
- patches, patch_for_commit, new_rtag_list, review_list = check_status(
- series, link, pwork)
- show_status(series, branch, dest_branch, force, patches, patch_for_commit,
- show_comments, new_rtag_list, review_list, test_repo)
+ patches = asyncio.run(check_status(link, pwork, True))
+
+ show_status(series, branch, dest_branch, force, patches, show_comments,
+ test_repo=test_repo)