From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from simark.ca by simark.ca with LMTP id DFEJCs4BkGoChQUAWB0awg (envelope-from ) for ; Thu, 27 Aug 2026 05:22:22 -0400 Authentication-Results: simark.ca; dkim=pass (1024-bit key; unprotected) header.d=suse.de header.i=@suse.de header.a=rsa-sha256 header.s=susede2_rsa header.b=shjONDBs; dkim=pass header.d=suse.de header.i=@suse.de header.a=ed25519-sha256 header.s=susede2_ed25519 header.b=MAisl5TM; dkim=pass (1024-bit key) header.d=suse.de header.i=@suse.de header.a=rsa-sha256 header.s=susede2_rsa header.b=S4D0Ran7; dkim=neutral header.d=suse.de header.i=@suse.de header.a=ed25519-sha256 header.s=susede2_ed25519 header.b=linu+Ciz; dkim-atps=neutral Received: by simark.ca (Postfix, from userid 112) id 018921E0A3; Thu, 27 Aug 2026 05:22:21 -0400 (EDT) X-Spam-Checker-Version: SpamAssassin 4.0.1 (2024-03-25) on simark.ca X-Spam-Level: X-Spam-Status: No, score=-5.4 required=5.0 tests=ARC_SIGNED,ARC_VALID,BAYES_00, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham autolearn_force=no version=4.0.1 Received: from vm01.sourceware.org (vm01.sourceware.org [38.145.34.32]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange x25519 server-signature ECDSA (prime256v1) server-digest SHA256) (No client certificate requested) by simark.ca (Postfix) with ESMTPS id 199591E09B for ; Thu, 27 Aug 2026 05:22:20 -0400 (EDT) Received: from vm01.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 2FB534BA2E35 for ; Thu, 27 Aug 2026 09:22:19 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 2FB534BA2E35 Authentication-Results: sourceware.org; dkim=pass (1024-bit key, unprotected) header.d=suse.de header.i=@suse.de header.a=rsa-sha256 header.s=susede2_rsa header.b=shjONDBs; dkim=pass header.d=suse.de header.i=@suse.de header.a=ed25519-sha256 header.s=susede2_ed25519 header.b=MAisl5TM; dkim=pass (1024-bit key) header.d=suse.de header.i=@suse.de header.a=rsa-sha256 header.s=susede2_rsa header.b=S4D0Ran7; dkim=neutral header.d=suse.de header.i=@suse.de header.a=ed25519-sha256 header.s=susede2_ed25519 header.b=linu+Ciz Received: from smtp-out1.suse.de (smtp-out1.suse.de [195.135.223.130]) by sourceware.org (Postfix) with ESMTPS id 11CA84BA2E24 for ; Thu, 27 Aug 2026 09:21:51 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 11CA84BA2E24 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=suse.de Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=suse.de ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 11CA84BA2E24 Authentication-Results: sourceware.org; arc=none smtp.remote-ip=195.135.223.130 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1787822511; cv=none; b=REb2Y3zz+raAHgSXnZj4T1lIHdYyLuIWw1nXjhFDwImPs0iy5qYYl6Vh7YP2kJaL5t3QSnxo0Bw4Yq4qnmFmKavlDg3bMl91V7PdnMNqC3S6o9IIs+gVxpTdeh0MxD3ZL/UE+fVhWewksfYg8M4W2xMi+U9Rl1EHzzl+YNiwP7I= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1787822511; c=relaxed/simple; bh=woxzV0VvfGH8H3odB7Q7gacu3c0mleeZ0gMINIZ0utY=; h=DKIM-Signature:DKIM-Signature:DKIM-Signature:DKIM-Signature: Message-ID:Date:MIME-Version:Subject:From:To; b=sAEYtssY9ZismYm7Sdx1VYqxcnSKbtn8h1ZpgHNG/6xmvmDlAFRV3RePs/uD354ZnVBudjKq3GtJRr8zVCSiNJIpgLv+XarfrQDiPlWKQwxblF894zrLo7zY21rrWV52Dq/NeKBbXQ+7J3AKclluUMhPZZNT/CgoJEWIwE1a8Hw= ARC-Authentication-Results: i=1; sourceware.org; dkim=pass (1024-bit key, unprotected) header.d=suse.de header.i=@suse.de header.a=rsa-sha256 header.s=susede2_rsa header.b=shjONDBs; dkim=pass header.d=suse.de header.i=@suse.de header.a=ed25519-sha256 header.s=susede2_ed25519 header.b=MAisl5TM; dkim=pass (1024-bit key) header.d=suse.de header.i=@suse.de header.a=rsa-sha256 header.s=susede2_rsa header.b=S4D0Ran7; dkim=neutral header.d=suse.de header.i=@suse.de header.a=ed25519-sha256 header.s=susede2_ed25519 header.b=linu+Ciz DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 11CA84BA2E24 Received: from imap1.dmz-prg2.suse.org (imap1.dmz-prg2.suse.org [IPv6:2a07:de40:b281:104:10:150:64:97]) (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 smtp-out1.suse.de (Postfix) with ESMTPS id 04F19211FB for ; Thu, 27 Aug 2026 09:21:41 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_rsa; t=1787822506; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc: mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=OQUBzVIWBMATwPVfzDIhG4K3xAk8OWylLaGMsrPjAX8=; b=shjONDBslJktx1eQGTprhKqJuuZfM4QTl8vxLW/u5Xu0afFyBZcPojrU8YiyZfWvpByLDv 1hZCOIi0slZ26Aw0msu5Y1ffk0P6mgOOP9+ZKNrz/2TU7c+9LghVeA8Y9xPOXnZnY4yj66 xKL5eqwclsB9XxtJOI/oIJM5RSSTh1c= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_ed25519; t=1787822506; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc: mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=OQUBzVIWBMATwPVfzDIhG4K3xAk8OWylLaGMsrPjAX8=; b=MAisl5TM4EHrBi+Ibg4teLaJaTdq6FVdM5T8HL41EShbeczPwDe1wAMbuvIH+udtEVRp+a OJCpPfCI2DXLEkBA== Authentication-Results: smtp-out1.suse.de; dkim=pass header.d=suse.de header.s=susede2_rsa header.b=S4D0Ran7; dkim=pass header.d=suse.de header.s=susede2_ed25519 header.b=linu+Ciz DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_rsa; t=1787822501; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc: mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=OQUBzVIWBMATwPVfzDIhG4K3xAk8OWylLaGMsrPjAX8=; b=S4D0Ran7vRVcDboiexIV6qfkcdYjlQ++D7XL+kBCXWlmYKl4/e2O9Wx+p5uahSuyKwlSlr bdaoElVBpXOQ35F5cyF/PvCGlIQAEntgAQLBI9400yvMalnaJZWJ4VdNPuDY5tdTwWDf+f /du+w4BOMzssIAKIdcojrEobfpcpn8A= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_ed25519; t=1787822501; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc: mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=OQUBzVIWBMATwPVfzDIhG4K3xAk8OWylLaGMsrPjAX8=; b=linu+CizGfhpariTYxxiHYwu1lU2ZEb4tuHT07u/rygdUAr6eqL8I/m8E2m+aRGH1AXUqF mu3o9H2DbjKsyLBg== Received: from imap1.dmz-prg2.suse.org (localhost [127.0.0.1]) (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 imap1.dmz-prg2.suse.org (Postfix) with ESMTPS id E99841352C for ; Thu, 27 Aug 2026 09:21:40 +0000 (UTC) Received: from dovecot-director2.suse.de ([2a07:de40:b281:106:10:150:64:167]) by imap1.dmz-prg2.suse.org with ESMTPSA id ZYe3N6QBkGpncQAAD6G6ig (envelope-from ) for ; Thu, 27 Aug 2026 09:21:40 +0000 Message-ID: <8be2c9d5-8003-44ed-8478-76c19c226fe9@suse.de> Date: Thu, 27 Aug 2026 11:21:40 +0200 MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: Re: [PATCH] [pre-commit] Don't allow pre-release revisions From: Tom de Vries To: gdb-patches@sourceware.org References: <20260813152834.2591696-1-tdevries@suse.de> Content-Language: en-US In-Reply-To: <20260813152834.2591696-1-tdevries@suse.de> Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit X-Rspamd-Queue-Id: 04F19211FB X-Rspamd-Server: rspamd1.dmz-prg2.suse.org X-Rspamd-Action: no action X-Spamd-Result: default: False [-4.51 / 50.00]; BAYES_HAM(-3.00)[100.00%]; NEURAL_HAM_LONG(-1.00)[-1.000]; R_DKIM_ALLOW(-0.20)[suse.de:s=susede2_rsa,suse.de:s=susede2_ed25519]; NEURAL_HAM_SHORT(-0.20)[-1.000]; MIME_GOOD(-0.10)[text/plain]; MX_GOOD(-0.01)[]; RCVD_TLS_ALL(0.00)[]; RCVD_VIA_SMTP_AUTH(0.00)[]; ARC_NA(0.00)[]; DBL_BLOCKED_OPENRESOLVER(0.00)[sourceware.org:url,imap1.dmz-prg2.suse.org:helo,imap1.dmz-prg2.suse.org:rdns,suse.de:dkim,suse.de:mid,pre-commit.py:url,gnu.org:url]; MIME_TRACE(0.00)[0:+]; RCPT_COUNT_ONE(0.00)[1]; MID_RHS_MATCH_FROM(0.00)[]; DNSWL_BLOCKED(0.00)[2a07:de40:b281:104:10:150:64:97:from]; DKIM_SIGNED(0.00)[suse.de:s=susede2_rsa,suse.de:s=susede2_ed25519]; FROM_EQ_ENVFROM(0.00)[]; FROM_HAS_DN(0.00)[]; SPAMHAUS_XBL(0.00)[2a07:de40:b281:104:10:150:64:97:from]; RCVD_COUNT_TWO(0.00)[2]; TO_MATCH_ENVRCPT_ALL(0.00)[]; TO_DN_NONE(0.00)[]; PREVIOUSLY_DELIVERED(0.00)[gdb-patches@sourceware.org]; DKIM_TRACE(0.00)[suse.de:+] X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gdb-patches-bounces~public-inbox=simark.ca@sourceware.org On 8/13/26 5:28 PM, Tom de Vries wrote: > Pre-commit has a convenient autoupdate command. The default behavior is: > update to the latest tagged version. > > For most tools this is fine, and not too frequent. > > Isort however also tags pre-releases, so that has resulted in more frequent > updates: > ... > $ git log .pre-commit-config.yaml | grep "Bump isort" > [pre-commit] Bump isort to 9.0.0b1 > [pre-commit] Bump isort to 9.0.0a3 > [pre-commit] Bump isort to 9.0.0a2 > [pre-commit] Bump isort to 8.0.1 > [pre-commit] Bump isort to 8.0.0 > ... > > Add a script gdb/contrib/pre-commit.py that for --config-check checks the > revision numbers of all repos, and errors out when finding something like > 9.0.0b1: > ... > $ ./gdb/contrib/pre-commit.py --config-check > Revision 9.0.0b1 for repo https://github.com/pycqa/isort not allowed. > ... > > Add a corresponding pre-commit check, and revert isort back to the last stable > release: 8.0.1, to make the check pass. > > Consequently, pre-commit autoupdate now breaks the pre-commit check: > ... > $ pre-commit autoupdate > [https://github.com/psf/black-pre-commit-mirror] already up to date! > [https://github.com/pycqa/flake8] already up to date! > [https://github.com/pycqa/isort] updating 8.0.1 -> 9.0.0b2 > [https://github.com/codespell-project/codespell] already up to date! > [https://github.com/nmoroze/tclint] already up to date! > [https://github.com/adrienverge/yamllint.git] already up to date! > $ ./gdb/contrib/pre-commit.py --config-check > Revision 9.0.0b2 for repo https://github.com/pycqa/isort not allowed. > ... > so add gdb/contrib/pre-commit.py --autoupdate that can be used instead: > ... > $ ./gdb/contrib/pre-commit.py --autoupdate > [https://github.com/psf/black-pre-commit-mirror] already up to date! > [https://github.com/pycqa/flake8] already up to date! > [https://github.com/pycqa/isort] updating 8.0.1 -> 9.0.0b2 > Revision 9.0.0b2 for repo https://github.com/pycqa/isort not allowed. > [https://github.com/codespell-project/codespell] already up to date! > [https://github.com/nmoroze/tclint] already up to date! > [https://github.com/adrienverge/yamllint.git] already up to date! > ... > > The script could be extended to check that frozen revs stay frozen, but that's > currently not needed. > I've pushed this, after fixing some nits Claude Code pointed out. Then I ran the script, and pushed the resulting commit updating isort to 9.0.0. Thanks, - Tom > Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=34393 > --- > .pre-commit-config.yaml | 9 ++- > gdb/contrib/pre-commit.py | 154 ++++++++++++++++++++++++++++++++++++++ > 2 files changed, 162 insertions(+), 1 deletion(-) > create mode 100755 gdb/contrib/pre-commit.py > > diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml > index 3cccec45ef7..7b97b9a0ce8 100644 > --- a/.pre-commit-config.yaml > +++ b/.pre-commit-config.yaml > @@ -70,7 +70,7 @@ repos: > files: *gdb_python_files > args: [--config, gdb/setup.cfg] > - repo: https://github.com/pycqa/isort > - rev: 9.0.0b1 > + rev: 8.0.1 > hooks: > - id: isort > types_or: *gdb_python_types > @@ -147,6 +147,13 @@ repos: > language: unsupported_script > entry: gdb/contrib/check-file-mode.sh > files: *gdb_files > + - id: &id5 pre-commit-config-check > + name: *id5 > + language: python > + entry: gdb/contrib/pre-commit.py > + args: [--config-check] > + additional_dependencies: ["pyyaml"] > + files: '^\.pre-commit-config.yaml$' > > # Local Variables: > # indent-tabs-mode: nil > diff --git a/gdb/contrib/pre-commit.py b/gdb/contrib/pre-commit.py > new file mode 100755 > index 00000000000..9ab746c7355 > --- /dev/null > +++ b/gdb/contrib/pre-commit.py > @@ -0,0 +1,154 @@ > +#!/usr/bin/env python3 > + > +# Copyright (C) 2026 Free Software Foundation, Inc. > +# This program is free software; you can redistribute it and/or modify > +# it under the terms of the GNU General Public License as published by > +# the Free Software Foundation; either version 3 of the License, or > +# (at your option) any later version. > +# > +# This program is distributed in the hope that it will be useful, > +# but WITHOUT ANY WARRANTY; without even the implied warranty of > +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > +# GNU General Public License for more details. > +# > +# You should have received a copy of the GNU General Public License > +# along with this program. If not, see . > + > +import re > +import subprocess > +import sys > + > +import yaml > + > + > +def get_repos(cfg): > + with open(cfg, "r") as f: > + data = yaml.safe_load(f) > + repos = data.get("repos") > + if not repos: > + raise RuntimeError("repos missing") > + return repos > + > + > +def config_check_repo(repo): > + name = repo.get("repo") > + if not name: > + raise RuntimeError("no repo") > + if name == "local": > + # Skip local repo, there's no revision to check. > + return True > + > + # Get the revision. > + rev = repo["rev"] > + if not rev or rev == "": > + raise RuntimeError("empty revision") > + > + # Normalize revision: skip 'v' prefix. > + if rev[0].lower() == "v": > + rev = rev[1:] > + > + # Check version number. Don't allow pre-releases like 9.0.0b1. > + # We currently only need to support x.y.z, but that could change. > + if not re.fullmatch(r"\d+[.]\d+[.]\d+", rev): > + print("Revision %s for repo %s not allowed." % (rev, name)) > + return False > + > + return True > + > + > +def config_check(cfg): > + for repo in get_repos(cfg): > + if not config_check_repo(repo): > + sys.exit(1) > + > + > +def run_cmd(cmd, **kwargs): > + res = subprocess.run(cmd, **kwargs) > + if res.returncode != 0: > + raise RuntimeError( > + "command %s failed with exit status %s" % (cmd, res.returncode) > + ) > + return res > + > + > +def autoupdate_repo(cfg, repo): > + name = repo["repo"] > + if name == "local": > + # Skip local repo, there's no revision to update. > + return > + > + cmd = ["pre-commit", "autoupdate", "--repo", name] > + run_cmd(cmd) > + > + cmd = ["git", "status", "--porcelain", cfg] > + res = run_cmd(cmd, capture_output=True, text=True) > + if res.stdout == "": > + # No autoupdate changes. > + return > + > + rev = repo["rev"] > + > + # Config has changed, refresh repo. > + found = False > + for new_repo in get_repos(cfg): > + if new_repo["repo"] == name: > + found = True > + break > + if not found: > + raise RuntimeError("Repo not found in updated %s" % cfg) > + repo = new_repo > + > + new_rev = repo["rev"] > + > + if not config_check_repo(repo): > + # Reject autoupdate for this repo. > + cmd = ["git", "checkout", "-f", cfg] > + # Capture and ignore output. > + run_cmd(cmd, capture_output=True, text=True) > + return > + > + # Commit autoupdate for this repo. > + try: > + name_for_msg = repo["hooks"][0]["id"] > + except (KeyError, IndexError): > + name_for_msg = name > + msg = "Update %s: %s -> %s" % (name_for_msg, rev, new_rev) > + cmd = ["git", "commit", "-m", msg, cfg] > + run_cmd(cmd) > + > + > +def autoupdate(cfg): > + for repo in get_repos(cfg): > + autoupdate_repo(cfg, repo) > + > + > +def usage(): > + print("Usage: pre-commit.py --config-check []") > + print(" --autoupdate") > + sys.exit(1) > + > + > +def main(): > + if len(sys.argv) < 2: > + usage() > + > + cfg = ".pre-commit-config.yaml" > + > + if sys.argv[1] == "--config-check": > + if len(sys.argv) not in [2, 3]: > + usage() > + if len(sys.argv) == 3: > + cfg = sys.argv[2] > + config_check(cfg) > + return > + > + if sys.argv[1] == "--autoupdate": > + if len(sys.argv) != 2: > + usage() > + autoupdate(cfg) > + return > + > + usage() > + > + > +main() > > base-commit: 1686e21559a7812ebbc05f57372cc30880768bf7