From patchwork Sun Mar 29 15:01:27 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 2076 Return-Path: X-Original-To: u-boot-concept@u-boot.org Delivered-To: u-boot-concept@u-boot.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1774796521; bh=bhoRALAIbxb1k8+aBA4Py3iYdLP1aryG8dG/DstmZL8=; h=From:To:Date:In-Reply-To:References:CC:Subject:List-Id: List-Archive:List-Help:List-Owner:List-Post:List-Subscribe: List-Unsubscribe:From; b=UgWStCLILHlvtXEt5eZvmAqMxKU+/9pNUON+ymjHhiBjZDmHoMzsTUtZ4f7HmvDKN O5MW6W7wjPBpR5S1cHQHt3oDJWN2K6UyNaFOGD1RFBlt6euDmFqQPwL10ntJIswtZJ 8yusv2EG+piIOhQuW3bZczpe75nfAzP5W9OVuojvQnV7FSsmwH2RE6fQYhVaRpbsSo /qi+4JfN2g+q9L1pe5TPifRK7VGMXTxYMZgmsq6QhuNTs9f9je6PgAB8K6ut7Sb4k5 /3sUAXo1o33fE+bXxFoYLPkT5m5hRU93gU7lvOI1DRiL4K/eDqyuPkxSPWaqgSzEoK DCSLeDhKKwyhA== Received: from localhost (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id AB6B26A2AB for ; Sun, 29 Mar 2026 09:02:01 -0600 (MDT) X-Virus-Scanned: Debian amavis at Received: from mail.u-boot.org ([127.0.0.1]) by localhost (mail.u-boot.org [127.0.0.1]) (amavis, port 10024) with ESMTP id 88ZPQkkrrXiJ for ; Sun, 29 Mar 2026 09:02:01 -0600 (MDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1774796521; bh=bhoRALAIbxb1k8+aBA4Py3iYdLP1aryG8dG/DstmZL8=; h=From:To:Date:In-Reply-To:References:CC:Subject:List-Id: List-Archive:List-Help:List-Owner:List-Post:List-Subscribe: List-Unsubscribe:From; b=UgWStCLILHlvtXEt5eZvmAqMxKU+/9pNUON+ymjHhiBjZDmHoMzsTUtZ4f7HmvDKN O5MW6W7wjPBpR5S1cHQHt3oDJWN2K6UyNaFOGD1RFBlt6euDmFqQPwL10ntJIswtZJ 8yusv2EG+piIOhQuW3bZczpe75nfAzP5W9OVuojvQnV7FSsmwH2RE6fQYhVaRpbsSo /qi+4JfN2g+q9L1pe5TPifRK7VGMXTxYMZgmsq6QhuNTs9f9je6PgAB8K6ut7Sb4k5 /3sUAXo1o33fE+bXxFoYLPkT5m5hRU93gU7lvOI1DRiL4K/eDqyuPkxSPWaqgSzEoK DCSLeDhKKwyhA== Received: from mail.u-boot.org (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id 665176A2DD for ; Sun, 29 Mar 2026 09:02:01 -0600 (MDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1774796518; bh=bdYU4nDQtCsSpa+cLHyO+dfv5R1g96AE7bOqRFV5Ibg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=QwmnAs+cn4bo06eoZWaelf37dtXdePpHgS4T/SixjQmwyCTWx2UL9JJme+pdntMf1 GOw/AH8y36L4U0UIe0PO4cuf+qxq/aNagiBVfTwPyAHvap3J3PLBeZK2oMHKyCu8SB E3f0i2eCbwdLx53u1h1l6hs/hSNVjwrtePeJyL4eB833hjvMvViRUn4UoPzwmgu8dv abKWl9qKVmJXC12ZXxIO/ctpoay+Alt6fUZ5kJSsJv0BkeKYYzMQtjh/3vGHtzDmAG 0JFw0PfUdzNpbdItaQJoWLpBk1+UzCwtLfuH6yt9Aa1jh0BCGF3a8b3KCgPtwpGOrX 9R+7gO71msmdA== Received: from localhost (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id A8A5E6A2D1; Sun, 29 Mar 2026 09:01:58 -0600 (MDT) X-Virus-Scanned: Debian amavis at Received: from mail.u-boot.org ([127.0.0.1]) by localhost (mail.u-boot.org [127.0.0.1]) (amavis, port 10026) with ESMTP id BpU9F3qLhCcA; Sun, 29 Mar 2026 09:01:58 -0600 (MDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1774796517; bh=0eBQISj7CjGwDSU9CagRdVSrJFCPiwZ5tv8RWJ2n0Yw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=GuGpdt4dH9izB34j6IN90fxKAXkrcZ4mZMQlPgjb48jFTOnIlySGV0BBBbuJPtw/Q DmT9gFI69jA1eXq1XVOKoDXgos8xnEvobgupZ59EDnOmzU6+r5Mf8jkiHGBHyWszwH KyGI+bYHDkQGRm7XyWLWS9D0oEq5vvCwA66pzZmeyqBfIYGw3ufb09LEUiXMoKsUcx GuCjienz6+zxOI5H3vPmZpoDSxANSY3e7YBV+JvwuTTPJa84gCFc3TycP6kHdA7bwI l45BqI8+QgNLaX1FVMIdS+fRMfoBBAdV2CfdrOiCkPAghR5PcxkZhkcRgdl66y3w+3 wGcWWO61W6l6w== Received: from u-boot.org (unknown [73.34.74.121]) by mail.u-boot.org (Postfix) with ESMTPSA id E98696A02E; Sun, 29 Mar 2026 09:01:56 -0600 (MDT) From: Simon Glass To: U-Boot Concept Date: Sun, 29 Mar 2026 09:01:27 -0600 Message-ID: <20260329150140.4095446-3-sjg@u-boot.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260329150140.4095446-1-sjg@u-boot.org> References: <20260329150140.4095446-1-sjg@u-boot.org> MIME-Version: 1.0 Message-ID-Hash: TRPZN2UXXU2NF5B42U4T5CSRGMFCCXQX X-Message-ID-Hash: TRPZN2UXXU2NF5B42U4T5CSRGMFCCXQX X-MailFrom: sjg@u-boot.org X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header CC: Simon Glass X-Mailman-Version: 3.3.10 Precedence: list Subject: [Concept] [PATCH 02/11] u_boot_pylib: Capture send-output to count sent patches List-Id: Discussion and patches related to U-Boot Concept Archived-At: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: From: Simon Glass Capture the git send-email output using an echo output function that writes to the terminal in real time while also buffering the output. After the command finishes, count "Result: " lines in the SMTP log to determine how many patches were actually sent. Change the return value to a (cmd_string, num_sent) tuple so callers can distinguish between a successful send and a user abort. Signed-off-by: Simon Glass --- tools/u_boot_pylib/gitutil.py | 37 +++++++++++++++++++++++------------ 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/tools/u_boot_pylib/gitutil.py b/tools/u_boot_pylib/gitutil.py index c96cd251776..22414d250a9 100644 --- a/tools/u_boot_pylib/gitutil.py +++ b/tools/u_boot_pylib/gitutil.py @@ -483,7 +483,9 @@ def email_patches(series, cover_fname, args, dry_run, warn_on_error, cc_fname, cwd (str): Path to use for patch files (None to use current dir) Returns: - Git command that was/would be run + tuple: + str: Git command that was/would be run + int: Number of patches successfully sent (0 for dry run) # For the duration of this doctest pretend that we ran patman with ./patman >>> _old_argv0 = sys.argv[0] @@ -501,22 +503,22 @@ def email_patches(series, cover_fname, args, dry_run, warn_on_error, cc_fname, >>> series['cc'] = ['mary'] >>> email_patches(series, 'cover', ['p1', 'p2'], True, True, 'cc-fname', \ False, alias) - 'git send-email --annotate --to "f.bloggs@napier.co.nz" --cc \ -"m.poppins@cloud.net" --cc-cmd "./patman send --cc-cmd cc-fname" cover p1 p2' + ('git send-email --annotate --to "f.bloggs@napier.co.nz" --cc \ +"m.poppins@cloud.net" --cc-cmd "./patman send --cc-cmd cc-fname" cover p1 p2', 0) >>> email_patches(series, None, ['p1'], True, True, 'cc-fname', False, \ alias) - 'git send-email --annotate --to "f.bloggs@napier.co.nz" --cc \ -"m.poppins@cloud.net" --cc-cmd "./patman send --cc-cmd cc-fname" p1' + ('git send-email --annotate --to "f.bloggs@napier.co.nz" --cc \ +"m.poppins@cloud.net" --cc-cmd "./patman send --cc-cmd cc-fname" p1', 0) >>> series['cc'] = ['all'] >>> email_patches(series, 'cover', ['p1', 'p2'], True, True, 'cc-fname', \ True, alias) - 'git send-email --annotate --to "this-is-me@me.com" --cc-cmd "./patman \ -send --cc-cmd cc-fname" cover p1 p2' + ('git send-email --annotate --to "this-is-me@me.com" --cc-cmd "./patman \ +send --cc-cmd cc-fname" cover p1 p2', 0) >>> email_patches(series, 'cover', ['p1', 'p2'], True, True, 'cc-fname', \ False, alias) - 'git send-email --annotate --to "f.bloggs@napier.co.nz" --cc \ + ('git send-email --annotate --to "f.bloggs@napier.co.nz" --cc \ "f.bloggs@napier.co.nz" --cc "j.bloggs@napier.co.nz" --cc \ -"m.poppins@cloud.net" --cc-cmd "./patman send --cc-cmd cc-fname" cover p1 p2' +"m.poppins@cloud.net" --cc-cmd "./patman send --cc-cmd cc-fname" cover p1 p2', 0) # Restore argv[0] since we clobbered it. >>> sys.argv[0] = _old_argv0 @@ -530,7 +532,7 @@ send --cc-cmd cc-fname" cover p1 p2' "Series-to: Fred Bloggs \n" "Or do something like this\n" "git config sendemail.to u-boot@lists.denx.de") - return None + return None, 0 cc = build_email_list(list(set(series.get('cc')) - set(series.get('to'))), alias, '--cc', warn_on_error) if self_only: @@ -553,10 +555,19 @@ send --cc-cmd cc-fname" cover p1 p2' if cover_fname: cmd.append(cover_fname) cmd += args + num_sent = 0 if not dry_run: - command.run(*cmd, capture=False, capture_stderr=False, cwd=cwd) - return' '.join([f'"{x}"' if ' ' in x and '"' not in x else x - for x in cmd]) + def echo_output(_stream, data): + os.write(sys.stdout.fileno(), data) + return False + + result = command.run_pipe( + [cmd], capture=True, output_func=echo_output, + raise_on_error=False, cwd=cwd) + num_sent = result.stdout.count('Result: ') + cmd_str = ' '.join([f'"{x}"' if ' ' in x and '"' not in x else x + for x in cmd]) + return cmd_str, num_sent def lookup_email(lookup_name, alias, warn_on_error=True, level=0):