diff options
author | Konstantin Ryabitsev <konstantin@linuxfoundation.org> | 2022-09-07 09:45:58 -0400 |
---|---|---|
committer | Konstantin Ryabitsev <konstantin@linuxfoundation.org> | 2022-09-07 09:45:58 -0400 |
commit | dcb1e99bce3edf0e80c1643124a2a93286a7043e (patch) | |
tree | 5d89520176eab54f906b23dda7fb24bbf6944478 | |
parent | 1911df7dd81e6bf0cf337f006ac94218097d191b (diff) | |
download | b4-dcb1e99bce3edf0e80c1643124a2a93286a7043e.tar.gz |
ez: add prep --manual-reroll COVER_MSGID
For folks who prefer to do the actual sending using git-send-email or
any other mechanism, provide a way to trigger the reroll magic manually.
Suggested-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Link: https://msgid.link/Yxecq5DHE5oW0XJD@google.com
Signed-off-by: Konstantin Ryabitsev <konstantin@linuxfoundation.org>
-rw-r--r-- | b4/__init__.py | 4 | ||||
-rw-r--r-- | b4/command.py | 8 | ||||
-rw-r--r-- | b4/ez.py | 48 |
3 files changed, 40 insertions, 20 deletions
diff --git a/b4/__init__.py b/b4/__init__.py index 4df1f42..4e2ec58 100644 --- a/b4/__init__.py +++ b/b4/__init__.py @@ -1413,7 +1413,7 @@ class LoreMessage: return hdata @staticmethod - def get_clean_msgid(msg, header='Message-Id'): + def get_clean_msgid(msg: email.message.Message, header='Message-Id') -> str: msgid = None raw = msg.get(header) if raw: @@ -1423,7 +1423,7 @@ class LoreMessage: return msgid @staticmethod - def get_preferred_duplicate(msg1, msg2): + def get_preferred_duplicate(msg1: email.message.Message, msg2: email.message.Message) -> email.message.Message: config = get_main_config() listid1 = LoreMessage.get_clean_msgid(msg1, 'list-id') if listid1: diff --git a/b4/command.py b/b4/command.py index 5cd4425..8a85232 100644 --- a/b4/command.py +++ b/b4/command.py @@ -254,12 +254,14 @@ def cmd(): sp_prep = subparsers.add_parser('prep', help='Work on patch series to submit for mailing list review') sp_prep.add_argument('--edit-cover', action='store_true', default=False, help='Edit the cover letter in your defined $EDITOR (or core.editor)') + sp_prep.add_argument('--format-patch', metavar='OUTPUT_DIR', + help='Output prep-tracked commits as patches') sp_prep.add_argument('--show-revision', action='store_true', default=False, help='Show current series revision number') - sp_prep.add_argument('--force-revision', default=False, metavar='N', type=int, + sp_prep.add_argument('--force-revision', metavar='N', type=int, help='Force revision to be this number instead') - sp_prep.add_argument('--format-patch', metavar='OUTPUT_DIR', - help='Output prep-tracked commits as patches') + sp_prep.add_argument('--manual-reroll', dest='reroll', default=None, metavar='COVER_MSGID', + help='Mark current revision as sent and reroll (requires cover letter msgid)') ag_prepn = sp_prep.add_argument_group('Create new branch', 'Create a new branch for working on patch series') ag_prepn.add_argument('-n', '--new', dest='new_series_name', help='Create a new branch for working on a patch series') @@ -1234,21 +1234,14 @@ def cmd_send(cmdargs: argparse.Namespace) -> None: if cmdargs.no_sign or config.get('send-no-patatt-sign', '').lower() in {'yes', 'true', 'y'}: sign = False - cover_msgid = cover_body = None + cover_msg = None # TODO: Need to send obsoleted-by follow-ups, just need to figure out where. send_msgs = list() for commit, msg in patches: if not msg: continue - if cover_msgid is None: - cover_msgid = b4.LoreMessage.get_clean_msgid(msg) - lsubject = b4.LoreSubject(msg.get('subject')) - cbody = msg.get_payload() - # Remove signature - chunks = cbody.rsplit('\n-- \n') - if len(chunks) > 1: - cbody = chunks[0] + '\n' - cover_body = lsubject.subject + '\n\n' + cbody + if cover_msg is None: + cover_msg = msg msg.add_header('To', b4.format_addrs(allto)) if allcc: @@ -1291,6 +1284,19 @@ def cmd_send(cmdargs: argparse.Namespace) -> None: logger.debug('Not updating cover/tracking on resend') return + reroll(mybranch, cover_msg) + + +def reroll(mybranch: str, cover_msg: email.message.Message, tagprefix: str = 'sent/'): + # Prepare annotated tag body from the cover letter + lsubject = b4.LoreSubject(cover_msg.get('subject')) + cbody = cover_msg.get_payload() + # Remove signature + chunks = cbody.rsplit('\n-- \n') + if len(chunks) > 1: + cbody = chunks[0] + '\n' + cover_body = lsubject.subject + '\n\n' + cbody + cover, tracking = load_cover(strip_comments=True) revision = tracking['series']['revision'] if mybranch.startswith('b4/'): @@ -1305,6 +1311,10 @@ def cmd_send(cmdargs: argparse.Namespace) -> None: try: strategy = get_cover_strategy() if strategy == 'commit': + # Find out the head commit, which is the end of our range + gitargs = ['rev-parse', 'HEAD'] + ecode, out = b4.git_run_command(None, gitargs) + end_commit = out.strip() # Detach the head at our parent commit and apply the cover-less series cover_commit = find_cover_commit() gitargs = ['checkout', f'{cover_commit}~1'] @@ -1312,8 +1322,7 @@ def cmd_send(cmdargs: argparse.Namespace) -> None: if ecode > 0: raise RuntimeError('Could not switch to a detached head') # cherry-pick from cover letter to the last commit - last_commit = patches[-1][0] - gitargs = ['cherry-pick', f'{cover_commit}..{last_commit}'] + gitargs = ['cherry-pick', f'{cover_commit}..{end_commit}'] ecode, out = b4.git_run_command(None, gitargs) if ecode > 0: raise RuntimeError('Could not cherry-pick the cover-less range') @@ -1348,9 +1357,7 @@ def cmd_send(cmdargs: argparse.Namespace) -> None: else: logger.info('NOTE: Tagname %s already exists', tagname) - if not cover_msgid: - return - + cover_msgid = b4.LoreMessage.get_clean_msgid(cover_msg) logger.info('Recording series message-id in cover letter tracking') cover, tracking = load_cover(strip_comments=False) vrev = f'v{revision}' @@ -1433,6 +1440,17 @@ def cmd_prep(cmdargs: argparse.Namespace) -> None: if cmdargs.edit_cover: return edit_cover() + if cmdargs.reroll: + msgid = cmdargs.reroll + msgs = b4.get_pi_thread_by_msgid(msgid, onlymsgids={msgid}, nocache=True) + mybranch = b4.git_get_current_branch(None) + if msgs: + for msg in msgs: + if b4.LoreMessage.get_clean_msgid(msg) == msgid: + return reroll(mybranch, msg) + logger.critical('CRITICAL: could not retrieve %s', msgid) + sys.exit(1) + if cmdargs.show_revision: return show_revision() |