tools.linux.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Rudraksha Gupta <guptarud@gmail.com>
To: "Kernel.org Tools" <tools@kernel.org>
Cc: Konstantin Ryabitsev <konstantin@linuxfoundation.org>,
	 Rudraksha Gupta <guptarud@gmail.com>
Subject: [PATCH b4] Add `flow` subcommand
Date: Sun, 02 Mar 2025 16:34:34 -0800	[thread overview]
Message-ID: <20250302-flow-v1-1-3247c022bbac@gmail.com> (raw)

`b4 flow` is an interactive session designed to handhold the user into
submitting patches upsteam. As b4 grows in complexity, there will be
multiple commands to remember. `b4 flow` covers the majority of cases and
shows the proper way to use the program.

Signed-off-by: Rudraksha Gupta <guptarud@gmail.com>
---
`b4 flow` is an interactive session designed to handhold the user into
submitting patches upsteam. As b4 grows in complexity, there will be
multiple commands to remember. `b4 flow` covers the majority of cases and
shows the proper way to use the program.
---
 src/b4/command.py | 75 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 75 insertions(+)

diff --git a/src/b4/command.py b/src/b4/command.py
index 617a2d7..c0ac71a 100644
--- a/src/b4/command.py
+++ b/src/b4/command.py
@@ -9,6 +9,9 @@ import argparse
 import logging
 import b4
 import sys
+import subprocess
+import os
+import tempfile
 
 logger = b4.logger
 
@@ -93,6 +96,74 @@ def cmd_send(cmdargs):
     b4.ez.cmd_send(cmdargs)
 
 
+def cmd_flow(cmdargs):
+    import b4.ez
+    def run_b4_recursively(command_args: str):
+        current_path = os.path.dirname(os.path.abspath(__file__))
+        command_args_run = [os.path.join(current_path, 'b4.sh')] + command_args.split(" ")
+        command_args_bak = [os.path.join(current_path, '..', '..', 'b4.sh')] + command_args.split(" ")
+        # TODO: can we deterministically see where the shell script executed from?
+        try:
+            out = subprocess.run(command_args_run, check=True)
+        except:
+            try:
+                out = subprocess.run(command_args_bak, check=True)
+            except:
+                return False
+        return True
+
+    def question_user(prompt: str, command: str) -> bool:
+        # We want to default this as a Y so that users can use the `yes` command
+        user_input = input(prompt + ' [Y/n]: ')
+        if user_input.strip().lower() not in ['y', '']:
+            return False
+        run_b4_recursively(command)
+        return True
+
+    # Colors
+    WARNING = '\033[93m'
+    ENDC = '\033[0m'
+
+    print("Starting up an interactive session to submit kernel patches upstream. Make your changes prior to running this. Press Ctrl+C to exit at any point.")
+    print(WARNING)
+    print("If you changed a commit message, trailers will NOT be applied for that patch. Please manually apply them.")
+    print(ENDC)
+
+    question_user("Retrieve trailers?", "trailers -u")
+    question_user("Edit cover letter?", "prep --edit-cover")
+    with tempfile.TemporaryDirectory() as tmpdir:
+        if question_user("View patches?", f'send -o {tmpdir}'):
+            for file in os.listdir(tmpdir):
+                print(f"viewing: {file}")
+                file_path = os.path.join(tmpdir, file)
+                with open(file_path, 'r') as f:
+                    content = f.read().encode()
+                    b4.edit_in_editor(content, filehint='Review Patches')
+        # needs to run `b4 send -o {tmpdir}` just in case user says no in the previous question
+        if question_user("Run checkpatch.pl?", f'send -o {tmpdir}'):
+            for file in os.listdir(tmpdir):
+                if file.startswith('0000-'):
+                    continue
+
+                print(file)
+                file_path = os.path.join(tmpdir, file)
+                subprocess.run(["./scripts/checkpatch.pl", file_path], check=True)
+
+    cover, tracking = b4.ez.load_cover(strip_comments=True)
+    revision = tracking['series'].get('revision')
+    if revision > 1:
+        question_user("Compare with previous version?", f"prep --compare-to v{revision - 1}")
+
+    question_user("Auto add emails?", "prep --auto-to-cc")
+    question_user("Check with b4?", "prep --check")
+    question_user("Reflect patches?", "send --reflect")
+
+    print(WARNING)
+    print("You are about to send your patches upstream.")
+    print(ENDC)
+    question_user("Send?", "send")
+
+
 def cmd_am(cmdargs):
     import b4.mbox
     b4.mbox.main(cmdargs)
@@ -389,6 +460,10 @@ def setup_parser() -> argparse.ArgumentParser:
                           help='Submit the token received via verification email')
     sp_send.set_defaults(func=cmd_send)
 
+    # b4 flow
+    sp_flow = subparsers.add_parser('flow', help='Interactive session to submit patches upstream')
+    sp_flow.set_defaults(func=cmd_flow)
+
     return parser
 
 

---
base-commit: 42535902a457332560d860608b770fca9eea1382
change-id: 20250302-flow-954294542408

Best regards,
-- 
Rudraksha Gupta <guptarud@gmail.com>


             reply	other threads:[~2025-03-03  0:34 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-03-03  0:34 Rudraksha Gupta [this message]
2025-03-05 19:41 ` [PATCH b4] Add `flow` subcommand Konstantin Ryabitsev
2025-03-11  4:04   ` Rudraksha Gupta

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20250302-flow-v1-1-3247c022bbac@gmail.com \
    --to=guptarud@gmail.com \
    --cc=konstantin@linuxfoundation.org \
    --cc=tools@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).