From patchwork Mon Apr 13 21:51:24 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sean Anderson X-Patchwork-Id: 1269965 X-Patchwork-Delegate: sjg@chromium.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=85.214.62.61; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=BoKQxTam; dkim-atps=neutral Received: from phobos.denx.de (phobos.denx.de [85.214.62.61]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 491MmB4hvKz9sQx for ; Tue, 14 Apr 2020 07:52:26 +1000 (AEST) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id DF20281552; Mon, 13 Apr 2020 23:52:14 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="BoKQxTam"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id E86B9814F8; Mon, 13 Apr 2020 23:51:59 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,SPF_HELO_NONE,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-qt1-x82d.google.com (mail-qt1-x82d.google.com [IPv6:2607:f8b0:4864:20::82d]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id CE72F80917 for ; Mon, 13 Apr 2020 23:51:55 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=seanga2@gmail.com Received: by mail-qt1-x82d.google.com with SMTP id w29so8108980qtv.3 for ; Mon, 13 Apr 2020 14:51:55 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=vT2Er8DMnsEWmDV17p43h/dx8Ht9YkiRxTP3TD1S5fE=; b=BoKQxTambR5lb+02Vd08ez6MbJClPXk31mpCeT47Lt047ikceRTp9xA6+DHuDwk6GU MUXHYamzzesua/Bx8Bi/4dFeOfQUGFWXqQ51K+jmQL90U2GqwOtRdvI+gqCOR/TnhpeV yI08TSFD1nGvyOvXBtOYa0mbbE8ki8Q+nWVI2W922ZyZt4uYkDNHVv7SOjB/IiUVXuNO D+OLlsswWffMrV1SoKCqX3Api/Eiz7WUWO0Fbs6X8OqJ13LEHECW6yFdX7gfluJZ+pkq PGtrca07pyHM8VoSvUbdv8RVTJMX7rTRUU5NEBaeCXSQGkcHDC434l9f8+8LLJLBVjeJ b3NA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=vT2Er8DMnsEWmDV17p43h/dx8Ht9YkiRxTP3TD1S5fE=; b=NpTwd2a6p6hT74+7MwMIKo5UuaJjdVBWHyQZHsB9vYKYNq0Y3O2x1YI3fLg+Av9emY d4ovW5pbWzKiOqEkEcd+ZnqstIepCKPcrc+rvWDx9uTJnVrF/8ZlpsQCVnc1Tu6NgohN b0ILxGDMdAlWWxeYbwjCsoLy0FjkKBoTenQnWH30xHf3R6EQfWPffcViOo7/s149NzQZ MkEsvPrQC1ziUssRxcez03DSrnTgLp2fhmZ85KsYeeeu9zVnqHi1BbICngWMGB08Dbta vG3NDy5tTPy+p1Khn1pINZP3t9qfpzAkSMFbACk0uIZ58avRzBwQhmInICtwAteTXpiq M7gQ== X-Gm-Message-State: AGi0PubnvgND66eOV+v8dOj+ODbNLwQu+5YQmTaAtt1oy+jIev9ftKPn 4NwliLifGiB2+5P83Aej0hSHggmoyNE= X-Google-Smtp-Source: APiQypJ7bvrMPkVvANN4vDCcMBtyIyqhB+gzYGWwxcqRSdbtB3NI51+dpvwz/3m4pguC+ykM2V181Q== X-Received: by 2002:ac8:2a68:: with SMTP id l37mr13267622qtl.77.1586814714243; Mon, 13 Apr 2020 14:51:54 -0700 (PDT) Received: from godwin.fios-router.home (pool-108-51-35-162.washdc.fios.verizon.net. [108.51.35.162]) by smtp.gmail.com with ESMTPSA id u13sm9003647qku.92.2020.04.13.14.51.53 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 13 Apr 2020 14:51:53 -0700 (PDT) From: Sean Anderson To: u-boot@lists.denx.de Cc: Simon Glass , Sean Anderson Subject: [PATCH v2 1/3] patman: Add option to suppress empty changelog entries Date: Mon, 13 Apr 2020 17:51:24 -0400 Message-Id: <20200413215126.548213-2-seanga2@gmail.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200413215126.548213-1-seanga2@gmail.com> References: <20200413215126.548213-1-seanga2@gmail.com> MIME-Version: 1.0 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.30rc1 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.102.2 at phobos.denx.de X-Virus-Status: Clean Patman outputs a line for every edition of the series in every patch, regardless of whether any changes were made. This can result in many redundant lines in patch changelogs, especially when a patch did not exist before a certain revision. For example, the existing behaviour could result in a changelog of Changes in v7: None Changes in v6: None Changes in v5: - Make a change Changes in v4: None Changes in v3: - New Changes in v2: None With this patch applied and with --no-empty-changes, the same patch would look like (no changes since v5) Changes in v5: - Make a change Changes in v3: - New This is entirely aesthetic, but I think it reduces clutter, especially for patches added later on in a series. Signed-off-by: Sean Anderson --- Changes in v2: - Add a note when there are no changes in the current revision - Make this the default behaviour, and remove the option tools/patman/patchstream.py | 2 +- tools/patman/series.py | 40 +++++++++++++++++++++++++++---------- 2 files changed, 30 insertions(+), 12 deletions(-) diff --git a/tools/patman/patchstream.py b/tools/patman/patchstream.py index df3eb7483b..a83497d79f 100644 --- a/tools/patman/patchstream.py +++ b/tools/patman/patchstream.py @@ -340,7 +340,7 @@ class PatchStream: elif line == '---': self.state = STATE_DIFFS - # Output the tags (signeoff first), then change list + # Output the tags (signoff first), then change list out = [] log = self.series.MakeChangeLog(self.commit) out += [line] diff --git a/tools/patman/series.py b/tools/patman/series.py index a15f7625ed..ca42e5e966 100644 --- a/tools/patman/series.py +++ b/tools/patman/series.py @@ -146,38 +146,56 @@ class Series(dict): Changes in v4: - Jog the dial back closer to the widget - Changes in v3: None Changes in v2: - Fix the widget - Jog the dial - etc. + If there are no new changes in a patch, a note will be added + + (no changes since v2) + + Changes in v2: + - Fix the widget + - Jog the dial """ + versions = sorted(self.changes, reverse=True) + newest_version = 1 + try: + newest_version = max(int(self.version), versions[0]) + except (IndexError, ValueError): + pass + final = [] process_it = self.get('process_log', '').split(',') process_it = [item.strip() for item in process_it] need_blank = False - for change in sorted(self.changes, reverse=True): + for version in versions: out = [] - for this_commit, text in self.changes[change]: + for this_commit, text in self.changes[version]: if commit and this_commit != commit: continue if 'uniq' not in process_it or text not in out: out.append(text) - line = 'Changes in v%d:' % change - have_changes = len(out) > 0 if 'sort' in process_it: out = sorted(out) + have_changes = len(out) > 0 + line = 'Changes in v%d:' % version if have_changes: out.insert(0, line) - else: - out = [line + ' None'] - if need_blank: - out.insert(0, '') + if version < newest_version: + out.insert(0, '') + out.insert(0, '(no changes since v%d)' % version) + newest_version = 0 + # Only add a new line if we output something + if need_blank: + out.insert(0, '') final += out need_blank = have_changes - if self.changes: + + if len(final) > 0: final.append('') + else: + final = ['(no changes since v1)', ''] return final def DoChecks(self): From patchwork Mon Apr 13 21:51:25 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sean Anderson X-Patchwork-Id: 1269966 X-Patchwork-Delegate: sjg@chromium.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=L/k4u0LN; dkim-atps=neutral Received: from phobos.denx.de (phobos.denx.de [IPv6:2a01:238:438b:c500:173d:9f52:ddab:ee01]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 491MmM0l4Kz9sQx for ; Tue, 14 Apr 2020 07:52:35 +1000 (AEST) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id DB17481469; Mon, 13 Apr 2020 23:52:21 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="L/k4u0LN"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id DB1A481469; Mon, 13 Apr 2020 23:52:07 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,SPF_HELO_NONE,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-qt1-x82d.google.com (mail-qt1-x82d.google.com [IPv6:2607:f8b0:4864:20::82d]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id 6DA6481469 for ; Mon, 13 Apr 2020 23:51:57 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=seanga2@gmail.com Received: by mail-qt1-x82d.google.com with SMTP id b10so8490176qtt.9 for ; Mon, 13 Apr 2020 14:51:57 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=fWk+HYv0RjTW71/9ArfcNfv6uxkQ/gd5jSgbQ93ilQI=; b=L/k4u0LN8WD3qzcQM3WQsqxNF3zes0vulUz61qNMqp+FE+RsJ5J56r+LNftOfdgNIo NO/eckKM+sRzFs+12zOnz335ooDuj5N5DwY2vKEu7wlV8Xrsx0mrQ/ebSGw+IkG0EYoy 45UdvK+uzzcQeJlRCXzjCnqXg8A10p9ZXKBHhc9NJ646WdzhPt0VcHWBd0IgULYfGf8k HjsUw2D2wqn9qvQ6nR62aeT9P0pEFMw8Rq4eJk0Vt6niDh5mLBPtHrBbUbnlQ+qgCpan MlxZt92R2GNsqwvJ72+JLwqQk78u3ggoWZXnkyx5pq0moJ0i/fZ4GMq3WMM2PGPPGHGn D1pA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=fWk+HYv0RjTW71/9ArfcNfv6uxkQ/gd5jSgbQ93ilQI=; b=YDR2rUf7Ap6dFsi/pMd2KVZFFN40kSsEotlB+pKu5yazKPYnqtLZ89F7SjYHQHoRKb JDV6+rO4eO4xhXBY3oDxBFC5qruuQG8b/hRi7mzhEq+GdwUCTYWLB5XuCYwYo1rS9LFM zRNCvFLwVwaDMGdS+mU0xqZ61fuk/4JB/8nLtce9+MaoMhri8duzD0wASgz2cdwcPSVp 06TRs9pRmf9brJUf1vkkXwDSI8Y0e6pq/r2gNwlYUpSHw0bF16F0AXqrAurmk8HmeQUz rOHkJk+YmcrMzCIHT7GouP6crQEPk201mtSYPkH6k0PRXWeUlfbFWir/1/GEg2Q69ECi gsXg== X-Gm-Message-State: AGi0PuY8RS275cL3Q2W+MYOcye6PQQa4H7c77jsvSZC1kRDVEiTosQjA BPZ9vzp1hV5KNG7igOlxKFdy4cPLlFA= X-Google-Smtp-Source: APiQypIxjwYk1GOesazdf25Tixxc2rqPq9ulh84PTVPjbX9fvCE8h6zRJulhFEkzbXEZveoKZZWBxA== X-Received: by 2002:aed:3b75:: with SMTP id q50mr13796647qte.23.1586814715770; Mon, 13 Apr 2020 14:51:55 -0700 (PDT) Received: from godwin.fios-router.home (pool-108-51-35-162.washdc.fios.verizon.net. [108.51.35.162]) by smtp.gmail.com with ESMTPSA id u13sm9003647qku.92.2020.04.13.14.51.54 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 13 Apr 2020 14:51:55 -0700 (PDT) From: Sean Anderson To: u-boot@lists.denx.de Cc: Simon Glass , Sean Anderson Subject: [PATCH v2 2/3] patman: Add new tags for finer-grained changelog control Date: Mon, 13 Apr 2020 17:51:25 -0400 Message-Id: <20200413215126.548213-3-seanga2@gmail.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200413215126.548213-1-seanga2@gmail.com> References: <20200413215126.548213-1-seanga2@gmail.com> MIME-Version: 1.0 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.30rc1 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.102.2 at phobos.denx.de X-Virus-Status: Clean By default patman generates a combined changelog for the cover letter. This may not always be desireable. Many patches may have the same changes. These can be coalesced with "Series-process-log: uniq", but this is imperfect. Similar changes like "Move foo to patch 7" will not be merged with the similar "Move foo to this patch from patch 6". Changes may not make sense outside of the patch they are written for. For example, a change line of "Add check for bar" does not make sense outside of the context in which bar might be checked for. Some changes like "New" or "Lint" may be repeated many times throughout different change logs, but carry no useful information in a summary. Lastly, I like to summarize the broad strokes of the changes I have made in the cover letter, while documenting all the details in the appropriate patches. I think this make it easier to get a good feel for what has changed, without making it difficult to wade through every change in the whole series. This patch adds two new tags to add changelog entries which only appear in the cover letter, or only appear in the commit. Changes documented with "Commit-changes" will only appear in the commit, and will not appear in the cover letter. Changes documented with "Cover-changes" will not appear in any commit, and will only appear in the cover letter. Signed-off-by: Sean Anderson --- Changes in v2: - Add documentation for new tags - Switch to using commit tags for changelog control, instead of command-line options tools/patman/README | 17 +++++++++ tools/patman/patchstream.py | 71 ++++++++++++++++++++++--------------- tools/patman/patman.py | 2 +- tools/patman/series.py | 13 +++++-- 4 files changed, 72 insertions(+), 31 deletions(-) diff --git a/tools/patman/README b/tools/patman/README index 02d5829744..ce912aacbb 100644 --- a/tools/patman/README +++ b/tools/patman/README @@ -247,6 +247,23 @@ Series-changes: n to update the log there and then, knowing that the script will do the rest. +Commit-changes: n +- This line will not appear in the cover-letter changelog + + This tag is like Series-changes, except changes in this changelog will + only appear in the changelog of the commit this tag is in. This is + useful when you want to add notes which may not make sense in the cover + letter. For example, you can have short changes such as "New" or + "Lint". + +Cover-changes: n +- This line will only appear in the cover letter + + This tag is like Series-changes, except changes in this changelog will + only appear in the cover-letter changelog. This is useful to summarize + changes made with Commit-changes, or to add additional context to + changes. + Patch-cc: Their Name This copies a single patch to another email address. Note that the Cc: used by git send-email is ignored by patman, but will be diff --git a/tools/patman/patchstream.py b/tools/patman/patchstream.py index a83497d79f..f29ad87e70 100644 --- a/tools/patman/patchstream.py +++ b/tools/patman/patchstream.py @@ -24,11 +24,8 @@ re_allowed_after_test = re.compile('^Signed-off-by:') # Signoffs re_signoff = re.compile('^Signed-off-by: *(.*)') -# The start of the cover letter -re_cover = re.compile('^Cover-letter:') - -# A cover letter Cc -re_cover_cc = re.compile('^Cover-letter-cc: *(.*)') +# Cover letter tag +re_cover = re.compile('^Cover-([a-z-]*): *(.*)') # Patch series tag re_series_tag = re.compile('^Series-([a-z-]*): *(.*)') @@ -65,7 +62,7 @@ class PatchStream: def __init__(self, series, name=None, is_log=False): self.skip_blank = False # True to skip a single blank line self.found_test = False # Found a TEST= line - self.lines_after_test = 0 # MNumber of lines found after TEST= + self.lines_after_test = 0 # Number of lines found after TEST= self.warn = [] # List of warnings we have collected self.linenum = 1 # Output line number we are up to self.in_section = None # Name of start...END section we are in @@ -73,7 +70,8 @@ class PatchStream: self.section = [] # The current section...END section self.series = series # Info about the patch series self.is_log = is_log # True if indent like git log - self.in_change = 0 # Non-zero if we are in a change list + self.in_change = None # Name of the change list we are in + self.change_version = 0 # Non-zero if we are in a change list self.blank_count = 0 # Number of blank lines stored up self.state = STATE_MSG_HEADER # What state are we in? self.signoff = [] # Contents of signoff line @@ -124,6 +122,14 @@ class PatchStream: self.skip_blank = True self.section = [] + def ParseVersion(self, value, line): + """Parse a version from a *-changes tag""" + try: + return int(value) + except ValueError as str: + raise ValueError("%s: Cannot decode version info '%s'" % + (self.commit.hash, line)) + def ProcessLine(self, line): """Process a single line of a patch file or commit log @@ -163,7 +169,6 @@ class PatchStream: change_id_match = re_change_id.match(line) commit_tag_match = re_commit_tag.match(line) cover_match = re_cover.match(line) - cover_cc_match = re_cover_cc.match(line) signoff_match = re_signoff.match(line) tag_match = None if self.state == STATE_PATCH_HEADER: @@ -183,8 +188,7 @@ class PatchStream: # If a tag is detected, or a new commit starts if series_tag_match or commit_tag_match or change_id_match or \ - cover_match or cover_cc_match or signoff_match or \ - self.state == STATE_MSG_HEADER: + cover_match or signoff_match or self.state == STATE_MSG_HEADER: # but we are already in a section, this means 'END' is missing # for that section, fix it up. if self.in_section: @@ -205,8 +209,9 @@ class PatchStream: # but we are already in a change list, that means a blank line # is missing, fix it up. if self.in_change: - self.warn.append("Missing 'blank line' in section 'Series-changes'") - self.in_change = 0 + self.warn.append("Missing 'blank line' in section '%s-changes'" % self.in_change) + self.in_change = None + self.change_version = 0 # If we are in a section, keep collecting lines until we see END if self.in_section: @@ -242,26 +247,37 @@ class PatchStream: elif self.skip_blank and is_blank: self.skip_blank = False - # Detect the start of a cover letter section + # Detect Cover-xxx tags elif cover_match: - self.in_section = 'cover' - self.skip_blank = False - - elif cover_cc_match: - value = cover_cc_match.group(1) - self.AddToSeries(line, 'cover-cc', value) + name = cover_match.group(1) + value = cover_match.group(2) + if name == 'letter': + self.in_section = 'cover' + self.skip_blank = False + elif name == 'letter-cc': + self.AddToSeries(line, 'cover-cc', value) + elif name == 'changes': + self.in_change = 'Cover' + self.change_version = self.ParseVersion(value, line) # If we are in a change list, key collected lines until a blank one elif self.in_change: if is_blank: # Blank line ends this change list - self.in_change = 0 + self.in_change = None + self.change_version = 0 elif line == '---': - self.in_change = 0 + self.in_change = None + self.change_version = 0 out = self.ProcessLine(line) else: if self.is_log: - self.series.AddChange(self.in_change, self.commit, line) + if self.in_change == 'Series': + self.series.AddChange(self.change_version, self.commit, line) + elif self.in_change == 'Cover': + self.series.AddChange(self.change_version, None, line) + elif self.in_change == 'Commit': + self.commit.AddChange(self.change_version, line) self.skip_blank = False # Detect Series-xxx tags @@ -270,12 +286,8 @@ class PatchStream: value = series_tag_match.group(2) if name == 'changes': # value is the version number: e.g. 1, or 2 - try: - value = int(value) - except ValueError as str: - raise ValueError("%s: Cannot decode version info '%s'" % - (self.commit.hash, line)) - self.in_change = int(value) + self.in_change = 'Series' + self.change_version = self.ParseVersion(value, line) else: self.AddToSeries(line, name, value) self.skip_blank = True @@ -297,6 +309,9 @@ class PatchStream: if name == 'notes': self.AddToCommit(line, name, value) self.skip_blank = True + elif name == 'changes': + self.in_change = 'Commit' + self.change_version = self.ParseVersion(value, line) # Detect the start of a new commit elif commit_match: diff --git a/tools/patman/patman.py b/tools/patman/patman.py index cf53e532dd..6ee0597ff4 100755 --- a/tools/patman/patman.py +++ b/tools/patman/patman.py @@ -61,7 +61,7 @@ parser.add_option('--no-check', action='store_false', dest='check_patch', default=True, help="Don't check for patch compliance") parser.add_option('--no-tags', action='store_false', dest='process_tags', - default=True, help="Don't process subject tags as aliaes") + default=True, help="Don't process subject tags as aliases") parser.add_option('--smtp-server', type='str', help="Specify the SMTP server to 'git send-email'") parser.add_option('-T', '--thread', action='store_true', dest='thread', diff --git a/tools/patman/series.py b/tools/patman/series.py index ca42e5e966..4fa06344b5 100644 --- a/tools/patman/series.py +++ b/tools/patman/series.py @@ -4,6 +4,7 @@ from __future__ import print_function +import collections import itertools import os @@ -158,7 +159,15 @@ class Series(dict): - Fix the widget - Jog the dial """ - versions = sorted(self.changes, reverse=True) + # Collect changes from the series and this commit + changes = collections.defaultdict(list) + for version, changelist in self.changes.items(): + changes[version] += changelist + if commit: + for version, changelist in commit.changes.items(): + changes[version] += [[commit, text] for text in changelist] + + versions = sorted(changes, reverse=True) newest_version = 1 try: newest_version = max(int(self.version), versions[0]) @@ -171,7 +180,7 @@ class Series(dict): need_blank = False for version in versions: out = [] - for this_commit, text in self.changes[version]: + for this_commit, text in changes[version]: if commit and this_commit != commit: continue if 'uniq' not in process_it or text not in out: From patchwork Mon Apr 13 21:51:26 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sean Anderson X-Patchwork-Id: 1269967 X-Patchwork-Delegate: sjg@chromium.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=epy+yiWL; dkim-atps=neutral Received: from phobos.denx.de (phobos.denx.de [IPv6:2a01:238:438b:c500:173d:9f52:ddab:ee01]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 491Mmb4H6Kz9sQx for ; Tue, 14 Apr 2020 07:52:47 +1000 (AEST) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 559BF81819; Mon, 13 Apr 2020 23:52:39 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="epy+yiWL"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 947BF8160C; Mon, 13 Apr 2020 23:52:09 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,SPF_HELO_NONE,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-qk1-x72b.google.com (mail-qk1-x72b.google.com [IPv6:2607:f8b0:4864:20::72b]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id 5E5158058D for ; Mon, 13 Apr 2020 23:51:58 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=seanga2@gmail.com Received: by mail-qk1-x72b.google.com with SMTP id w70so6976888qkb.7 for ; Mon, 13 Apr 2020 14:51:58 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=176Ci7hKqEA5GVDE9ta1zFCbgdLza56X2SvvOV0/URc=; b=epy+yiWLpqudy3kpLjOpvnAajA52ACUyYL9wvp5rUtju3oHp9HybXn4HfsdU1rj0lf Tx+AU75/L+9+YtrWtWbtlGEZkHh+UxiB/2bM1ysH4MK2sUOOYM486ER2LW+q5gLr8pVr 3ls2V9XcEoS/DcpLbkuqBEh/gMPlZ8kUSlpcTKladqu2c1g3QVIO2lTm3gufVMA4wyqZ EXSAe/fzPpA8CrVPGro/vgXuXP9vTGQ1A4S2iGuX8mNROd7FGcCTmYhlC16LDamcL3/j vT1owBKdn+/Gbd7I/zY3IHnF23GGTkpVs7wieSPGp1Ze+hTffqu61cRrMe4SzFwYc0BQ 865g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=176Ci7hKqEA5GVDE9ta1zFCbgdLza56X2SvvOV0/URc=; b=lDT4MZ7JVFTTZesOafY7V9ENJMT9fEJbBaVB0KjsTZ37msvE4uerf8vM/viwvMZipp 0mumntkXQ8dbrxK8BGmkc7KVCaaWf/lKNG3FWNwRCha/Xexje8ti8Y9OBG7gTqhX0ffE PGPX5z84BggiBLCjMMs/IWHE0CsYzpVYlniWqnEhuWyRWbQil2sWrk/qchaLe1fFJpbT Ga7CSnQbTpC8b5IB5SSvxU/9O3zLWouxHKUG57NUxw+0n44Ytje/sJ4rqxrkRKreXJLO tlv9dUxA67pqNUamQ3qX6TMccZePnTHP5NW2nGdrJjO4S43K+xBAMuUHNk7t8rDLNs5w Ez6w== X-Gm-Message-State: AGi0PuZkMhn7M4zANsV/QUnCqUsmlvvwj2R3+bZ0X26MWcScpBYWbED9 yymEEwo2d7sdBWudKWpYW+HbvPhHKcM= X-Google-Smtp-Source: APiQypLpVodG/wz3cRxryttLnbBy0v2cHRuBIbrUBT1rMu8/fw5+EVt6FBwFIQIlJju3n3Bu3x/rng== X-Received: by 2002:a05:620a:307:: with SMTP id s7mr3883544qkm.407.1586814716672; Mon, 13 Apr 2020 14:51:56 -0700 (PDT) Received: from godwin.fios-router.home (pool-108-51-35-162.washdc.fios.verizon.net. [108.51.35.162]) by smtp.gmail.com with ESMTPSA id u13sm9003647qku.92.2020.04.13.14.51.55 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 13 Apr 2020 14:51:56 -0700 (PDT) From: Sean Anderson To: u-boot@lists.denx.de Cc: Simon Glass , Sean Anderson Subject: [PATCH v2 3/3] patman: Support multi-line changes in changelogs Date: Mon, 13 Apr 2020 17:51:26 -0400 Message-Id: <20200413215126.548213-4-seanga2@gmail.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200413215126.548213-1-seanga2@gmail.com> References: <20200413215126.548213-1-seanga2@gmail.com> MIME-Version: 1.0 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.30rc1 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.102.2 at phobos.denx.de X-Virus-Status: Clean This patch adds support to multi-line changes. That is, if one has a line in a changelog like - Do a thing but it spans multiple lines Using Series-process-log sort would sort as if those lines were unrelated. With this patch, any change line starting with whitespace will be considered part of the change before it. Signed-off-by: Sean Anderson --- Changes in v2: - New tools/patman/README | 10 ++++++++-- tools/patman/patchstream.py | 35 +++++++++++++++++++++++++++-------- 2 files changed, 35 insertions(+), 10 deletions(-) diff --git a/tools/patman/README b/tools/patman/README index ce912aacbb..433bbf1683 100644 --- a/tools/patman/README +++ b/tools/patman/README @@ -270,8 +270,14 @@ Patch-cc: Their Name interpreted by git send-email if you use it. Series-process-log: sort, uniq - This tells patman to sort and/or uniq the change logs. It is - assumed that each change log entry is only a single line long. + This tells patman to sort and/or uniq the change logs. Changes may be + multiple lines long, as long as each subsequent line of a change begins + with a whitespace character. For example, + +- This change + continues onto the next line +- But this change is separate + Use 'sort' to sort the entries, and 'uniq' to include only unique entries. If omitted, no change log processing is done. Separate each tag with a comma. diff --git a/tools/patman/patchstream.py b/tools/patman/patchstream.py index f29ad87e70..eeac5d268e 100644 --- a/tools/patman/patchstream.py +++ b/tools/patman/patchstream.py @@ -45,6 +45,9 @@ re_commit = re.compile('^commit ([0-9a-f]*)$') # We detect these since checkpatch doesn't always do it re_space_before_tab = re.compile('^[+].* \t') +# Match indented lines for changes +re_leading_whitespace = re.compile('^\s') + # States we can be in - can we use range() and still have comments? STATE_MSG_HEADER = 0 # Still in the message header STATE_PATCH_SUBJECT = 1 # In patch subject (first line of log for a commit) @@ -72,6 +75,7 @@ class PatchStream: self.is_log = is_log # True if indent like git log self.in_change = None # Name of the change list we are in self.change_version = 0 # Non-zero if we are in a change list + self.change_lines = [] # Lines of the current change self.blank_count = 0 # Number of blank lines stored up self.state = STATE_MSG_HEADER # What state are we in? self.signoff = [] # Contents of signoff line @@ -130,6 +134,20 @@ class PatchStream: raise ValueError("%s: Cannot decode version info '%s'" % (self.commit.hash, line)) + def FinalizeChange(self): + """Finalize a (multi-line) change and add it to the series or commit""" + if not self.change_lines: + return + change = '\n'.join(self.change_lines) + + if self.in_change == 'Series': + self.series.AddChange(self.change_version, self.commit, change) + elif self.in_change == 'Cover': + self.series.AddChange(self.change_version, None, change) + elif self.in_change == 'Commit': + self.commit.AddChange(self.change_version, change) + self.change_lines = [] + def ProcessLine(self, line): """Process a single line of a patch file or commit log @@ -170,6 +188,7 @@ class PatchStream: commit_tag_match = re_commit_tag.match(line) cover_match = re_cover.match(line) signoff_match = re_signoff.match(line) + leading_whitespace_match = re_leading_whitespace.match(line) tag_match = None if self.state == STATE_PATCH_HEADER: tag_match = re_tag.match(line) @@ -210,6 +229,7 @@ class PatchStream: # is missing, fix it up. if self.in_change: self.warn.append("Missing 'blank line' in section '%s-changes'" % self.in_change) + self.FinalizeChange() self.in_change = None self.change_version = 0 @@ -264,20 +284,18 @@ class PatchStream: elif self.in_change: if is_blank: # Blank line ends this change list + self.FinalizeChange() self.in_change = None self.change_version = 0 elif line == '---': + self.FinalizeChange() self.in_change = None self.change_version = 0 out = self.ProcessLine(line) - else: - if self.is_log: - if self.in_change == 'Series': - self.series.AddChange(self.change_version, self.commit, line) - elif self.in_change == 'Cover': - self.series.AddChange(self.change_version, None, line) - elif self.in_change == 'Commit': - self.commit.AddChange(self.change_version, line) + elif self.is_log: + if not leading_whitespace_match: + self.FinalizeChange() + self.change_lines.append(line) self.skip_blank = False # Detect Series-xxx tags @@ -370,6 +388,7 @@ class PatchStream: def Finalize(self): """Close out processing of this patch stream""" + self.FinalizeChange() self.CloseCommit() if self.lines_after_test: self.warn.append('Found %d lines after TEST=' %