From unknown Fri Sep 19 04:01:23 2025 X-Loop: help-debbugs@gnu.org Subject: bug#74604: 30.0.92; FR: M-x package-upgrade - offer an option to show a diff on upgrade Resent-From: Daniel Mendler Original-Sender: "Debbugs-submit" Resent-CC: philipk@posteo.net, bug-gnu-emacs@gnu.org Resent-Date: Fri, 29 Nov 2024 15:40:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: report 74604 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: To: 74604@debbugs.gnu.org Cc: Philip Kaludercic X-Debbugs-Original-To: bug-gnu-emacs@gnu.org X-Debbugs-Original-Xcc: Philip Kaludercic Received: via spool by submit@debbugs.gnu.org id=B.173289479427947 (code B ref -1); Fri, 29 Nov 2024 15:40:02 +0000 Received: (at submit) by debbugs.gnu.org; 29 Nov 2024 15:39:54 +0000 Received: from localhost ([127.0.0.1]:44078 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1tH361-0007Gf-HZ for submit@debbugs.gnu.org; Fri, 29 Nov 2024 10:39:53 -0500 Received: from lists.gnu.org ([209.51.188.17]:37432) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1tH360-0007GY-9e for submit@debbugs.gnu.org; Fri, 29 Nov 2024 10:39:52 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tH35z-0005Ct-Df for bug-gnu-emacs@gnu.org; Fri, 29 Nov 2024 10:39:51 -0500 Received: from server.qxqx.de ([2a01:4f8:c012:9177::1] helo=mail.qxqx.de) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tH35x-0008B4-3O for bug-gnu-emacs@gnu.org; Fri, 29 Nov 2024 10:39:50 -0500 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=daniel-mendler.de; s=key; h=Content-Type:MIME-Version:Message-ID:Date: Subject:To:From:Sender:Reply-To:Cc:Content-Transfer-Encoding:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:In-Reply-To:References:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=BZSGb/Tq1EzCcQ6plhTjI+Q9vASbIa2lijBFW1IJ1tM=; b=mXUMML4jCxLUNrJwsp88Zif6pF PT6yfeiLY7DiVzgUcdYSkX5Gm7IObipYkNCAwoOzv15RSDWRqo9AWML5XrC9TXLqCfXh5bFSyOeEl Qw6HZGtxIANlmZ1FpC4gkFLdPpAW54eT1ZUDZbcnRxpc2gGOBmAqT/7N/KgpjSVYQkPI=; From: Daniel Mendler Date: Fri, 29 Nov 2024 16:39:27 +0100 Message-ID: <87h67quk0g.fsf@daniel-mendler.de> User-Agent: Gnus/5.13 (Gnus v5.13) MIME-Version: 1.0 Content-Type: text/plain Received-SPF: pass client-ip=2a01:4f8:c012:9177::1; envelope-from=mail@daniel-mendler.de; helo=mail.qxqx.de X-Spam_score_int: -27 X-Spam_score: -2.8 X-Spam_bar: -- X-Spam_report: (-2.8 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-Spam-Score: -1.4 (-) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -2.4 (--) This is a feature request for the security wishlist. When upgrading package it would be good to show a diff between the new and old package files. Such an option could help performing review casually as part of the upgrade process and may improve the security of the package archives. More eyes would look at new package versions. This would make it harder to inject malicious code either via the source repository or via attacks on the package archives. From unknown Fri Sep 19 04:01:23 2025 X-Loop: help-debbugs@gnu.org Subject: bug#74604: 30.0.92; FR: M-x package-upgrade - offer an option to show a diff on upgrade Resent-From: Philip Kaludercic Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Sun, 01 Dec 2024 22:06:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 74604 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: To: Daniel Mendler Cc: 74604@debbugs.gnu.org Received: via spool by 74604-submit@debbugs.gnu.org id=B74604.173309073712497 (code B ref 74604); Sun, 01 Dec 2024 22:06:02 +0000 Received: (at 74604) by debbugs.gnu.org; 1 Dec 2024 22:05:37 +0000 Received: from localhost ([127.0.0.1]:53358 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1tHs4P-0003FU-5n for submit@debbugs.gnu.org; Sun, 01 Dec 2024 17:05:37 -0500 Received: from mout01.posteo.de ([185.67.36.65]:35883) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1tHs4M-0003FD-NV for 74604@debbugs.gnu.org; Sun, 01 Dec 2024 17:05:36 -0500 Received: from submission (posteo.de [185.67.36.169]) by mout01.posteo.de (Postfix) with ESMTPS id 8C85B240028 for <74604@debbugs.gnu.org>; Sun, 1 Dec 2024 23:05:26 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=posteo.net; s=2017; t=1733090727; bh=poT7kDM1hC/XRg6guZLizsL6/i3nGej561Cs95g293k=; h=From:To:Cc:Subject:Autocrypt:OpenPGP:Date:Message-ID:MIME-Version: Content-Type:From; b=A0pf3rSW0mCmVLIIgxgG2XS4CM6wDFObvjTQqvKc4znPx+pXyT2iNiEcrepLmKHqo lCCy3m8zIZskOoxi2dLCfDvZjGvxcgyaOErAItzzwx0qLS7GLjE+n4JtxK9y9H+tAX e6jt588yKqQ1Knd6MMFATnhLQcxKuLvyz2mLC9UeXccqFqiHHfT7Jmy5gtjlydKZHV I2m3OqDctHAsDi05HOfrqO6HBTPUK+QbOeyvPmNV6wUaRH925eA3dHzf3ZzCHJ6gQQ VPGyUsW0FnU/M3dTo/+LECTemTMerkczc87qMEwZI5u5++YzCmrneygRFUJka93o2t MpD28P0+1QbAw== Received: from customer (localhost [127.0.0.1]) by submission (posteo.de) with ESMTPSA id 4Y1gvn6tNlz9rxN; Sun, 1 Dec 2024 23:05:25 +0100 (CET) From: Philip Kaludercic In-Reply-To: <87h67quk0g.fsf@daniel-mendler.de> (Daniel Mendler's message of "Fri, 29 Nov 2024 16:39:27 +0100") References: <87h67quk0g.fsf@daniel-mendler.de> Autocrypt: addr=philipk@posteo.net; keydata= mDMEZBBQQhYJKwYBBAHaRw8BAQdAHJuofBrfqFh12uQu0Yi7mrl525F28eTmwUDflFNmdui0QlBo aWxpcCBLYWx1ZGVyY2ljIChnZW5lcmF0ZWQgYnkgYXV0b2NyeXB0LmVsKSA8cGhpbGlwa0Bwb3N0 ZW8ubmV0PoiWBBMWCAA+FiEEDg7HY17ghYlni8XN8xYDWXahwukFAmQQUEICGwMFCQHhM4AFCwkI BwIGFQoJCAsCBBYCAwECHgECF4AACgkQ8xYDWXahwulikAEA77hloUiSrXgFkUVJhlKBpLCHUjA0 mWZ9j9w5d08+jVwBAK6c4iGP7j+/PhbkxaEKa4V3MzIl7zJkcNNjHCXmvFcEuDgEZBBQQhIKKwYB BAGXVQEFAQEHQI5NLiLRjZy3OfSt1dhCmFyn+fN/QKELUYQetiaoe+MMAwEIB4h+BBgWCAAmFiEE Dg7HY17ghYlni8XN8xYDWXahwukFAmQQUEICGwwFCQHhM4AACgkQ8xYDWXahwukm+wEA8cml4JpK NeAu65rg+auKrPOP6TP/4YWRCTIvuYDm0joBALw98AMz7/qMHvSCeU/hw9PL6u6R2EScxtpKnWof z4oM OpenPGP: id=philipk@posteo.net; url="https://keys.openpgp.org/vks/v1/by-email/philipk@posteo.net"; preference=signencrypt Date: Sun, 01 Dec 2024 22:05:24 +0000 Message-ID: <87zflfqct7.fsf@posteo.net> MIME-Version: 1.0 Content-Type: text/plain X-Spam-Score: -2.3 (--) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -3.3 (---) Daniel Mendler writes: > This is a feature request for the security wishlist. When upgrading > package it would be good to show a diff between the new and old package > files. Such an option could help performing review casually as part of > the upgrade process and may improve the security of the package > archives. More eyes would look at new package versions. This would make > it harder to inject malicious code either via the source repository or > via attacks on the package archives. That sounds like a good option to have! I'll look into adding something like this via a user option that adjusts how to confirm a package upgrade. Note that package-vc has something similar with the `package-vc-log-incoming' command. From unknown Fri Sep 19 04:01:23 2025 X-Loop: help-debbugs@gnu.org Subject: bug#74604: 30.0.92; FR: M-x package-upgrade - offer an option to show a diff on upgrade Resent-From: Ship Mints Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Sun, 01 Dec 2024 22:49:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 74604 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: To: Philip Kaludercic Cc: Daniel Mendler , 74604@debbugs.gnu.org Received: via spool by 74604-submit@debbugs.gnu.org id=B74604.173309333220726 (code B ref 74604); Sun, 01 Dec 2024 22:49:02 +0000 Received: (at 74604) by debbugs.gnu.org; 1 Dec 2024 22:48:52 +0000 Received: from localhost ([127.0.0.1]:53405 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1tHskG-0005OE-19 for submit@debbugs.gnu.org; Sun, 01 Dec 2024 17:48:52 -0500 Received: from mail-vs1-f42.google.com ([209.85.217.42]:44227) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1tHskD-0005O5-8p for 74604@debbugs.gnu.org; Sun, 01 Dec 2024 17:48:50 -0500 Received: by mail-vs1-f42.google.com with SMTP id ada2fe7eead31-4af3de962a7so790197137.0 for <74604@debbugs.gnu.org>; Sun, 01 Dec 2024 14:48:49 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1733093269; x=1733698069; darn=debbugs.gnu.org; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:from:to:cc:subject:date:message-id:reply-to; bh=WybPA5gNbOL2ylhShiKbpZI0PBvwOfnISIXiOZ+Ym14=; b=JTe7nuu1Vtq6CB1YO5y5xt0Mfo6jk1GN7xsF53i4dYKOG9F9cW5B9lDdfdmqapLJQc 0Zp3ZGmb995BNqc03YH3BtgeViiyrJX82K4/WKohWnwnijCiBAIdAfZinY3esQ1pUo07 gWC2IDeusqt8/PPd8yZezhahuyHY3ynn6/XwMpRD4yfVAxszU/VmQbVAGQBHFe2FgoOj r22LNfNp74fHdHTP1El0TQR6Ps2K6XmTGwSoSvw4QEWPNeBcbwX95vQckvuG5U5Ew7db ggOKggoK37KRqBxp+FWf+QQVAeXbOiZ5Ag7ccWYBd+KX8WpITvr+UUsdG0ckxYbJnlql Qq/Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1733093269; x=1733698069; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=WybPA5gNbOL2ylhShiKbpZI0PBvwOfnISIXiOZ+Ym14=; b=jaCOdo/l6MYiGWMcqJQpy/TA+XWkvi7/Iw+SMEpkS1wPYM4o54l4gVjprWt1DDOA1b NXx0OmJhfck6QlwIqsM6hcbxrgmLXSPr6GoVot2GKXdaxoTwwv59aCMnWlS/nSSdiZe6 TOdWWmJRdWCqX8GHcPvwKAScoWUitNe3ilDmtLqE/4F/ptVOvM/CcwW3v/tVNsv4+M8p c29H7hSaOqfBUkkKoms5n2MLc6DNKIEwCF5zNoi2lw481GLXNJrHNsao59EkwaO7p6R8 K3tD7kUeeqV1LLjWFLedNPowOnZTCaxTUgIzNfVcj2NP9seI+BAu2e15fwaTb+H+UDUA DTTA== X-Forwarded-Encrypted: i=1; AJvYcCUmLMG6oj4/0GqaTiJTmBNtiKKIpVCt6AguuhMFyp6KgFROG6zpOgwlmmoBW6T2q8KcjSkmrg==@debbugs.gnu.org X-Gm-Message-State: AOJu0Yz/NqSGu6afvTSENNgk6yR9z09cUSoezQkkQGFPEkMNuPZi+XHe AQYQOFxsVQKcBURk5ZRDO3nKS23iqaMUt047GFSnDjBXuvMHvrYmyCQ8wLI0lfe70JZQOjgeeP6 +dR1fHhggQjJaC/Q20Uq26/vPhm8= X-Gm-Gg: ASbGnctL1MLcpoIUSB+Ml0lvYraT/79VaVs5HfddMvODY8OZMmx9jAKZEmhO2mpl5FU NwXtFb4kQZ4OPxoYlepSyRLtBBIKxyDw= X-Google-Smtp-Source: AGHT+IHQHiTV1avnircBmqlbCXsH3asNk/sJfSodLlQS6xv5+2S5OiC6d5PdOVg9cObBrQ+taK442N5HGQci+7X4cWU= X-Received: by 2002:a05:6102:c93:b0:4af:2e54:ed69 with SMTP id ada2fe7eead31-4af448ca640mr26856386137.14.1733093268784; Sun, 01 Dec 2024 14:47:48 -0800 (PST) MIME-Version: 1.0 References: <87h67quk0g.fsf@daniel-mendler.de> <87zflfqct7.fsf@posteo.net> In-Reply-To: <87zflfqct7.fsf@posteo.net> From: Ship Mints Date: Sun, 1 Dec 2024 17:47:21 -0500 Message-ID: Content-Type: multipart/alternative; boundary="000000000000a60e7606283d38b1" X-Spam-Score: 0.0 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) --000000000000a60e7606283d38b1 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable I like this idea, too. I spend a reasonable amount of time trying to understand what people have changed and if it will affect me negatively (the defensive part) or positively (for new features, user options, deprecations). Showing a source-code diff may be a bit technical for some users, though. I wonder if there could be either a link to a changelog, or a way to encourage a changelog convention so one could be displayed for users prior to a decision to update a package. -Stephane On Sun, Dec 1, 2024 at 5:06=E2=80=AFPM Philip Kaludercic wrote: > Daniel Mendler writes: > > > This is a feature request for the security wishlist. When upgrading > > package it would be good to show a diff between the new and old package > > files. Such an option could help performing review casually as part of > > the upgrade process and may improve the security of the package > > archives. More eyes would look at new package versions. This would make > > it harder to inject malicious code either via the source repository or > > via attacks on the package archives. > > That sounds like a good option to have! I'll look into adding something > like this via a user option that adjusts how to confirm a package upgrade= . > > Note that package-vc has something similar with the > `package-vc-log-incoming' command. > > > > --000000000000a60e7606283d38b1 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
I like this idea,=C2=A0too. I spend a=C2=A0reasonable=C2=A0amount of=C2= =A0time trying to understand what people=C2=A0have changed and if it will a= ffect=C2=A0me negatively (the defensive part) or positively (for new=C2=A0f= eatures,=C2=A0user options, deprecations). Showing a source-code diff may b= e a bit technical for some users, though. I wonder if there could be either= a link to a changelog, or a way to encourage a changelog convention so one= could be displayed for users prior to a decision to update a package.

-Stephane

On= Sun, Dec 1, 2024 at 5:06=E2=80=AFPM Philip Kaludercic <philipk@posteo.net> wrote:
Daniel Mendler <mail@daniel-mendler.de> = writes:

> This is a feature request for the security wishlist. When upgrading > package it would be good to show a diff between the new and old packag= e
> files. Such an option could help performing review casually as part of=
> the upgrade process and may improve the security of the package
> archives. More eyes would look at new package versions. This would mak= e
> it harder to inject malicious code either via the source repository or=
> via attacks on the package archives.

That sounds like a good option to have!=C2=A0 I'll look into adding som= ething
like this via a user option that adjusts how to confirm a package upgrade.<= br>
Note that package-vc has something similar with the
`package-vc-log-incoming' command.



--000000000000a60e7606283d38b1-- From unknown Fri Sep 19 04:01:23 2025 X-Loop: help-debbugs@gnu.org Subject: bug#74604: 30.0.92; FR: M-x package-upgrade - offer an option to show a diff on upgrade Resent-From: Daniel Mendler Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Sun, 01 Dec 2024 23:15:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 74604 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: To: Philip Kaludercic Cc: 74604@debbugs.gnu.org Received: via spool by 74604-submit@debbugs.gnu.org id=B74604.173309487625662 (code B ref 74604); Sun, 01 Dec 2024 23:15:02 +0000 Received: (at 74604) by debbugs.gnu.org; 1 Dec 2024 23:14:36 +0000 Received: from localhost ([127.0.0.1]:53435 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1tHt99-0006fq-Sq for submit@debbugs.gnu.org; Sun, 01 Dec 2024 18:14:36 -0500 Received: from server.qxqx.de ([49.12.34.165]:52297 helo=mail.qxqx.de) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1tHt97-0006fY-1z for 74604@debbugs.gnu.org; Sun, 01 Dec 2024 18:14:34 -0500 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=daniel-mendler.de; s=key; h=Content-Type:MIME-Version:Message-ID:Date: References:In-Reply-To:Subject:Cc:To:From:Sender:Reply-To: Content-Transfer-Encoding:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Id: List-Help:List-Unsubscribe:List-Subscribe:List-Post:List-Owner:List-Archive; bh=nUEAJ+3kNcyvPomeRvmhsFGzOfTetBxfm1nUppNn/jA=; b=HJAfZo96hpGMTQBukAdkFRIjD7 hzGtU7SICLcOp6Xb18LAj2/olB48LTI3DHX58knkOvHgF6dumheBGctYcECEQeRHzPDevFXqESyZ4 ffc80ZraU9heDKA4FUyViXspPbPZkffxGi/fEF70ZrzrdMMJej37FCUT8j4f3NB9tOSw=; From: Daniel Mendler In-Reply-To: <87zflfqct7.fsf@posteo.net> (Philip Kaludercic's message of "Sun, 01 Dec 2024 22:05:24 +0000") References: <87h67quk0g.fsf@daniel-mendler.de> <87zflfqct7.fsf@posteo.net> Date: Mon, 02 Dec 2024 00:12:15 +0100 Message-ID: <8734j7hub4.fsf@daniel-mendler.de> User-Agent: Gnus/5.13 (Gnus v5.13) MIME-Version: 1.0 Content-Type: text/plain X-Spam-Score: -0.7 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.7 (-) Philip Kaludercic writes: > Daniel Mendler writes: > >> This is a feature request for the security wishlist. When upgrading >> package it would be good to show a diff between the new and old package >> files. Such an option could help performing review casually as part of >> the upgrade process and may improve the security of the package >> archives. More eyes would look at new package versions. This would make >> it harder to inject malicious code either via the source repository or >> via attacks on the package archives. > > That sounds like a good option to have! I'll look into adding something > like this via a user option that adjusts how to confirm a package upgrade. Thanks! I am happy to test if you have a patch ready. Daniel From unknown Fri Sep 19 04:01:23 2025 X-Loop: help-debbugs@gnu.org Subject: bug#74604: 30.0.92; FR: M-x package-upgrade - offer an option to show a diff on upgrade Resent-From: Philip Kaludercic Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Mon, 02 Dec 2024 09:00:03 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 74604 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: To: Ship Mints Cc: Daniel Mendler , 74604@debbugs.gnu.org Received: via spool by 74604-submit@debbugs.gnu.org id=B74604.173312997211354 (code B ref 74604); Mon, 02 Dec 2024 09:00:03 +0000 Received: (at 74604) by debbugs.gnu.org; 2 Dec 2024 08:59:32 +0000 Received: from localhost ([127.0.0.1]:54232 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1tI2HE-0002x4-FJ for submit@debbugs.gnu.org; Mon, 02 Dec 2024 03:59:32 -0500 Received: from mout02.posteo.de ([185.67.36.66]:41147) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1tI2HB-0002wf-LN for 74604@debbugs.gnu.org; Mon, 02 Dec 2024 03:59:31 -0500 Received: from submission (posteo.de [185.67.36.169]) by mout02.posteo.de (Postfix) with ESMTPS id B820F240101 for <74604@debbugs.gnu.org>; Mon, 2 Dec 2024 09:59:19 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=posteo.net; s=2017; t=1733129960; bh=E+LQFPHrcDHNjTCHl6NUHoHF1tkJ8PyMAepoLErUuyk=; h=From:To:Cc:Subject:Autocrypt:OpenPGP:Date:Message-ID:MIME-Version: Content-Type:Content-Transfer-Encoding:From; b=gtXHxi61lXGvuy2fGPsesCynHfmxaB+4py/Ps+SooOgvsO2Kaj7QmcFJyY5zdl1uj 4u1zQ5gXwU+sDN8NLAscYucBuoC2TSjMUQRGI4zJMH6QWE+oiQUzy8rKUx2y3P8yDI VQwumJH3N4XmLPplEbkSXGgIj6hO/sk9S1SyIMVgYX1dFaKDFmJCVJ14+e4F/xTZbh UbEo8l56ZTi+vfPIvwVKJNDL6dG3TthfldCRySVkcMv8VmJNxlPJXYcFAKA7ms0XIG rRec75mi3JOuyEKWBvT4EWSjcAyPGEvuws0MmcYLLD1ZzEbQEMMqOMZDqH4pevHDfj cNI3xCQusIMOQ== Received: from customer (localhost [127.0.0.1]) by submission (posteo.de) with ESMTPSA id 4Y1yQG4jb6z9rxV; Mon, 2 Dec 2024 09:59:18 +0100 (CET) From: Philip Kaludercic In-Reply-To: (Ship Mints's message of "Sun, 1 Dec 2024 17:47:21 -0500") References: <87h67quk0g.fsf@daniel-mendler.de> <87zflfqct7.fsf@posteo.net> Autocrypt: addr=philipk@posteo.net; keydata= mDMEZBBQQhYJKwYBBAHaRw8BAQdAHJuofBrfqFh12uQu0Yi7mrl525F28eTmwUDflFNmdui0QlBo aWxpcCBLYWx1ZGVyY2ljIChnZW5lcmF0ZWQgYnkgYXV0b2NyeXB0LmVsKSA8cGhpbGlwa0Bwb3N0 ZW8ubmV0PoiWBBMWCAA+FiEEDg7HY17ghYlni8XN8xYDWXahwukFAmQQUEICGwMFCQHhM4AFCwkI BwIGFQoJCAsCBBYCAwECHgECF4AACgkQ8xYDWXahwulikAEA77hloUiSrXgFkUVJhlKBpLCHUjA0 mWZ9j9w5d08+jVwBAK6c4iGP7j+/PhbkxaEKa4V3MzIl7zJkcNNjHCXmvFcEuDgEZBBQQhIKKwYB BAGXVQEFAQEHQI5NLiLRjZy3OfSt1dhCmFyn+fN/QKELUYQetiaoe+MMAwEIB4h+BBgWCAAmFiEE Dg7HY17ghYlni8XN8xYDWXahwukFAmQQUEICGwwFCQHhM4AACgkQ8xYDWXahwukm+wEA8cml4JpK NeAu65rg+auKrPOP6TP/4YWRCTIvuYDm0joBALw98AMz7/qMHvSCeU/hw9PL6u6R2EScxtpKnWof z4oM OpenPGP: id=philipk@posteo.net; url="https://keys.openpgp.org/vks/v1/by-email/philipk@posteo.net"; preference=signencrypt Date: Mon, 02 Dec 2024 08:59:12 +0000 Message-ID: <87r06qqx3z.fsf@posteo.net> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-Spam-Score: -2.3 (--) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -3.3 (---) Ship Mints writes: > I like this idea, too. I spend a reasonable amount of time trying to > understand what people have changed and if it will affect me negatively > (the defensive part) or positively (for new features, user options, > deprecations). Showing a source-code diff may be a bit technical for some > users, though. I wonder if there could be either a link to a changelog, or > a way to encourage a changelog convention so one could be displayed for > users prior to a decision to update a package. Note that packages can distribute this information. Currently, if a tarball includes a "news" file, it will be displayed by `describe-package. IIRC no package archive generates these right now. But if we implement a user option like that described above (or below?), then we can add that as an option as well. The main issue is that not all package maintainers ensure that there are changelog/news sources that ELPA could use to provide this information. > -Stephane > > On Sun, Dec 1, 2024 at 5:06=E2=80=AFPM Philip Kaludercic wrote: > >> Daniel Mendler writes: >> >> > This is a feature request for the security wishlist. When upgrading >> > package it would be good to show a diff between the new and old package >> > files. Such an option could help performing review casually as part of >> > the upgrade process and may improve the security of the package >> > archives. More eyes would look at new package versions. This would make >> > it harder to inject malicious code either via the source repository or >> > via attacks on the package archives. >> >> That sounds like a good option to have! I'll look into adding something >> like this via a user option that adjusts how to confirm a package upgrad= e. >> >> Note that package-vc has something similar with the >> `package-vc-log-incoming' command. >> >> >> >> From unknown Fri Sep 19 04:01:23 2025 X-Loop: help-debbugs@gnu.org Subject: bug#74604: 30.0.92; FR: M-x package-upgrade - offer an option to show a diff on upgrade Resent-From: Ship Mints Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Mon, 02 Dec 2024 12:07:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 74604 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: To: Philip Kaludercic Cc: Daniel Mendler , 74604@debbugs.gnu.org Received: via spool by 74604-submit@debbugs.gnu.org id=B74604.173314116115559 (code B ref 74604); Mon, 02 Dec 2024 12:07:01 +0000 Received: (at 74604) by debbugs.gnu.org; 2 Dec 2024 12:06:01 +0000 Received: from localhost ([127.0.0.1]:54498 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1tI5Bh-00042e-8x for submit@debbugs.gnu.org; Mon, 02 Dec 2024 07:06:01 -0500 Received: from mail-oa1-f53.google.com ([209.85.160.53]:46163) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1tI5Be-00042D-BW for 74604@debbugs.gnu.org; Mon, 02 Dec 2024 07:05:59 -0500 Received: by mail-oa1-f53.google.com with SMTP id 586e51a60fabf-29e52a97a90so633264fac.0 for <74604@debbugs.gnu.org>; Mon, 02 Dec 2024 04:05:58 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1733141092; x=1733745892; darn=debbugs.gnu.org; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:from:to:cc:subject:date:message-id:reply-to; bh=znozZYFEyjDfo4Cbxj5WvkzPk2XLWcfkMs8kKfioQng=; b=fX9PXaIs7MfBedZ6D5itMwFqbDArNl1WfSuL0KB3a7XMpG5AUaIggL5AangpDWs05A pM9SGP/CzEthN4IMlJyImg/Tx9eUJHaC+aga2PfofS3JCT9K7J7bO7WgNoECMHNGg9VH cPfMaHA8VIJQUSjPctYPWIWPjDIsQMvOq04LE/HoWkapMFU+iPUiGRW6ADHR8hX9QxO8 Adb8/htRRV3voppTh8XG95W4TSOYG0kVpPzBFLpi/bxAWMPIrvRQbe1UWcxhEkmiEXAU 8xBm35NlBzI5kaZW1s+bQtM4jT9xw/JF9v/6E7VxhbH8GuGHCgrJsWd3im90i9UdXKeX WotA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1733141092; x=1733745892; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=znozZYFEyjDfo4Cbxj5WvkzPk2XLWcfkMs8kKfioQng=; b=NMNgtFrCrH3vUwfMfV5jO2g9TV9C4SFvSYP7Mh6ZJ9GGt+P0kO7J2Lcpg7TmRIPRC+ xZDE80NOCnMPLRjL8mPT2a6e2r1UaLS+GSwMWXmkl89ibBO1tC7DYzxdwETkj0Icz3tx DUjxuYPyD3QKFSprQB/DJmllfGd/RwnKFIxnanD++Y/2+hBjZkN6FIwfAtXb1keR9r0M HLVqwAzndc7/ZFU/XlUwGHRZtWkLyxFz0miz1arxQf4nEIItwfVjTzWY81kAVtYkm9DK okzYPKFXvN7Q9JW31R46nVRCExQ8GCVsRoDELQu+wnd7REI63FUkh5WIy4o0nf4wDLA8 Xhpg== X-Forwarded-Encrypted: i=1; AJvYcCXPIBM6ltDuDXpDruIZt0lbEPIIqN9YdyScCRgaFIfKSSHVjwx1OJ7qnWV6mUsCd+gfZ8zZ1w==@debbugs.gnu.org X-Gm-Message-State: AOJu0YwT78WqH9v3mNzD18dzyU2KvIWKROLFkk1rQN76vLwoQwDxtgB6 tjnTAS3JoUjkcRblmxWEoMuDHLrkMLSWV/StwbwjZ/viXARlKtnZdGU+dkFTXIkdu4Nn0ezcF1X Zzkmv1s1GgkHRagwdm+HXUBQ3Mis= X-Gm-Gg: ASbGncvgvSohTszDtCUsIdc65gISyZG4k3LCJWpMhusrYBBBvnDEVanQeRySu57MCCx BEh2HA5VP7diobd1t4zHW9iT7YUAhhbs= X-Google-Smtp-Source: AGHT+IHiJv0Ns5rtVWixosGfNsmOtH6CZgQKk1kBd59NQQTPHq6xcQdTej042Bsk0qdljPbp0nHJ2tH9qZsn7w00esg= X-Received: by 2002:a05:6359:459b:b0:1c5:e2f3:bb1d with SMTP id e5c5f4694b2df-1cab15a6626mr678597155d.4.1733141092285; Mon, 02 Dec 2024 04:04:52 -0800 (PST) MIME-Version: 1.0 References: <87h67quk0g.fsf@daniel-mendler.de> <87zflfqct7.fsf@posteo.net> <87r06qqx3z.fsf@posteo.net> In-Reply-To: <87r06qqx3z.fsf@posteo.net> From: Ship Mints Date: Mon, 2 Dec 2024 07:04:24 -0500 Message-ID: Content-Type: multipart/alternative; boundary="00000000000026c4c80628485b6b" X-Spam-Score: 0.0 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) --00000000000026c4c80628485b6b Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Isn't it the case that describe-package works only on installed packages, not prospectively installed packages? To help determine the value/risk of a package install or update, I'd think it better to show this in advance. Daniel's diff suggestion is similar but more technical. On Mon, Dec 2, 2024 at 3:59=E2=80=AFAM Philip Kaludercic wrote: > Ship Mints writes: > > > I like this idea, too. I spend a reasonable amount of time trying to > > understand what people have changed and if it will affect me negatively > > (the defensive part) or positively (for new features, user options, > > deprecations). Showing a source-code diff may be a bit technical for so= me > > users, though. I wonder if there could be either a link to a changelog, > or > > a way to encourage a changelog convention so one could be displayed for > > users prior to a decision to update a package. > > Note that packages can distribute this information. Currently, if a > tarball includes a "news" file, it will be displayed by > `describe-package. IIRC no package archive generates these right now. > But if we implement a user option like that described above (or below?), > then we can add that as an option as well. > > The main issue is that not all package maintainers ensure that there are > changelog/news sources that ELPA could use to provide this information. > > > -Stephane > > > > On Sun, Dec 1, 2024 at 5:06=E2=80=AFPM Philip Kaludercic > wrote: > > > >> Daniel Mendler writes: > >> > >> > This is a feature request for the security wishlist. When upgrading > >> > package it would be good to show a diff between the new and old > package > >> > files. Such an option could help performing review casually as part = of > >> > the upgrade process and may improve the security of the package > >> > archives. More eyes would look at new package versions. This would > make > >> > it harder to inject malicious code either via the source repository = or > >> > via attacks on the package archives. > >> > >> That sounds like a good option to have! I'll look into adding somethi= ng > >> like this via a user option that adjusts how to confirm a package > upgrade. > >> > >> Note that package-vc has something similar with the > >> `package-vc-log-incoming' command. > >> > >> > >> > >> > --00000000000026c4c80628485b6b Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
Isn't it the case that describe-package works only on installed pack= ages, not prospectively installed packages? To help determine the value/ris= k of a package install or update, I'd think it better to show this in a= dvance. Daniel's diff suggestion is similar but more technical.

On= Mon, Dec 2, 2024 at 3:59=E2=80=AFAM Philip Kaludercic <philipk@posteo.net> wrote:
Ship Mints <shipmints@gmail.com> writes:
> I like this idea, too. I spend a reasonable amount of time trying to > understand what people have changed and if it will affect me negativel= y
> (the defensive part) or positively (for new features, user options, > deprecations). Showing a source-code diff may be a bit technical for s= ome
> users, though. I wonder if there could be either a link to a changelog= , or
> a way to encourage a changelog convention so one could be displayed fo= r
> users prior to a decision to update a package.

Note that packages can distribute this information.=C2=A0 Currently, if a tarball includes a "news" file, it will be displayed by
`describe-package.=C2=A0 IIRC no package archive generates these right now.=
But if we implement a user option like that described above (or below?), then we can add that as an option as well.

The main issue is that not all package maintainers ensure that there are changelog/news sources that ELPA could use to provide this information.

> -Stephane
>
> On Sun, Dec 1, 2024 at 5:06=E2=80=AFPM Philip Kaludercic <philipk@posteo.net>= wrote:
>
>> Daniel Mendler <mail@daniel-mendler.de> writes:
>>
>> > This is a feature request for the security wishlist. When upg= rading
>> > package it would be good to show a diff between the new and o= ld package
>> > files. Such an option could help performing review casually a= s part of
>> > the upgrade process and may improve the security of the packa= ge
>> > archives. More eyes would look at new package versions. This = would make
>> > it harder to inject malicious code either via the source repo= sitory or
>> > via attacks on the package archives.
>>
>> That sounds like a good option to have!=C2=A0 I'll look into a= dding something
>> like this via a user option that adjusts how to confirm a package = upgrade.
>>
>> Note that package-vc has something similar with the
>> `package-vc-log-incoming' command.
>>
>>
>>
>>
--00000000000026c4c80628485b6b-- From unknown Fri Sep 19 04:01:23 2025 X-Loop: help-debbugs@gnu.org Subject: bug#74604: 30.0.92; FR: M-x package-upgrade - offer an option to show a diff on upgrade Resent-From: Philip Kaludercic Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Mon, 02 Dec 2024 12:19:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 74604 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: To: Ship Mints Cc: Daniel Mendler , 74604@debbugs.gnu.org Received: via spool by 74604-submit@debbugs.gnu.org id=B74604.173314191617873 (code B ref 74604); Mon, 02 Dec 2024 12:19:02 +0000 Received: (at 74604) by debbugs.gnu.org; 2 Dec 2024 12:18:36 +0000 Received: from localhost ([127.0.0.1]:54540 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1tI5Ns-0004eD-CX for submit@debbugs.gnu.org; Mon, 02 Dec 2024 07:18:36 -0500 Received: from mout02.posteo.de ([185.67.36.66]:40345) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1tI5Np-0004dr-Nn for 74604@debbugs.gnu.org; Mon, 02 Dec 2024 07:18:34 -0500 Received: from submission (posteo.de [185.67.36.169]) by mout02.posteo.de (Postfix) with ESMTPS id 4227F240103 for <74604@debbugs.gnu.org>; Mon, 2 Dec 2024 13:18:26 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=posteo.net; s=2017; t=1733141906; bh=xohouX+lZ2+Ae3wnov2GhEm7d80TryaZlkoD0obAXM8=; h=From:To:Cc:Subject:Autocrypt:OpenPGP:Date:Message-ID:MIME-Version: Content-Type:Content-Transfer-Encoding:From; b=rgLrOBsYdJYV2tvh+ZrIxNIFkPvbTSnmuZ4yylDYseBzdsxYF7YK2dXRln3HKxC7n 0XForueKjPjCyD8qJzjJTbK1teP0RPvCnogzsBPvl2gQD8bRxj7Ba6BQjvIGd9MICl DjGtypOu9IZ4kK4MnE3emA4HM6np4+peYKhim3wWKipoh+c40i4phAQEb/mqteMww5 9VuEtCRA/0UIMeocH/Y50q0bHbJsKQXqDKwRkpl/Xj4Ly9bz/hZADZ4X9ipNkltlO3 4LRKA/zSdB2AQKF7ue/8nReFJooM7QSpSqWzl2Wu8LqDKfecyq/e7ahINZjQGy54VV qFg7pNP0HXTWw== Received: from customer (localhost [127.0.0.1]) by submission (posteo.de) with ESMTPSA id 4Y22r15Bxyz6tyH; Mon, 2 Dec 2024 13:18:25 +0100 (CET) From: Philip Kaludercic In-Reply-To: (Ship Mints's message of "Mon, 2 Dec 2024 07:04:24 -0500") References: <87h67quk0g.fsf@daniel-mendler.de> <87zflfqct7.fsf@posteo.net> <87r06qqx3z.fsf@posteo.net> Autocrypt: addr=philipk@posteo.net; keydata= mDMEZBBQQhYJKwYBBAHaRw8BAQdAHJuofBrfqFh12uQu0Yi7mrl525F28eTmwUDflFNmdui0QlBo aWxpcCBLYWx1ZGVyY2ljIChnZW5lcmF0ZWQgYnkgYXV0b2NyeXB0LmVsKSA8cGhpbGlwa0Bwb3N0 ZW8ubmV0PoiWBBMWCAA+FiEEDg7HY17ghYlni8XN8xYDWXahwukFAmQQUEICGwMFCQHhM4AFCwkI BwIGFQoJCAsCBBYCAwECHgECF4AACgkQ8xYDWXahwulikAEA77hloUiSrXgFkUVJhlKBpLCHUjA0 mWZ9j9w5d08+jVwBAK6c4iGP7j+/PhbkxaEKa4V3MzIl7zJkcNNjHCXmvFcEuDgEZBBQQhIKKwYB BAGXVQEFAQEHQI5NLiLRjZy3OfSt1dhCmFyn+fN/QKELUYQetiaoe+MMAwEIB4h+BBgWCAAmFiEE Dg7HY17ghYlni8XN8xYDWXahwukFAmQQUEICGwwFCQHhM4AACgkQ8xYDWXahwukm+wEA8cml4JpK NeAu65rg+auKrPOP6TP/4YWRCTIvuYDm0joBALw98AMz7/qMHvSCeU/hw9PL6u6R2EScxtpKnWof z4oM OpenPGP: id=philipk@posteo.net; url="https://keys.openpgp.org/vks/v1/by-email/philipk@posteo.net"; preference=signencrypt Date: Mon, 02 Dec 2024 12:18:06 +0000 Message-ID: <87msheqnwh.fsf@posteo.net> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-Spam-Score: -2.3 (--) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -3.3 (---) Ship Mints writes: > Isn't it the case that describe-package works only on installed packages, > not prospectively installed packages? To help determine the value/risk of= a > package install or update, I'd think it better to show this in advance. > Daniel's diff suggestion is similar but more technical. describe-package (C-h p) works on all packages, but the news feature I described wouldn't work as it uses a local file. But that is not a hard-constraint, we could serve news data as well. I don't know how much sense it makes to present a diff when installing a package. News files are probably also not that interesting. We could provide a command like package-vc-checkout that just fetches the package source and places it somewhere for the user to inspect. > On Mon, Dec 2, 2024 at 3:59=E2=80=AFAM Philip Kaludercic wrote: > >> Ship Mints writes: >> >> > I like this idea, too. I spend a reasonable amount of time trying to >> > understand what people have changed and if it will affect me negatively >> > (the defensive part) or positively (for new features, user options, >> > deprecations). Showing a source-code diff may be a bit technical for s= ome >> > users, though. I wonder if there could be either a link to a changelog, >> or >> > a way to encourage a changelog convention so one could be displayed for >> > users prior to a decision to update a package. >> >> Note that packages can distribute this information. Currently, if a >> tarball includes a "news" file, it will be displayed by >> `describe-package. IIRC no package archive generates these right now. >> But if we implement a user option like that described above (or below?), >> then we can add that as an option as well. >> >> The main issue is that not all package maintainers ensure that there are >> changelog/news sources that ELPA could use to provide this information. >> >> > -Stephane >> > >> > On Sun, Dec 1, 2024 at 5:06=E2=80=AFPM Philip Kaludercic >> wrote: >> > >> >> Daniel Mendler writes: >> >> >> >> > This is a feature request for the security wishlist. When upgrading >> >> > package it would be good to show a diff between the new and old >> package >> >> > files. Such an option could help performing review casually as part= of >> >> > the upgrade process and may improve the security of the package >> >> > archives. More eyes would look at new package versions. This would >> make >> >> > it harder to inject malicious code either via the source repository= or >> >> > via attacks on the package archives. >> >> >> >> That sounds like a good option to have! I'll look into adding someth= ing >> >> like this via a user option that adjusts how to confirm a package >> upgrade. >> >> >> >> Note that package-vc has something similar with the >> >> `package-vc-log-incoming' command. >> >> >> >> >> >> >> >> >> From unknown Fri Sep 19 04:01:23 2025 X-Loop: help-debbugs@gnu.org Subject: bug#74604: 30.0.92; FR: M-x package-upgrade - offer an option to show a diff on upgrade Resent-From: Daniel Mendler Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Mon, 02 Dec 2024 12:28:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 74604 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: To: Ship Mints Cc: Philip Kaludercic , 74604@debbugs.gnu.org Received: via spool by 74604-submit@debbugs.gnu.org id=B74604.173314246219859 (code B ref 74604); Mon, 02 Dec 2024 12:28:02 +0000 Received: (at 74604) by debbugs.gnu.org; 2 Dec 2024 12:27:42 +0000 Received: from localhost ([127.0.0.1]:54570 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1tI5Wg-0005AF-AD for submit@debbugs.gnu.org; Mon, 02 Dec 2024 07:27:42 -0500 Received: from server.qxqx.de ([49.12.34.165]:35211 helo=mail.qxqx.de) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1tI5Wd-00059q-WE for 74604@debbugs.gnu.org; Mon, 02 Dec 2024 07:27:40 -0500 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=daniel-mendler.de; s=key; h=Content-Type:MIME-Version:Message-ID:Date: References:In-Reply-To:Subject:Cc:To:From:Sender:Reply-To: Content-Transfer-Encoding:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Id: List-Help:List-Unsubscribe:List-Subscribe:List-Post:List-Owner:List-Archive; bh=Enf8E+/k7HdKczuLo5z09Feo27w8h9Ke6hXSpOpKX0g=; b=USbUzYVo9qYEB+nPNKaly1TSPL 2UCaZEyW1hofEFtn3lb1BarCXRUlqCGg6sWP+UjhK7+RI3wCRuFCTXm5yhYXAJujeZF7iZuabnNUa EGrsvnkvSCukfysS1BeyvpVhUET7CaFtHdZ60Z150f2YKbVAP8PllHdsr7a1wyogm+p0=; From: Daniel Mendler In-Reply-To: (Ship Mints's message of "Mon, 2 Dec 2024 07:04:24 -0500") References: <87h67quk0g.fsf@daniel-mendler.de> <87zflfqct7.fsf@posteo.net> <87r06qqx3z.fsf@posteo.net> Date: Mon, 02 Dec 2024 13:25:22 +0100 Message-ID: <87iks2gtl9.fsf@daniel-mendler.de> User-Agent: Gnus/5.13 (Gnus v5.13) MIME-Version: 1.0 Content-Type: text/plain X-Spam-Score: -0.7 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.7 (-) Ship Mints writes: > To help determine the value/risk of a > package install or update, I'd think it better to show this in advance. > Daniel's diff suggestion is similar but more technical. I think your idea of adding an option to show the change log is good. It would be nice to have a `package-upgrade-review' option which could be set to `nil', `news' or to `diff'. But I want to emphasize that your suggestion misses the security aspect. Security is the main reason why I made the proposal. The goal is to make it easier and more convenient for users (yes, users who are "technical" and familiar with Elisp) to assess the safety of package upgrades and possibly report any irregularities to the package archive maintainers. While packages are commonly reviewed at the time of their inclusion in package archives, this is often not the case later on. My proposal does not address or affect the first time installation of a package. At this time it doesn't make sense to show a "diff" and the user must first check the package closely anyway. Daniel From unknown Fri Sep 19 04:01:23 2025 X-Loop: help-debbugs@gnu.org Subject: bug#74604: 30.0.92; FR: M-x package-upgrade - offer an option to show a diff on upgrade In-Reply-To: <87h67quk0g.fsf@daniel-mendler.de> Resent-From: Howard Melman Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Thu, 05 Dec 2024 22:43:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 74604 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: To: 74604@debbugs.gnu.org X-Debbugs-Original-To: bug-gnu-emacs@gnu.org Received: via spool by submit@debbugs.gnu.org id=B.173343854430335 (code B ref -1); Thu, 05 Dec 2024 22:43:02 +0000 Received: (at submit) by debbugs.gnu.org; 5 Dec 2024 22:42:24 +0000 Received: from localhost ([127.0.0.1]:41321 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1tJKYB-0007tC-KM for submit@debbugs.gnu.org; Thu, 05 Dec 2024 17:42:23 -0500 Received: from lists.gnu.org ([209.51.188.17]:50224) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1tJKY9-0007t1-Ss for submit@debbugs.gnu.org; Thu, 05 Dec 2024 17:42:22 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tJKY9-0005MD-MT for bug-gnu-emacs@gnu.org; Thu, 05 Dec 2024 17:42:21 -0500 Received: from ciao.gmane.io ([116.202.254.214]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tJKY8-00054F-FC for bug-gnu-emacs@gnu.org; Thu, 05 Dec 2024 17:42:21 -0500 Received: from list by ciao.gmane.io with local (Exim 4.92) (envelope-from ) id 1tJKY4-0006kE-Pp for bug-gnu-emacs@gnu.org; Thu, 05 Dec 2024 23:42:16 +0100 X-Injected-Via-Gmane: http://gmane.org/ From: Howard Melman Date: Thu, 05 Dec 2024 17:42:08 -0500 Message-ID: References: <87h67quk0g.fsf@daniel-mendler.de> <87zflfqct7.fsf@posteo.net> <87r06qqx3z.fsf@posteo.net> <87iks2gtl9.fsf@daniel-mendler.de> Mime-Version: 1.0 Content-Type: text/plain User-Agent: Gnus/5.13 (Gnus v5.13) Cancel-Lock: sha1:/yPKSQv6wIU8w2d1akKBUyJP/m8= Received-SPF: pass client-ip=116.202.254.214; envelope-from=geb-bug-gnu-emacs@m.gmane-mx.org; helo=ciao.gmane.io X-Spam_score_int: 0 X-Spam_score: 0.0 X-Spam_bar: / X-Spam_report: (0.0 / 5.0 requ) BAYES_00=-1.9, DKIM_ADSP_CUSTOM_MED=0.001, FORGED_GMAIL_RCVD=1, FREEMAIL_FORGED_FROMDOMAIN=0.001, FREEMAIL_FROM=0.001, HEADER_FROM_DIFFERENT_DOMAINS=0.001, NML_ADSP_CUSTOM_MED=0.9, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-Spam-Score: -0.1 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.1 (-) Daniel Mendler via "Bug reports for GNU Emacs, the Swiss army knife of text editors" writes: > Ship Mints writes: > >> To help determine the value/risk of a >> package install or update, I'd think it better to show this in advance. >> Daniel's diff suggestion is similar but more technical. > > I think your idea of adding an option to show the change log is good. It > would be nice to have a `package-upgrade-review' option which could be > set to `nil', `news' or to `diff'. There was a package called paradox which had more features on the package UI. It included a command paradox-commit-list that opened a buffer showing one line per commit with the commit message and a button that was a link to the commits diff. It bolded the commits since the current installed version to make it easy to see the changes. It only worked on github hosted packages. It would be great to have this functionality in package.el particularly if it worked on non-github hosted packages. -- Howard From unknown Fri Sep 19 04:01:23 2025 X-Loop: help-debbugs@gnu.org Subject: bug#74604: 30.0.92; FR: M-x package-upgrade - offer an option to show a diff on upgrade Resent-From: Stefan Monnier Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Wed, 15 Jan 2025 13:52:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 74604 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: To: Ship Mints Cc: Daniel Mendler , Philip Kaludercic , 74604@debbugs.gnu.org Received: via spool by 74604-submit@debbugs.gnu.org id=B74604.17369490875435 (code B ref 74604); Wed, 15 Jan 2025 13:52:02 +0000 Received: (at 74604) by debbugs.gnu.org; 15 Jan 2025 13:51:27 +0000 Received: from localhost ([127.0.0.1]:57270 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1tY3nq-0001Pa-Og for submit@debbugs.gnu.org; Wed, 15 Jan 2025 08:51:27 -0500 Received: from mailscanner.iro.umontreal.ca ([132.204.25.50]:6308) by debbugs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.84_2) (envelope-from ) id 1tY3nn-0001P9-CN for 74604@debbugs.gnu.org; Wed, 15 Jan 2025 08:51:25 -0500 Received: from pmg2.iro.umontreal.ca (localhost.localdomain [127.0.0.1]) by pmg2.iro.umontreal.ca (Proxmox) with ESMTP id 65F7380878; Wed, 15 Jan 2025 08:51:16 -0500 (EST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=iro.umontreal.ca; s=mail; t=1736949075; bh=wv9rO7Pw1ZOK0+hQU31nqdquHQdg7TyER7r9yW/sUE8=; h=From:To:Cc:Subject:In-Reply-To:References:Date:From; b=e6jFyrM89+AGGPUr98uCKhFoe/L7AtSlyuMSoL64qACFtA5R7vzHz4jISQdFTTRTf OVXgSoEn5V04o3YJled8j9DmzoXNoLXqYERvgvysWe0i7ftGoPVGViprxG5qiiMtwT HW8zQO1PPP228y4yOtNXUYWA6gDwcaIIx3zOwRE+wJZt02DWyh8nv4gGbrfR13uOJd 4zezTWFRYVQjGsd6FLdtLLMxkN8hUg+YFUBHwvJWBrAS3diW2CUdc9hxUYF8LFwTQH uY2oCGwnft1rxmdw1ZqiQ+OLa1AjC7ZgkKtxTONz+oD2+Pr8To8BNnhZDs2MWmwmkl 18p7Sdq8ecTJg== Received: from mail01.iro.umontreal.ca (unknown [172.31.2.1]) by pmg2.iro.umontreal.ca (Proxmox) with ESMTP id 76EDE803A3; Wed, 15 Jan 2025 08:51:15 -0500 (EST) Received: from pastel (104-195-232-86.cpe.teksavvy.com [104.195.232.86]) by mail01.iro.umontreal.ca (Postfix) with ESMTPSA id 465C31208BA; Wed, 15 Jan 2025 08:51:15 -0500 (EST) From: Stefan Monnier In-Reply-To: (Ship Mints's message of "Sun, 1 Dec 2024 17:47:21 -0500") Message-ID: References: <87h67quk0g.fsf@daniel-mendler.de> <87zflfqct7.fsf@posteo.net> Date: Wed, 15 Jan 2025 08:51:08 -0500 User-Agent: Gnus/5.13 (Gnus v5.13) MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-SPAM-INFO: Spam detection results: 0 ALL_TRUSTED -1 Passed through trusted hosts only via SMTP AWL -0.030 Adjusted score from AWL reputation of From: address BAYES_00 -1.9 Bayes spam probability is 0 to 1% DKIM_SIGNED 0.1 Message has a DKIM or DK signature, not necessarily valid DKIM_VALID -0.1 Message has at least one valid DKIM or DK signature DKIM_VALID_AU -0.1 Message has a valid DKIM or DK signature from author's domain DKIM_VALID_EF -0.1 Message has a valid DKIM or DK signature from envelope-from domain X-SPAM-LEVEL: X-Spam-Score: -2.3 (--) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -3.3 (---) >>> This is a feature request for the security wishlist. When upgrading >>> package it would be good to show a diff between the new and old package >>> files. +1 >>> Such an option could help performing review casually as part of >>> the upgrade process and may improve the security of the package >>> archives. More eyes would look at new package versions. This would ma= ke >>> it harder to inject malicious code either via the source repository or >>> via attacks on the package archives. In addition to improving security it would encourage users to become familiar with the code, which is very much the driving force behind a lot of Emacs's design. >> That sounds like a good option to have! I'll look into adding something >> like this via a user option that adjusts how to confirm a package upgrad= e. Maybe the UI could be a simple confirmation prompt, where "show diff" is one of the options. >> Note that package-vc has something similar with the >> `package-vc-log-incoming' command. [ Ideally the two could/should share some aspects (UI-wise or implementation-wise). ] > Showing a source-code diff may be a bit technical for some users, > though. I wonder if there could be either a link to a changelog, or > a way to encourage a changelog convention so one could be displayed > for users prior to a decision to update a package. The prompt could offer a choice of "just upgrade / show news / show diff". Currently, on the (Non)GNU ELPA side, there *is* a convention for a changelog file. This is used to create the "Recent NEWS" part of release announcements (see https://lists.gnu.org/archive/html/gnu-emacs-sources/2025-01/msg00027.html for an example) and the "News" section on the package's web page (See http://elpa.gnu.org/packages/ellama.html). But: - Many packages don't follow it (I try to shame the maintainers, but maybe too softly? See https://lists.gnu.org/archive/html/gnu-emacs-sources/2025-01/msg00024= .html for an example). - There is no convention to relate specific parts of the changelog to specific versions, so we just display the first N lines (for email announcements, this is arguably the right thing, since we don't know what is the reader's current version). - There is even less of a convention to propagate that changelog info through the ELPA protocol (i.e. from elpa.gnu.org to the users's machines). In any case, it sounds everybody likes the idea, so I hope Someone=E2=84=A2= will provide a patch soon! Stefan From unknown Fri Sep 19 04:01:23 2025 X-Loop: help-debbugs@gnu.org Subject: bug#74604: 30.0.92; FR: M-x package-upgrade - offer an option to show a diff on upgrade Resent-From: Daniel Mendler Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Wed, 15 Jan 2025 14:18:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 74604 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: To: Stefan Monnier Cc: Philip Kaludercic , Ship Mints , 74604@debbugs.gnu.org Received: via spool by 74604-submit@debbugs.gnu.org id=B74604.173695064910068 (code B ref 74604); Wed, 15 Jan 2025 14:18:02 +0000 Received: (at 74604) by debbugs.gnu.org; 15 Jan 2025 14:17:29 +0000 Received: from localhost ([127.0.0.1]:57317 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1tY4D3-0002cK-1w for submit@debbugs.gnu.org; Wed, 15 Jan 2025 09:17:29 -0500 Received: from server.qxqx.de ([2a01:4f8:c012:9177::1]:55487 helo=mail.qxqx.de) by debbugs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.84_2) (envelope-from ) id 1tY4Cw-0002c0-B6 for 74604@debbugs.gnu.org; Wed, 15 Jan 2025 09:17:26 -0500 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=daniel-mendler.de; s=key; h=Content-Type:MIME-Version:Message-ID:Date: References:In-Reply-To:Subject:Cc:To:From:Sender:Reply-To: Content-Transfer-Encoding:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Id: List-Help:List-Unsubscribe:List-Subscribe:List-Post:List-Owner:List-Archive; bh=Jxo4tthU3wlhYEJIeXoqkMpF+YiZ+2Fr0r6D6SDJbmk=; b=Yq+glcwiSY8iJaXjsGUe//z/dH c5KFBCj/gANu8k++fa8bQvOwiXPE0fkw/cd+t77PYwPZkHj/tLqCGseZm0ZXkWs5jXymqGtgHfGtl 3qiCM0vK9MhedIGorMuHwL0FTm5xtN4wZFlLmpccc43ZBpdSDVaZLCD8oMyhkOvY4ra0=; From: Daniel Mendler In-Reply-To: (Stefan Monnier's message of "Wed, 15 Jan 2025 08:51:08 -0500") References: <87h67quk0g.fsf@daniel-mendler.de> <87zflfqct7.fsf@posteo.net> Date: Wed, 15 Jan 2025 15:17:13 +0100 Message-ID: <87sepkqhzq.fsf@daniel-mendler.de> User-Agent: Gnus/5.13 (Gnus v5.13) MIME-Version: 1.0 Content-Type: text/plain X-Spam-Score: -0.7 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.7 (-) Stefan Monnier writes: >>>> Such an option could help performing review casually as part of >>>> the upgrade process and may improve the security of the package >>>> archives. More eyes would look at new package versions. This would make >>>> it harder to inject malicious code either via the source repository or >>>> via attacks on the package archives. > > In addition to improving security it would encourage users to become > familiar with the code, which is very much the driving force behind > a lot of Emacs's design. Yes, this is the point of the proposal. >> Showing a source-code diff may be a bit technical for some users, >> though. I wonder if there could be either a link to a changelog, or >> a way to encourage a changelog convention so one could be displayed >> for users prior to a decision to update a package. > > The prompt could offer a choice of "just upgrade / show news / > show diff". Good idea. I think I would also like to have a customization option `package-upgrade-diff' where the behavior can be customized, since I always want to see the diff even for my own packages to check if recent changes have arrived. If `package-upgrade-diff' is nil, the confirmation prompt could offer a key to display the diff. A key could also be reserved to show the change log in case it is present, but as I mentioned before in this bug report, displaying the change log is not a security feature and the code as "driving force" is hidden. Daniel From unknown Fri Sep 19 04:01:23 2025 X-Loop: help-debbugs@gnu.org Subject: bug#74604: 30.0.92; FR: M-x package-upgrade - offer an option to show a diff on upgrade Resent-From: Philip Kaludercic Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Thu, 16 Jan 2025 09:06:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 74604 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: To: Stefan Monnier Cc: Daniel Mendler , Ship Mints , 74604@debbugs.gnu.org Received: via spool by 74604-submit@debbugs.gnu.org id=B74604.173701831924677 (code B ref 74604); Thu, 16 Jan 2025 09:06:01 +0000 Received: (at 74604) by debbugs.gnu.org; 16 Jan 2025 09:05:19 +0000 Received: from localhost ([127.0.0.1]:59989 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1tYLoU-0006Px-Pe for submit@debbugs.gnu.org; Thu, 16 Jan 2025 04:05:19 -0500 Received: from mout01.posteo.de ([185.67.36.65]:55491) by debbugs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.84_2) (envelope-from ) id 1tYLoP-0006Nq-OK for 74604@debbugs.gnu.org; Thu, 16 Jan 2025 04:05:16 -0500 Received: from submission (posteo.de [185.67.36.169]) by mout01.posteo.de (Postfix) with ESMTPS id 6EDEC240027 for <74604@debbugs.gnu.org>; Thu, 16 Jan 2025 10:05:05 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=posteo.net; s=2017; t=1737018305; bh=8gFG2wn21T+LdcSCiY9saUPBbtZ1VsgLnCJ8aaVeyvw=; h=From:To:Cc:Subject:Autocrypt:OpenPGP:Date:Message-ID:MIME-Version: Content-Type:Content-Transfer-Encoding:From; b=YdViabqawckzodt0yUlDpXVayTBQz3e3/KeKvl4snllRcoxss5BV3BvCGsSIwTC1Z KerW3OgZdUMLpwTBz7kBgIL4B27TlC1Ljbksn+upoPOZ0Wa4CcVuJqr3KNO7p8swFg zjx3k98aLMqoVZDZVwiHj2Oht3AFIxXjCWwfXZBJC8ondHDMLd7zDhKaLCoP1quyBI O1EBkujXId6swv5ZiSn98CZrkNCavAesXX5Ce//J7JbWn9+Kcn6zkk2LlzHZTNI5i6 bsQnAxb3O37pTUPphfWyA7J0KpDrEOcSWdst0NkWUOTX9nXK2Jqhj/Sy/B/h/I7Usb paOcMmGitSA0Q== Received: from customer (localhost [127.0.0.1]) by submission (posteo.de) with ESMTPSA id 4YYcQ83k84z9rxD; Thu, 16 Jan 2025 10:05:04 +0100 (CET) From: Philip Kaludercic In-Reply-To: (Stefan Monnier's message of "Wed, 15 Jan 2025 08:51:08 -0500") References: <87h67quk0g.fsf@daniel-mendler.de> <87zflfqct7.fsf@posteo.net> Autocrypt: addr=philipk@posteo.net; keydata= mDMEZBBQQhYJKwYBBAHaRw8BAQdAHJuofBrfqFh12uQu0Yi7mrl525F28eTmwUDflFNmdui0QlBo aWxpcCBLYWx1ZGVyY2ljIChnZW5lcmF0ZWQgYnkgYXV0b2NyeXB0LmVsKSA8cGhpbGlwa0Bwb3N0 ZW8ubmV0PoiWBBMWCAA+FiEEDg7HY17ghYlni8XN8xYDWXahwukFAmQQUEICGwMFCQHhM4AFCwkI BwIGFQoJCAsCBBYCAwECHgECF4AACgkQ8xYDWXahwulikAEA77hloUiSrXgFkUVJhlKBpLCHUjA0 mWZ9j9w5d08+jVwBAK6c4iGP7j+/PhbkxaEKa4V3MzIl7zJkcNNjHCXmvFcEuDgEZBBQQhIKKwYB BAGXVQEFAQEHQI5NLiLRjZy3OfSt1dhCmFyn+fN/QKELUYQetiaoe+MMAwEIB4h+BBgWCAAmFiEE Dg7HY17ghYlni8XN8xYDWXahwukFAmQQUEICGwwFCQHhM4AACgkQ8xYDWXahwukm+wEA8cml4JpK NeAu65rg+auKrPOP6TP/4YWRCTIvuYDm0joBALw98AMz7/qMHvSCeU/hw9PL6u6R2EScxtpKnWof z4oM OpenPGP: id=7126E1DE2F0CE35C770BED01F2C3CC513DB89F66; url="https://keys.openpgp.org/vks/v1/by-fingerprint/7126E1DE2F0CE35C770BED01F2C3CC513DB89F66"; preference=signencrypt Date: Thu, 16 Jan 2025 09:05:03 +0000 Message-ID: <87frlj86yo.fsf@posteo.net> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-Spam-Score: -2.3 (--) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -3.3 (---) Stefan Monnier writes: >>> Note that package-vc has something similar with the >>> `package-vc-log-incoming' command. > > [ Ideally the two could/should share some aspects (UI-wise or > implementation-wise). ] Right now `package-vc-log-incoming' just re-uses `vc-log-incoming', so I don't know how easy this would be without creating a pseudo-VC backend. >> Showing a source-code diff may be a bit technical for some users, >> though. I wonder if there could be either a link to a changelog, or >> a way to encourage a changelog convention so one could be displayed >> for users prior to a decision to update a package. > > The prompt could offer a choice of "just upgrade / show news / > show diff". > > Currently, on the (Non)GNU ELPA side, there *is* a convention for > a changelog file. This is used to create the "Recent NEWS" part of > release announcements (see > https://lists.gnu.org/archive/html/gnu-emacs-sources/2025-01/msg00027.html > for an example) and the "News" section on the package's web page (See > http://elpa.gnu.org/packages/ellama.html). But: > > - Many packages don't follow it (I try to shame the maintainers, but > maybe too softly? > See https://lists.gnu.org/archive/html/gnu-emacs-sources/2025-01/msg000= 24.html > for an example). > > - There is no convention to relate specific parts of the changelog > to specific versions, so we just display the first N lines (for email > announcements, this is arguably the right thing, since we don't know > what is the reader's current version). > > - There is even less of a convention to propagate that changelog info > through the ELPA protocol (i.e. from elpa.gnu.org to the users's > machines). Package.el does show the contents of the "news" file in the describe-package buffer, but we currently don't generate these on the elpa side. > In any case, it sounds everybody likes the idea, so I hope Someone=E2=84= =A2 will > provide a patch soon! I'd be glad to tackle this and a number of other package.el/elpa-related issues that have been accumulating recently. (I'm just submitting my master's thesis in less than two weeks, so I a bit short on time.) > > Stefan From unknown Fri Sep 19 04:01:23 2025 X-Loop: help-debbugs@gnu.org Subject: bug#74604: [PATCH v1] package.el: Add diff display and confirmation for package upgrades (Bug#74604) References: <87h67quk0g.fsf@daniel-mendler.de> In-Reply-To: <87h67quk0g.fsf@daniel-mendler.de> Resent-From: Nobuyuki Kamimoto Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Sun, 31 Aug 2025 08:09:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 74604 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: To: 74604@debbugs.gnu.org X-Debbugs-Original-To: bug-gnu-emacs@gnu.org Received: via spool by submit@debbugs.gnu.org id=B.175662768421988 (code B ref -1); Sun, 31 Aug 2025 08:09:01 +0000 Received: (at submit) by debbugs.gnu.org; 31 Aug 2025 08:08:04 +0000 Received: from localhost ([127.0.0.1]:51866 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1usd6Y-0005iM-CW for submit@debbugs.gnu.org; Sun, 31 Aug 2025 04:08:04 -0400 Received: from lists.gnu.org ([2001:470:142::17]:50198) by debbugs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.84_2) (envelope-from ) id 1usYdT-0003fY-SP for submit@debbugs.gnu.org; Sat, 30 Aug 2025 23:21:45 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1usYdM-0007am-EN for bug-gnu-emacs@gnu.org; Sat, 30 Aug 2025 23:21:36 -0400 Received: from mail-pf1-x432.google.com ([2607:f8b0:4864:20::432]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1usYdJ-0005ZF-2N for bug-gnu-emacs@gnu.org; Sat, 30 Aug 2025 23:21:36 -0400 Received: by mail-pf1-x432.google.com with SMTP id d2e1a72fcca58-771f90a45easo2735663b3a.1 for ; Sat, 30 Aug 2025 20:21:32 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1756610491; x=1757215291; darn=gnu.org; h=content-transfer-encoding:subject:from:to:content-language :user-agent:mime-version:date:message-id:from:to:cc:subject:date :message-id:reply-to; bh=11T2xMH+7RLAao6BSkuHEnDwOmYWRqM2zQpTvN+lkaY=; b=SvDfMR5CEg5YfzBHW9byyfFSgYwcRdVnLHopwVBclY4uTa92lSnqHJYoON4x2MVBVf BA9Cuyb9sh3RcqimvFHi1B+U1quOarWWHVGIc2h3QtwJrH6C5L8wR7nZ0Zfbt6Ag7x03 KmTH1XY+J5Xawk6L51mDqygDQlhVRnwiJLEEGOh4mYS9IKGA4b3JfOw9brwkLFQpNaok EbX9CjprpC0rf+RRRcgwPSBpwlOsJkcuLWfYmt3KCtacruujpElq0OdNTd5UnP3iC7LF nk189dQLpPAERf6guANwh1z3Pe3ISRaFLbCF5yo7R5zIJb/qeHuPh6dKeDtZ1D3w0zSk VAMg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1756610491; x=1757215291; h=content-transfer-encoding:subject:from:to:content-language :user-agent:mime-version:date:message-id:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=11T2xMH+7RLAao6BSkuHEnDwOmYWRqM2zQpTvN+lkaY=; b=PXiSgKKGVhv3R2C+j3PowC8nHXiup1EnTBTx+bhHZEUm24h6A8Sb+k5DFW6rw84eNy Onsw8rkkuL8crWs9epmc48pg8FcGqbxxoO9tJi9EAA4v8Zp/45y7bW1LiWpncaEq678n MSJ+JLrypvFhn/qDUOs9mbICA/MQtzyFuHoLAD+87lyva60nwQ2BgbPd7BRaMQAHIclg il7WvHA1xayVHiJJVpmd27qGowc5ghCL9GsJrjIhVTlpHZH3WJKahC5bze+buOMzvWCt Zgdvr/PA3ZC6YhSglHTEV1aOhba+F8MnmhVE+SF8uvk1Mf0LvX5mtENbwpAodydRLHsN i0pA== X-Gm-Message-State: AOJu0Yw+jzRBs68rJ/cIk+JrIf+3Rc38FRZJrHZ8Q6uxYwaW8VQT3bcr yO0A9xA+5Ddv8i0yTeIG+VC9co3smx0cmTkJaqm6hSW+/n06Sic3FWXslb7PcAJG X-Gm-Gg: ASbGncscscJO+0qnYcUQyYWXtPXwNkX5JsHQcplQlbQNyQVwKIAf+vop/rBgrWGz51l +b9Eps2VUe+LS5mtwjiBWe8HyPt2qaKUxm1WOa15I9zOvSje+LPjL0K3QdkQ7fspeev5gMlN89j OW2yh2wX5XGNSo5dnOimpg98B5EniqNBf0WUqhz51hN+LCqrUV5uUE7IY8Q1RaiF44JYwEZ8BD+ TAGt2DVyrPvgfAjHXPppUMuQPGj+Jy+tbwyLJFeaRSASCYptVTjTHH7zXT1tAqIkk6Dhg4m/78U ZYl7I8EamZRFXwDTmZ1fYL3OMzibxwQCQn7W65N20RNo/fUiPy9t7PbmsfhQOLcKt/IOrDGV2f6 goR61741G3in/71mVs+qR8O5/ZeSfN5US5maWnNi1bEfwh7u+4sJi9pPKo3oIJ4dqNVpMXaDR/Q == X-Google-Smtp-Source: AGHT+IGgia5Ok2F295qIPWzWfUBcNu85hCbXZ2ahl5uukkkdqWV7aQTrpgVu54/vsU8A1iCQKvcTtw== X-Received: by 2002:aa7:8895:0:b0:771:fab2:83ca with SMTP id d2e1a72fcca58-7723e21e641mr4980480b3a.4.1756610490840; Sat, 30 Aug 2025 20:21:30 -0700 (PDT) Received: from ?IPV6:240b:c020:633:136d:596:2c5:acda:cb45? ([240b:c020:633:136d:596:2c5:acda:cb45]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-7722a4bac60sm6547538b3a.63.2025.08.30.20.21.29 for (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Sat, 30 Aug 2025 20:21:30 -0700 (PDT) Message-ID: <54fadfd1-21f6-48cb-a17e-8d0878a68f1d@gmail.com> Date: Sun, 31 Aug 2025 12:20:39 +0900 MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Content-Language: en-US From: Nobuyuki Kamimoto Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit Received-SPF: pass client-ip=2607:f8b0:4864:20::432; envelope-from=kamimoto527@gmail.com; helo=mail-pf1-x432.google.com X-Spam_score_int: -17 X-Spam_score: -1.8 X-Spam_bar: - X-Spam_report: (-1.8 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_ENVFROM_END_DIGIT=0.25, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-Spam-Score: 1.2 (+) X-Spam-Report: Spam detection software, running on the system "debbugs.gnu.org", has NOT identified this incoming email as spam. The original message has been attached to this so you can view it or label similar future email. If you have any questions, see the administrator of that system for details. Content preview: Hello, This patch implements a new feature for package upgrades, as discussed in Bug#74604. Summary: - Shows diffs between the installed and the new version of a package =?UTF-8?Q?=C2=A0?= before upgrading. - Lets the user review changes and confirm whether to proceed. - Supports both regular tarball packag [...] Content analysis details: (1.2 points, 10.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at https://www.dnswl.org/, no trust [2001:470:142:0:0:0:0:17 listed in] [list.dnswl.org] 1.0 SPF_SOFTFAIL SPF: sender does not match SPF record (softfail) 0.0 FREEMAIL_FROM Sender email is commonly abused enduser mail provider (kamimoto527[at]gmail.com) 0.2 FREEMAIL_ENVFROM_END_DIGIT Envelope-from freemail username ends in digit (kamimoto527[at]gmail.com) -0.0 SPF_HELO_PASS SPF: HELO matches SPF record X-Mailman-Approved-At: Sun, 31 Aug 2025 04:08:01 -0400 X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: 0.2 (/) Hello, This patch implements a new feature for package upgrades, as discussed in Bug#74604. Summary: - Shows diffs between the installed and the new version of a package   before upgrading. - Lets the user review changes and confirm whether to proceed. - Supports both regular tarball packages and VC packages. - New user options:   - package-show-upgrade-diffs   - package-upgrade-diff-exclude-packages   - package-upgrade-diff-exclude-archives   - package-vc-show-upgrade-diffs   - package-vc-upgrade-diff-exclude-packages - Updated documentation (doc/emacs/package.texi). - Added entry to etc/NEWS. Testing: - Built Emacs from the patched branch. - Verified interactive upgrade of both tarball and VC packages. - Ran `make check` and confirmed tests pass. See Bug#74604 for context. Best regards, Nobuyuki Kamimoto ---8<---cut here---8<--- From f1793d5c62b194c37a61d8d4d02b655dc8b714c3 Mon Sep 17 00:00:00 2001 From: Nobuyuki Kamimoto Date: Sun, 31 Aug 2025 12:08:50 +0900 Subject: [PATCH] Add diff display and confirmation for package upgrades Show differences between current and new versions before upgrading packages, allowing users to review changes and choose whether to proceed. This applies to both regular packages and VC packages. * lisp/emacs-lisp/package.el (package-show-upgrade-diffs) (package-upgrade-diff-exclude-packages) (package-upgrade-diff-exclude-archives): New user options to control diff display for package upgrades. (package--extract-tarball-to-temp, package--get-installed-package-dir) (package--show-package-diff, package--confirm-tarball-upgrade): New functions to handle diff display and confirmation for tarball upgrades. (package-upgrade): Check if tarball package upgrade needs confirmation. (package-menu--perform-transaction): Handle diff confirmation in menu. * lisp/emacs-lisp/package-vc.el (package-vc-show-upgrade-diffs) (package-vc-upgrade-diff-exclude-packages): New user options to control diff display for VC package upgrades. (package-vc--show-diff, package-vc--confirm-upgrade): New functions to handle diff display and confirmation for VC package upgrades. (package-vc-upgrade): Integrate diff confirmation into upgrade process. * doc/emacs/package.texi (Package Installation): Document the new diff display functionality for both regular and VC package upgrades, including the new user options for controlling the behavior. * etc/NEWS: Add announcement for the new package upgrade diff feature. ---  doc/emacs/package.texi        |  37 ++++++++  etc/NEWS                      |  16 ++++  lisp/emacs-lisp/package-vc.el | 140 ++++++++++++++++++++++-------  lisp/emacs-lisp/package.el    | 165 ++++++++++++++++++++++++++++++----  4 files changed, 308 insertions(+), 50 deletions(-) diff --git a/doc/emacs/package.texi b/doc/emacs/package.texi index c29beea3b08..1f57910a207 100644 --- a/doc/emacs/package.texi +++ b/doc/emacs/package.texi @@ -389,6 +389,25 @@ Package Installation  use these bulk commands if you want to update only a small number of  built-in packages. +@vindex package-show-upgrade-diffs +@vindex package-upgrade-diff-exclude-packages +@vindex package-upgrade-diff-exclude-archives +  By default, Emacs shows a diff of the changes when upgrading +packages, allowing you to review what has changed between the current +and new version before proceeding.  This is controlled by the +@code{package-show-upgrade-diffs} variable.  When non-@code{nil} (the +default), package upgrades will display the differences and ask for +confirmation before proceeding.  You can disable this behavior by +setting @code{package-show-upgrade-diffs} to @code{nil}. + +  You can exclude specific packages or package archives from diff +checking using @code{package-upgrade-diff-exclude-packages} and +@code{package-upgrade-diff-exclude-archives}.  The first variable +takes a list of package names (as symbols), while the second takes a +list of archive names (as strings).  Packages or archives in these +lists will upgrade without showing diffs, even when +@code{package-show-upgrade-diffs} is non-@code{nil}. +  @cindex package requirements    A package may @dfn{require} certain other packages to be installed,  because it relies on functionality provided by them.  When Emacs @@ -645,6 +664,24 @@ Fetching Package Sources    Note that currently, built-in packages cannot be upgraded using  @code{package-vc-install}. +@vindex package-vc-show-upgrade-diffs +@vindex package-vc-upgrade-diff-exclude-packages +  Like regular package upgrades, VC package upgrades can also show +diffs before proceeding.  This is controlled by the +@code{package-vc-show-upgrade-diffs} variable, which operates +independently of @code{package-show-upgrade-diffs}.  When +non-@code{nil} (the default), upgrading VC packages will display the +differences between the current and updated versions, allowing you to +review the changes before confirming the upgrade. + +  You can exclude specific VC packages from diff checking by adding +their names (as symbols) to @code{package-vc-upgrade-diff-exclude-packages}. +Packages in this list will upgrade without showing diffs, even when +@code{package-vc-show-upgrade-diffs} is non-@code{nil}.  This +exclusion list is separate from @code{package-upgrade-diff-exclude-packages} +to allow independent control over diff behavior for VC packages versus +regular packages. +  @findex package-report-bug  @findex package-vc-prepare-patch    With the source checkout, you might want to reproduce a bug against diff --git a/etc/NEWS b/etc/NEWS index 8a139cb03ca..2fdbd1c291f 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -74,6 +74,22 @@ done from early-init.el, such as adding to 'package-directory-list'.  ** 'prettify-symbols-mode' attempts to ignore undisplayable characters.  Previously, such characters would be rendered as, e.g., white boxes. ++++ +** Package management now shows diffs before upgrades. +Package upgrades can now display differences between the current and +new version before proceeding.  This applies to both regular packages +and VC packages installed from version control repositories. + +The behavior is controlled by these new user options: +- 'package-show-upgrade-diffs': Enable/disable diff display for regular packages +- 'package-vc-show-upgrade-diffs': Enable/disable diff display for VC packages +- 'package-upgrade-diff-exclude-packages': Exclude specific packages from diff checking +- 'package-upgrade-diff-exclude-archives': Exclude specific archives from diff checking +- 'package-vc-upgrade-diff-exclude-packages': Exclude specific VC packages from diff checking + +When enabled (the default), users will see a diff buffer showing changes +and can choose whether to proceed with or cancel the upgrade. +  +++  ** 'standard-display-table' now has more extra slots.  'standard-display-table' has been extended to allow specifying glyphs diff --git a/lisp/emacs-lisp/package-vc.el b/lisp/emacs-lisp/package-vc.el index 7433fce2d89..da9977b429f 100644 --- a/lisp/emacs-lisp/package-vc.el +++ b/lisp/emacs-lisp/package-vc.el @@ -83,6 +83,27 @@ package-vc-register-as-project    :type 'boolean    :version "30.1") +(defcustom package-vc-show-upgrade-diffs t +  "Non-nil means to show diffs before upgrading VC packages. +This controls whether VC package upgrades show a diff buffer +comparing the current and updated versions of the package before +proceeding with the upgrade.  This is independent of the +`package-show-upgrade-diffs' variable which controls diff +display for regular package upgrades." +  :type 'boolean +  :group 'package-vc +  :version "31.1") + +(defcustom package-vc-upgrade-diff-exclude-packages nil +  "List of VC package names to exclude from upgrade diff checking. +This list contains package names (as symbols) for which diff checking +should be skipped when upgrading VC packages.  This is separate from +`package-upgrade-diff-exclude-packages' to allow independent control +of diff exclusions for VC packages versus regular package upgrades." +  :type '(repeat symbol) +  :group 'package-vc +  :version "31.1") +  (defvar package-vc-selected-packages) ; pacify byte-compiler  ;;;###autoload @@ -729,6 +750,55 @@ package-vc-upgrade-all  (declare-function vc-dir-prepare-status-buffer "vc-dir"                    (bname dir backend &optional create-new)) +(defun package-vc--show-diff (old-dir new-dir) +  "Show diff between OLD-DIR and NEW-DIR package directories. +Return t if user confirms to continue, nil to cancel." +  (let ((diff-buffer "*Package VC Diff*")) +    (with-current-buffer (get-buffer-create diff-buffer) +      (erase-buffer) +      (let ((inhibit-read-only t) +            (exit-status (call-process "diff" nil t nil "-ru" old-dir new-dir))) +        (cond +         ((eq exit-status 0) +          (insert "No differences found between current and updated package versions.\n")) +         ((eq exit-status 1) +          ;; Normal case: differences found, they're already in buffer +          nil) +         (t +          ;; Error case +          (insert (format "Error running diff (exit status %d).\n" exit-status))))) +      (diff-mode) +      (read-only-mode 1) +      (goto-char (point-min))) +    (display-buffer diff-buffer) +    (let ((response (yes-or-no-p "Show differences. Continue with upgrade? "))) +      (kill-buffer diff-buffer) +      response))) + +(defun package-vc--confirm-upgrade (pkg-desc) +  "Show diff for VC package upgrade and ask for confirmation. +Return t if user wants to proceed, nil otherwise." +  ;; Check exclusion list first +  (let ((package-name (package-desc-name pkg-desc))) +    ;; If package-vc-show-upgrade-diffs is nil, or package is excluded, proceed without diffs +    (if (or (not package-vc-show-upgrade-diffs) +            (memq package-name package-vc-upgrade-diff-exclude-packages)) +        t  ; Skip diff checking, proceed with upgrade +      (let* ((pkg-dir (package-desc-dir pkg-desc)) +             (temp-dir (make-temp-file "package-vc-diff-" t)) +             (pkg-spec (package-vc--desc->spec pkg-desc))) +        ;; Delete temp directory so package-vc--clone can create and populate it +        (delete-directory temp-dir) +        (unwind-protect +            (progn +              ;; Clone the updated version to temp directory +              (package-vc--clone pkg-desc pkg-spec temp-dir nil) +              ;; Show diff and get user confirmation +              (package-vc--show-diff pkg-dir temp-dir)) +          ;; Clean up temp directory +          (when (file-exists-p temp-dir) +            (delete-directory temp-dir t))))))) +  ;;;###autoload  (defun package-vc-upgrade (pkg-desc)    "Upgrade the package described by PKG-DESC from package's VC repository. @@ -736,40 +806,42 @@ package-vc-upgrade  This may fail if the local VCS state of the package conflicts  with the remote repository state."    (interactive (list (package-vc--read-package-desc "Upgrade VC package: " t))) -  ;; HACK: To run `package-vc--unpack-1' after checking out the new -  ;; revision, we insert a hook into `vc-post-command-functions', and -  ;; remove it right after it ran.  To avoid running the hook multiple -  ;; times or even for the wrong repository (as `vc-pull' is often -  ;; asynchronous), we extract the relevant arguments using a pseudo -  ;; filter for `vc-filter-command-function', executed only for the -  ;; side effect, and store them in the lexical scope.  When the hook -  ;; is run, we check if the arguments are the same (`eq') as the ones -  ;; previously extracted, and only in that case will be call -  ;; `package-vc--unpack-1'.  Ugh... -  ;; -  ;; If there is a better way to do this, it should be done. -  (cl-assert (package-vc-p pkg-desc)) -  (letrec ((pkg-dir (package-desc-dir pkg-desc)) -           (vc-flags) -           (vc-filter-command-function -            (lambda (command file-or-list flags) -              (setq vc-flags flags) -              (list command file-or-list flags))) -           (post-upgrade -            (lambda (_command _file-or-list flags) -              (when (and (file-equal-p pkg-dir default-directory) -                         (eq flags vc-flags)) -                (unwind-protect -                    (with-demoted-errors "Failed to activate: %S" -                      (package-vc--unpack-1 pkg-desc pkg-dir)) -                  (remove-hook 'vc-post-command-functions post-upgrade)))))) -    (add-hook 'vc-post-command-functions post-upgrade) -    (with-demoted-errors "Failed to fetch: %S" -      (require 'vc-dir) -      (with-current-buffer (vc-dir-prepare-status-buffer -                            (format " *package-vc-dir: %s*" pkg-dir) -                            pkg-dir (vc-responsible-backend pkg-dir)) -        (vc-pull))))) +  ;; Check if user wants to see diff and confirm upgrade +  (when (package-vc--confirm-upgrade pkg-desc) +    ;; HACK: To run `package-vc--unpack-1' after checking out the new +    ;; revision, we insert a hook into `vc-post-command-functions', and +    ;; remove it right after it ran.  To avoid running the hook multiple +    ;; times or even for the wrong repository (as `vc-pull' is often +    ;; asynchronous), we extract the relevant arguments using a pseudo +    ;; filter for `vc-filter-command-function', executed only for the +    ;; side effect, and store them in the lexical scope.  When the hook +    ;; is run, we check if the arguments are the same (`eq') as the ones +    ;; previously extracted, and only in that case will be call +    ;; `package-vc--unpack-1'.  Ugh... +    ;; +    ;; If there is a better way to do this, it should be done. +    (cl-assert (package-vc-p pkg-desc)) +    (letrec ((pkg-dir (package-desc-dir pkg-desc)) +             (vc-flags) +             (vc-filter-command-function +              (lambda (command file-or-list flags) +                (setq vc-flags flags) +                (list command file-or-list flags))) +             (post-upgrade +              (lambda (_command _file-or-list flags) +                (when (and (file-equal-p pkg-dir default-directory) +                           (eq flags vc-flags)) +                  (unwind-protect +                      (with-demoted-errors "Failed to activate: %S" +                        (package-vc--unpack-1 pkg-desc pkg-dir)) +                    (remove-hook 'vc-post-command-functions post-upgrade)))))) +      (add-hook 'vc-post-command-functions post-upgrade) +      (with-demoted-errors "Failed to fetch: %S" +        (require 'vc-dir) +        (with-current-buffer (vc-dir-prepare-status-buffer +                              (format " *package-vc-dir: %s*" pkg-dir) +                              pkg-dir (vc-responsible-backend pkg-dir)) +          (vc-pull))))))  (defun package-vc--archives-initialize ()    "Initialize package.el and fetch package specifications." diff --git a/lisp/emacs-lisp/package.el b/lisp/emacs-lisp/package.el index ba9999c20e6..1d1266b7ede 100644 --- a/lisp/emacs-lisp/package.el +++ b/lisp/emacs-lisp/package.el @@ -450,6 +450,44 @@ package-archive-column-width    :type 'natnum    :version "28.1") +(defcustom package-show-upgrade-diffs t +  "Whether to show diffs before upgrading packages. +When non-nil, package upgrades will display the differences between +the current and new version before proceeding.  Users can review the +changes and choose whether to continue with the upgrade. +When nil, packages upgrade without showing diffs." +  :type 'boolean +  :group 'package +  :version "31.1") + +(defcustom package-upgrade-diff-exclude-packages nil +  "List of package names to exclude from diff checking during upgrades. +When a package name is in this list, the upgrade will proceed +without showing diffs, even if `package-show-upgrade-diffs' is non-nil. +Package names should be specified as symbols. + +For example: \\='(emacs magit org-mode) + +This allows for fine-grained control over which packages show +diffs during upgrades." +  :type '(repeat symbol) +  :group 'package +  :version "31.1") + +(defcustom package-upgrade-diff-exclude-archives nil +  "List of package archives to exclude from diff checking during upgrades. +When a package's archive is in this list, the upgrade will proceed +without showing diffs, even if `package-show-upgrade-diffs' is non-nil. +Archive names should be specified as strings. + +For example: \\='(\"melpa-stable\" \"nongnu\") + +This allows for fine-grained control over which archives show +diffs during package upgrades." +  :type '(repeat string) +  :group 'package +  :version "31.1") +    ;;; `package-desc' object definition  ;; This is the struct used internally to represent packages. @@ -1019,6 +1057,77 @@ package--alist-to-plist-args  (declare-function dired-get-marked-files "dired") +(defun package--extract-tarball-to-temp (buffer pkg-desc temp-dir) +  "Extract tarball from BUFFER to TEMP-DIR for PKG-DESC. +Returns the directory where package was extracted." +  (let ((pkg-dir (expand-file-name (package-desc-full-name pkg-desc) temp-dir))) +    (make-directory temp-dir t) +    (with-current-buffer buffer +      (let ((default-directory temp-dir)) +        (package-untar-buffer (package-desc-full-name pkg-desc)))) +    pkg-dir)) + +(defun package--get-installed-package-dir (pkg-desc) +  "Get directory of installed PKG-DESC package." +  (expand-file-name (package-desc-full-name pkg-desc) package-user-dir)) + +(defun package--show-package-diff (old-dir new-dir) +  "Show diff between OLD-DIR and NEW-DIR package directories. +Return t if user confirms to continue, nil to cancel." +  (let ((diff-buffer "*Package Diff*")) +    (with-current-buffer (get-buffer-create diff-buffer) +      (erase-buffer) +      (let ((inhibit-read-only t) +            (exit-status (call-process "diff" nil t nil "-ru" old-dir new-dir))) +        (cond +         ((eq exit-status 0) +          (insert "No differences found between old and new package versions.\n")) +         ((eq exit-status 1) +          ;; Normal case: differences found, they're already in buffer +          nil) +         (t +          ;; Error case +          (insert (format "Error running diff (exit status %d).\n" exit-status))))) +      (diff-mode) +      (read-only-mode 1) +      (goto-char (point-min))) +    (display-buffer diff-buffer) +    (let ((response (yes-or-no-p "Show differences. Continue with upgrade? "))) +      (kill-buffer diff-buffer) +      response))) + +(defun package--confirm-tarball-upgrade (pkg-desc new-pkg-desc) +  "Show diff for tarball package upgrade and ask for confirmation. +Return t if user wants to proceed, nil otherwise." +  ;; Check exclusion lists first +  (let ((package-name (package-desc-name new-pkg-desc)) +        (package-archive (package-desc-archive new-pkg-desc))) +    ;; If package-show-upgrade-diffs is nil, or package/archive is excluded, proceed without diffs +    (if (or (not package-show-upgrade-diffs) +            (memq package-name package-upgrade-diff-exclude-packages) +            (member package-archive package-upgrade-diff-exclude-archives)) +        t  ; Skip diff checking, proceed with upgrade +      (let* ((temp-dir (make-temp-file "package-diff-" t)) +             (old-dir (package--get-installed-package-dir pkg-desc)) +             new-dir) +        (unwind-protect +            (progn +              ;; Download and extract new version to temp directory +              (let* ((location (package-archive-base new-pkg-desc)) +                     (file (concat (package-desc-full-name new-pkg-desc) +                                   (package-desc-suffix new-pkg-desc)))) +                (package--with-response-buffer location :file file +                  (setq new-dir (package--extract-tarball-to-temp +                                 (current-buffer) new-pkg-desc temp-dir)))) +              ;; Show diff and get user confirmation +              (if (file-exists-p old-dir) +                  (package--show-package-diff old-dir new-dir) +                ;; If no old version exists, just confirm +                (yes-or-no-p "New package installation. Continue? "))) +          ;; Clean up temp directory +          (when (file-exists-p temp-dir) +            (delete-directory temp-dir t))))))) +  (defun package-unpack (pkg-desc)    "Install the contents of the current buffer as a package."    (let* ((name (package-desc-name pkg-desc)) @@ -2290,16 +2399,31 @@ package-upgrade                    (package--upgradeable-packages t) nil t))))    (cl-check-type name symbol)    (let* ((pkg-desc (cadr (assq name package-alist))) -         (package-install-upgrade-built-in (not pkg-desc))) +         (package-install-upgrade-built-in (not pkg-desc)) +         (new-pkg-desc (cadr (assq name package-archive-contents))))      ;; `pkg-desc' will be nil when the package is an "active built-in".      (if (and pkg-desc (package-vc-p pkg-desc))          (package-vc-upgrade pkg-desc) -      (when pkg-desc -        (package-delete pkg-desc 'force 'dont-unselect)) -      (package-install name -                       ;; An active built-in has never been "selected" -                       ;; before.  Mark it as installed explicitly. -                       (and pkg-desc 'dont-select))))) +      ;; Check if this is a tarball package upgrade that needs diff confirmation +      (if (and pkg-desc new-pkg-desc +               (eq (package-desc-kind new-pkg-desc) 'tar)) +          ;; For tarball packages, show diff and ask for confirmation +          (if (package--confirm-tarball-upgrade pkg-desc new-pkg-desc) +              (progn +                (package-delete pkg-desc 'force 'dont-unselect) +                (package-install name +                                 ;; An active built-in has never been "selected" +                                 ;; before.  Mark it as installed explicitly. +                                 (and pkg-desc 'dont-select))) +            (message "Package upgrade cancelled")) +        ;; For non-tarball packages, proceed with normal upgrade +        (progn +          (when pkg-desc +            (package-delete pkg-desc 'force 'dont-unselect)) +          (package-install name +                           ;; An active built-in has never been "selected" +                           ;; before.  Mark it as installed explicitly. +                           (and pkg-desc 'dont-select)))))))  (defun package--upgradeable-packages (&optional include-builtins)    ;; Initialize the package system to get the list of package @@ -2688,16 +2812,16 @@ package-isolate  in a clean environment."    (interactive     (cl-loop for p in (cl-loop for p in (package--alist) append (cdr p)) -        unless (package-built-in-p p) -        collect (cons (package-desc-full-name p) p) into table -        finally return -        (list +            unless (package-built-in-p p) +            collect (cons (package-desc-full-name p) p) into table +            finally return +            (list               (cl-loop for c in                        (completing-read-multiple                         "Packages to isolate: " table                         nil t) -                   collect (alist-get c table nil nil #'string=)) -                  current-prefix-arg))) +                      collect (alist-get c table nil nil #'string=)) +             current-prefix-arg)))    (let* ((name (concat "package-isolate-"                         (mapconcat #'package-desc-full-name packages ",")))           (all-packages (delete-consecutive-dups @@ -4172,9 +4296,18 @@ package-menu--perform-transaction                    (format status-format (incf i)))              (force-mode-line-update)              (redisplay 'force) -            ;; Don't mark as selected, `package-menu-execute' already -            ;; does that. -            (package-install pkg 'dont-select)))) +            ;; Check if this is a tarball package upgrade and needs confirmation +            (let* ((pkg-name (package-desc-name pkg)) +                   (old-pkg (cl-find-if (lambda (del-pkg) +                                          (eq (package-desc-name del-pkg) pkg-name)) +                                        delete-list))) +              (if (and old-pkg (eq (package-desc-kind pkg) 'tar)) +                  ;; This is a tarball upgrade - ask for confirmation +                  (if (package--confirm-tarball-upgrade old-pkg pkg) +                      (package-install pkg 'dont-select) +                    (push (package-desc-full-name pkg) errors)) +                ;; Normal installation +                (package-install pkg 'dont-select))))))      (let ((package-menu--transaction-status ":Deleting"))        (force-mode-line-update)        (redisplay 'force) -- 2.43.0 From unknown Fri Sep 19 04:01:23 2025 X-Loop: help-debbugs@gnu.org Subject: bug#74604: [PATCH v1] package.el: Add diff display and confirmation for package upgrades (Bug#74604) Resent-From: Philip Kaludercic Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Tue, 02 Sep 2025 15:39:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 74604 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: To: Nobuyuki Kamimoto Cc: Daniel Mendler , 74604@debbugs.gnu.org Received: via spool by 74604-submit@debbugs.gnu.org id=B74604.175682753923370 (code B ref 74604); Tue, 02 Sep 2025 15:39:02 +0000 Received: (at 74604) by debbugs.gnu.org; 2 Sep 2025 15:38:59 +0000 Received: from localhost ([127.0.0.1]:35958 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1utT61-00064p-1b for submit@debbugs.gnu.org; Tue, 02 Sep 2025 11:38:58 -0400 Received: from mout02.posteo.de ([185.67.36.66]:54733) by debbugs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.84_2) (envelope-from ) id 1utT5u-00064O-UZ for 74604@debbugs.gnu.org; Tue, 02 Sep 2025 11:38:53 -0400 Received: from submission (posteo.de [185.67.36.169]) by mout02.posteo.de (Postfix) with ESMTPS id 639CB240101 for <74604@debbugs.gnu.org>; Tue, 2 Sep 2025 17:38:43 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=posteo.net; s=2017; t=1756827523; bh=jRs+dU2HTR/MftZLoctAFRlMWmyE5ojRjo6iNDDSgYY=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version:Content-Type: Content-Transfer-Encoding:From; b=NGDbmXnysOuQn25x4uigDkNXLuhRj7TCTHChwttwV61xdcQJvZOfELFwg3buki9SA WNlVd+QJrOEkPFbyNVHFqVYZ0TNI/flkcrsvTL54yi8sNx3tK6woYj9vYwnNmZ3Li0 OL+YcgycSb5oz5jnOMk0S4oHEjlTMOXvs+he82N/Dz6oQDVWXdF+1yrL0xac7kxX39 lJualHSawW+kVfa75jZwrkkCE8L6rBcHEydIA/kqwrhqtZqRZEh1BmdaIzaGt9zD6n +sdnyE56u9gzw1CLWf22G4ge9qoKuGjCm38WNnNzt308vTHCHffk++hjmRK34ANYgg g23KJe3wgI3SA== Received: from customer (localhost [127.0.0.1]) by submission (posteo.de) with ESMTPSA id 4cGVJf1knhz9rxB; Tue, 2 Sep 2025 17:38:42 +0200 (CEST) From: Philip Kaludercic In-Reply-To: <54fadfd1-21f6-48cb-a17e-8d0878a68f1d@gmail.com> References: <87h67quk0g.fsf@daniel-mendler.de> <54fadfd1-21f6-48cb-a17e-8d0878a68f1d@gmail.com> Date: Tue, 02 Sep 2025 15:38:42 +0000 Message-ID: <87ldmweuf2.fsf@posteo.net> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-Spam-Score: -2.3 (--) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -3.3 (---) Nobuyuki Kamimoto writes: > Hello, > > This patch implements a new feature for package upgrades, as discussed > in Bug#74604. Thanks! I have added Daniel to the CCs as he was involved in the discussion you reference, and I assume is interested in the discussion. > Summary: > - Shows diffs between the installed and the new version of a package > =C2=A0 before upgrading. > - Lets the user review changes and confirm whether to proceed. > - Supports both regular tarball packages and VC packages. > - New user options: > =C2=A0 - package-show-upgrade-diffs > =C2=A0 - package-upgrade-diff-exclude-packages > =C2=A0 - package-upgrade-diff-exclude-archives > =C2=A0 - package-vc-show-upgrade-diffs > =C2=A0 - package-vc-upgrade-diff-exclude-packages This is already implemented in package-vc, but in a different way. With `package-vc-log-incoming' you get a log of all the changes that will be pulled in. The interface is not exactly the same, but I would rather we avoid duplicating the functionality in similar but inconsistent ways. > - Updated documentation (doc/emacs/package.texi). > - Added entry to etc/NEWS. > > Testing: > - Built Emacs from the patched branch. > - Verified interactive upgrade of both tarball and VC packages. > - Ran `make check` and confirmed tests pass. > > See Bug#74604 for context. > > Best regards, > Nobuyuki Kamimoto > > > ---8<---cut here---8<--- > From f1793d5c62b194c37a61d8d4d02b655dc8b714c3 Mon Sep 17 00:00:00 2001 > From: Nobuyuki Kamimoto > Date: Sun, 31 Aug 2025 12:08:50 +0900 > Subject: [PATCH] Add diff display and confirmation for package upgrades > > Show differences between current and new versions before upgrading > packages, allowing users to review changes and choose whether to > proceed. This applies to both regular packages and VC packages. > > * lisp/emacs-lisp/package.el (package-show-upgrade-diffs) > (package-upgrade-diff-exclude-packages) > (package-upgrade-diff-exclude-archives): New user options to control > diff display for package upgrades. > (package--extract-tarball-to-temp, package--get-installed-package-dir) > (package--show-package-diff, package--confirm-tarball-upgrade): New > functions to handle diff display and confirmation for tarball upgrades. > (package-upgrade): Check if tarball package upgrade needs confirmation. > (package-menu--perform-transaction): Handle diff confirmation in menu. > > * lisp/emacs-lisp/package-vc.el (package-vc-show-upgrade-diffs) > (package-vc-upgrade-diff-exclude-packages): New user options to control > diff display for VC package upgrades. > (package-vc--show-diff, package-vc--confirm-upgrade): New functions to > handle diff display and confirmation for VC package upgrades. > (package-vc-upgrade): Integrate diff confirmation into upgrade process. > > * doc/emacs/package.texi (Package Installation): Document the new diff > display functionality for both regular and VC package upgrades, > including the new user options for controlling the behavior. > > * etc/NEWS: Add announcement for the new package upgrade diff feature. > --- > =C2=A0doc/emacs/package.texi=C2=A0 =C2=A0 =C2=A0 =C2=A0 |=C2=A0 37 +++++= +++ > =C2=A0etc/NEWS=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 |=C2=A0 16 ++++ > =C2=A0lisp/emacs-lisp/package-vc.el | 140 ++++++++++++++++++++++------- > =C2=A0lisp/emacs-lisp/package.el=C2=A0 =C2=A0 | 165 ++++++++++++++++++++= ++++++++++---- > =C2=A04 files changed, 308 insertions(+), 50 deletions(-) Just a general comment, your message appears to have a number of non-breaking whitespaces (0xA0). Can you try to attach your patch in the future, to avoid these kinds of problems in the future? > > diff --git a/doc/emacs/package.texi b/doc/emacs/package.texi > index c29beea3b08..1f57910a207 100644 > --- a/doc/emacs/package.texi > +++ b/doc/emacs/package.texi > @@ -389,6 +389,25 @@ Package Installation > =C2=A0use these bulk commands if you want to update only a small number = of > =C2=A0built-in packages. > > +@vindex package-show-upgrade-diffs > +@vindex package-upgrade-diff-exclude-packages > +@vindex package-upgrade-diff-exclude-archives > +=C2=A0 By default, Emacs shows a diff of the changes when upgrading > +packages, allowing you to review what has changed between the current > +and new version before proceeding.=C2=A0 This is controlled by the > +@code{package-show-upgrade-diffs} variable.=C2=A0 When non-@code{nil} (t= he ^ user-option > +default), package upgrades will display the differences and ask for > +confirmation before proceeding.=C2=A0 You can disable this behavior by > +setting @code{package-show-upgrade-diffs} to @code{nil}. > + > +=C2=A0 You can exclude specific packages or package archives from diff > +checking using @code{package-upgrade-diff-exclude-packages} and > +@code{package-upgrade-diff-exclude-archives}.=C2=A0 The first variable > +takes a list of package names (as symbols), while the second takes a > +list of archive names (as strings).=C2=A0 Packages or archives in these > +lists will upgrade without showing diffs, even when > +@code{package-show-upgrade-diffs} is non-@code{nil}. > + > =C2=A0@cindex package requirements > =C2=A0 =C2=A0A package may @dfn{require} certain other packages to be in= stalled, > =C2=A0because it relies on functionality provided by them.=C2=A0 When Em= acs > @@ -645,6 +664,24 @@ Fetching Package Sources > =C2=A0 =C2=A0Note that currently, built-in packages cannot be upgraded u= sing > =C2=A0@code{package-vc-install}. > > +@vindex package-vc-show-upgrade-diffs > +@vindex package-vc-upgrade-diff-exclude-packages > +=C2=A0 Like regular package upgrades, VC package upgrades can also show > +diffs before proceeding.=C2=A0 This is controlled by the > +@code{package-vc-show-upgrade-diffs} variable, which operates > +independently of @code{package-show-upgrade-diffs}.=C2=A0 When > +non-@code{nil} (the default), upgrading VC packages will display the > +differences between the current and updated versions, allowing you to > +review the changes before confirming the upgrade. > + > +=C2=A0 You can exclude specific VC packages from diff checking by adding > +their names (as symbols) to=20 > @code{package-vc-upgrade-diff-exclude-packages}. > +Packages in this list will upgrade without showing diffs, even when > +@code{package-vc-show-upgrade-diffs} is non-@code{nil}.=C2=A0 This > +exclusion list is separate from=20 > @code{package-upgrade-diff-exclude-packages} > +to allow independent control over diff behavior for VC packages versus > +regular packages. > + > =C2=A0@findex package-report-bug > =C2=A0@findex package-vc-prepare-patch > =C2=A0 =C2=A0With the source checkout, you might want to reproduce a bug= against > > diff --git a/etc/NEWS b/etc/NEWS > index 8a139cb03ca..2fdbd1c291f 100644 > --- a/etc/NEWS > +++ b/etc/NEWS > @@ -74,6 +74,22 @@ done from early-init.el, such as adding to=20 > 'package-directory-list'. > =C2=A0** 'prettify-symbols-mode' attempts to ignore undisplayable charac= ters. > =C2=A0Previously, such characters would be rendered as, e.g., white boxe= s. > > ++++ > +** Package management now shows diffs before upgrades. > +Package upgrades can now display differences between the current and > +new version before proceeding.=C2=A0 This applies to both regular packag= es > +and VC packages installed from version control repositories. > + > +The behavior is controlled by these new user options: > +- 'package-show-upgrade-diffs': Enable/disable diff display for regular= =20 > packages > +- 'package-vc-show-upgrade-diffs': Enable/disable diff display for VC=20 > packages > +- 'package-upgrade-diff-exclude-packages': Exclude specific packages=20 > from diff checking > +- 'package-upgrade-diff-exclude-archives': Exclude specific archives=20 > from diff checking > +- 'package-vc-upgrade-diff-exclude-packages': Exclude specific VC=20 > packages from diff checking > + > +When enabled (the default), users will see a diff buffer showing changes > +and can choose whether to proceed with or cancel the upgrade. This description is probably a bit too detailed for a NEWS entry. I would not go into the new user options is that great of a detail. Also, if we decide to enable this by default (which I am not certain of right now), the news entry should be more clear in what the change is that will affect all users: For instance, it is not "can now display" but "will now display". > + > =C2=A0+++ > =C2=A0** 'standard-display-table' now has more extra slots. > =C2=A0'standard-display-table' has been extended to allow specifying gly= phs > > diff --git a/lisp/emacs-lisp/package-vc.el b/lisp/emacs-lisp/package-vc.el > index 7433fce2d89..da9977b429f 100644 > --- a/lisp/emacs-lisp/package-vc.el > +++ b/lisp/emacs-lisp/package-vc.el > @@ -83,6 +83,27 @@ package-vc-register-as-project > =C2=A0 =C2=A0:type 'boolean > =C2=A0 =C2=A0:version "30.1") > > +(defcustom package-vc-show-upgrade-diffs t > +=C2=A0 "Non-nil means to show diffs before upgrading VC packages. > +This controls whether VC package upgrades show a diff buffer > +comparing the current and updated versions of the package before > +proceeding with the upgrade.=C2=A0 This is independent of the > +`package-show-upgrade-diffs' variable which controls diff > +display for regular package upgrades." > +=C2=A0 :type 'boolean > +=C2=A0 :group 'package-vc (General: You don't need to specify the group, `defcustom' will by default re-use the last group defined at macro-expansion time.) > +=C2=A0 :version "31.1") > + > +(defcustom package-vc-upgrade-diff-exclude-packages nil > +=C2=A0 "List of VC package names to exclude from upgrade diff checking. > +This list contains package names (as symbols) for which diff checking > +should be skipped when upgrading VC packages.=C2=A0 This is separate from > +`package-upgrade-diff-exclude-packages' to allow independent control > +of diff exclusions for VC packages versus regular package upgrades." > +=C2=A0 :type '(repeat symbol) > +=C2=A0 :group 'package-vc > +=C2=A0 :version "31.1") > + > =C2=A0(defvar package-vc-selected-packages) ; pacify byte-compiler > > =C2=A0;;;###autoload > @@ -729,6 +750,55 @@ package-vc-upgrade-all > =C2=A0(declare-function vc-dir-prepare-status-buffer "vc-dir" > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(bn= ame dir backend &optional create-new)) > > +(defun package-vc--show-diff (old-dir new-dir) > +=C2=A0 "Show diff between OLD-DIR and NEW-DIR package directories. > +Return t if user confirms to continue, nil to cancel." > +=C2=A0 (let ((diff-buffer "*Package VC Diff*")) > +=C2=A0 =C2=A0 (with-current-buffer (get-buffer-create diff-buffer) > +=C2=A0 =C2=A0 =C2=A0 (erase-buffer) > +=C2=A0 =C2=A0 =C2=A0 (let ((inhibit-read-only t) > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (exit-status (call-process "di= ff" nil t nil "-ru" old-dir=20 > new-dir))) > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 (cond > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0((eq exit-status 0) > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (insert "No differences found between= current and updated=20 > package versions.\n")) > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0((eq exit-status 1) > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ;; Normal case: differences found, th= ey're already in buffer > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 nil) > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(t > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ;; Error case > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (insert (format "Error running diff (= exit status %d).\n"=20 > exit-status))))) > +=C2=A0 =C2=A0 =C2=A0 (diff-mode) > +=C2=A0 =C2=A0 =C2=A0 (read-only-mode 1) > +=C2=A0 =C2=A0 =C2=A0 (goto-char (point-min))) > +=C2=A0 =C2=A0 (display-buffer diff-buffer) > +=C2=A0 =C2=A0 (let ((response (yes-or-no-p "Show differences. Continue w= ith=20 > upgrade? "))) > +=C2=A0 =C2=A0 =C2=A0 (kill-buffer diff-buffer) > +=C2=A0 =C2=A0 =C2=A0 response))) > + > +(defun package-vc--confirm-upgrade (pkg-desc) > +=C2=A0 "Show diff for VC package upgrade and ask for confirmation. > +Return t if user wants to proceed, nil otherwise." > +=C2=A0 ;; Check exclusion list first > +=C2=A0 (let ((package-name (package-desc-name pkg-desc))) > +=C2=A0 =C2=A0 ;; If package-vc-show-upgrade-diffs is nil, or package is = excluded,=20 > proceed without diffs > +=C2=A0 =C2=A0 (if (or (not package-vc-show-upgrade-diffs) > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (memq package-name package-vc-= upgrade-diff-exclude-packages)) > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 t=C2=A0 ; Skip diff checking, proceed with u= pgrade > +=C2=A0 =C2=A0 =C2=A0 (let* ((pkg-dir (package-desc-dir pkg-desc)) > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(temp-dir (make-temp-fil= e "package-vc-diff-" t)) > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(pkg-spec (package-vc--d= esc->spec pkg-desc))) > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 ;; Delete temp directory so package-vc--clon= e can create and=20 > populate it > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 (delete-directory temp-dir) > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 (unwind-protect > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (progn > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ;; Clone the updated ve= rsion to temp directory > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (package-vc--clone pkg-= desc pkg-spec temp-dir nil) > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ;; Show diff and get us= er confirmation > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (package-vc--show-diff = pkg-dir temp-dir)) > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ;; Clean up temp directory > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (when (file-exists-p temp-dir) > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (delete-directory temp-dir t))= ))))) > + > =C2=A0;;;###autoload > =C2=A0(defun package-vc-upgrade (pkg-desc) > =C2=A0 =C2=A0"Upgrade the package described by PKG-DESC from package's V= C repository. > @@ -736,40 +806,42 @@ package-vc-upgrade > =C2=A0This may fail if the local VCS state of the package conflicts > =C2=A0with the remote repository state." > =C2=A0 =C2=A0(interactive (list (package-vc--read-package-desc "Upgrade = VC=20 > package: " t))) > -=C2=A0 ;; HACK: To run `package-vc--unpack-1' after checking out the new > -=C2=A0 ;; revision, we insert a hook into `vc-post-command-functions', a= nd > -=C2=A0 ;; remove it right after it ran.=C2=A0 To avoid running the hook = multiple > -=C2=A0 ;; times or even for the wrong repository (as `vc-pull' is often > -=C2=A0 ;; asynchronous), we extract the relevant arguments using a pseudo > -=C2=A0 ;; filter for `vc-filter-command-function', executed only for the > -=C2=A0 ;; side effect, and store them in the lexical scope.=C2=A0 When t= he hook > -=C2=A0 ;; is run, we check if the arguments are the same (`eq') as the o= nes > -=C2=A0 ;; previously extracted, and only in that case will be call > -=C2=A0 ;; `package-vc--unpack-1'.=C2=A0 Ugh... > -=C2=A0 ;; > -=C2=A0 ;; If there is a better way to do this, it should be done. > -=C2=A0 (cl-assert (package-vc-p pkg-desc)) > -=C2=A0 (letrec ((pkg-dir (package-desc-dir pkg-desc)) > -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(vc-flags) > -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(vc-filter-command-function > -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (lambda (command file-or-list = flags) > -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (setq vc-flags flags) > -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (list command file-or-l= ist flags))) > -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(post-upgrade > -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (lambda (_command _file-or-lis= t flags) > -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (when (and (file-equal-= p pkg-dir default-directory) > -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0(eq flags vc-flags)) > -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (unwind-protect > -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (w= ith-demoted-errors "Failed to activate: %S" > -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 (package-vc--unpack-1 pkg-desc pkg-dir)) > -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (remove-h= ook 'vc-post-command-functions=20 > post-upgrade)))))) > -=C2=A0 =C2=A0 (add-hook 'vc-post-command-functions post-upgrade) > -=C2=A0 =C2=A0 (with-demoted-errors "Failed to fetch: %S" > -=C2=A0 =C2=A0 =C2=A0 (require 'vc-dir) > -=C2=A0 =C2=A0 =C2=A0 (with-current-buffer (vc-dir-prepare-status-buffer > -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 (format " *package-vc-dir: %s*" pkg-dir) > -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 pkg-dir (vc-responsible-backend pkg-dir)) > -=C2=A0 =C2=A0 =C2=A0 =C2=A0 (vc-pull))))) > +=C2=A0 ;; Check if user wants to see diff and confirm upgrade > +=C2=A0 (when (package-vc--confirm-upgrade pkg-desc) > +=C2=A0 =C2=A0 ;; HACK: To run `package-vc--unpack-1' after checking out = the new > +=C2=A0 =C2=A0 ;; revision, we insert a hook into `vc-post-command-functi= ons', and > +=C2=A0 =C2=A0 ;; remove it right after it ran.=C2=A0 To avoid running th= e hook multiple > +=C2=A0 =C2=A0 ;; times or even for the wrong repository (as `vc-pull' is= often > +=C2=A0 =C2=A0 ;; asynchronous), we extract the relevant arguments using = a pseudo > +=C2=A0 =C2=A0 ;; filter for `vc-filter-command-function', executed only = for the > +=C2=A0 =C2=A0 ;; side effect, and store them in the lexical scope.=C2=A0= When the hook > +=C2=A0 =C2=A0 ;; is run, we check if the arguments are the same (`eq') a= s the ones > +=C2=A0 =C2=A0 ;; previously extracted, and only in that case will be call > +=C2=A0 =C2=A0 ;; `package-vc--unpack-1'.=C2=A0 Ugh... > +=C2=A0 =C2=A0 ;; > +=C2=A0 =C2=A0 ;; If there is a better way to do this, it should be done. > +=C2=A0 =C2=A0 (cl-assert (package-vc-p pkg-desc)) > +=C2=A0 =C2=A0 (letrec ((pkg-dir (package-desc-dir pkg-desc)) > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(vc-flags) > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(vc-filter-command-funct= ion > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (lambda (command file-o= r-list flags) > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (setq vc-flags f= lags) > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (list command fi= le-or-list flags))) > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(post-upgrade > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (lambda (_command _file= -or-list flags) > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (when (and (file= -equal-p pkg-dir default-directory) > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0(eq flags vc-flags)) > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (unwind-p= rotect > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 (with-demoted-errors "Failed to activate: %S" > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 (package-vc--unpack-1 pkg-desc pkg-dir)) > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (r= emove-hook 'vc-post-command-functions=20 > post-upgrade)))))) > +=C2=A0 =C2=A0 =C2=A0 (add-hook 'vc-post-command-functions post-upgrade) > +=C2=A0 =C2=A0 =C2=A0 (with-demoted-errors "Failed to fetch: %S" > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 (require 'vc-dir) > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 (with-current-buffer (vc-dir-prepare-status-= buffer > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (format " *package-vc-dir: %s*" pkg-dir) > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 pkg-dir (vc-responsible-backend pkg-dir)) > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (vc-pull)))))) I hope it is fine that I will not comment on this file any more, because I am not convinced of the approach (among other things having to make a fresh clone of the entire repository every time the package is being upgraded, which for larger packages like auctex can take a while). That is not to say that I am not open to UI suggestions based on `package-vc-log-incoming', if you want to suggest anything like that. > > =C2=A0(defun package-vc--archives-initialize () > =C2=A0 =C2=A0"Initialize package.el and fetch package specifications." > > diff --git a/lisp/emacs-lisp/package.el b/lisp/emacs-lisp/package.el > index ba9999c20e6..1d1266b7ede 100644 > --- a/lisp/emacs-lisp/package.el > +++ b/lisp/emacs-lisp/package.el > @@ -450,6 +450,44 @@ package-archive-column-width > =C2=A0 =C2=A0:type 'natnum > =C2=A0 =C2=A0:version "28.1") > > +(defcustom package-show-upgrade-diffs t > +=C2=A0 "Whether to show diffs before upgrading packages. > +When non-nil, package upgrades will display the differences between > +the current and new version before proceeding.=C2=A0 Users can review the > +changes and choose whether to continue with the upgrade. > +When nil, packages upgrade without showing diffs." > +=C2=A0 :type 'boolean > +=C2=A0 :group 'package > +=C2=A0 :version "31.1") > + > +(defcustom package-upgrade-diff-exclude-packages nil > +=C2=A0 "List of package names to exclude from diff checking during upgra= des. > +When a package name is in this list, the upgrade will proceed > +without showing diffs, even if `package-show-upgrade-diffs' is non-nil. > +Package names should be specified as symbols. > + > +For example: \\=3D'(emacs magit org-mode) > + > +This allows for fine-grained control over which packages show > +diffs during upgrades." > +=C2=A0 :type '(repeat symbol) > +=C2=A0 :group 'package > +=C2=A0 :version "31.1") > + > +(defcustom package-upgrade-diff-exclude-archives nil > +=C2=A0 "List of package archives to exclude from diff checking during up= grades. > +When a package's archive is in this list, the upgrade will proceed > +without showing diffs, even if `package-show-upgrade-diffs' is non-nil. > +Archive names should be specified as strings. > + > +For example: \\=3D'(\"melpa-stable\" \"nongnu\") > + > +This allows for fine-grained control over which archives show > +diffs during package upgrades." > +=C2=A0 :type '(repeat string) > +=C2=A0 :group 'package > +=C2=A0 :version "31.1") I wonder if instead of having multiple user options, it might be cleaner to replace `package-show-upgrade-diffs' with a non-boolean user option that can select the packages to trust/mistrust, sort of like how `buffer-match-p' can select buffers. So the user option instead a list consisting of (package foo) (archive "bar") entries or t, if you want to mistrust everything. Also, shouldn't we also be able to configure what files to diff?=20=20 Also also, IIRC another discussion from bug#74604 was to allow just prompting the user what packages they want to upgrade. Perhaps we should orient ourselves on `save-some-buffers' and query the user for each package if they want to upgrade it, keep it as is (perhaps even remember this for the future) and/or show a diff. > + > =C2=A0 > =C2=A0;;; `package-desc' object definition > =C2=A0;; This is the struct used internally to represent packages. > @@ -1019,6 +1057,77 @@ package--alist-to-plist-args > > =C2=A0(declare-function dired-get-marked-files "dired") > +(defun package--extract-tarball-to-temp (buffer pkg-desc temp-dir) > +=C2=A0 "Extract tarball from BUFFER to TEMP-DIR for PKG-DESC. > +Returns the directory where package was extracted." > +=C2=A0 (let ((pkg-dir (expand-file-name (package-desc-full-name pkg-desc= )=20 > temp-dir))) > +=C2=A0 =C2=A0 (make-directory temp-dir t) > +=C2=A0 =C2=A0 (with-current-buffer buffer > +=C2=A0 =C2=A0 =C2=A0 (let ((default-directory temp-dir)) > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 (package-untar-buffer (package-desc-full-nam= e pkg-desc)))) > +=C2=A0 =C2=A0 pkg-dir)) > + > +(defun package--get-installed-package-dir (pkg-desc) > +=C2=A0 "Get directory of installed PKG-DESC package." > +=C2=A0 (expand-file-name (package-desc-full-name pkg-desc) package-user-= dir)) > + > +(defun package--show-package-diff (old-dir new-dir) > +=C2=A0 "Show diff between OLD-DIR and NEW-DIR package directories. > +Return t if user confirms to continue, nil to cancel." > +=C2=A0 (let ((diff-buffer "*Package Diff*")) > +=C2=A0 =C2=A0 (with-current-buffer (get-buffer-create diff-buffer) > +=C2=A0 =C2=A0 =C2=A0 (erase-buffer) > +=C2=A0 =C2=A0 =C2=A0 (let ((inhibit-read-only t) > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (exit-status (call-process "di= ff" nil t nil "-ru" old-dir=20 ^ generally, I think it is better to use --long-options to make the code more readab= le. > new-dir))) > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 (cond > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0((eq exit-status 0) > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (insert "No differences found between= old and new package=20 > versions.\n")) > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0((eq exit-status 1) > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ;; Normal case: differences found, th= ey're already in buffer > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 nil) > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(t > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ;; Error case > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (insert (format "Error running diff (= exit status %d).\n"=20 > exit-status))))) > +=C2=A0 =C2=A0 =C2=A0 (diff-mode) Is there a reason you don't just use the `diff' function with NO-ASYNC set to a non-nil value? > +=C2=A0 =C2=A0 =C2=A0 (read-only-mode 1) I think it is interesting to consider not setting the buffer to be read-only by default, as it allows the user to manipulate the diff. This also relates to the fact that the user might have made local adjustment that they might want to keep between upgrades... > +=C2=A0 =C2=A0 =C2=A0 (goto-char (point-min))) > +=C2=A0 =C2=A0 (display-buffer diff-buffer) > +=C2=A0 =C2=A0 (let ((response (yes-or-no-p "Show differences. Continue w= ith ^ What do you mean by show differences here? It sounds imperative, but I am not sure if that is what you mean. > upgrade? "))) > +=C2=A0 =C2=A0 =C2=A0 (kill-buffer diff-buffer) > +=C2=A0 =C2=A0 =C2=A0 response))) You can use `prog1' here to avoid storing `response'. > + > +(defun package--confirm-tarball-upgrade (pkg-desc new-pkg-desc) > +=C2=A0 "Show diff for tarball package upgrade and ask for confirmation. > +Return t if user wants to proceed, nil otherwise." > +=C2=A0 ;; Check exclusion lists first > +=C2=A0 (let ((package-name (package-desc-name new-pkg-desc)) > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 (package-archive (package-desc-archive new-p= kg-desc))) > +=C2=A0 =C2=A0 ;; If package-show-upgrade-diffs is nil, or package/archiv= e is=20 > excluded, proceed without diffs > +=C2=A0 =C2=A0 (if (or (not package-show-upgrade-diffs) > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (memq package-name package-upg= rade-diff-exclude-packages) > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (member package-archive packag= e-upgrade-diff-exclude-archives)) > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 t=C2=A0 ; Skip diff checking, proceed with u= pgrade > +=C2=A0 =C2=A0 =C2=A0 (let* ((temp-dir (make-temp-file "package-diff-" t)) > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(old-dir (package--get-i= nstalled-package-dir pkg-desc)) > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0new-dir) > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 (unwind-protect > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (progn > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ;; Download and extract= new version to temp directory > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (let* ((location (packa= ge-archive-base new-pkg-desc)) > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0(file (concat (package-desc-full-name new-pkg-desc) > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(package-desc-suffix= new-pkg-desc)))) > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (package--with-r= esponse-buffer location :file file > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (setq new= -dir (package--extract-tarball-to-temp > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(current-buffer) new-pkg-de= sc temp-dir)))) > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ;; Show diff and get us= er confirmation > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (if (file-exists-p old-= dir) > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (package-= -show-package-diff old-dir new-dir) > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ;; If no old ver= sion exists, just confirm > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (yes-or-no-p "Ne= w package installation. Continue? "))) > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ;; Clean up temp directory > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (when (file-exists-p temp-dir) > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (delete-directory temp-dir t))= ))))) My preferred approach to solving this would be if we could split `package-install-from-archive' or `package-unpack' into two, allowing us to install the new package without compiling, generating autoloads, and then to resume that part later on. This would require some refactoring, but would allow us to express the upgrade procedure as 1. Fetch the new source but not process it, 2. Compute the diff and present it to the user, 3. If they are fine with the changes, delete old package and finish initialising the package we just downloaded, 4. Otherwise we remove and forget about the code we had just downloaded and keep everything as is. I imagine that this approach should keep the upgrade procedure more uniform and setting aside changes caused by re-indenting code we factor out of existing functionality, result in a simpler upgrade-logic. > + > =C2=A0(defun package-unpack (pkg-desc) > =C2=A0 =C2=A0"Install the contents of the current buffer as a package." > =C2=A0 =C2=A0(let* ((name (package-desc-name pkg-desc)) > @@ -2290,16 +2399,31 @@ package-upgrade > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(pa= ckage--upgradeable-packages t) nil t)))) > =C2=A0 =C2=A0(cl-check-type name symbol) > =C2=A0 =C2=A0(let* ((pkg-desc (cadr (assq name package-alist))) > -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(package-install-upgrade-built-in (not= pkg-desc))) > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(package-install-upgrade-built-in (not= pkg-desc)) > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(new-pkg-desc (cadr (assq name package= -archive-contents)))) > =C2=A0 =C2=A0 =C2=A0;; `pkg-desc' will be nil when the package is an "ac= tive built-in". > =C2=A0 =C2=A0 =C2=A0(if (and pkg-desc (package-vc-p pkg-desc)) > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(package-vc-upgrade pkg-desc) > -=C2=A0 =C2=A0 =C2=A0 (when pkg-desc > -=C2=A0 =C2=A0 =C2=A0 =C2=A0 (package-delete pkg-desc 'force 'dont-unsele= ct)) > -=C2=A0 =C2=A0 =C2=A0 (package-install name > -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0;; An active built-in has never been "selected" > -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0;; before.=C2=A0 Mark it as installed explicitly. > -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0(and pkg-desc 'dont-select))))) > +=C2=A0 =C2=A0 =C2=A0 ;; Check if this is a tarball package upgrade that = needs diff=20 > confirmation > +=C2=A0 =C2=A0 =C2=A0 (if (and pkg-desc new-pkg-desc > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(eq (package-desc= -kind new-pkg-desc) 'tar)) > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ;; For tarball packages, show diff an= d ask for confirmation > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (if (package--confirm-tarball-upgrade= pkg-desc new-pkg-desc) > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (progn > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (package-delete = pkg-desc 'force 'dont-unselect) > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (package-install= name > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0;; An active built-in has n= ever been=20 > "selected" > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0;; before.=C2=A0 Mark it as= installed=20 > explicitly. > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(and pkg-desc 'dont-select)= )) > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (message "Package upgrade canc= elled")) > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 ;; For non-tarball packages, proceed with no= rmal upgrade > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 (progn > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (when pkg-desc > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (package-delete pkg-desc 'forc= e 'dont-unselect)) > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (package-install name > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0;; An active built-in has never been "selected" > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0;; before.=C2=A0 Mark it as installed explicitly. > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0(and pkg-desc 'dont-select))))))) Why shouldn't we prompt the user with a diff for non-tarball upgrades?=20=20 > > =C2=A0(defun package--upgradeable-packages (&optional include-builtins) > =C2=A0 =C2=A0;; Initialize the package system to get the list of package > @@ -2688,16 +2812,16 @@ package-isolate > =C2=A0in a clean environment." > =C2=A0 =C2=A0(interactive > =C2=A0 =C2=A0 (cl-loop for p in (cl-loop for p in (package--alist) appen= d (cdr p)) > -=C2=A0 =C2=A0 =C2=A0 =C2=A0 unless (package-built-in-p p) > -=C2=A0 =C2=A0 =C2=A0 =C2=A0 collect (cons (package-desc-full-name p) p) = into table > -=C2=A0 =C2=A0 =C2=A0 =C2=A0 finally return > -=C2=A0 =C2=A0 =C2=A0 =C2=A0 (list > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 unless (package-built-in-p p) > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 collect (cons (package-desc-fu= ll-name p) p) into table > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 finally return > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (list > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (cl-loop for c in > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0(completing-read-multiple > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 "Packages to isolate: " table > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 nil t) > -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0col= lect (alist-get c table nil nil #'string=3D)) > -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 current-p= refix-arg))) > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 collect (alist-get c table nil nil #'string=3D)) > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0current-prefix-arg))) These are unrelated changes, right? > =C2=A0 =C2=A0(let* ((name (concat "package-isolate-" > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 (mapconcat #'package-desc-full-name packages ","))) > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (all-packages (delete-consecutive-dups > @@ -4172,9 +4296,18 @@ package-menu--perform-transaction > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(fo= rmat status-format (incf i))) > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(force-mode-line-update) > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(redisplay 'force) > -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ;; Don't mark as selected, `pa= ckage-menu-execute' already > -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ;; does that. > -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (package-install pkg 'dont-sel= ect)))) > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ;; Check if this is a tarball = package upgrade and needs=20 > confirmation > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (let* ((pkg-name (package-desc= -name pkg)) > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(ol= d-pkg (cl-find-if (lambda (del-pkg) > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 (eq (package-desc-name=20 > del-pkg) pkg-name)) > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 delet= e-list))) > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (if (and old-pkg (eq (p= ackage-desc-kind pkg) 'tar)) > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ;; This i= s a tarball upgrade - ask for confirmation > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (if (pack= age--confirm-tarball-upgrade old-pkg pkg) > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 (package-install pkg 'dont-select) > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (p= ush (package-desc-full-name pkg) errors)) > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ;; Normal instal= lation > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (package-install= pkg 'dont-select)))))) > =C2=A0 =C2=A0 =C2=A0(let ((package-menu--transaction-status ":Deleting")) > =C2=A0 =C2=A0 =C2=A0 =C2=A0(force-mode-line-update) > =C2=A0 =C2=A0 =C2=A0 =C2=A0(redisplay 'force) Final request, I have just pushed a branch called feature/package-revamp where among other thing I want to split package.el into multiple smaller files and have the package-menu re-use the package-upgrade logic. If everything goes as intended, this will be merged into master at some point. It would be great if you could try to re-base your work on that branch, or at least keep it in mind. --=20 Philip Kaludercic From unknown Fri Sep 19 04:01:23 2025 X-Loop: help-debbugs@gnu.org Subject: bug#74604: [PATCH v1] package.el: Add diff display and confirmation for package upgrades (Bug#74604) Resent-From: Daniel Mendler Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Tue, 02 Sep 2025 19:48:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 74604 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: To: Philip Kaludercic Cc: Nobuyuki Kamimoto , 74604@debbugs.gnu.org Received: via spool by 74604-submit@debbugs.gnu.org id=B74604.17568424367112 (code B ref 74604); Tue, 02 Sep 2025 19:48:02 +0000 Received: (at 74604) by debbugs.gnu.org; 2 Sep 2025 19:47:16 +0000 Received: from localhost ([127.0.0.1]:36751 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1utWyI-0001qa-1u for submit@debbugs.gnu.org; Tue, 02 Sep 2025 15:47:16 -0400 Received: from server.qxqx.de ([2a01:4f8:c012:9177::1]:35419 helo=mail.qxqx.de) by debbugs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.84_2) (envelope-from ) id 1utWyA-0001pa-Hn for 74604@debbugs.gnu.org; Tue, 02 Sep 2025 15:47:12 -0400 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=daniel-mendler.de; s=key; h=Content-Transfer-Encoding:Content-Type: MIME-Version:Message-ID:Date:References:In-Reply-To:Subject:Cc:To:From:Sender :Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help: List-Unsubscribe:List-Subscribe:List-Post:List-Owner:List-Archive; bh=rortp9W2Qzss3gbpJ11t3zcrg4l4sPRksZ3G8FP8MIk=; b=HF4opTZw5OnqiVYPsGkJozB6qa QPXUQ90loYipbnDu2mEgGnONNZYlvOxIOAzPcUYZH9D4kZpWS4uyGn2D0QKBAaPMjh392pOUtq1yi C286sayoUzyOwlogjg3V56wQX10UKVtK0AIhrbc9sHU0cuzQ9rM2G7gY+4heXSdD1kd0=; From: Daniel Mendler In-Reply-To: <87ldmweuf2.fsf@posteo.net> References: <87h67quk0g.fsf@daniel-mendler.de> <54fadfd1-21f6-48cb-a17e-8d0878a68f1d@gmail.com> <87ldmweuf2.fsf@posteo.net> Date: Tue, 02 Sep 2025 21:46:54 +0200 Message-ID: <87ecsovdqp.fsf@daniel-mendler.de> User-Agent: Gnus/5.13 (Gnus v5.13) MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-Spam-Score: -0.7 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.7 (-) Philip Kaludercic writes: > Nobuyuki Kamimoto writes: > >> Hello, >> >> This patch implements a new feature for package upgrades, as discussed >> in Bug#74604. > > Thanks! I have added Daniel to the CCs as he was involved in the > discussion you reference, and I assume is interested in the discussion. Philip, thanks for adding me. I wonder why I haven't received the message earlier on, given that I've created bug#74604. I much appreciate the work on this feature. >> Summary: >> - Shows diffs between the installed and the new version of a package >> =C2=A0 before upgrading. >> - Lets the user review changes and confirm whether to proceed. >> - Supports both regular tarball packages and VC packages. >> - New user options: >> =C2=A0 - package-show-upgrade-diffs >> =C2=A0 - package-upgrade-diff-exclude-packages >> =C2=A0 - package-upgrade-diff-exclude-archives >> =C2=A0 - package-vc-show-upgrade-diffs >> =C2=A0 - package-vc-upgrade-diff-exclude-packages > > This is already implemented in package-vc, but in a different way. With > `package-vc-log-incoming' you get a log of all the changes that will be > pulled in. The interface is not exactly the same, but I would rather we > avoid duplicating the functionality in similar but inconsistent ways. I don't see how the package-vc-log-incoming functionality could be reused here. package-vc-log-incoming simply calls vc-log-incoming, but this new feature does not rely vc? >> - Updated documentation (doc/emacs/package.texi). >> - Added entry to etc/NEWS. >> >> Testing: >> - Built Emacs from the patched branch. >> - Verified interactive upgrade of both tarball and VC packages. >> - Ran `make check` and confirmed tests pass. >> >> See Bug#74604 for context. >> >> Best regards, >> Nobuyuki Kamimoto >> >> >> ---8<---cut here---8<--- >> From f1793d5c62b194c37a61d8d4d02b655dc8b714c3 Mon Sep 17 00:00:00 2001 >> From: Nobuyuki Kamimoto >> Date: Sun, 31 Aug 2025 12:08:50 +0900 >> Subject: [PATCH] Add diff display and confirmation for package upgrades >> >> Show differences between current and new versions before upgrading >> packages, allowing users to review changes and choose whether to >> proceed. This applies to both regular packages and VC packages. >> >> * lisp/emacs-lisp/package.el (package-show-upgrade-diffs) >> (package-upgrade-diff-exclude-packages) >> (package-upgrade-diff-exclude-archives): New user options to control >> diff display for package upgrades. >> (package--extract-tarball-to-temp, package--get-installed-package-dir) >> (package--show-package-diff, package--confirm-tarball-upgrade): New >> functions to handle diff display and confirmation for tarball upgrades. >> (package-upgrade): Check if tarball package upgrade needs confirmation. >> (package-menu--perform-transaction): Handle diff confirmation in menu. >> >> * lisp/emacs-lisp/package-vc.el (package-vc-show-upgrade-diffs) >> (package-vc-upgrade-diff-exclude-packages): New user options to control >> diff display for VC package upgrades. >> (package-vc--show-diff, package-vc--confirm-upgrade): New functions to >> handle diff display and confirmation for VC package upgrades. >> (package-vc-upgrade): Integrate diff confirmation into upgrade process. >> >> * doc/emacs/package.texi (Package Installation): Document the new diff >> display functionality for both regular and VC package upgrades, >> including the new user options for controlling the behavior. >> >> * etc/NEWS: Add announcement for the new package upgrade diff feature. >> --- >> =C2=A0doc/emacs/package.texi=C2=A0 =C2=A0 =C2=A0 =C2=A0 |=C2=A0 37 ++++= ++++ >> =C2=A0etc/NEWS=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 |=C2=A0 16 ++++ >> =C2=A0lisp/emacs-lisp/package-vc.el | 140 ++++++++++++++++++++++------- >> =C2=A0lisp/emacs-lisp/package.el=C2=A0 =C2=A0 | 165 +++++++++++++++++++= +++++++++++---- >> =C2=A04 files changed, 308 insertions(+), 50 deletions(-) > > Just a general comment, your message appears to have a number of > non-breaking whitespaces (0xA0). Can you try to attach your patch in > the future, to avoid these kinds of problems in the future? > >> >> diff --git a/doc/emacs/package.texi b/doc/emacs/package.texi >> index c29beea3b08..1f57910a207 100644 >> --- a/doc/emacs/package.texi >> +++ b/doc/emacs/package.texi >> @@ -389,6 +389,25 @@ Package Installation >> =C2=A0use these bulk commands if you want to update only a small number= of >> =C2=A0built-in packages. >> >> +@vindex package-show-upgrade-diffs >> +@vindex package-upgrade-diff-exclude-packages >> +@vindex package-upgrade-diff-exclude-archives >> +=C2=A0 By default, Emacs shows a diff of the changes when upgrading >> +packages, allowing you to review what has changed between the current >> +and new version before proceeding.=C2=A0 This is controlled by the >> +@code{package-show-upgrade-diffs} variable.=C2=A0 When non-@code{nil} (= the > ^ > user-option > >> +default), package upgrades will display the differences and ask for >> +confirmation before proceeding.=C2=A0 You can disable this behavior by >> +setting @code{package-show-upgrade-diffs} to @code{nil}. >> + >> +=C2=A0 You can exclude specific packages or package archives from diff >> +checking using @code{package-upgrade-diff-exclude-packages} and >> +@code{package-upgrade-diff-exclude-archives}.=C2=A0 The first variable >> +takes a list of package names (as symbols), while the second takes a >> +list of archive names (as strings).=C2=A0 Packages or archives in these >> +lists will upgrade without showing diffs, even when >> +@code{package-show-upgrade-diffs} is non-@code{nil}. >> + >> =C2=A0@cindex package requirements >> =C2=A0 =C2=A0A package may @dfn{require} certain other packages to be i= nstalled, >> =C2=A0because it relies on functionality provided by them.=C2=A0 When E= macs >> @@ -645,6 +664,24 @@ Fetching Package Sources >> =C2=A0 =C2=A0Note that currently, built-in packages cannot be upgraded = using >> =C2=A0@code{package-vc-install}. >> >> +@vindex package-vc-show-upgrade-diffs >> +@vindex package-vc-upgrade-diff-exclude-packages >> +=C2=A0 Like regular package upgrades, VC package upgrades can also show >> +diffs before proceeding.=C2=A0 This is controlled by the >> +@code{package-vc-show-upgrade-diffs} variable, which operates >> +independently of @code{package-show-upgrade-diffs}.=C2=A0 When >> +non-@code{nil} (the default), upgrading VC packages will display the >> +differences between the current and updated versions, allowing you to >> +review the changes before confirming the upgrade. >> + >> +=C2=A0 You can exclude specific VC packages from diff checking by adding >> +their names (as symbols) to=20 >> @code{package-vc-upgrade-diff-exclude-packages}. >> +Packages in this list will upgrade without showing diffs, even when >> +@code{package-vc-show-upgrade-diffs} is non-@code{nil}.=C2=A0 This >> +exclusion list is separate from=20 >> @code{package-upgrade-diff-exclude-packages} >> +to allow independent control over diff behavior for VC packages versus >> +regular packages. >> + >> =C2=A0@findex package-report-bug >> =C2=A0@findex package-vc-prepare-patch >> =C2=A0 =C2=A0With the source checkout, you might want to reproduce a bu= g against >> >> diff --git a/etc/NEWS b/etc/NEWS >> index 8a139cb03ca..2fdbd1c291f 100644 >> --- a/etc/NEWS >> +++ b/etc/NEWS >> @@ -74,6 +74,22 @@ done from early-init.el, such as adding to=20 >> 'package-directory-list'. >> =C2=A0** 'prettify-symbols-mode' attempts to ignore undisplayable chara= cters. >> =C2=A0Previously, such characters would be rendered as, e.g., white box= es. >> >> ++++ >> +** Package management now shows diffs before upgrades. >> +Package upgrades can now display differences between the current and >> +new version before proceeding.=C2=A0 This applies to both regular packa= ges >> +and VC packages installed from version control repositories. >> + >> +The behavior is controlled by these new user options: >> +- 'package-show-upgrade-diffs': Enable/disable diff display for regular= =20 >> packages >> +- 'package-vc-show-upgrade-diffs': Enable/disable diff display for VC=20 >> packages >> +- 'package-upgrade-diff-exclude-packages': Exclude specific packages=20 >> from diff checking >> +- 'package-upgrade-diff-exclude-archives': Exclude specific archives=20 >> from diff checking >> +- 'package-vc-upgrade-diff-exclude-packages': Exclude specific VC=20 >> packages from diff checking >> + >> +When enabled (the default), users will see a diff buffer showing changes >> +and can choose whether to proceed with or cancel the upgrade. > > This description is probably a bit too detailed for a NEWS entry. I > would not go into the new user options is that great of a detail. > > Also, if we decide to enable this by default (which I am not certain of > right now), the news entry should be more clear in what the change is > that will affect all users: For instance, it is not "can now display" > but "will now display". Yes, the feature should not be enabled by default, only via user option. We could consider adding an option to the package installation confirmation. Instead of pressing y and n, the user could press d to see the diff. >> + >> =C2=A0+++ >> =C2=A0** 'standard-display-table' now has more extra slots. >> =C2=A0'standard-display-table' has been extended to allow specifying gl= yphs >> >> diff --git a/lisp/emacs-lisp/package-vc.el b/lisp/emacs-lisp/package-vc.= el >> index 7433fce2d89..da9977b429f 100644 >> --- a/lisp/emacs-lisp/package-vc.el >> +++ b/lisp/emacs-lisp/package-vc.el >> @@ -83,6 +83,27 @@ package-vc-register-as-project >> =C2=A0 =C2=A0:type 'boolean >> =C2=A0 =C2=A0:version "30.1") >> >> +(defcustom package-vc-show-upgrade-diffs t >> +=C2=A0 "Non-nil means to show diffs before upgrading VC packages. >> +This controls whether VC package upgrades show a diff buffer >> +comparing the current and updated versions of the package before >> +proceeding with the upgrade.=C2=A0 This is independent of the >> +`package-show-upgrade-diffs' variable which controls diff >> +display for regular package upgrades." >> +=C2=A0 :type 'boolean >> +=C2=A0 :group 'package-vc > > (General: You don't need to specify the group, `defcustom' will by > default re-use the last group defined at macro-expansion time.) > >> +=C2=A0 :version "31.1") >> + >> +(defcustom package-vc-upgrade-diff-exclude-packages nil >> +=C2=A0 "List of VC package names to exclude from upgrade diff checking. >> +This list contains package names (as symbols) for which diff checking >> +should be skipped when upgrading VC packages.=C2=A0 This is separate fr= om >> +`package-upgrade-diff-exclude-packages' to allow independent control >> +of diff exclusions for VC packages versus regular package upgrades." >> +=C2=A0 :type '(repeat symbol) >> +=C2=A0 :group 'package-vc >> +=C2=A0 :version "31.1") >> + >> =C2=A0(defvar package-vc-selected-packages) ; pacify byte-compiler >> >> =C2=A0;;;###autoload >> @@ -729,6 +750,55 @@ package-vc-upgrade-all >> =C2=A0(declare-function vc-dir-prepare-status-buffer "vc-dir" >> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(b= name dir backend &optional create-new)) >> >> +(defun package-vc--show-diff (old-dir new-dir) >> +=C2=A0 "Show diff between OLD-DIR and NEW-DIR package directories. >> +Return t if user confirms to continue, nil to cancel." >> +=C2=A0 (let ((diff-buffer "*Package VC Diff*")) >> +=C2=A0 =C2=A0 (with-current-buffer (get-buffer-create diff-buffer) >> +=C2=A0 =C2=A0 =C2=A0 (erase-buffer) >> +=C2=A0 =C2=A0 =C2=A0 (let ((inhibit-read-only t) >> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (exit-status (call-process "d= iff" nil t nil "-ru" old-dir=20 >> new-dir))) >> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 (cond >> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0((eq exit-status 0) >> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (insert "No differences found betwee= n current and updated=20 >> package versions.\n")) >> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0((eq exit-status 1) >> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ;; Normal case: differences found, t= hey're already in buffer >> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 nil) >> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(t >> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ;; Error case >> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (insert (format "Error running diff = (exit status %d).\n"=20 >> exit-status))))) >> +=C2=A0 =C2=A0 =C2=A0 (diff-mode) >> +=C2=A0 =C2=A0 =C2=A0 (read-only-mode 1) >> +=C2=A0 =C2=A0 =C2=A0 (goto-char (point-min))) >> +=C2=A0 =C2=A0 (display-buffer diff-buffer) >> +=C2=A0 =C2=A0 (let ((response (yes-or-no-p "Show differences. Continue = with=20 >> upgrade? "))) >> +=C2=A0 =C2=A0 =C2=A0 (kill-buffer diff-buffer) >> +=C2=A0 =C2=A0 =C2=A0 response))) >> + >> +(defun package-vc--confirm-upgrade (pkg-desc) >> +=C2=A0 "Show diff for VC package upgrade and ask for confirmation. >> +Return t if user wants to proceed, nil otherwise." >> +=C2=A0 ;; Check exclusion list first >> +=C2=A0 (let ((package-name (package-desc-name pkg-desc))) >> +=C2=A0 =C2=A0 ;; If package-vc-show-upgrade-diffs is nil, or package is= excluded,=20 >> proceed without diffs >> +=C2=A0 =C2=A0 (if (or (not package-vc-show-upgrade-diffs) >> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (memq package-name package-vc= -upgrade-diff-exclude-packages)) >> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 t=C2=A0 ; Skip diff checking, proceed with = upgrade >> +=C2=A0 =C2=A0 =C2=A0 (let* ((pkg-dir (package-desc-dir pkg-desc)) >> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(temp-dir (make-temp-fi= le "package-vc-diff-" t)) >> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(pkg-spec (package-vc--= desc->spec pkg-desc))) >> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 ;; Delete temp directory so package-vc--clo= ne can create and=20 >> populate it >> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 (delete-directory temp-dir) >> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 (unwind-protect >> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (progn >> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ;; Clone the updated v= ersion to temp directory >> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (package-vc--clone pkg= -desc pkg-spec temp-dir nil) >> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ;; Show diff and get u= ser confirmation >> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (package-vc--show-diff= pkg-dir temp-dir)) >> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ;; Clean up temp directory >> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (when (file-exists-p temp-dir) >> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (delete-directory temp-dir t)= )))))) >> + >> =C2=A0;;;###autoload >> =C2=A0(defun package-vc-upgrade (pkg-desc) >> =C2=A0 =C2=A0"Upgrade the package described by PKG-DESC from package's = VC repository. >> @@ -736,40 +806,42 @@ package-vc-upgrade >> =C2=A0This may fail if the local VCS state of the package conflicts >> =C2=A0with the remote repository state." >> =C2=A0 =C2=A0(interactive (list (package-vc--read-package-desc "Upgrade= VC=20 >> package: " t))) >> -=C2=A0 ;; HACK: To run `package-vc--unpack-1' after checking out the new >> -=C2=A0 ;; revision, we insert a hook into `vc-post-command-functions', = and >> -=C2=A0 ;; remove it right after it ran.=C2=A0 To avoid running the hook= multiple >> -=C2=A0 ;; times or even for the wrong repository (as `vc-pull' is often >> -=C2=A0 ;; asynchronous), we extract the relevant arguments using a pseu= do >> -=C2=A0 ;; filter for `vc-filter-command-function', executed only for the >> -=C2=A0 ;; side effect, and store them in the lexical scope.=C2=A0 When = the hook >> -=C2=A0 ;; is run, we check if the arguments are the same (`eq') as the = ones >> -=C2=A0 ;; previously extracted, and only in that case will be call >> -=C2=A0 ;; `package-vc--unpack-1'.=C2=A0 Ugh... >> -=C2=A0 ;; >> -=C2=A0 ;; If there is a better way to do this, it should be done. >> -=C2=A0 (cl-assert (package-vc-p pkg-desc)) >> -=C2=A0 (letrec ((pkg-dir (package-desc-dir pkg-desc)) >> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(vc-flags) >> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(vc-filter-command-function >> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (lambda (command file-or-list= flags) >> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (setq vc-flags flags) >> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (list command file-or-= list flags))) >> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(post-upgrade >> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (lambda (_command _file-or-li= st flags) >> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (when (and (file-equal= -p pkg-dir default-directory) >> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0(eq flags vc-flags)) >> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (unwind-protect >> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (= with-demoted-errors "Failed to activate: %S" >> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 (package-vc--unpack-1 pkg-desc pkg-dir)) >> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (remove-= hook 'vc-post-command-functions=20 >> post-upgrade)))))) >> -=C2=A0 =C2=A0 (add-hook 'vc-post-command-functions post-upgrade) >> -=C2=A0 =C2=A0 (with-demoted-errors "Failed to fetch: %S" >> -=C2=A0 =C2=A0 =C2=A0 (require 'vc-dir) >> -=C2=A0 =C2=A0 =C2=A0 (with-current-buffer (vc-dir-prepare-status-buffer >> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 (format " *package-vc-dir: %s*" pkg-dir) >> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 pkg-dir (vc-responsible-backend pkg-dir)) >> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 (vc-pull))))) >> +=C2=A0 ;; Check if user wants to see diff and confirm upgrade >> +=C2=A0 (when (package-vc--confirm-upgrade pkg-desc) >> +=C2=A0 =C2=A0 ;; HACK: To run `package-vc--unpack-1' after checking out= the new >> +=C2=A0 =C2=A0 ;; revision, we insert a hook into `vc-post-command-funct= ions', and >> +=C2=A0 =C2=A0 ;; remove it right after it ran.=C2=A0 To avoid running t= he hook multiple >> +=C2=A0 =C2=A0 ;; times or even for the wrong repository (as `vc-pull' i= s often >> +=C2=A0 =C2=A0 ;; asynchronous), we extract the relevant arguments using= a pseudo >> +=C2=A0 =C2=A0 ;; filter for `vc-filter-command-function', executed only= for the >> +=C2=A0 =C2=A0 ;; side effect, and store them in the lexical scope.=C2= =A0 When the hook >> +=C2=A0 =C2=A0 ;; is run, we check if the arguments are the same (`eq') = as the ones >> +=C2=A0 =C2=A0 ;; previously extracted, and only in that case will be ca= ll >> +=C2=A0 =C2=A0 ;; `package-vc--unpack-1'.=C2=A0 Ugh... >> +=C2=A0 =C2=A0 ;; >> +=C2=A0 =C2=A0 ;; If there is a better way to do this, it should be done. >> +=C2=A0 =C2=A0 (cl-assert (package-vc-p pkg-desc)) >> +=C2=A0 =C2=A0 (letrec ((pkg-dir (package-desc-dir pkg-desc)) >> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(vc-flags) >> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(vc-filter-command-func= tion >> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (lambda (command file-= or-list flags) >> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (setq vc-flags = flags) >> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (list command f= ile-or-list flags))) >> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(post-upgrade >> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (lambda (_command _fil= e-or-list flags) >> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (when (and (fil= e-equal-p pkg-dir default-directory) >> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0(eq flags vc-flags)) >> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (unwind-= protect >> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 (with-demoted-errors "Failed to activate: %S" >> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 (package-vc--unpack-1 pkg-desc pkg-dir)) >> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (= remove-hook 'vc-post-command-functions=20 >> post-upgrade)))))) >> +=C2=A0 =C2=A0 =C2=A0 (add-hook 'vc-post-command-functions post-upgrade) >> +=C2=A0 =C2=A0 =C2=A0 (with-demoted-errors "Failed to fetch: %S" >> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 (require 'vc-dir) >> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 (with-current-buffer (vc-dir-prepare-status= -buffer >> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (format " *package-vc-dir: %s*" pkg-dir) >> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 pkg-dir (vc-responsible-backend pkg-dir)) >> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (vc-pull)))))) > > I hope it is fine that I will not comment on this file any more, because > I am not convinced of the approach (among other things having to make a > fresh clone of the entire repository every time the package is being > upgraded, which for larger packages like auctex can take a while). That > is not to say that I am not open to UI suggestions based on > `package-vc-log-incoming', if you want to suggest anything like that. Do I understand correctly that for package-vc we don't need a new addition at all since one can use package-vc-log-incoming? >> >> =C2=A0(defun package-vc--archives-initialize () >> =C2=A0 =C2=A0"Initialize package.el and fetch package specifications." >> >> diff --git a/lisp/emacs-lisp/package.el b/lisp/emacs-lisp/package.el >> index ba9999c20e6..1d1266b7ede 100644 >> --- a/lisp/emacs-lisp/package.el >> +++ b/lisp/emacs-lisp/package.el >> @@ -450,6 +450,44 @@ package-archive-column-width >> =C2=A0 =C2=A0:type 'natnum >> =C2=A0 =C2=A0:version "28.1") >> >> +(defcustom package-show-upgrade-diffs t >> +=C2=A0 "Whether to show diffs before upgrading packages. >> +When non-nil, package upgrades will display the differences between >> +the current and new version before proceeding.=C2=A0 Users can review t= he >> +changes and choose whether to continue with the upgrade. >> +When nil, packages upgrade without showing diffs." >> +=C2=A0 :type 'boolean >> +=C2=A0 :group 'package >> +=C2=A0 :version "31.1") >> + >> +(defcustom package-upgrade-diff-exclude-packages nil >> +=C2=A0 "List of package names to exclude from diff checking during upgr= ades. >> +When a package name is in this list, the upgrade will proceed >> +without showing diffs, even if `package-show-upgrade-diffs' is non-nil. >> +Package names should be specified as symbols. >> + >> +For example: \\=3D'(emacs magit org-mode) >> + >> +This allows for fine-grained control over which packages show >> +diffs during upgrades." >> +=C2=A0 :type '(repeat symbol) >> +=C2=A0 :group 'package >> +=C2=A0 :version "31.1") >> + >> +(defcustom package-upgrade-diff-exclude-archives nil >> +=C2=A0 "List of package archives to exclude from diff checking during u= pgrades. >> +When a package's archive is in this list, the upgrade will proceed >> +without showing diffs, even if `package-show-upgrade-diffs' is non-nil. >> +Archive names should be specified as strings. >> + >> +For example: \\=3D'(\"melpa-stable\" \"nongnu\") >> + >> +This allows for fine-grained control over which archives show >> +diffs during package upgrades." >> +=C2=A0 :type '(repeat string) >> +=C2=A0 :group 'package >> +=C2=A0 :version "31.1") > > I wonder if instead of having multiple user options, it might be cleaner > to replace `package-show-upgrade-diffs' with a non-boolean user option > that can select the packages to trust/mistrust, sort of like how > `buffer-match-p' can select buffers. So the user option instead a list > consisting of > > (package foo) > (archive "bar") > > entries or t, if you want to mistrust everything. Sounds good to me. > Also, shouldn't we also be able to configure what files to diff? Such an option might be good to have, but my preference would be to always see the whole diff, even if potentially "harmless" files are added. I would also mistrust everything. So from my perspective, more rigid and secure defaults would work too. > Also also, IIRC another discussion from bug#74604 was to allow just > prompting the user what packages they want to upgrade. Perhaps we > should orient ourselves on `save-some-buffers' and query the user for > each package if they want to upgrade it, keep it as is (perhaps even > remember this for the future) and/or show a diff. > >> + >> =C2=A0 >> =C2=A0;;; `package-desc' object definition >> =C2=A0;; This is the struct used internally to represent packages. >> @@ -1019,6 +1057,77 @@ package--alist-to-plist-args >> >> =C2=A0(declare-function dired-get-marked-files "dired") > >> +(defun package--extract-tarball-to-temp (buffer pkg-desc temp-dir) >> +=C2=A0 "Extract tarball from BUFFER to TEMP-DIR for PKG-DESC. >> +Returns the directory where package was extracted." >> +=C2=A0 (let ((pkg-dir (expand-file-name (package-desc-full-name pkg-des= c)=20 >> temp-dir))) >> +=C2=A0 =C2=A0 (make-directory temp-dir t) >> +=C2=A0 =C2=A0 (with-current-buffer buffer >> +=C2=A0 =C2=A0 =C2=A0 (let ((default-directory temp-dir)) >> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 (package-untar-buffer (package-desc-full-na= me pkg-desc)))) >> +=C2=A0 =C2=A0 pkg-dir)) >> + >> +(defun package--get-installed-package-dir (pkg-desc) >> +=C2=A0 "Get directory of installed PKG-DESC package." >> +=C2=A0 (expand-file-name (package-desc-full-name pkg-desc) package-user= -dir)) >> + >> +(defun package--show-package-diff (old-dir new-dir) >> +=C2=A0 "Show diff between OLD-DIR and NEW-DIR package directories. >> +Return t if user confirms to continue, nil to cancel." >> +=C2=A0 (let ((diff-buffer "*Package Diff*")) >> +=C2=A0 =C2=A0 (with-current-buffer (get-buffer-create diff-buffer) >> +=C2=A0 =C2=A0 =C2=A0 (erase-buffer) >> +=C2=A0 =C2=A0 =C2=A0 (let ((inhibit-read-only t) >> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (exit-status (call-process "d= iff" nil t nil "-ru" old-dir=20 > ^ > generally, I > think it is > better to use > --long-options > to make the > code more read= able. > >> new-dir))) >> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 (cond >> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0((eq exit-status 0) >> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (insert "No differences found betwee= n old and new package=20 >> versions.\n")) >> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0((eq exit-status 1) >> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ;; Normal case: differences found, t= hey're already in buffer >> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 nil) >> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(t >> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ;; Error case >> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (insert (format "Error running diff = (exit status %d).\n"=20 >> exit-status))))) >> +=C2=A0 =C2=A0 =C2=A0 (diff-mode) > > Is there a reason you don't just use the `diff' function with NO-ASYNC > set to a non-nil value? > >> +=C2=A0 =C2=A0 =C2=A0 (read-only-mode 1) > > I think it is interesting to consider not setting the buffer to be > read-only by default, as it allows the user to manipulate the diff. > This also relates to the fact that the user might have made local > adjustment that they might want to keep between upgrades... Isn't this orthogonal to the problem here - if you want to make local changes, you should install the package from source or via package-vc. If you install a package via the standard mechanism, the package should be installed in the form provided by the archive and therefore a read-only diff should be fine. >> +=C2=A0 =C2=A0 =C2=A0 (goto-char (point-min))) >> +=C2=A0 =C2=A0 (display-buffer diff-buffer) >> +=C2=A0 =C2=A0 (let ((response (yes-or-no-p "Show differences. Continue = with > ^ > What do you mean by show differences > here? It sounds imperative, but I > am not sure if that is what you mean. >> upgrade? "))) >> +=C2=A0 =C2=A0 =C2=A0 (kill-buffer diff-buffer) >> +=C2=A0 =C2=A0 =C2=A0 response))) > > You can use `prog1' here to avoid storing `response'. > >> + >> +(defun package--confirm-tarball-upgrade (pkg-desc new-pkg-desc) >> +=C2=A0 "Show diff for tarball package upgrade and ask for confirmation. >> +Return t if user wants to proceed, nil otherwise." >> +=C2=A0 ;; Check exclusion lists first >> +=C2=A0 (let ((package-name (package-desc-name new-pkg-desc)) >> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 (package-archive (package-desc-archive new-= pkg-desc))) >> +=C2=A0 =C2=A0 ;; If package-show-upgrade-diffs is nil, or package/archi= ve is=20 >> excluded, proceed without diffs >> +=C2=A0 =C2=A0 (if (or (not package-show-upgrade-diffs) >> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (memq package-name package-up= grade-diff-exclude-packages) >> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (member package-archive packa= ge-upgrade-diff-exclude-archives)) >> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 t=C2=A0 ; Skip diff checking, proceed with = upgrade >> +=C2=A0 =C2=A0 =C2=A0 (let* ((temp-dir (make-temp-file "package-diff-" t= )) >> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(old-dir (package--get-= installed-package-dir pkg-desc)) >> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0new-dir) >> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 (unwind-protect >> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (progn >> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ;; Download and extrac= t new version to temp directory >> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (let* ((location (pack= age-archive-base new-pkg-desc)) >> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0(file (concat (package-desc-full-name new-pkg-desc) >> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(package-desc-suffix= new-pkg-desc)))) >> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (package--with-= response-buffer location :file file >> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (setq ne= w-dir (package--extract-tarball-to-temp >> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(current-buffer) new-pkg-de= sc temp-dir)))) >> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ;; Show diff and get u= ser confirmation >> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (if (file-exists-p old= -dir) >> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (package= --show-package-diff old-dir new-dir) >> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ;; If no old ve= rsion exists, just confirm >> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (yes-or-no-p "N= ew package installation. Continue? "))) >> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ;; Clean up temp directory >> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (when (file-exists-p temp-dir) >> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (delete-directory temp-dir t)= )))))) > > My preferred approach to solving this would be if we could split > `package-install-from-archive' or `package-unpack' into two, allowing us > to install the new package without compiling, generating autoloads, and > then to resume that part later on. This would require some refactoring, > but would allow us to express the upgrade procedure as > > 1. Fetch the new source but not process it, > > 2. Compute the diff and present it to the user, > > 3. If they are fine with the changes, delete old package and finish > initialising the package we just downloaded, > > 4. Otherwise we remove and forget about the code we had just downloaded > and keep everything as is. > > I imagine that this approach should keep the upgrade procedure more > uniform and setting aside changes caused by re-indenting code we factor > out of existing functionality, result in a simpler upgrade-logic. I see your point but I would generally be careful with performing "half" of the installation before showing the diff. Until the user has reviewed the diff, the new package should be considered malicious so it might be better if it does not yet end up in the ~/.config/emacs/elpa/ directory. Maybe a separate review directory could be used, e.g., ~/.config/emacs/package-review/ and then the package could be moved to the final destination in the end. Generally regarding rollback, package.el is not robust right now (there is another bug about that). The original package can stay deleted if installation fails. This can happen due to multiple reasons - package archive metadata outdated, package tarball not available, some other failure during installation. In these case, Emacs can end up in a broken state with a missing package. >> + >> =C2=A0(defun package-unpack (pkg-desc) >> =C2=A0 =C2=A0"Install the contents of the current buffer as a package." >> =C2=A0 =C2=A0(let* ((name (package-desc-name pkg-desc)) >> @@ -2290,16 +2399,31 @@ package-upgrade >> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(p= ackage--upgradeable-packages t) nil t)))) >> =C2=A0 =C2=A0(cl-check-type name symbol) >> =C2=A0 =C2=A0(let* ((pkg-desc (cadr (assq name package-alist))) >> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(package-install-upgrade-built-in (no= t pkg-desc))) >> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(package-install-upgrade-built-in (no= t pkg-desc)) >> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(new-pkg-desc (cadr (assq name packag= e-archive-contents)))) >> =C2=A0 =C2=A0 =C2=A0;; `pkg-desc' will be nil when the package is an "a= ctive built-in". >> =C2=A0 =C2=A0 =C2=A0(if (and pkg-desc (package-vc-p pkg-desc)) >> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(package-vc-upgrade pkg-desc) >> -=C2=A0 =C2=A0 =C2=A0 (when pkg-desc >> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 (package-delete pkg-desc 'force 'dont-unsel= ect)) >> -=C2=A0 =C2=A0 =C2=A0 (package-install name >> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0;; An active built-in has never been "selected" >> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0;; before.=C2=A0 Mark it as installed explicitly. >> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0(and pkg-desc 'dont-select))))) >> +=C2=A0 =C2=A0 =C2=A0 ;; Check if this is a tarball package upgrade that= needs diff=20 >> confirmation >> +=C2=A0 =C2=A0 =C2=A0 (if (and pkg-desc new-pkg-desc >> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(eq (package-des= c-kind new-pkg-desc) 'tar)) >> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ;; For tarball packages, show diff a= nd ask for confirmation >> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (if (package--confirm-tarball-upgrad= e pkg-desc new-pkg-desc) >> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (progn >> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (package-delete= pkg-desc 'force 'dont-unselect) >> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (package-instal= l name >> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0;; An active built-in has n= ever been=20 >> "selected" >> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0;; before.=C2=A0 Mark it as= installed=20 >> explicitly. >> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(and pkg-desc 'dont-select)= )) >> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (message "Package upgrade can= celled")) >> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 ;; For non-tarball packages, proceed with n= ormal upgrade >> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 (progn >> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (when pkg-desc >> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (package-delete pkg-desc 'for= ce 'dont-unselect)) >> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (package-install name >> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0;; An active built-in has never been "selected" >> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0;; before.=C2=A0 Mark it as installed explicitly. >> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0(and pkg-desc 'dont-select))))))) > > Why shouldn't we prompt the user with a diff for non-tarball upgrades?=20= =20 +1 >> =C2=A0(defun package--upgradeable-packages (&optional include-builtins) >> =C2=A0 =C2=A0;; Initialize the package system to get the list of package >> @@ -2688,16 +2812,16 @@ package-isolate >> =C2=A0in a clean environment." >> =C2=A0 =C2=A0(interactive >> =C2=A0 =C2=A0 (cl-loop for p in (cl-loop for p in (package--alist) appe= nd (cdr p)) >> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 unless (package-built-in-p p) >> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 collect (cons (package-desc-full-name p) p)= into table >> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 finally return >> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 (list >> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 unless (package-built-in-p p) >> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 collect (cons (package-desc-f= ull-name p) p) into table >> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 finally return >> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (list >> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (cl-loop for c in >> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0(completing-read-multiple >> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 "Packages to isolate: " table >> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 nil t) >> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0co= llect (alist-get c table nil nil #'string=3D)) >> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 current-= prefix-arg))) >> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 collect (alist-get c table nil nil #'string=3D)) >> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0current-prefix-arg))) > > These are unrelated changes, right? > >> =C2=A0 =C2=A0(let* ((name (concat "package-isolate-" >> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 (mapconcat #'package-desc-full-name packages ","))) >> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (all-packages (delete-consecutive-du= ps >> @@ -4172,9 +4296,18 @@ package-menu--perform-transaction >> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(f= ormat status-format (incf i))) >> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(force-mode-line-update) >> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(redisplay 'force) >> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ;; Don't mark as selected, `p= ackage-menu-execute' already >> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ;; does that. >> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (package-install pkg 'dont-se= lect)))) >> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ;; Check if this is a tarball= package upgrade and needs=20 >> confirmation >> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (let* ((pkg-name (package-des= c-name pkg)) >> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(o= ld-pkg (cl-find-if (lambda (del-pkg) >> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 (eq (package-desc-name=20 >> del-pkg) pkg-name)) >> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 delet= e-list))) >> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (if (and old-pkg (eq (= package-desc-kind pkg) 'tar)) >> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ;; This = is a tarball upgrade - ask for confirmation >> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (if (pac= kage--confirm-tarball-upgrade old-pkg pkg) >> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 (package-install pkg 'dont-select) >> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (= push (package-desc-full-name pkg) errors)) >> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ;; Normal insta= llation >> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (package-instal= l pkg 'dont-select)))))) >> =C2=A0 =C2=A0 =C2=A0(let ((package-menu--transaction-status ":Deleting"= )) >> =C2=A0 =C2=A0 =C2=A0 =C2=A0(force-mode-line-update) >> =C2=A0 =C2=A0 =C2=A0 =C2=A0(redisplay 'force) > > Final request, I have just pushed a branch called feature/package-revamp > where among other thing I want to split package.el into multiple smaller > files and have the package-menu re-use the package-upgrade logic. If > everything goes as intended, this will be merged into master at some > point. It would be great if you could try to re-base your work on that > branch, or at least keep it in mind. From unknown Fri Sep 19 04:01:23 2025 X-Loop: help-debbugs@gnu.org Subject: bug#74604: [PATCH v1] package.el: Add diff display and confirmation for package upgrades (Bug#74604) Resent-From: Philip Kaludercic Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Tue, 02 Sep 2025 23:10:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 74604 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: To: Daniel Mendler Cc: Nobuyuki Kamimoto , 74604@debbugs.gnu.org Received: via spool by 74604-submit@debbugs.gnu.org id=B74604.175685454610662 (code B ref 74604); Tue, 02 Sep 2025 23:10:02 +0000 Received: (at 74604) by debbugs.gnu.org; 2 Sep 2025 23:09:06 +0000 Received: from localhost ([127.0.0.1]:37094 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1uta7d-0002lu-D2 for submit@debbugs.gnu.org; Tue, 02 Sep 2025 19:09:06 -0400 Received: from mout02.posteo.de ([185.67.36.66]:48569) by debbugs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.84_2) (envelope-from ) id 1uta7a-0002lO-3e for 74604@debbugs.gnu.org; Tue, 02 Sep 2025 19:09:03 -0400 Received: from submission (posteo.de [185.67.36.169]) by mout02.posteo.de (Postfix) with ESMTPS id 53150240101 for <74604@debbugs.gnu.org>; Wed, 3 Sep 2025 01:08:55 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=posteo.net; s=2017; t=1756854535; bh=m238Id2rKOeNLUmX1LZAB+o45kOgppLBoKPsnv4ZRhI=; h=From:To:Cc:Subject:Autocrypt:OpenPGP:Date:Message-ID:MIME-Version: Content-Type:Content-Transfer-Encoding:From; b=OIa2Ois9T35XnnTGSVJH02f+AgtnLFRRbolGn50H+I1QI7PomaZTAdXfMIuXogxU/ QGh6ybSdtSySzy1lWV522fqGHybxM4y/gDvoRKvlFNVwVM7ViHlnksLHp6RzCB2r/c 5xs2/0o+CapTxZQED+vZwGvATFRtOdfvNGqf0mShqMsd9oNpMLyweG3KtBwUO0oERv fusR3l2n9K7ghjgYMBkYpufKzXkhhQnvlx0iOCS50HqewR/AdgUMxao+8N/CoxGh7l 4h64suRduqCupbryNTn3imM/Gn9WBD8GRb/G+a4rruQ9tcUie2eDitwGgBB39dTJGq +xL0BjohYMsMg== Received: from customer (localhost [127.0.0.1]) by submission (posteo.de) with ESMTPSA id 4cGhJ64fmCz6tw2; Wed, 3 Sep 2025 01:08:54 +0200 (CEST) From: Philip Kaludercic In-Reply-To: <87ecsovdqp.fsf@daniel-mendler.de> References: <87h67quk0g.fsf@daniel-mendler.de> <54fadfd1-21f6-48cb-a17e-8d0878a68f1d@gmail.com> <87ldmweuf2.fsf@posteo.net> <87ecsovdqp.fsf@daniel-mendler.de> Autocrypt: addr=philipk@posteo.net; keydata= mDMEZBBQQhYJKwYBBAHaRw8BAQdAHJuofBrfqFh12uQu0Yi7mrl525F28eTmwUDflFNmdui0QlBo aWxpcCBLYWx1ZGVyY2ljIChnZW5lcmF0ZWQgYnkgYXV0b2NyeXB0LmVsKSA8cGhpbGlwa0Bwb3N0 ZW8ubmV0PoiWBBMWCAA+FiEEDg7HY17ghYlni8XN8xYDWXahwukFAmQQUEICGwMFCQHhM4AFCwkI BwIGFQoJCAsCBBYCAwECHgECF4AACgkQ8xYDWXahwulikAEA77hloUiSrXgFkUVJhlKBpLCHUjA0 mWZ9j9w5d08+jVwBAK6c4iGP7j+/PhbkxaEKa4V3MzIl7zJkcNNjHCXmvFcEuDgEZBBQQhIKKwYB BAGXVQEFAQEHQI5NLiLRjZy3OfSt1dhCmFyn+fN/QKELUYQetiaoe+MMAwEIB4h+BBgWCAAmFiEE Dg7HY17ghYlni8XN8xYDWXahwukFAmQQUEICGwwFCQHhM4AACgkQ8xYDWXahwukm+wEA8cml4JpK NeAu65rg+auKrPOP6TP/4YWRCTIvuYDm0joBALw98AMz7/qMHvSCeU/hw9PL6u6R2EScxtpKnWof z4oM OpenPGP: id=7126E1DE2F0CE35C770BED01F2C3CC513DB89F66; url="https://keys.openpgp.org/vks/v1/by-fingerprint/7126E1DE2F0CE35C770BED01F2C3CC513DB89F66"; preference=signencrypt Date: Tue, 02 Sep 2025 23:08:54 +0000 Message-ID: <87seh4tptl.fsf@posteo.net> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-Spam-Score: -2.3 (--) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -3.3 (---) Daniel Mendler writes: > Philip Kaludercic writes: > >> Nobuyuki Kamimoto writes: >> >>> Hello, >>> >>> This patch implements a new feature for package upgrades, as discussed >>> in Bug#74604. >> >> Thanks! I have added Daniel to the CCs as he was involved in the >> discussion you reference, and I assume is interested in the discussion. > > Philip, thanks for adding me. I wonder why I haven't received the > message earlier on, given that I've created bug#74604. I much appreciate > the work on this feature. I am not sure either... >>> Summary: >>> - Shows diffs between the installed and the new version of a package >>> =C2=A0 before upgrading. >>> - Lets the user review changes and confirm whether to proceed. >>> - Supports both regular tarball packages and VC packages. >>> - New user options: >>> =C2=A0 - package-show-upgrade-diffs >>> =C2=A0 - package-upgrade-diff-exclude-packages >>> =C2=A0 - package-upgrade-diff-exclude-archives >>> =C2=A0 - package-vc-show-upgrade-diffs >>> =C2=A0 - package-vc-upgrade-diff-exclude-packages >> >> This is already implemented in package-vc, but in a different way. With >> `package-vc-log-incoming' you get a log of all the changes that will be >> pulled in. The interface is not exactly the same, but I would rather we >> avoid duplicating the functionality in similar but inconsistent ways. > > I don't see how the package-vc-log-incoming functionality could be > reused here. package-vc-log-incoming simply calls vc-log-incoming, but > this new feature does not rely vc? To be clear, I was referencing the last two user options, as I hopefully clarify below. [...] >>> ++++ >>> +** Package management now shows diffs before upgrades. >>> +Package upgrades can now display differences between the current and >>> +new version before proceeding.=C2=A0 This applies to both regular pack= ages >>> +and VC packages installed from version control repositories. >>> + >>> +The behavior is controlled by these new user options: >>> +- 'package-show-upgrade-diffs': Enable/disable diff display for regula= r=20 >>> packages >>> +- 'package-vc-show-upgrade-diffs': Enable/disable diff display for VC= =20 >>> packages >>> +- 'package-upgrade-diff-exclude-packages': Exclude specific packages=20 >>> from diff checking >>> +- 'package-upgrade-diff-exclude-archives': Exclude specific archives=20 >>> from diff checking >>> +- 'package-vc-upgrade-diff-exclude-packages': Exclude specific VC=20 >>> packages from diff checking >>> + >>> +When enabled (the default), users will see a diff buffer showing chang= es >>> +and can choose whether to proceed with or cancel the upgrade. >> >> This description is probably a bit too detailed for a NEWS entry. I >> would not go into the new user options is that great of a detail. >> >> Also, if we decide to enable this by default (which I am not certain of >> right now), the news entry should be more clear in what the change is >> that will affect all users: For instance, it is not "can now display" >> but "will now display". > > Yes, the feature should not be enabled by default, only via user option. > We could consider adding an option to the package installation > confirmation. Instead of pressing y and n, the user could press d to see > the diff. 1+ Another key like "n" or "c" to show the news/changes might also be useful to have. Perhaps the configuration we want is actually just to specify what packages can be updated without any checks, and what packages should be "approved". [...] >> >> I hope it is fine that I will not comment on this file any more, because >> I am not convinced of the approach (among other things having to make a >> fresh clone of the entire repository every time the package is being >> upgraded, which for larger packages like auctex can take a while). That >> is not to say that I am not open to UI suggestions based on >> `package-vc-log-incoming', if you want to suggest anything like that. > > Do I understand correctly that for package-vc we don't need a new > addition at all since one can use package-vc-log-incoming? Right, that is at least my current understanding. We can combine `vc-log-incoming' with an upgrade procedure. The interface will probably not be the same, also because I don't think that batch-upgrading VC packages is good practice. [...] >>> +This allows for fine-grained control over which archives show >>> +diffs during package upgrades." >>> +=C2=A0 :type '(repeat string) >>> +=C2=A0 :group 'package >>> +=C2=A0 :version "31.1") >> >> I wonder if instead of having multiple user options, it might be cleaner >> to replace `package-show-upgrade-diffs' with a non-boolean user option >> that can select the packages to trust/mistrust, sort of like how >> `buffer-match-p' can select buffers. So the user option instead a list >> consisting of >> >> (package foo) >> (archive "bar") >> >> entries or t, if you want to mistrust everything. > > Sounds good to me. > >> Also, shouldn't we also be able to configure what files to diff? > > Such an option might be good to have, but my preference would be to > always see the whole diff, even if potentially "harmless" files are > added. I would also mistrust everything. So from my perspective, more > rigid and secure defaults would work too. I agree. [...] >>> +=C2=A0 =C2=A0 =C2=A0 (read-only-mode 1) >> >> I think it is interesting to consider not setting the buffer to be >> read-only by default, as it allows the user to manipulate the diff. >> This also relates to the fact that the user might have made local >> adjustment that they might want to keep between upgrades... > > Isn't this orthogonal to the problem here - if you want to make local > changes, you should install the package from source or via package-vc. > If you install a package via the standard mechanism, the package should > be installed in the form provided by the archive and therefore a > read-only diff should be fine. You are right, this is just a general thought I haven't thought out myself that we can ignore for now. >>> +=C2=A0 =C2=A0 =C2=A0 (goto-char (point-min))) >>> +=C2=A0 =C2=A0 (display-buffer diff-buffer) >>> +=C2=A0 =C2=A0 (let ((response (yes-or-no-p "Show differences. Continue= with >> ^ >> What do you mean by show differences >> here? It sounds imperative, but I >> am not sure if that is what you mean. >>> upgrade? "))) >>> +=C2=A0 =C2=A0 =C2=A0 (kill-buffer diff-buffer) >>> +=C2=A0 =C2=A0 =C2=A0 response))) >> >> You can use `prog1' here to avoid storing `response'. >> >>> + >>> +(defun package--confirm-tarball-upgrade (pkg-desc new-pkg-desc) >>> +=C2=A0 "Show diff for tarball package upgrade and ask for confirmation. >>> +Return t if user wants to proceed, nil otherwise." >>> +=C2=A0 ;; Check exclusion lists first >>> +=C2=A0 (let ((package-name (package-desc-name new-pkg-desc)) >>> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 (package-archive (package-desc-archive new= -pkg-desc))) >>> +=C2=A0 =C2=A0 ;; If package-show-upgrade-diffs is nil, or package/arch= ive is=20 >>> excluded, proceed without diffs >>> +=C2=A0 =C2=A0 (if (or (not package-show-upgrade-diffs) >>> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (memq package-name package-u= pgrade-diff-exclude-packages) >>> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (member package-archive pack= age-upgrade-diff-exclude-archives)) >>> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 t=C2=A0 ; Skip diff checking, proceed with= upgrade >>> +=C2=A0 =C2=A0 =C2=A0 (let* ((temp-dir (make-temp-file "package-diff-" = t)) >>> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(old-dir (package--get= -installed-package-dir pkg-desc)) >>> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0new-dir) >>> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 (unwind-protect >>> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (progn >>> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ;; Download and extra= ct new version to temp directory >>> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (let* ((location (pac= kage-archive-base new-pkg-desc)) >>> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0(file (concat (package-desc-full-name new-pkg-desc) >>> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(package-desc-suffix= new-pkg-desc)))) >>> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (package--with= -response-buffer location :file file >>> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (setq n= ew-dir (package--extract-tarball-to-temp >>> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(current-buffer) new-pkg-de= sc temp-dir)))) >>> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ;; Show diff and get = user confirmation >>> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (if (file-exists-p ol= d-dir) >>> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (packag= e--show-package-diff old-dir new-dir) >>> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ;; If no old v= ersion exists, just confirm >>> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (yes-or-no-p "= New package installation. Continue? "))) >>> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ;; Clean up temp directory >>> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (when (file-exists-p temp-dir) >>> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (delete-directory temp-dir t= ))))))) >> >> My preferred approach to solving this would be if we could split >> `package-install-from-archive' or `package-unpack' into two, allowing us >> to install the new package without compiling, generating autoloads, and >> then to resume that part later on. This would require some refactoring, >> but would allow us to express the upgrade procedure as >> >> 1. Fetch the new source but not process it, >> >> 2. Compute the diff and present it to the user, >> >> 3. If they are fine with the changes, delete old package and finish >> initialising the package we just downloaded, >> >> 4. Otherwise we remove and forget about the code we had just downloaded >> and keep everything as is. >> >> I imagine that this approach should keep the upgrade procedure more >> uniform and setting aside changes caused by re-indenting code we factor >> out of existing functionality, result in a simpler upgrade-logic. > > I see your point but I would generally be careful with performing "half" > of the installation before showing the diff. Until the user has reviewed > the diff, the new package should be considered malicious so it might be > better if it does not yet end up in the ~/.config/emacs/elpa/ directory. > Maybe a separate review directory could be used, e.g., > ~/.config/emacs/package-review/ and then the package could be moved to > the final destination in the end. You are right, that is important to keep in mind. My main focus here is that we should avoid downloading the package twice. FWIW it should be fine if the package is first cloned into /tmp/ and then copied over to ~/.config/emacs/elpa/ after being approved, or is your point with .../package-review/ that the list of not-yet-reviewed should stay persistent? > Generally regarding rollback, package.el is not robust right now (there > is another bug about that). The original package can stay deleted if > installation fails. This can happen due to multiple reasons - package > archive metadata outdated, package tarball not available, some other > failure during installation. In these case, Emacs can end up in a broken > state with a missing package. That is true and something I want to improve upon independently of this bug report (but we shouldn't make it worse either). [...] From unknown Fri Sep 19 04:01:23 2025 X-Loop: help-debbugs@gnu.org Subject: bug#74604: [PATCH v1] package.el: Add diff display and confirmation for package upgrades (Bug#74604) Resent-From: Daniel Mendler Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Wed, 03 Sep 2025 09:25:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 74604 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: To: Philip Kaludercic Cc: Nobuyuki Kamimoto , 74604@debbugs.gnu.org Received: via spool by 74604-submit@debbugs.gnu.org id=B74604.175689149012814 (code B ref 74604); Wed, 03 Sep 2025 09:25:01 +0000 Received: (at 74604) by debbugs.gnu.org; 3 Sep 2025 09:24:50 +0000 Received: from localhost ([127.0.0.1]:38561 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1utjjV-0003Kc-EK for submit@debbugs.gnu.org; Wed, 03 Sep 2025 05:24:49 -0400 Received: from server.qxqx.de ([2a01:4f8:c012:9177::1]:58693 helo=mail.qxqx.de) by debbugs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.84_2) (envelope-from ) id 1utjjR-0003KM-Oa for 74604@debbugs.gnu.org; Wed, 03 Sep 2025 05:24:47 -0400 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=daniel-mendler.de; s=key; h=Content-Type:MIME-Version:Message-ID:Date: References:In-Reply-To:Subject:Cc:To:From:Sender:Reply-To: Content-Transfer-Encoding:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Id: List-Help:List-Unsubscribe:List-Subscribe:List-Post:List-Owner:List-Archive; bh=W5CSZEgTOoVzzuB7LRFpZ3AZOVMH0oXXEgT09JsKVVs=; b=oB3H6u5QTpBjbP1wye/pICLVcF xIIKJnjOqDY17FxukNTds+wpKWHWRk8tsZEU9JuWV/JB9jajrNOJaKnZZRf+u/NdrxmT3hItiVYOx g3G6zPEugVCZjTU1ww9lYkv8yC+l6xp714gamTMoI6+4QMwdVnde7H6SeDwvCZWtrjKw=; From: Daniel Mendler In-Reply-To: <87seh4tptl.fsf@posteo.net> References: <87h67quk0g.fsf@daniel-mendler.de> <54fadfd1-21f6-48cb-a17e-8d0878a68f1d@gmail.com> <87ldmweuf2.fsf@posteo.net> <87ecsovdqp.fsf@daniel-mendler.de> <87seh4tptl.fsf@posteo.net> Date: Wed, 03 Sep 2025 11:24:37 +0200 Message-ID: <87zfbbx50q.fsf@daniel-mendler.de> User-Agent: Gnus/5.13 (Gnus v5.13) MIME-Version: 1.0 Content-Type: text/plain X-Spam-Score: -0.7 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.7 (-) >>> Also, if we decide to enable this by default (which I am not certain of >>> right now), the news entry should be more clear in what the change is >>> that will affect all users: For instance, it is not "can now display" >>> but "will now display". >> >> Yes, the feature should not be enabled by default, only via user option. >> We could consider adding an option to the package installation >> confirmation. Instead of pressing y and n, the user could press d to see >> the diff. > > 1+ > > Another key like "n" or "c" to show the news/changes might also be > useful to have. Perhaps the configuration we want is actually just to > specify what packages can be updated without any checks, and what > packages should be "approved". Yes, but as I mentioned I would use "paranoid" settings (display the diff always for everything). To clarify the motivation - this would offer some protection against all kinds of attacks, e.g., even a manipulated package archive or build process, even if the package itself and the git does not look suspicious. If anything suspicious stands out during upgrade (or the diff is particularly large), a closer investigation could be done on the repository directly. I hope if a couple of experienced users enable this feature we would get robust sanity checking of the entire supply chain, at least for widely installed packages, but these are the ones which would affect most of the users. >>> I hope it is fine that I will not comment on this file any more, because >>> I am not convinced of the approach (among other things having to make a >>> fresh clone of the entire repository every time the package is being >>> upgraded, which for larger packages like auctex can take a while). That >>> is not to say that I am not open to UI suggestions based on >>> `package-vc-log-incoming', if you want to suggest anything like that. >> >> Do I understand correctly that for package-vc we don't need a new >> addition at all since one can use package-vc-log-incoming? > > Right, that is at least my current understanding. We can combine > `vc-log-incoming' with an upgrade procedure. The interface will > probably not be the same, also because I don't think that > batch-upgrading VC packages is good practice. Agree. >>> I imagine that this approach should keep the upgrade procedure more >>> uniform and setting aside changes caused by re-indenting code we factor >>> out of existing functionality, result in a simpler upgrade-logic. >> >> I see your point but I would generally be careful with performing "half" >> of the installation before showing the diff. Until the user has reviewed >> the diff, the new package should be considered malicious so it might be >> better if it does not yet end up in the ~/.config/emacs/elpa/ directory. >> Maybe a separate review directory could be used, e.g., >> ~/.config/emacs/package-review/ and then the package could be moved to >> the final destination in the end. > > You are right, that is important to keep in mind. My main focus here is > that we should avoid downloading the package twice. FWIW it should be > fine if the package is first cloned into /tmp/ and then copied over to > ~/.config/emacs/elpa/ after being approved, or is your point with > .../package-review/ that the list of not-yet-reviewed should stay > persistent? Absolutely agree that we should avoid downloading and unpacking twice. My idea was to remove the package after review and I proposed a directory close to the emacs/elpa/ directory since then the directory can be renamed. /tmp could be on a different FS, so it would involve copying, but not that it matters. I hadn't thought about this, but maybe it is not such a bad idea if the non-approved package stays around for inspection in a separate directory. Otoh this would increase the risk for accidental execution, in particular with macro expansion and code execution and if we generally trust the content of the ~/.config/emacs/ directory, as could be configured by the trusted-content variable. >> Generally regarding rollback, package.el is not robust right now (there >> is another bug about that). The original package can stay deleted if >> installation fails. This can happen due to multiple reasons - package >> archive metadata outdated, package tarball not available, some other >> failure during installation. In these case, Emacs can end up in a broken >> state with a missing package. > > That is true and something I want to improve upon independently of this > bug report (but we shouldn't make it worse either). Thanks. Indeed :) Daniel From unknown Fri Sep 19 04:01:23 2025 X-Loop: help-debbugs@gnu.org Subject: bug#74604: [PATCH v1] package.el: Add diff display and confirmation for package upgrades (Bug#74604) Resent-From: Nobuyuki Kamimoto Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Sat, 13 Sep 2025 04:23:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 74604 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: To: Philip Kaludercic , Daniel Mendler Cc: 74604@debbugs.gnu.org Received: via spool by 74604-submit@debbugs.gnu.org id=B74604.17577373744338 (code B ref 74604); Sat, 13 Sep 2025 04:23:01 +0000 Received: (at 74604) by debbugs.gnu.org; 13 Sep 2025 04:22:54 +0000 Received: from localhost ([127.0.0.1]:52250 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1uxHml-00017p-3p for submit@debbugs.gnu.org; Sat, 13 Sep 2025 00:22:54 -0400 Received: from mail-pl1-x633.google.com ([2607:f8b0:4864:20::633]:59418) by debbugs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.84_2) (envelope-from ) id 1uxDiw-0003Mo-BK for 74604@debbugs.gnu.org; Fri, 12 Sep 2025 20:02:42 -0400 Received: by mail-pl1-x633.google.com with SMTP id d9443c01a7336-24cbd9d9f09so31607955ad.2 for <74604@debbugs.gnu.org>; Fri, 12 Sep 2025 17:02:38 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1757721752; x=1758326552; darn=debbugs.gnu.org; h=in-reply-to:from:content-language:references:cc:to:subject :user-agent:mime-version:date:message-id:from:to:cc:subject:date :message-id:reply-to; bh=8Eid+djh5WbnGGrI35Ohes02e4278Z5fv/PT3GZhxKc=; b=g6lrNBtoYvWEr98QHoUHEtOrUat9n+zVm4OjDmVhNlSWP+9UlV4eo3afKRqvFwCpHq ktbnMJHrlBFxeuqbBbE6kRbW9TzT58T7auA+aydzLiIF7xfrHwNiYGjFM2Yki3YIwVYx zQDy2M7qqRqEUIXWKyc/n/PQLRZIcKNjcTY9QHYuaBsjRQDu0rbC9uRlbAYS7rnAFlLG BEnIVoy67C+QvyuTFmo6i1Hqo1O3f1R3rHFKaRSyCgIN1e+72/w0cBaRyJTXT9eoAN/d K/ufyzM3/P3MSGWD3/sinAlMmKbBSGEY2R+ZRIjuKI+LUbKZgJMQjyDvnfTiFMttIg1Q /02A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1757721752; x=1758326552; h=in-reply-to:from:content-language:references:cc:to:subject :user-agent:mime-version:date:message-id:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=8Eid+djh5WbnGGrI35Ohes02e4278Z5fv/PT3GZhxKc=; b=tfkay3/HXTEA2DubFZhwebl+pwtJi131VD6sDn0uIQqPGJ3b5fIJpyiID/RnL7lOlz aLMoaz9vssSUNZVE59BAvIrjg6A9FN6bf0P5lAYljAKIaWDmZ7D/vW1lxYw+kKIQA+eu SXR0aMqyD5y0N77PGTv1+tOinneKaOMuCXyX3kQqyDrJXsHyIRStdgERcvqC1pkRICwd JDjoXbbcA1NMjhfdeZ7iu1ujpH4g7K2b2nLa0n873v6A8C0mcYvrKsMijoxWuu2Q7SGZ NlAp4C0tbqM5HT+wz8f1shieRMgXEw1Tw0wZl8XzRtiNdHHXasFxrw4bzREDPspl/3hc uQHw== X-Gm-Message-State: AOJu0Yz+8Mvsryf6DM71izTZ9AeE2h++mq6RnjCmK4febs9seXfnDE2z OnkbiD0w53GGzij5QKfY6I49aANfCSgr4aTCz0naz47WAgkRFvvdssVp X-Gm-Gg: ASbGncsasnHL6BgrHW1Zuy2oT4Y/l0QxcKGhjG7hfl5NMckCSu4OE7jkzp9+Wr7k4uE DN0pM0VCF5t5kmESD2ug4y3qDYDjghwfjtG1ZiDvpFD0xkYi6WvbDFcudR+2O9MeEVU+Fcw+JuY un8SpTEiesfCIOxGjz4MFI++FFw/HEfZqn9Jjdm6Vj9YHIJ5SkoGFsoSbNqKFQDuYZY6pVDHUEQ 96smHip9K6FpmrZqCcu6MStqtPn8gIRasRh9Xua+0kO364ZY9iHAxIeB4cnWL4sI1fApx3wvB7v IOmRCjIDhJggNK5C5hJ94xuVM8hy8EXZwAOPYBnEJatDLAmuCtmFF3buAKSm54WXFjewgFL4MzY vdSG8agTDlUYDRmvR/R9XIIYxlPwPdy1dfuKev9b+rxnN9T6d0mAmyQXJi8m/5RSBfgjq5rwjFF tEflmdz0Qu4SzXeg== X-Google-Smtp-Source: AGHT+IFN1gQLmKAgnT9D2ajCts2pDVtdRt+2I70SQip06cNZXOBRIby9pgYEEff6S69YJ/omg74ONw== X-Received: by 2002:a17:903:1b25:b0:246:d70e:ea82 with SMTP id d9443c01a7336-25d2528da26mr53141405ad.5.1757721751393; Fri, 12 Sep 2025 17:02:31 -0700 (PDT) Received: from ?IPV6:240b:c020:633:378e:5121:e5de:b18f:eb5e? ([240b:c020:633:378e:5121:e5de:b18f:eb5e]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-25c36cc6c71sm61022015ad.19.2025.09.12.17.02.29 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Fri, 12 Sep 2025 17:02:30 -0700 (PDT) Content-Type: multipart/mixed; boundary="------------fbZRW2EvGyfUKUcjKcvjyeca" Message-ID: <312bce53-f1de-4dfb-8338-a71f4d7cebfb@gmail.com> Date: Sat, 13 Sep 2025 09:01:33 +0900 MIME-Version: 1.0 User-Agent: Mozilla Thunderbird References: <87h67quk0g.fsf@daniel-mendler.de> <54fadfd1-21f6-48cb-a17e-8d0878a68f1d@gmail.com> <87ldmweuf2.fsf@posteo.net> <87ecsovdqp.fsf@daniel-mendler.de> <87seh4tptl.fsf@posteo.net> Content-Language: en-US From: Nobuyuki Kamimoto In-Reply-To: <87seh4tptl.fsf@posteo.net> X-Spam-Score: 0.3 (/) X-Mailman-Approved-At: Sat, 13 Sep 2025 00:22:49 -0400 X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -0.7 (/) This is a multi-part message in MIME format. --------------fbZRW2EvGyfUKUcjKcvjyeca Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit Hello Philip and Daniel, Thank you for your detailed feedback on the initial patch. You raised excellent points about avoiding duplication of existing VC functionality and improving the overall approach. I've completely revised the implementation based on your suggestions: Key Changes For VC Packages: - Now uses existing package-vc-log-incoming and vc-root-diff-incoming functions instead of creating custom clone-based diff functionality - Eliminates the expensive full repository cloning approach - The 'd' option in the interactive prompt now shows both log and source diff using standard VC functions Unified Configuration: - Replaced multiple defcustom options with a single package-upgrade-confirmation-policy that accepts:   - t (default): Show diffs and confirm for all packages   - nil: Auto-upgrade without confirmation   - List format like ((package magit) (archive "melpa")) for fine-grained control Interactive Prompt System: - Implements y/n/d/c interface (Yes/No/Diff/Changelog/Quit) - Consistent between tarball and VC packages - Uses existing VC infrastructure for VC packages Addressing Your Concerns - No VC functionality duplication: Now leverages existing vc-log-incoming/vc-root-diff-incoming - Performance: No more expensive repository cloning for VC packages - Configuration simplicity: Single unified option instead of multiple variables - Standards compliance: Uses standard Emacs diff and VC functionality Regarding feature/package-revamp I'd be happy to test and adapt this work for the feature/package-revamp branch. Would you prefer me to: 1. Rebase this current patch against that branch, or 2. Wait for the branch to be merged and then adapt? The revised patch is attached to avoid formatting issues with non-breaking spaces. I believe this approach better aligns with Emacs conventions while providing the user interface improvements discussed in Bug#74604. Best regards, Nobuyuki Kamimoto On 2025/09/03 8:08, Philip Kaludercic wrote: > Daniel Mendler writes: > >> Philip Kaludercic writes: >> >>> Nobuyuki Kamimoto writes: >>> >>>> Hello, >>>> >>>> This patch implements a new feature for package upgrades, as discussed >>>> in Bug#74604. >>> Thanks! I have added Daniel to the CCs as he was involved in the >>> discussion you reference, and I assume is interested in the discussion. >> Philip, thanks for adding me. I wonder why I haven't received the >> message earlier on, given that I've created bug#74604. I much appreciate >> the work on this feature. > I am not sure either... > >>>> Summary: >>>> - Shows diffs between the installed and the new version of a package >>>>   before upgrading. >>>> - Lets the user review changes and confirm whether to proceed. >>>> - Supports both regular tarball packages and VC packages. >>>> - New user options: >>>>   - package-show-upgrade-diffs >>>>   - package-upgrade-diff-exclude-packages >>>>   - package-upgrade-diff-exclude-archives >>>>   - package-vc-show-upgrade-diffs >>>>   - package-vc-upgrade-diff-exclude-packages >>> This is already implemented in package-vc, but in a different way. With >>> `package-vc-log-incoming' you get a log of all the changes that will be >>> pulled in. The interface is not exactly the same, but I would rather we >>> avoid duplicating the functionality in similar but inconsistent ways. >> I don't see how the package-vc-log-incoming functionality could be >> reused here. package-vc-log-incoming simply calls vc-log-incoming, but >> this new feature does not rely vc? > To be clear, I was referencing the last two user options, as I hopefully > clarify below. > > > [...] > >>>> ++++ >>>> +** Package management now shows diffs before upgrades. >>>> +Package upgrades can now display differences between the current and >>>> +new version before proceeding.  This applies to both regular packages >>>> +and VC packages installed from version control repositories. >>>> + >>>> +The behavior is controlled by these new user options: >>>> +- 'package-show-upgrade-diffs': Enable/disable diff display for regular >>>> packages >>>> +- 'package-vc-show-upgrade-diffs': Enable/disable diff display for VC >>>> packages >>>> +- 'package-upgrade-diff-exclude-packages': Exclude specific packages >>>> from diff checking >>>> +- 'package-upgrade-diff-exclude-archives': Exclude specific archives >>>> from diff checking >>>> +- 'package-vc-upgrade-diff-exclude-packages': Exclude specific VC >>>> packages from diff checking >>>> + >>>> +When enabled (the default), users will see a diff buffer showing changes >>>> +and can choose whether to proceed with or cancel the upgrade. >>> This description is probably a bit too detailed for a NEWS entry. I >>> would not go into the new user options is that great of a detail. >>> >>> Also, if we decide to enable this by default (which I am not certain of >>> right now), the news entry should be more clear in what the change is >>> that will affect all users: For instance, it is not "can now display" >>> but "will now display". >> Yes, the feature should not be enabled by default, only via user option. >> We could consider adding an option to the package installation >> confirmation. Instead of pressing y and n, the user could press d to see >> the diff. > 1+ > > Another key like "n" or "c" to show the news/changes might also be > useful to have. Perhaps the configuration we want is actually just to > specify what packages can be updated without any checks, and what > packages should be "approved". > > [...] > >>> I hope it is fine that I will not comment on this file any more, because >>> I am not convinced of the approach (among other things having to make a >>> fresh clone of the entire repository every time the package is being >>> upgraded, which for larger packages like auctex can take a while). That >>> is not to say that I am not open to UI suggestions based on >>> `package-vc-log-incoming', if you want to suggest anything like that. >> Do I understand correctly that for package-vc we don't need a new >> addition at all since one can use package-vc-log-incoming? > Right, that is at least my current understanding. We can combine > `vc-log-incoming' with an upgrade procedure. The interface will > probably not be the same, also because I don't think that > batch-upgrading VC packages is good practice. > > > [...] > >>>> +This allows for fine-grained control over which archives show >>>> +diffs during package upgrades." >>>> +  :type '(repeat string) >>>> +  :group 'package >>>> +  :version "31.1") >>> I wonder if instead of having multiple user options, it might be cleaner >>> to replace `package-show-upgrade-diffs' with a non-boolean user option >>> that can select the packages to trust/mistrust, sort of like how >>> `buffer-match-p' can select buffers. So the user option instead a list >>> consisting of >>> >>> (package foo) >>> (archive "bar") >>> >>> entries or t, if you want to mistrust everything. >> Sounds good to me. >> >>> Also, shouldn't we also be able to configure what files to diff? >> Such an option might be good to have, but my preference would be to >> always see the whole diff, even if potentially "harmless" files are >> added. I would also mistrust everything. So from my perspective, more >> rigid and secure defaults would work too. > I agree. > > [...] > >>>> +      (read-only-mode 1) >>> I think it is interesting to consider not setting the buffer to be >>> read-only by default, as it allows the user to manipulate the diff. >>> This also relates to the fact that the user might have made local >>> adjustment that they might want to keep between upgrades... >> Isn't this orthogonal to the problem here - if you want to make local >> changes, you should install the package from source or via package-vc. >> If you install a package via the standard mechanism, the package should >> be installed in the form provided by the archive and therefore a >> read-only diff should be fine. > You are right, this is just a general thought I haven't thought out > myself that we can ignore for now. > >>>> +      (goto-char (point-min))) >>>> +    (display-buffer diff-buffer) >>>> +    (let ((response (yes-or-no-p "Show differences. Continue with >>> ^ >>> What do you mean by show differences >>> here? It sounds imperative, but I >>> am not sure if that is what you mean. >>>> upgrade? "))) >>>> +      (kill-buffer diff-buffer) >>>> +      response))) >>> You can use `prog1' here to avoid storing `response'. >>> >>>> + >>>> +(defun package--confirm-tarball-upgrade (pkg-desc new-pkg-desc) >>>> +  "Show diff for tarball package upgrade and ask for confirmation. >>>> +Return t if user wants to proceed, nil otherwise." >>>> +  ;; Check exclusion lists first >>>> +  (let ((package-name (package-desc-name new-pkg-desc)) >>>> +        (package-archive (package-desc-archive new-pkg-desc))) >>>> +    ;; If package-show-upgrade-diffs is nil, or package/archive is >>>> excluded, proceed without diffs >>>> +    (if (or (not package-show-upgrade-diffs) >>>> +            (memq package-name package-upgrade-diff-exclude-packages) >>>> +            (member package-archive package-upgrade-diff-exclude-archives)) >>>> +        t  ; Skip diff checking, proceed with upgrade >>>> +      (let* ((temp-dir (make-temp-file "package-diff-" t)) >>>> +             (old-dir (package--get-installed-package-dir pkg-desc)) >>>> +             new-dir) >>>> +        (unwind-protect >>>> +            (progn >>>> +              ;; Download and extract new version to temp directory >>>> +              (let* ((location (package-archive-base new-pkg-desc)) >>>> +                     (file (concat (package-desc-full-name new-pkg-desc) >>>> +                                   (package-desc-suffix new-pkg-desc)))) >>>> +                (package--with-response-buffer location :file file >>>> +                  (setq new-dir (package--extract-tarball-to-temp >>>> +                                 (current-buffer) new-pkg-desc temp-dir)))) >>>> +              ;; Show diff and get user confirmation >>>> +              (if (file-exists-p old-dir) >>>> +                  (package--show-package-diff old-dir new-dir) >>>> +                ;; If no old version exists, just confirm >>>> +                (yes-or-no-p "New package installation. Continue? "))) >>>> +          ;; Clean up temp directory >>>> +          (when (file-exists-p temp-dir) >>>> +            (delete-directory temp-dir t))))))) >>> My preferred approach to solving this would be if we could split >>> `package-install-from-archive' or `package-unpack' into two, allowing us >>> to install the new package without compiling, generating autoloads, and >>> then to resume that part later on. This would require some refactoring, >>> but would allow us to express the upgrade procedure as >>> >>> 1. Fetch the new source but not process it, >>> >>> 2. Compute the diff and present it to the user, >>> >>> 3. If they are fine with the changes, delete old package and finish >>> initialising the package we just downloaded, >>> >>> 4. Otherwise we remove and forget about the code we had just downloaded >>> and keep everything as is. >>> >>> I imagine that this approach should keep the upgrade procedure more >>> uniform and setting aside changes caused by re-indenting code we factor >>> out of existing functionality, result in a simpler upgrade-logic. >> I see your point but I would generally be careful with performing "half" >> of the installation before showing the diff. Until the user has reviewed >> the diff, the new package should be considered malicious so it might be >> better if it does not yet end up in the ~/.config/emacs/elpa/ directory. >> Maybe a separate review directory could be used, e.g., >> ~/.config/emacs/package-review/ and then the package could be moved to >> the final destination in the end. > You are right, that is important to keep in mind. My main focus here is > that we should avoid downloading the package twice. FWIW it should be > fine if the package is first cloned into /tmp/ and then copied over to > ~/.config/emacs/elpa/ after being approved, or is your point with > .../package-review/ that the list of not-yet-reviewed should stay > persistent? > >> Generally regarding rollback, package.el is not robust right now (there >> is another bug about that). The original package can stay deleted if >> installation fails. This can happen due to multiple reasons - package >> archive metadata outdated, package tarball not available, some other >> failure during installation. In these case, Emacs can end up in a broken >> state with a missing package. > That is true and something I want to improve upon independently of this > bug report (but we shouldn't make it worse either). > > [...] --------------fbZRW2EvGyfUKUcjKcvjyeca Content-Type: text/plain; charset=UTF-8; name="0001-Enhance-package-upgrade-UI-with-interactive-y-n-d-c-.patch" Content-Disposition: attachment; filename*0="0001-Enhance-package-upgrade-UI-with-interactive-y-n-d-c-.pa"; filename*1="tch" Content-Transfer-Encoding: base64 RnJvbSBhNDFjOTM0YjljMzllOTllOWFhZjM3OTUxOWYwZDY2YTcxYjM5OTY2IE1vbiBTZXAg MTcgMDA6MDA6MDAgMjAwMQpGcm9tOiBOb2J1eXVraSBLYW1pbW90byA8a2FtaW1vdG81MjdA Z21haWwuY29tPgpEYXRlOiBGcmksIDEyIFNlcCAyMDI1IDIxOjEyOjUzICswOTAwClN1Ympl Y3Q6IFtQQVRDSF0gRW5oYW5jZSBwYWNrYWdlIHVwZ3JhZGUgVUkgd2l0aCBpbnRlcmFjdGl2 ZSB5L24vZC9jIHByb21wdHMKCkFkZCBpbnRlcmFjdGl2ZSBjb25maXJtYXRpb24gc3lzdGVt IGZvciBwYWNrYWdlIHVwZ3JhZGVzIHdpdGggb3B0aW9ucyBmb3I6Ci0gWWVzL05vIHVwZ3Jh ZGUgZGVjaXNpb25zCi0gRGlmZiBkaXNwbGF5IGJldHdlZW4gcGFja2FnZSB2ZXJzaW9ucwot IENoYW5nZWxvZyB2aWV3aW5nIHdpdGggZmlsZSBleGNsdXNpb24gcGF0dGVybnMKLSBDb25m aWd1cmFibGUgY29uZmlybWF0aW9uIHBvbGljeSBwZXIgcGFja2FnZS9hcmNoaXZlCgpJbmNs dWRlcyBjb21wcmVoZW5zaXZlIGRpZmYgdXRpbGl0aWVzIGZvciB0YXJiYWxsIHBhY2thZ2Vz IGFuZCBWQyBwYWNrYWdlcywKd2l0aCBwcm9wZXIgZXJyb3IgaGFuZGxpbmcgYW5kIHVzZXIt ZnJpZW5kbHkgZGlzcGxheSBidWZmZXJzLgotLS0KIGRvYy9lbWFjcy9wYWNrYWdlLnRleGkg ICAgICAgICAgfCAgNDIgKysrKwogZXRjL05FV1MgICAgICAgICAgICAgICAgICAgICAgICB8 ICAxMCArCiBsaXNwL3BhY2thZ2UvcGFja2FnZS1jb3JlLmVsICAgIHwgMTU4ICsrKysrKysr KysrKysrCiBsaXNwL3BhY2thZ2UvcGFja2FnZS1pbnN0YWxsLmVsIHwgMzU2ICsrKysrKysr KysrKysrKysrKysrKysrKysrKysrKystCiBsaXNwL3BhY2thZ2UvcGFja2FnZS1tZW51LmVs ICAgIHwgIDQ4ICsrKy0tCiBsaXNwL3BhY2thZ2UvcGFja2FnZS12Yy5lbCAgICAgIHwgMjE4 ICsrKysrKysrKysrKysrKy0tLS0KIDYgZmlsZXMgY2hhbmdlZCwgNzc0IGluc2VydGlvbnMo KyksIDU4IGRlbGV0aW9ucygtKQoKZGlmZiAtLWdpdCBhL2RvYy9lbWFjcy9wYWNrYWdlLnRl eGkgYi9kb2MvZW1hY3MvcGFja2FnZS50ZXhpCmluZGV4IDVhYTlmOWE3NGJmLi4zYjJhNTlk ZGEyMyAxMDA2NDQKLS0tIGEvZG9jL2VtYWNzL3BhY2thZ2UudGV4aQorKysgYi9kb2MvZW1h Y3MvcGFja2FnZS50ZXhpCkBAIC0zODksNiArMzg5LDM4IEBAIFBhY2thZ2UgSW5zdGFsbGF0 aW9uCiB1c2UgdGhlc2UgYnVsayBjb21tYW5kcyBpZiB5b3Ugd2FudCB0byB1cGRhdGUgb25s eSBhIHNtYWxsIG51bWJlciBvZgogYnVpbHQtaW4gcGFja2FnZXMuCiAKK0B2aW5kZXggcGFj a2FnZS11cGdyYWRlLWNvbmZpcm1hdGlvbi1wb2xpY3kKKyAgQnkgZGVmYXVsdCwgRW1hY3Mg c2hvd3MgYSBkaWZmIG9mIHRoZSBjaGFuZ2VzIHdoZW4gdXBncmFkaW5nCitwYWNrYWdlcywg YWxsb3dpbmcgeW91IHRvIHJldmlldyB3aGF0IGhhcyBjaGFuZ2VkIGJldHdlZW4gdGhlIGN1 cnJlbnQKK2FuZCBuZXcgdmVyc2lvbiBiZWZvcmUgcHJvY2VlZGluZy4gIFRoaXMgaXMgY29u dHJvbGxlZCBieSB0aGUKK0Bjb2Rle3BhY2thZ2UtdXBncmFkZS1jb25maXJtYXRpb24tcG9s aWN5fSB1c2VyIG9wdGlvbi4gIFdoZW4gc2V0IHRvIEBjb2Rle3R9ICh0aGUKK2RlZmF1bHQp LCBwYWNrYWdlIHVwZ3JhZGVzIHdpbGwgZGlzcGxheSB0aGUgZGlmZmVyZW5jZXMgYW5kIGFz ayBmb3IKK2NvbmZpcm1hdGlvbiBiZWZvcmUgcHJvY2VlZGluZy4gIFlvdSBjYW4gZGlzYWJs ZSB0aGlzIGJlaGF2aW9yIGJ5CitzZXR0aW5nIEBjb2Rle3BhY2thZ2UtdXBncmFkZS1jb25m aXJtYXRpb24tcG9saWN5fSB0byBAY29kZXtuaWx9IHRvIHVwZ3JhZGUKK2FsbCBwYWNrYWdl cyBhdXRvbWF0aWNhbGx5IHdpdGhvdXQgc2hvd2luZyBkaWZmcy4KKworICBZb3UgY2FuIGFs c28gc3BlY2lmeSB3aGljaCBwYWNrYWdlcyBvciBhcmNoaXZlcyByZXF1aXJlIGNvbmZpcm1h dGlvbiBieQorc2V0dGluZyBAY29kZXtwYWNrYWdlLXVwZ3JhZGUtY29uZmlybWF0aW9uLXBv bGljeX0gdG8gYSBsaXN0IG9mIHNwZWNpZmljCitwYWNrYWdlcyBhbmQgYXJjaGl2ZXMuICBP bmx5IHRoZSBwYWNrYWdlcyBhbmQgYXJjaGl2ZXMgaW4gdGhlIGxpc3Qgd2lsbCBzaG93Citj b25maXJtYXRpb24gcHJvbXB0cywgd2hpbGUgYWxsIG90aGVycyB3aWxsIHVwZ3JhZGUgYXV0 b21hdGljYWxseS4KKworQG5vaW5kZW50CitFeGFtcGxlcyBvZiBsaXN0LWJhc2VkIGNvbmZp Z3VyYXRpb246CisKK0BleGFtcGxlCis7OyBPbmx5IGNvbmZpcm0gbWFnaXQgYW5kIGhlbG0g dXBncmFkZXMsIGF1dG8tdXBncmFkZSBldmVyeXRoaW5nIGVsc2UKKyhzZXRxIHBhY2thZ2Ut dXBncmFkZS1jb25maXJtYXRpb24tcG9saWN5CisgICAgICAnKChwYWNrYWdlIG1hZ2l0KSAo cGFja2FnZSBoZWxtKSkpCisKKzs7IE9ubHkgY29uZmlybSBwYWNrYWdlcyBmcm9tIG1lbHBh IGFyY2hpdmUsIGF1dG8tdXBncmFkZSBvdGhlcnMKKyhzZXRxIHBhY2thZ2UtdXBncmFkZS1j b25maXJtYXRpb24tcG9saWN5CisgICAgICAnKChhcmNoaXZlICJtZWxwYSIpKSkKKworOzsg TWl4ZWQ6IGNvbmZpcm0gb3JnIHBhY2thZ2UgYW5kIGFsbCBtZWxwYS1zdGFibGUgcGFja2Fn ZXMKKyhzZXRxIHBhY2thZ2UtdXBncmFkZS1jb25maXJtYXRpb24tcG9saWN5CisgICAgICAn KChwYWNrYWdlIG9yZykgKGFyY2hpdmUgIm1lbHBhLXN0YWJsZSIpKSkKK0BlbmQgZXhhbXBs ZQorCiBAY2luZGV4IHBhY2thZ2UgcmVxdWlyZW1lbnRzCiAgIEEgcGFja2FnZSBtYXkgQGRm bntyZXF1aXJlfSBjZXJ0YWluIG90aGVyIHBhY2thZ2VzIHRvIGJlIGluc3RhbGxlZCwKIGJl Y2F1c2UgaXQgcmVsaWVzIG9uIGZ1bmN0aW9uYWxpdHkgcHJvdmlkZWQgYnkgdGhlbS4gIFdo ZW4gRW1hY3MKQEAgLTY1NSw2ICs2ODcsMTYgQEAgRmV0Y2hpbmcgUGFja2FnZSBTb3VyY2Vz CiAgIE5vdGUgdGhhdCBjdXJyZW50bHksIGJ1aWx0LWluIHBhY2thZ2VzIGNhbm5vdCBiZSB1 cGdyYWRlZCB1c2luZwogQGNvZGV7cGFja2FnZS12Yy1pbnN0YWxsfS4KIAorICBMaWtlIHJl Z3VsYXIgcGFja2FnZSB1cGdyYWRlcywgVkMgcGFja2FnZSB1cGdyYWRlcyBjYW4gYWxzbyBz aG93CitkaWZmcyBiZWZvcmUgcHJvY2VlZGluZy4gIFRoaXMgYmVoYXZpb3IgaXMgY29udHJv bGxlZCBieSB0aGUgc2FtZQorQGNvZGV7cGFja2FnZS11cGdyYWRlLWNvbmZpcm1hdGlvbi1w b2xpY3l9IHVzZXIgb3B0aW9uIHRoYXQgY29udHJvbHMgcmVndWxhcgorcGFja2FnZSB1cGdy YWRlcy4gIFdoZW4gc2V0IHRvIEBjb2Rle3R9ICh0aGUgZGVmYXVsdCksIHVwZ3JhZGluZyBW QworcGFja2FnZXMgd2lsbCBkaXNwbGF5IHRoZSBkaWZmZXJlbmNlcyBiZXR3ZWVuIHRoZSBj dXJyZW50IGFuZCB1cGRhdGVkCit2ZXJzaW9ucywgYWxsb3dpbmcgeW91IHRvIHJldmlldyB0 aGUgY2hhbmdlcyBiZWZvcmUgY29uZmlybWluZyB0aGUgdXBncmFkZS4KKworICBWQyBwYWNr YWdlcyB1c2UgdGhlIHNhbWUgY29uZmlybWF0aW9uIHBvbGljeSBhbmQgZmlsZSBleGNsdXNp b24gcGF0dGVybnMKK2FzIHJlZ3VsYXIgcGFja2FnZXMsIGVuc3VyaW5nIGNvbnNpc3RlbnQg YmVoYXZpb3IgYWNyb3NzIGFsbCBwYWNrYWdlIHR5cGVzLgorCiBAZmluZGV4IHBhY2thZ2Ut cmVwb3J0LWJ1ZwogQGZpbmRleCBwYWNrYWdlLXZjLXByZXBhcmUtcGF0Y2gKICAgV2l0aCB0 aGUgc291cmNlIGNoZWNrb3V0LCB5b3UgbWlnaHQgd2FudCB0byByZXByb2R1Y2UgYSBidWcg YWdhaW5zdApkaWZmIC0tZ2l0IGEvZXRjL05FV1MgYi9ldGMvTkVXUwppbmRleCBhYzhlNTYz MjZiZi4uOTA0NTkyNTc3YTAgMTAwNjQ0Ci0tLSBhL2V0Yy9ORVdTCisrKyBiL2V0Yy9ORVdT CkBAIC03NCw2ICs3NCwxNiBAQCBkb25lIGZyb20gZWFybHktaW5pdC5lbCwgc3VjaCBhcyBh ZGRpbmcgdG8gJ3BhY2thZ2UtZGlyZWN0b3J5LWxpc3QnLgogKiogJ3ByZXR0aWZ5LXN5bWJv bHMtbW9kZScgYXR0ZW1wdHMgdG8gaWdub3JlIHVuZGlzcGxheWFibGUgY2hhcmFjdGVycy4K IFByZXZpb3VzbHksIHN1Y2ggY2hhcmFjdGVycyB3b3VsZCBiZSByZW5kZXJlZCBhcywgZS5n Liwgd2hpdGUgYm94ZXMuCiAKKysrKworKiogUGFja2FnZSBtYW5hZ2VtZW50IG5vdyBzaG93 cyBkaWZmcyBiZWZvcmUgdXBncmFkZXMuCitQYWNrYWdlIHVwZ3JhZGVzIHdpbGwgbm93IGRp c3BsYXkgZGlmZmVyZW5jZXMgYmV0d2VlbiB0aGUgY3VycmVudCBhbmQKK25ldyB2ZXJzaW9u IGJlZm9yZSBwcm9jZWVkaW5nLiAgVGhpcyBhcHBsaWVzIHRvIGJvdGggcmVndWxhciBwYWNr YWdlcworYW5kIFZDIHBhY2thZ2VzIGluc3RhbGxlZCBmcm9tIHZlcnNpb24gY29udHJvbCBy ZXBvc2l0b3JpZXMuCisKK1VzZXJzIHdpbGwgc2VlIGEgZGlmZiBidWZmZXIgc2hvd2luZyBj aGFuZ2VzIGFuZCBjYW4gY2hvb3NlIHdoZXRoZXIgdG8KK3Byb2NlZWQgd2l0aCBvciBjYW5j ZWwgdGhlIHVwZ3JhZGUuICBUaGlzIGJlaGF2aW9yIGNhbiBiZSBjb250cm9sbGVkCit0aHJv dWdoIHRoZSAncGFja2FnZS11cGdyYWRlLWNvbmZpcm1hdGlvbi1wb2xpY3knIHVzZXIgb3B0 aW9uLgorCiArKysKICoqICdzdGFuZGFyZC1kaXNwbGF5LXRhYmxlJyBub3cgaGFzIG1vcmUg ZXh0cmEgc2xvdHMuCiAnc3RhbmRhcmQtZGlzcGxheS10YWJsZScgaGFzIGJlZW4gZXh0ZW5k ZWQgdG8gYWxsb3cgc3BlY2lmeWluZyBnbHlwaHMKZGlmZiAtLWdpdCBhL2xpc3AvcGFja2Fn ZS9wYWNrYWdlLWNvcmUuZWwgYi9saXNwL3BhY2thZ2UvcGFja2FnZS1jb3JlLmVsCmluZGV4 IGU1MjY1NGFhNTNkLi5iMGIxODMxZTFlZCAxMDA2NDQKLS0tIGEvbGlzcC9wYWNrYWdlL3Bh Y2thZ2UtY29yZS5lbAorKysgYi9saXNwL3BhY2thZ2UvcGFja2FnZS1jb3JlLmVsCkBAIC0y ODQsNiArMjg0LDE2NCBAQCBwYWNrYWdlLXNlbGVjdGVkLXBhY2thZ2VzCiAgIDp2ZXJzaW9u ICIyNS4xIgogICA6dHlwZSAnKHJlcGVhdCBzeW1ib2wpKQogCis7OyBJbnRlcmFjdGl2ZSB1 cGdyYWRlIHByb21wdCBjb25zdGFudHMKKyhkZWZjb25zdCBwYWNrYWdlLXVwZ3JhZGUtaW50 ZXJhY3RpdmUtY29tbWFuZHMKKyAgJygoP3kgLiB1cGdyYWRlKQorICAgICg/biAuIGNhbmNl bCkKKyAgICAoP2QgLiBzaG93LWRpZmYpCisgICAgKD9jIC4gc2hvdy1jaGFuZ2Vsb2cpCisg ICAgKD9xIC4gcXVpdCkpCisgICJJbnRlcmFjdGl2ZSBjb21tYW5kcyBmb3IgcGFja2FnZSB1 cGdyYWRlIGNvbmZpcm1hdGlvbi4iKQorCisoZGVmY29uc3QgcGFja2FnZS11cGdyYWRlLXBy b21wdC1tZXNzYWdlCisgICJVcGdyYWRlICVzPyAoeSllcywgKG4pbywgKGQpaWZmLCAoYylo YW5nZWxvZywgKHEpdWl0OiAiCisgICJQcm9tcHQgbWVzc2FnZSBmb3JtYXQgZm9yIHBhY2th Z2UgdXBncmFkZSBjb25maXJtYXRpb24uIikKKworKGRlZmNvbnN0IHBhY2thZ2UtZGlmZi1j b250ZXh0LWxpbmVzIDMKKyAgIk51bWJlciBvZiBjb250ZXh0IGxpbmVzIHRvIHNob3cgaW4g cGFja2FnZSBhbmQgY2hhbmdlbG9nIGRpZmZzLiIpCisKKyhkZWZjb25zdCBwYWNrYWdlLWNo YW5nZWxvZy1tYXgtc2l6ZSAoKiAxMDI0IDEwMjQpCisgICJNYXhpbXVtIHNpemUgaW4gYnl0 ZXMgZm9yIGNoYW5nZWxvZyBmaWxlcyB0byBwcm9jZXNzLiIpCisKKyhkZWZjdXN0b20gcGFj a2FnZS11cGdyYWRlLWNvbmZpcm1hdGlvbi1wb2xpY3kgdAorICAiUG9saWN5IGZvciBjb25m aXJtaW5nIHBhY2thZ2VzIGR1cmluZyB1cGdyYWRlcy4KK1RoaXMgZGV0ZXJtaW5lcyB3aGlj aCBwYWNrYWdlcyByZXF1aXJlIHVzZXIgY29uZmlybWF0aW9uIGJlZm9yZSB1cGdyYWRpbmcu CisKK1Bvc3NpYmxlIHZhbHVlczoKKworXFw9YHRcXD0nIC0gRGVmYXVsdAorICAgIFNob3cg ZGlmZnMgYW5kIHByb21wdCBmb3IgYWxsIHBhY2thZ2UgdXBncmFkZXMuCisKK1xcPWBuaWxc XD0nCisgICAgQXV0b21hdGljYWxseSB1cGdyYWRlIGFsbCBwYWNrYWdlcyB3aXRob3V0IHNo b3dpbmcgZGlmZnMuCisKK0EgbGlzdCBvZiBzcGVjaWZpYyBwYWNrYWdlcy9hcmNoaXZlcyB0 byBjb25maXJtCisgICAgT25seSB0aGUgcGFja2FnZXMgYW5kIGFyY2hpdmVzIGxpc3RlZCB3 aWxsIHNob3cgY29uZmlybWF0aW9uIHByb21wdHMuCisgICAgQWxsIG90aGVycyB3aWxsIGJl IHVwZ3JhZGVkIGF1dG9tYXRpY2FsbHkuCisKKyAgICBMaXN0IGZvcm1hdDoKKyAgICAocGFj a2FnZSBQQUNLQUdFLVNZTUJPTCkgIC0gU2hvdyBkaWZmIGZvciB0aGlzIHNwZWNpZmljIHBh Y2thZ2UKKyAgICAoYXJjaGl2ZSBBUkNISVZFLU5BTUUpICAgIC0gU2hvdyBkaWZmIGZvciBh bGwgcGFja2FnZXMgaW4gdGhpcyBhcmNoaXZlCisKK0V4YW1wbGVzOgorICAgIFxcPScoKHBh Y2thZ2UgbWFnaXQpIChwYWNrYWdlIGhlbG0pKQorICAgICAgICAtIE9ubHkgY29uZmlybSBt YWdpdCBhbmQgaGVsbSB1cGdyYWRlcworICAgICAgICAtIEFsbCBvdGhlciBwYWNrYWdlcyB1 cGdyYWRlIGF1dG9tYXRpY2FsbHkKKworICAgIFxcPScoKGFyY2hpdmUgXCJtZWxwYVwiKSAo cGFja2FnZSBvcmcpKQorICAgICAgICAtIENvbmZpcm0gYWxsIG1lbHBhIGFyY2hpdmUgcGFj a2FnZXMKKyAgICAgICAgLSBDb25maXJtIG9yZyBwYWNrYWdlIHVwZ3JhZGVzCisgICAgICAg IC0gQWxsIG90aGVyIHBhY2thZ2VzIHVwZ3JhZGUgYXV0b21hdGljYWxseQorCisgICAgXFw9 JygocGFja2FnZSBtYWdpdCkpCisgICAgICAgIC0gT25seSBjb25maXJtIG1hZ2l0IHVwZ3Jh ZGVzCisgICAgICAgIC0gQWxsIG90aGVyIHBhY2thZ2VzIHVwZ3JhZGUgYXV0b21hdGljYWxs eSIKKyAgOnR5cGUgJyhjaG9pY2UKKyAgICAgICAgICAoY29uc3QgOnRhZyAiQWx3YXlzIHNo b3cgZGlmZnMiIHQpCisgICAgICAgICAgKGNvbnN0IDp0YWcgIk5ldmVyIHNob3cgZGlmZnMi IG5pbCkKKyAgICAgICAgICAocmVwZWF0IDp0YWcgIlNwZWNpZmljIHBhY2thZ2VzL2FyY2hp dmVzIHRvIGNvbmZpcm0iCisgICAgICAgICAgICAgICAgICAoY2hvaWNlCisgICAgICAgICAg ICAgICAgICAgKGxpc3QgOnRhZyAiUGFja2FnZSBydWxlIiAoY29uc3QgcGFja2FnZSkgc3lt Ym9sKQorICAgICAgICAgICAgICAgICAgIChsaXN0IDp0YWcgIkFyY2hpdmUgcnVsZSIgKGNv bnN0IGFyY2hpdmUpIHN0cmluZykpKSkKKyAgOnZlcnNpb24gIjMxLjEiKQorCisoZGVmdW4g cGFja2FnZS0tbWF0Y2gtcnVsZS1wIChydWxlIHBhY2thZ2UtbmFtZSBwYWNrYWdlLWFyY2hp dmUpCisgICJDaGVjayBpZiBSVUxFIG1hdGNoZXMgUEFDS0FHRS1OQU1FIGFuZCBQQUNLQUdF LUFSQ0hJVkUuIgorICAocGNhc2UgcnVsZQorICAgIChgKHBhY2thZ2UgLG5hbWUpIChlcSBu YW1lIHBhY2thZ2UtbmFtZSkpCisgICAgKGAoYXJjaGl2ZSAsYXJjaGl2ZSkgKHN0cmluZz0g YXJjaGl2ZSBwYWNrYWdlLWFyY2hpdmUpKQorICAgIChfIG5pbCkpKQorCisoZGVmdW4gcGFj a2FnZS0tc2hvdWxkLXNob3ctZGlmZi1wIChwa2ctZGVzYykKKyAgIkNoZWNrIGlmIGRpZmYg c2hvdWxkIGJlIHNob3duIGZvciBQS0ctREVTQyBiYXNlZCBvbiBjb25maXJtYXRpb24gcG9s aWN5LiIKKyAgKGxldCAoKHBhY2thZ2UtbmFtZSAocGFja2FnZS1kZXNjLW5hbWUgcGtnLWRl c2MpKQorICAgICAgICAocGFja2FnZS1hcmNoaXZlIChwYWNrYWdlLWRlc2MtYXJjaGl2ZSBw a2ctZGVzYykpCisgICAgICAgIChwb2xpY3kgcGFja2FnZS11cGdyYWRlLWNvbmZpcm1hdGlv bi1wb2xpY3kpKQorICAgIChjb25kCisgICAgICgoZXEgcG9saWN5IHQpIHQpCisgICAgICgo ZXEgcG9saWN5IG5pbCkgbmlsKQorICAgICAoKGxpc3RwIHBvbGljeSkKKyAgICAgIDs7IExp c3QgbW9kZTogb25seSBzaG93IGRpZmYgZm9yIHBhY2thZ2VzL2FyY2hpdmVzIGluIHRoZSBs aXN0CisgICAgICAoc2VxLXNvbWUgKGxhbWJkYSAocnVsZSkKKyAgICAgICAgICAgICAgICAg IChwYWNrYWdlLS1tYXRjaC1ydWxlLXAgcnVsZSBwYWNrYWdlLW5hbWUgcGFja2FnZS1hcmNo aXZlKSkKKyAgICAgICAgICAgICAgICBwb2xpY3kpKQorICAgICAodCB0KSkpKQorCisoZGVm Y3VzdG9tIHBhY2thZ2UtY2hhbmdlbG9nLXBhdHRlcm5zCisgICcoIkNIQU5HRUxPRyoiICJO RVdTKiIgIkNoYW5nZUxvZyoiICJDSEFOR0VTKiIgIkhJU1RPUlkqIikKKyAgIkZpbGUgcGF0 dGVybnMgdG8gbWF0Y2ggY2hhbmdlbG9nIGZpbGVzLiIKKyAgOnR5cGUgJyhyZXBlYXQgc3Ry aW5nKQorICA6dmVyc2lvbiAiMzEuMSIpCisKKyhkZWZ2YXIgcGFja2FnZS1jaGFuZ2Vsb2ct ZmlsZS1yZWdleAorICAoY29uY2F0ICJcXCgiIChtYXBjb25jYXQgKGxhbWJkYSAocGF0dGVy bikKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIChyZXBsYWNlLXJlZ2V4cC1pbi1zdHJp bmcgIlxcKiIgIi4qIiBwYXR0ZXJuKSkKKyAgICAgICAgICAgICAgICAgICAgICAgICBwYWNr YWdlLWNoYW5nZWxvZy1wYXR0ZXJucyAiXFx8IikgIlxcKSIpCisgICJSZWd1bGFyIGV4cHJl c3Npb24gdG8gbWF0Y2ggY2hhbmdlbG9nIGZpbGVzIGJhc2VkIG9uIHBhdHRlcm5zLiIpCisK Kzs7IENoYW5nZWxvZyBmaWxlIHV0aWxpdGllcworKGRlY2xhcmUtZnVuY3Rpb24gZGlmZi1u by1zZWxlY3QgImRpZmYiIChvbGQgbmV3ICZvcHRpb25hbCBzd2l0Y2hlcyBuby1hc3luYykp CisKKyhkZWZ1biBwYWNrYWdlLS1maW5kLWNoYW5nZWxvZy1maWxlcyAoZGlyZWN0b3J5KQor ICAiRmluZCBhbGwgY2hhbmdlbG9nIGZpbGVzIGluIERJUkVDVE9SWSB1c2luZyByZWd1bGFy IGV4cHJlc3Npb24gbWF0Y2hpbmcuCitSZXR1cm5zIGEgbGlzdCBvZiBwYXRocyB0byBhbGwg bWF0Y2hpbmcgY2hhbmdlbG9nIGZpbGVzIGZvdW5kLCBvciBuaWwgaWYgbm9uZS4iCisgICh3 aGVuIChhbmQgZGlyZWN0b3J5IChzdHJpbmdwIGRpcmVjdG9yeSkgKGZpbGUtZGlyZWN0b3J5 LXAgZGlyZWN0b3J5KSkKKyAgICAoY29uZGl0aW9uLWNhc2UgZXJyCisgICAgICAgIChsZXQg KChmaWxlcyAoZGlyZWN0b3J5LWZpbGVzIGRpcmVjdG9yeSB0ICJeW14uXSIgdCkpCisgICAg ICAgICAgICAgIChjYW5kaWRhdGVzIG5pbCkpCisgICAgICAgICAgOzsgQ29sbGVjdCBhbGwg bWF0Y2hpbmcgZmlsZXMKKyAgICAgICAgICAoZG9saXN0IChmaWxlIGZpbGVzKQorICAgICAg ICAgICAgKHdoZW4gKGFuZCAoZmlsZS1yZWd1bGFyLXAgZmlsZSkKKyAgICAgICAgICAgICAg ICAgICAgICAgKGZpbGUtcmVhZGFibGUtcCBmaWxlKQorICAgICAgICAgICAgICAgICAgICAg ICAobGV0ICgoYmFzZW5hbWUgKGZpbGUtbmFtZS1ub25kaXJlY3RvcnkgZmlsZSkpKQorICAg ICAgICAgICAgICAgICAgICAgICAgIChzdHJpbmctbWF0Y2gtcCBwYWNrYWdlLWNoYW5nZWxv Zy1maWxlLXJlZ2V4CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg IChkb3duY2FzZSBiYXNlbmFtZSkpKSkKKyAgICAgICAgICAgICAgKHB1c2ggZmlsZSBjYW5k aWRhdGVzKSkpCisgICAgICAgICAgOzsgUmV0dXJuIGFsbCBjYW5kaWRhdGVzIHNvcnRlZCBi eSBuYW1lIGZvciBjb25zaXN0ZW50IG9yZGVyaW5nCisgICAgICAgICAgKHNvcnQgY2FuZGlk YXRlcyAjJ3N0cmluZzwpKQorICAgICAgKGZpbGUtZXJyb3IKKyAgICAgICAobWVzc2FnZSAi RmlsZSBhY2Nlc3MgZXJyb3Igc2VhcmNoaW5nIGZvciBjaGFuZ2Vsb2cgZmlsZXMgaW4gJXM6 ICVzIgorICAgICAgICAgICAgICAgIGRpcmVjdG9yeSAoZXJyb3ItbWVzc2FnZS1zdHJpbmcg ZXJyKSkKKyAgICAgICBuaWwpCisgICAgICAoZXJyb3IKKyAgICAgICAobWVzc2FnZSAiRXJy b3Igc2VhcmNoaW5nIGZvciBjaGFuZ2Vsb2cgZmlsZXMgaW4gJXM6ICVzIgorICAgICAgICAg ICAgICAgIGRpcmVjdG9yeSAoZXJyb3ItbWVzc2FnZS1zdHJpbmcgZXJyKSkKKyAgICAgICBu aWwpKSkpCisKKyhkZWZ1biBwYWNrYWdlLS1kaWZmLWF2YWlsYWJsZS1wICgpCisgICJDaGVj ayBpZiBkaWZmIGZ1bmN0aW9uYWxpdHkgaXMgYXZhaWxhYmxlLgorU2luY2Ugd2UgdXNlIGJ1 aWx0LWluIEVtYWNzIGRpZmYgZnVuY3Rpb25zLCB0aGlzIGFsd2F5cyByZXR1cm5zIHQuIgor ICAocmVxdWlyZSAnZGlmZikKKyAgdCkKKworKGRlZnVuIHBhY2thZ2UtLWRpZmYtY2hhbmdl bG9nLWZpbGVzIChvbGQtZmlsZSBuZXctZmlsZSkKKyAgIkdlbmVyYXRlIHVuaWZpZWQgZGlm ZiBiZXR3ZWVuIE9MRC1GSUxFIGFuZCBORVctRklMRS4KK1JldHVybnMgZGlmZiBvdXRwdXQg YXMgc3RyaW5nLCBvciBuaWwgaWYgZGlmZiBpcyBub3QgYXZhaWxhYmxlLiIKKyAgKHdoZW4g KGFuZCBvbGQtZmlsZSBuZXctZmlsZQorICAgICAgICAgICAgIChmaWxlLWV4aXN0cy1wIG9s ZC1maWxlKQorICAgICAgICAgICAgIChmaWxlLWV4aXN0cy1wIG5ldy1maWxlKQorICAgICAg ICAgICAgIChwYWNrYWdlLS1kaWZmLWF2YWlsYWJsZS1wKSkKKyAgICAobGV0ICgob2xkLXNp emUgKG50aCA3IChmaWxlLWF0dHJpYnV0ZXMgb2xkLWZpbGUpKSkKKyAgICAgICAgICAobmV3 LXNpemUgKG50aCA3IChmaWxlLWF0dHJpYnV0ZXMgbmV3LWZpbGUpKSkpCisgICAgICA7OyBD aGVjayBmaWxlIHNpemUgbGltaXRzCisgICAgICAod2hlbiAoYW5kICg8IG9sZC1zaXplIHBh Y2thZ2UtY2hhbmdlbG9nLW1heC1zaXplKQorICAgICAgICAgICAgICAgICAoPCBuZXctc2l6 ZSBwYWNrYWdlLWNoYW5nZWxvZy1tYXgtc2l6ZSkpCisgICAgICAgIChsZXQgKChkaWZmLWJ1 ZmZlciAoZGlmZi1uby1zZWxlY3Qgb2xkLWZpbGUgbmV3LWZpbGUKKyAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoZm9ybWF0ICItLXVuaWZpZWQ9JWQiIHBh Y2thZ2UtZGlmZi1jb250ZXh0LWxpbmVzKSB0KSkpCisgICAgICAgICAgKHdoZW4gZGlmZi1i dWZmZXIKKyAgICAgICAgICAgICh3aXRoLWN1cnJlbnQtYnVmZmVyIGRpZmYtYnVmZmVyCisg ICAgICAgICAgICAgIChsZXQgKChkaWZmLW91dHB1dCAoYnVmZmVyLXN0cmluZykpKQorICAg ICAgICAgICAgICAgIChraWxsLWJ1ZmZlciBkaWZmLWJ1ZmZlcikKKyAgICAgICAgICAgICAg ICAod2hlbiAoPiAobGVuZ3RoIGRpZmYtb3V0cHV0KSAwKQorICAgICAgICAgICAgICAgICAg ZGlmZi1vdXRwdXQpKSkpKSkpKSkKKworKGRlZnVuIHBhY2thZ2UtLWZvcm1hdC1jaGFuZ2Vs b2ctZGlmZiAoKQorICAiRm9ybWF0IGFuZCBoaWdobGlnaHQgZGlmZiBvdXRwdXQgaW4gY3Vy cmVudCBidWZmZXIuCitVc2VzIGRpZmYtbW9kZSBmZWF0dXJlcyBmb3Igc3ludGF4IGhpZ2hs aWdodGluZy4iCisgICh3aGVuIChmYm91bmRwICdkaWZmLW1vZGUpCisgICAgKGRpZmYtbW9k ZSkKKyAgICAoZm9udC1sb2NrLWVuc3VyZSkpKQorCiA7OyBQc2V1ZG8gZmllbGRzLgogKGRl ZnVuIHBhY2thZ2UtdmVyc2lvbi1qb2luICh2bGlzdCkKICAgIlJldHVybiB0aGUgdmVyc2lv biBzdHJpbmcgY29ycmVzcG9uZGluZyB0byB0aGUgbGlzdCBWTElTVC4KZGlmZiAtLWdpdCBh L2xpc3AvcGFja2FnZS9wYWNrYWdlLWluc3RhbGwuZWwgYi9saXNwL3BhY2thZ2UvcGFja2Fn ZS1pbnN0YWxsLmVsCmluZGV4IDg0MDFhNzc2OWI3Li4zNDQ2OGMxMDliNSAxMDA2NDQKLS0t IGEvbGlzcC9wYWNrYWdlL3BhY2thZ2UtaW5zdGFsbC5lbAorKysgYi9saXNwL3BhY2thZ2Uv cGFja2FnZS1pbnN0YWxsLmVsCkBAIC0zODAsNiArMzgwLDcgQEAgcGFja2FnZS1pbnN0YWxs CiAgICAgICAobWVzc2FnZSAiYCVzJyBpcyBhbHJlYWR5IGluc3RhbGxlZCIgbmFtZSkpKSkK IAogKGRlY2xhcmUtZnVuY3Rpb24gcGFja2FnZS12Yy11cGdyYWRlICJwYWNrYWdlLXZjIiAo cGtnKSkKKyhkZWNsYXJlLWZ1bmN0aW9uIGRpZmYtbm8tc2VsZWN0ICJkaWZmIiAob2xkIG5l dyAmb3B0aW9uYWwgc3dpdGNoZXMgbm8tYXN5bmMpKQogCiA7OzsjIyNhdXRvbG9hZAogKGRl ZnVuIHBhY2thZ2UtdXBncmFkZSAobmFtZSkKQEAgLTM5MiwxNiArMzkzLDI2IEBAIHBhY2th Z2UtdXBncmFkZQogICAgICAgICAgICAgICAgICAgKHBhY2thZ2UtLXVwZ3JhZGVhYmxlLXBh Y2thZ2VzIHQpIG5pbCB0KSkpKQogICAoY2wtY2hlY2stdHlwZSBuYW1lIHN5bWJvbCkKICAg KGxldCogKChwa2ctZGVzYyAoY2FkciAoYXNzcSBuYW1lIHBhY2thZ2UtYWxpc3QpKSkKLSAg ICAgICAgIChwYWNrYWdlLWluc3RhbGwtdXBncmFkZS1idWlsdC1pbiAobm90IHBrZy1kZXNj KSkpCisgICAgICAgICAocGFja2FnZS1pbnN0YWxsLXVwZ3JhZGUtYnVpbHQtaW4gKG5vdCBw a2ctZGVzYykpCisgICAgICAgICAobmV3LXBrZy1kZXNjIChjYWRyIChhc3NxIG5hbWUgcGFj a2FnZS1hcmNoaXZlLWNvbnRlbnRzKSkpKQogICAgIDs7IGBwa2ctZGVzYycgd2lsbCBiZSBu aWwgd2hlbiB0aGUgcGFja2FnZSBpcyBhbiAiYWN0aXZlIGJ1aWx0LWluIi4KICAgICAoaWYg KGFuZCBwa2ctZGVzYyAocGFja2FnZS12Yy1wIHBrZy1kZXNjKSkKICAgICAgICAgKHBhY2th Z2UtdmMtdXBncmFkZSBwa2ctZGVzYykKLSAgICAgICh3aGVuIHBrZy1kZXNjCi0gICAgICAg IChwYWNrYWdlLWRlbGV0ZSBwa2ctZGVzYyAnZm9yY2UgJ2RvbnQtdW5zZWxlY3QpKQotICAg ICAgKHBhY2thZ2UtaW5zdGFsbCBuYW1lCi0gICAgICAgICAgICAgICAgICAgICAgIDs7IEFu IGFjdGl2ZSBidWlsdC1pbiBoYXMgbmV2ZXIgYmVlbiAic2VsZWN0ZWQiCi0gICAgICAgICAg ICAgICAgICAgICAgIDs7IGJlZm9yZS4gIE1hcmsgaXQgYXMgaW5zdGFsbGVkIGV4cGxpY2l0 bHkuCi0gICAgICAgICAgICAgICAgICAgICAgIChhbmQgcGtnLWRlc2MgJ2RvbnQtc2VsZWN0 KSkpKSkKKyAgICAgIDs7IENoZWNrIGlmIHRoaXMgaXMgYSB0YXJiYWxsIHBhY2thZ2UgdXBn cmFkZSB0aGF0IG5lZWRzIGRpZmYgY29uZmlybWF0aW9uCisgICAgICAoaWYgKGFuZCBwa2ct ZGVzYyBuZXctcGtnLWRlc2MKKyAgICAgICAgICAgICAgIChlcSAocGFja2FnZS1kZXNjLWtp bmQgbmV3LXBrZy1kZXNjKSAndGFyKSkKKyAgICAgICAgICA7OyBGb3IgdGFyYmFsbCBwYWNr YWdlcywgc2hvdyBkaWZmIGFuZCBhc2sgZm9yIGNvbmZpcm1hdGlvbgorICAgICAgICAgIDs7 IFRoZSBmdW5jdGlvbiBub3cgaGFuZGxlcyB0aGUgY29tcGxldGUgdXBncmFkZSBwcm9jZXNz IGludGVybmFsbHkKKyAgICAgICAgICAodW5sZXNzIChwYWNrYWdlLS1jb25maXJtLXRhcmJh bGwtdXBncmFkZSBwa2ctZGVzYyBuZXctcGtnLWRlc2MpCisgICAgICAgICAgICAobWVzc2Fn ZSAiUGFja2FnZSB1cGdyYWRlIGNhbmNlbGxlZCIpKQorICAgICAgICA7OyBGb3Igbm9uLXRh cmJhbGwgcGFja2FnZXMsIHByb2NlZWQgd2l0aCBub3JtYWwgdXBncmFkZQorICAgICAgICAo cHJvZ24KKyAgICAgICAgICAod2hlbiBwa2ctZGVzYworICAgICAgICAgICAgKHBhY2thZ2Ut ZGVsZXRlIHBrZy1kZXNjICdmb3JjZSAnZG9udC11bnNlbGVjdCkpCisgICAgICAgICAgKHBh Y2thZ2UtaW5zdGFsbCBuYW1lCisgICAgICAgICAgICAgICAgICAgICAgICAgICA7OyBBbiBh Y3RpdmUgYnVpbHQtaW4gaGFzIG5ldmVyIGJlZW4gInNlbGVjdGVkIgorICAgICAgICAgICAg ICAgICAgICAgICAgICAgOzsgYmVmb3JlLiAgTWFyayBpdCBhcyBpbnN0YWxsZWQgZXhwbGlj aXRseS4KKyAgICAgICAgICAgICAgICAgICAgICAgICAgIChhbmQgcGtnLWRlc2MgJ2RvbnQt c2VsZWN0KSkpKSkpKQogCiAoZGVmdW4gcGFja2FnZS0tdXBncmFkZWFibGUtcGFja2FnZXMg KCZvcHRpb25hbCBpbmNsdWRlLWJ1aWx0aW5zKQogICA7OyBJbml0aWFsaXplIHRoZSBwYWNr YWdlIHN5c3RlbSB0byBnZXQgdGhlIGxpc3Qgb2YgcGFja2FnZQpAQCAtMTEwOCw1ICsxMTE5 LDMzNiBAQCBwYWNrYWdlLXJlY29tcGlsZS1hbGwKICAgICAod2l0aC1kZW1vdGVkLWVycm9y cyAiRXJyb3Igd2hpbGUgcmVjb21waWxpbmc6ICVTIgogICAgICAgKHBhY2thZ2UtcmVjb21w aWxlIHBrZy1kZXNjKSkpKQogCis7OyBQYWNrYWdlIHVwZ3JhZGUgZGlmZiB1dGlsaXRpZXMK KworKGRlZnVuIHBhY2thZ2UtLXNhZmUtaW5zZXJ0LWZpbGUgKGZpbGUgJm9wdGlvbmFsIGVy cm9yLW1zZykKKyAgIlNhZmVseSBpbnNlcnQgRklMRSBjb250ZW50cywgc2hvd2luZyBFUlJP Ui1NU0cgb24gZmFpbHVyZS4iCisgIChjb25kaXRpb24tY2FzZSBlcnIKKyAgICAgICh3aGVu IChhbmQgZmlsZSAoZmlsZS1yZWFkYWJsZS1wIGZpbGUpKQorICAgICAgICAoaW5zZXJ0LWZp bGUtY29udGVudHMgZmlsZSkpCisgICAgKGZpbGUtZXJyb3IKKyAgICAgKGluc2VydCAob3Ig ZXJyb3ItbXNnCisgICAgICAgICAgICAgICAgIChmb3JtYXQgIkZpbGUgYWNjZXNzIGVycm9y OiAlcyIgKGVycm9yLW1lc3NhZ2Utc3RyaW5nIGVycikpKSkpCisgICAgKGVycm9yCisgICAg IChpbnNlcnQgKG9yIGVycm9yLW1zZworICAgICAgICAgICAgICAgICAoZm9ybWF0ICJFcnJv ciByZWFkaW5nIGZpbGU6ICVzIiAoZXJyb3ItbWVzc2FnZS1zdHJpbmcgZXJyKSkpKSkpKQor CisoZGVmdW4gcGFja2FnZS0tc2hvdy1jaGFuZ2Vsb2cgKG9sZC1kaXIgbmV3LWRpcikKKyAg IlNob3cgZGlmZiBvZiBhbGwgY2hhbmdlbG9nIGZpbGVzIGJldHdlZW4gT0xELURJUiBhbmQg TkVXLURJUi4KK0Rpc3BsYXlzIHVuaWZpZWQgZGlmZiBzaG93aW5nIHdoYXQgY2hhbmdlZCBp biBhbGwgbWF0Y2hlZCBjaGFuZ2Vsb2cgZmlsZXMuCitSZXR1cm5zIHQgaWYgYW55IGNoYW5n ZWxvZyBkaWZmIHdhcyBkaXNwbGF5ZWQsIG5pbCBvdGhlcndpc2UuIgorICAobGV0ICgob2xk LWNoYW5nZWxvZ3MgKHdoZW4gb2xkLWRpciAocGFja2FnZS0tZmluZC1jaGFuZ2Vsb2ctZmls ZXMgb2xkLWRpcikpKQorICAgICAgICAobmV3LWNoYW5nZWxvZ3MgKHdoZW4gbmV3LWRpciAo cGFja2FnZS0tZmluZC1jaGFuZ2Vsb2ctZmlsZXMgbmV3LWRpcikpKQorICAgICAgICAoZGlz cGxheWVkLWFueSBuaWwpKQorICAgIChjb25kCisgICAgIDs7IEJvdGggZGlyZWN0b3JpZXMg aGF2ZSBjaGFuZ2Vsb2cgZmlsZXMKKyAgICAgKChvciBvbGQtY2hhbmdlbG9ncyBuZXctY2hh bmdlbG9ncykKKyAgICAgIChzZXRxIGRpc3BsYXllZC1hbnkgKHBhY2thZ2UtLWRpc3BsYXkt YWxsLWNoYW5nZWxvZy1kaWZmcyBvbGQtY2hhbmdlbG9ncyBuZXctY2hhbmdlbG9ncykpKQor ICAgICA7OyBObyBjaGFuZ2Vsb2cgZmlsZXMgZm91bmQgaW4gZWl0aGVyIGRpcmVjdG9yeQor ICAgICAodAorICAgICAgKG1lc3NhZ2UgIk5vIGNoYW5nZWxvZyBmaWxlcyBmb3VuZCIpCisg ICAgICBuaWwpKQorICAgIGRpc3BsYXllZC1hbnkpKQorCisoZGVmdW4gcGFja2FnZS0tZGlz cGxheS1hbGwtY2hhbmdlbG9nLWRpZmZzIChvbGQtZmlsZXMgbmV3LWZpbGVzKQorICAiRGlz cGxheSBkaWZmcyBmb3IgYWxsIGNoYW5nZWxvZyBmaWxlcyBiZXR3ZWVuIE9MRC1GSUxFUyBh bmQgTkVXLUZJTEVTLgorUmV0dXJucyB0IGlmIGFueSBkaWZmIHdhcyBkaXNwbGF5ZWQsIG5p bCBvdGhlcndpc2UuIgorICAobGV0ICgoYnVmZmVyLW5hbWUgIipQYWNrYWdlIENoYW5nZWxv ZyBEaWZmKiIpCisgICAgICAgIChkaXNwbGF5ZWQtYW55IG5pbCkKKyAgICAgICAgKHVuaXF1 ZS1maWxlbmFtZXMgbmlsKSkKKyAgICA7OyBLaWxsIGV4aXN0aW5nIGJ1ZmZlciBpZiBpdCBl eGlzdHMKKyAgICAod2hlbiAoZ2V0LWJ1ZmZlciBidWZmZXItbmFtZSkKKyAgICAgIChraWxs LWJ1ZmZlciBidWZmZXItbmFtZSkpCisKKyAgICA7OyBHZXQgdW5pcXVlIGZpbGVuYW1lcyBm cm9tIGJvdGggbGlzdHMKKyAgICAoc2V0cSB1bmlxdWUtZmlsZW5hbWVzCisgICAgICAgICAg KGRlbGV0ZS1kdXBzCisgICAgICAgICAgIChhcHBlbmQgKG1hcGNhciAjJ2ZpbGUtbmFtZS1u b25kaXJlY3Rvcnkgb2xkLWZpbGVzKQorICAgICAgICAgICAgICAgICAgIChtYXBjYXIgIydm aWxlLW5hbWUtbm9uZGlyZWN0b3J5IG5ldy1maWxlcykpKSkKKworICAgICh3aXRoLWN1cnJl bnQtYnVmZmVyIChnZXQtYnVmZmVyLWNyZWF0ZSBidWZmZXItbmFtZSkKKyAgICAgIChsZXQg KChpbmhpYml0LXJlYWQtb25seSB0KSkKKyAgICAgICAgKGVyYXNlLWJ1ZmZlcikKKyAgICAg ICAgKGluc2VydCAiQ2hhbmdlbG9nIGRpZmZlcmVuY2VzIGJldHdlZW4gb2xkIGFuZCBuZXcg dmVyc2lvbnM6XG4iKQorICAgICAgICAoaW5zZXJ0IChtYWtlLXN0cmluZyA1NSA/PSkpCisg ICAgICAgIChpbnNlcnQgIlxuXG4iKQorCisgICAgICAgIDs7IFByb2Nlc3MgZWFjaCB1bmlx dWUgZmlsZW5hbWUKKyAgICAgICAgKGRvbGlzdCAoZmlsZW5hbWUgdW5pcXVlLWZpbGVuYW1l cykKKyAgICAgICAgICAobGV0ICgob2xkLWZpbGUgKGNhciAoc2VxLWZpbHRlciAobGFtYmRh IChmKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHN0 cmluZz0gZmlsZW5hbWUgKGZpbGUtbmFtZS1ub25kaXJlY3RvcnkgZikpKQorICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9sZC1maWxlcykpKQorICAgICAg ICAgICAgICAgIChuZXctZmlsZSAoY2FyIChzZXEtZmlsdGVyIChsYW1iZGEgKGYpCisgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoc3RyaW5nPSBmaWxl bmFtZSAoZmlsZS1uYW1lLW5vbmRpcmVjdG9yeSBmKSkpCisgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgbmV3LWZpbGVzKSkpKQorICAgICAgICAgICAgKGNv bmQKKyAgICAgICAgICAgICA7OyBCb3RoIG9sZCBhbmQgbmV3IHZlcnNpb25zIGV4aXN0OiBz aG93IGRpZmYKKyAgICAgICAgICAgICAoKGFuZCBvbGQtZmlsZSBuZXctZmlsZSkKKyAgICAg ICAgICAgICAgKHBhY2thZ2UtLWluc2VydC1maWxlLWRpZmYgZmlsZW5hbWUgb2xkLWZpbGUg bmV3LWZpbGUpCisgICAgICAgICAgICAgIChzZXRxIGRpc3BsYXllZC1hbnkgdCkpCisgICAg ICAgICAgICAgOzsgT25seSBuZXcgZmlsZSBleGlzdHM6IHNob3cgYXMgbmV3IGFkZGl0aW9u CisgICAgICAgICAgICAgKChhbmQgKG5vdCBvbGQtZmlsZSkgbmV3LWZpbGUpCisgICAgICAg ICAgICAgIChwYWNrYWdlLS1pbnNlcnQtbmV3LWZpbGUgZmlsZW5hbWUgbmV3LWZpbGUpCisg ICAgICAgICAgICAgIChzZXRxIGRpc3BsYXllZC1hbnkgdCkpCisgICAgICAgICAgICAgOzsg T25seSBvbGQgZmlsZSBleGlzdHM6IHNob3cgYXMgcmVtb3ZhbAorICAgICAgICAgICAgICgo YW5kIG9sZC1maWxlIChub3QgbmV3LWZpbGUpKQorICAgICAgICAgICAgICAoaW5zZXJ0IChm b3JtYXQgIi0tLSAlcyAoUkVNT1ZFRCBpbiBuZXcgdmVyc2lvbikgLS0tXG5cbiIgZmlsZW5h bWUpKQorICAgICAgICAgICAgICAoc2V0cSBkaXNwbGF5ZWQtYW55IHQpKSkpKQorCisgICAg ICAgIChpZiBkaXNwbGF5ZWQtYW55CisgICAgICAgICAgICAocHJvZ24KKyAgICAgICAgICAg ICAgKHBhY2thZ2UtLWZvcm1hdC1jaGFuZ2Vsb2ctZGlmZikKKyAgICAgICAgICAgICAgKGdv dG8tY2hhciAocG9pbnQtbWluKSkKKyAgICAgICAgICAgICAgKHJlYWQtb25seS1tb2RlIDEp KQorICAgICAgICAgIChpbnNlcnQgIk5vIGNoYW5nZWxvZyBkaWZmZXJlbmNlcyBmb3VuZC5c biIpCisgICAgICAgICAgKHJlYWQtb25seS1tb2RlIDEpKSkKKworICAgICAgKGRpc3BsYXkt YnVmZmVyIGJ1ZmZlci1uYW1lKQorICAgICAgZGlzcGxheWVkLWFueSkpKQorCisoZGVmdW4g cGFja2FnZS0taW5zZXJ0LWZpbGUtZGlmZiAoZmlsZW5hbWUgb2xkLWZpbGUgbmV3LWZpbGUp CisgICJJbnNlcnQgZGlmZiBjb250ZW50IGZvciBhIHNpbmdsZSBmaWxlIGludG8gY3VycmVu dCBidWZmZXIuIgorICAoaW5zZXJ0IChmb3JtYXQgIi0tLSAlcyAtLS1cbiIgZmlsZW5hbWUp KQorICAobGV0ICgoZGlmZi1vdXRwdXQgKHBhY2thZ2UtLWRpZmYtY2hhbmdlbG9nLWZpbGVz IG9sZC1maWxlIG5ldy1maWxlKSkpCisgICAgKGlmIGRpZmYtb3V0cHV0CisgICAgICAgIChp bnNlcnQgZGlmZi1vdXRwdXQpCisgICAgICA7OyBGYWxsYmFjayBpZiBkaWZmIGlzIHVuYXZh aWxhYmxlCisgICAgICAoaW5zZXJ0ICJEaWZmIHVuYXZhaWxhYmxlLiBTaG93aW5nIGZ1bGwg bmV3IGNvbnRlbnQ6XG4iKQorICAgICAgKHBhY2thZ2UtLXNhZmUtaW5zZXJ0LWZpbGUgbmV3 LWZpbGUpKQorICAgIChpbnNlcnQgIlxuXG4iKSkpCisKKyhkZWZ1biBwYWNrYWdlLS1pbnNl cnQtbmV3LWZpbGUgKGZpbGVuYW1lIG5ldy1maWxlKQorICAiSW5zZXJ0IG5ldyBmaWxlIGNv bnRlbnQgaW50byBjdXJyZW50IGJ1ZmZlci4iCisgIChpbnNlcnQgKGZvcm1hdCAiLS0tICVz IChORVcgaW4gdGhpcyB2ZXJzaW9uKSAtLS1cbiIgZmlsZW5hbWUpKQorICAocGFja2FnZS0t c2FmZS1pbnNlcnQtZmlsZSBuZXctZmlsZSkKKyAgKGluc2VydCAiXG5cbiIpKQorCisoZGVm dW4gcGFja2FnZS0tc2hvdy1wYWNrYWdlLWRpZmYgKG9sZC1kaXIgbmV3LWRpciBwa2ctZGVz YykKKyAgIlNob3cgZGlmZiBiZXR3ZWVuIE9MRC1ESVIgYW5kIE5FVy1ESVIgcGFja2FnZSBk aXJlY3RvcmllcyBmb3IgUEtHLURFU0MuCitUaGlzIGZ1bmN0aW9uIG9ubHkgZGlzcGxheXMg dGhlIGRpZmYgd2l0aG91dCBwcm9tcHRpbmcgZm9yIHVzZXIgY29uZmlybWF0aW9uLiIKKyAg OzsgRW5zdXJlIGRpZmYgaXMgbG9hZGVkIGFuZCByZWFkeSBiZWZvcmUgcHJvY2VlZGluZwor ICAocmVxdWlyZSAnZGlmZikKKyAgOzsgRW5zdXJlIGRpZmYgZmVhdHVyZSBpcyBmdWxseSBs b2FkZWQgb24gZmlyc3QgcnVuCisgICh1bmxlc3MgKGZlYXR1cmVwICdkaWZmKQorICAgIChz aXQtZm9yIDAuMSkpCisgIDs7IEFkZGl0aW9uYWwgc2FmZXR5OiBlbnN1cmUgZGlmZiBmdW5j dGlvbnMgYXJlIGF2YWlsYWJsZQorICAodW5sZXNzIChmYm91bmRwICdkaWZmLW1vZGUpCisg ICAgKGF1dG9sb2FkICdkaWZmLW1vZGUgImRpZmYiICJEaWZmIG1ham9yIG1vZGUiIHQpKQor ICAoY29uZGl0aW9uLWNhc2Ugb3V0ZXItZXJyCisgICAgICAobGV0ICgoZGlmZi1idWZmZXIt bmFtZSAiKlBhY2thZ2UgRGlmZioiKSkKKyAgICAgICAgOzsgS2lsbCBleGlzdGluZyBidWZm ZXIgdG8gYXZvaWQgcmVhZC1vbmx5IGlzc3VlcworICAgICAgICAod2hlbiAoZ2V0LWJ1ZmZl ciBkaWZmLWJ1ZmZlci1uYW1lKQorICAgICAgICAgIChraWxsLWJ1ZmZlciBkaWZmLWJ1ZmZl ci1uYW1lKSkKKworICAgICAgICA7OyBDaGVjayBpZiBkaXJlY3RvcmllcyBleGlzdCBiZWZv cmUgcHJvY2VlZGluZworICAgICAgICAodW5sZXNzIChhbmQgKGZpbGUtZGlyZWN0b3J5LXAg b2xkLWRpcikgKGZpbGUtZGlyZWN0b3J5LXAgbmV3LWRpcikpCisgICAgICAgICAgKGVycm9y ICJPbmUgb3IgYm90aCBkaXJlY3RvcmllcyBkbyBub3QgZXhpc3Q6ICVzLCAlcyIgb2xkLWRp ciBuZXctZGlyKSkKKworICAgICAgICAoY29uZGl0aW9uLWNhc2UgZGlmZi1lcnIKKyAgICAg ICAgICAgIDs7IFVzZSBidWlsdC1pbiBkaWZmLW5vLXNlbGVjdCBpbnN0ZWFkIG9mIGV4dGVy bmFsIGNvbW1hbmRzCisgICAgICAgICAgICAobGV0ICgoZGlmZi1idWZmZXIgKGRpZmYtbm8t c2VsZWN0IG9sZC1kaXIgbmV3LWRpciAiLS11bmlmaWVkIiB0KSkpCisgICAgICAgICAgICAg IChpZiBkaWZmLWJ1ZmZlcgorICAgICAgICAgICAgICAgICAgKHByb2duCisgICAgICAgICAg ICAgICAgICAgIDs7IFNhZmVseSBjb25maWd1cmUgZGlmZiBidWZmZXIgYmVmb3JlIHJlbmFt aW5nCisgICAgICAgICAgICAgICAgICAgICh3aXRoLWN1cnJlbnQtYnVmZmVyIGRpZmYtYnVm ZmVyCisgICAgICAgICAgICAgICAgICAgICAgOzsgRW5zdXJlIGRpZmYtbW9kZSBpcyBwcm9w ZXJseSBpbml0aWFsaXplZCBmaXJzdAorICAgICAgICAgICAgICAgICAgICAgICh3aGVuIChm Ym91bmRwICdkaWZmLW1vZGUpCisgICAgICAgICAgICAgICAgICAgICAgICAoZGlmZi1tb2Rl KSkKKyAgICAgICAgICAgICAgICAgICAgICA7OyBDb25maWd1cmUgYnVmZmVyIGZvciBzdGFi bGUgc2Nyb2xsaW5nCisgICAgICAgICAgICAgICAgICAgICAgKHNldHEgYnVmZmVyLXJlYWQt b25seSB0KQorICAgICAgICAgICAgICAgICAgICAgIChzZXRxIHRydW5jYXRlLWxpbmVzIG5p bCkgIDsgQWxsb3cgbGluZSB3cmFwcGluZworICAgICAgICAgICAgICAgICAgICAgIDs7IERp c2FibGUgcG90ZW50aWFsbHkgcHJvYmxlbWF0aWMgZGlmZiBmZWF0dXJlcworICAgICAgICAg ICAgICAgICAgICAgICh3aGVuIChib3VuZHAgJ2RpZmYtcmVmaW5lLWh1bmspCisgICAgICAg ICAgICAgICAgICAgICAgICAoc2V0IChtYWtlLWxvY2FsLXZhcmlhYmxlICdkaWZmLXJlZmlu ZS1odW5rKSBuaWwpKQorICAgICAgICAgICAgICAgICAgICAgIChnb3RvLWNoYXIgKHBvaW50 LW1pbikpCisgICAgICAgICAgICAgICAgICAgICAgOzsgTm93IHNhZmVseSByZW5hbWUgdGhl IGJ1ZmZlcgorICAgICAgICAgICAgICAgICAgICAgIChyZW5hbWUtYnVmZmVyIGRpZmYtYnVm ZmVyLW5hbWUgdCkpCisgICAgICAgICAgICAgICAgICAgIDs7IERpc3BsYXkgdGhlIHByb3Bl cmx5IGNvbmZpZ3VyZWQgYnVmZmVyCisgICAgICAgICAgICAgICAgICAgIChkaXNwbGF5LWJ1 ZmZlciBkaWZmLWJ1ZmZlci1uYW1lKSkKKyAgICAgICAgICAgICAgICA7OyBObyBkaWZmZXJl bmNlcyBmb3VuZAorICAgICAgICAgICAgICAgICh3aXRoLWN1cnJlbnQtYnVmZmVyIChnZXQt YnVmZmVyLWNyZWF0ZSBkaWZmLWJ1ZmZlci1uYW1lKQorICAgICAgICAgICAgICAgICAgKGxl dCAoKGluaGliaXQtcmVhZC1vbmx5IHQpKQorICAgICAgICAgICAgICAgICAgICAoZXJhc2Ut YnVmZmVyKQorICAgICAgICAgICAgICAgICAgICAoaW5zZXJ0IChmb3JtYXQgIk5vIHNpZ25p ZmljYW50IGRpZmZlcmVuY2VzIGZvdW5kIGJldHdlZW4gb2xkIGFuZCBuZXcgdmVyc2lvbnMg b2YgJXMuXG4iCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAocGFja2Fn ZS1kZXNjLW5hbWUgcGtnLWRlc2MpKSkKKyAgICAgICAgICAgICAgICAgICAgKGdvdG8tY2hh ciAocG9pbnQtbWluKSkKKyAgICAgICAgICAgICAgICAgICAgKHJlYWQtb25seS1tb2RlIDEp KQorICAgICAgICAgICAgICAgICAgKGRpc3BsYXktYnVmZmVyIGRpZmYtYnVmZmVyLW5hbWUp KSkpCisgICAgICAgICAgKGVycm9yCisgICAgICAgICAgIDs7IElmIGRpZmYgZmFpbHMsIGNy ZWF0ZSBhIHNpbXBsZSBlcnJvciBtZXNzYWdlCisgICAgICAgICAgICh3aXRoLWN1cnJlbnQt YnVmZmVyIChnZXQtYnVmZmVyLWNyZWF0ZSBkaWZmLWJ1ZmZlci1uYW1lKQorICAgICAgICAg ICAgIChsZXQgKChpbmhpYml0LXJlYWQtb25seSB0KSkKKyAgICAgICAgICAgICAgIChlcmFz ZS1idWZmZXIpCisgICAgICAgICAgICAgICAoaW5zZXJ0IChmb3JtYXQgIkVycm9yIHJ1bm5p bmcgZGlmZiBvcGVyYXRpb246ICVzXG5cbiIgKGVycm9yLW1lc3NhZ2Utc3RyaW5nIGRpZmYt ZXJyKSkpCisgICAgICAgICAgICAgICAoaW5zZXJ0ICJUaGlzIG1heSBiZSBkdWUgdG86XG4i KQorICAgICAgICAgICAgICAgKGluc2VydCAiLSBGaWxlIGFjY2VzcyBwZXJtaXNzaW9uc1xu IikKKyAgICAgICAgICAgICAgIChpbnNlcnQgIi0gRGlyZWN0b3J5IHN0cnVjdHVyZSBpc3N1 ZXNcbiIpCisgICAgICAgICAgICAgICAoaW5zZXJ0ICItIE1lbW9yeSBsaW1pdGF0aW9ucyBm b3IgbGFyZ2UgZGlmZnNcbiIpCisgICAgICAgICAgICAgICAocmVhZC1vbmx5LW1vZGUgMSkp CisgICAgICAgICAgICAgKGRpc3BsYXktYnVmZmVyIGRpZmYtYnVmZmVyLW5hbWUpKSkpCisg ICAgICAgIDs7IFJldHVybiB0IHRvIGluZGljYXRlIHN1Y2Nlc3MKKyAgICAgICAgdCkKKyAg ICAoZXJyb3IKKyAgICAgKG1lc3NhZ2UgIkVycm9yIHNob3dpbmcgcGFja2FnZSBkaWZmOiAl cyAoUmV0cnkgbWF5IHdvcmspIiAoZXJyb3ItbWVzc2FnZS1zdHJpbmcgb3V0ZXItZXJyKSkK KyAgICAgOzsgUmV0dXJuIG5pbCB0byBpbmRpY2F0ZSBmYWlsdXJlIGJ1dCBhbGxvdyByZXRy eQorICAgICBuaWwpKSkKKworKGRlZnVuIHBhY2thZ2UtLWhhbmRsZS1pbnRlcmFjdGl2ZS1j b21tYW5kIChjb21tYW5kIHBrZy1kZXNjIG9sZC1kaXIgbmV3LWRpcikKKyAgIkhhbmRsZSBp bnRlcmFjdGl2ZSBDT01NQU5EIGZvciBQS0ctREVTQyB1cGdyYWRlLiIKKyAgKHBjYXNlIGNv bW1hbmQKKyAgICAoJ3VwZ3JhZGUgJ3VwZ3JhZGUpCisgICAgKCdjYW5jZWwgJ2NhbmNlbCkK KyAgICAoJ3Nob3ctZGlmZgorICAgICAoY29uZGl0aW9uLWNhc2UgZXJyCisgICAgICAgICAo aWYgKGFuZCBvbGQtZGlyIG5ldy1kaXIpCisgICAgICAgICAgICAgKHByb2duCisgICAgICAg ICAgICAgICAobGV0ICgocmVzdWx0IChwYWNrYWdlLS1zaG93LXBhY2thZ2UtZGlmZiBvbGQt ZGlyIG5ldy1kaXIgcGtnLWRlc2MpKSkKKyAgICAgICAgICAgICAgICAgKGlmIHJlc3VsdAor ICAgICAgICAgICAgICAgICAgICAgKG1lc3NhZ2UgIkRpZmYgZGlzcGxheWVkLiBQcmVzcyB5 IHRvIHVwZ3JhZGUsIG4gdG8gY2FuY2VsLCBjIGZvciBjaGFuZ2Vsb2cuIikKKyAgICAgICAg ICAgICAgICAgICAobWVzc2FnZSAiRGlmZiBkaXNwbGF5IGZhaWxlZC4gUGxlYXNlIHRyeSBh Z2FpbiBvciB1c2UgY2hhbmdlbG9nIChjKS4iKSkpKQorICAgICAgICAgICAobWVzc2FnZSAi UGFja2FnZSBkaXJlY3RvcmllcyBub3QgYXZhaWxhYmxlIGZvciBkaWZmLiIpKQorICAgICAg IChlcnJvcgorICAgICAgICAobWVzc2FnZSAiRXJyb3IgZGlzcGxheWluZyBkaWZmOiAlcyAo VHJ5IGFnYWluIHdpdGggJ2QnIG9yIHVzZSBjaGFuZ2Vsb2cgd2l0aCAnYycpIgorICAgICAg ICAgICAgICAgICAoZXJyb3ItbWVzc2FnZS1zdHJpbmcgZXJyKSkpKQorICAgICA7OyBBbHdh eXMgcmV0dXJuIG5pbCB0byBwcmV2ZW50IHByb2Nlc3MgdGVybWluYXRpb24KKyAgICAgbmls KQorICAgICgnc2hvdy1jaGFuZ2Vsb2cKKyAgICAgKGNvbmRpdGlvbi1jYXNlIGVycgorICAg ICAgICAgKGlmIChwYWNrYWdlLS1zaG93LWNoYW5nZWxvZyBvbGQtZGlyIG5ldy1kaXIpCisg ICAgICAgICAgICAgKG1lc3NhZ2UgIkNoYW5nZWxvZyBkaXNwbGF5ZWQuIFByZXNzIHkgdG8g dXBncmFkZSwgbiB0byBjYW5jZWwsIGQgZm9yIGZ1bGwgZGlmZi4iKQorICAgICAgICAgICAo bWVzc2FnZSAiTm8gY2hhbmdlbG9nIGRpZmZlcmVuY2VzIGZvdW5kLiBQcmVzcyB5IHRvIHVw Z3JhZGUsIG4gdG8gY2FuY2VsLiIpKQorICAgICAgIChlcnJvcgorICAgICAgICAobWVzc2Fn ZSAiRXJyb3IgZGlzcGxheWluZyBjaGFuZ2Vsb2c6ICVzIiAoZXJyb3ItbWVzc2FnZS1zdHJp bmcgZXJyKSkpKQorICAgICBuaWwpCisgICAgKCdxdWl0ICdxdWl0KQorICAgIChfCisgICAg IChtZXNzYWdlICJJbnZhbGlkIGNob2ljZS4gVXNlOiB5PXVwZ3JhZGUsIG49Y2FuY2VsLCBk PWRpZmYsIGM9Y2hhbmdlbG9nLCBxPXF1aXQiKQorICAgICAoc2l0LWZvciAxLjUpCisgICAg IG5pbCkpKQorCisoZGVmdW4gcGFja2FnZS0tdXBncmFkZS1pbnRlcmFjdGl2ZS1wcm9tcHQg KHBrZy1kZXNjICZvcHRpb25hbCBvbGQtZGlyIG5ldy1kaXIpCisgICJJbnRlcmFjdGl2ZSBw cm9tcHQgZm9yIHBhY2thZ2UgdXBncmFkZSBjb25maXJtYXRpb24uIgorICAobGV0ICgocGFj a2FnZS1uYW1lIChwYWNrYWdlLWRlc2MtbmFtZSBwa2ctZGVzYykpCisgICAgICAgIChwcm9t cHQtY2hvaWNlcyAobWFwY2FyICMnY2FyIHBhY2thZ2UtdXBncmFkZS1pbnRlcmFjdGl2ZS1j b21tYW5kcykpKQorICAgIChjYXRjaCAncmVzdWx0CisgICAgICAod2hpbGUgdAorICAgICAg ICAoY29uZGl0aW9uLWNhc2UgZXJyCisgICAgICAgICAgICAobGV0KiAoKGNob2ljZSAocmVh ZC1jaGFyLWNob2ljZQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIChmb3JtYXQgcGFj a2FnZS11cGdyYWRlLXByb21wdC1tZXNzYWdlIHBhY2thZ2UtbmFtZSkKKyAgICAgICAgICAg ICAgICAgICAgICAgICAgICBwcm9tcHQtY2hvaWNlcykpCisgICAgICAgICAgICAgICAgICAg KGNvbW1hbmQgKGNkciAoYXNzcSBjaG9pY2UgcGFja2FnZS11cGdyYWRlLWludGVyYWN0aXZl LWNvbW1hbmRzKSkpCisgICAgICAgICAgICAgICAgICAgKHJlc3VsdCAocGFja2FnZS0taGFu ZGxlLWludGVyYWN0aXZlLWNvbW1hbmQgY29tbWFuZCBwa2ctZGVzYyBvbGQtZGlyIG5ldy1k aXIpKSkKKyAgICAgICAgICAgICAgKHdoZW4gcmVzdWx0CisgICAgICAgICAgICAgICAgKHRo cm93ICdyZXN1bHQgcmVzdWx0KSkpCisgICAgICAgICAgKHF1aXQKKyAgICAgICAgICAgKG1l c3NhZ2UgIlBhY2thZ2UgdXBncmFkZSBjYW5jZWxsZWQgYnkgdXNlciIpCisgICAgICAgICAg ICh0aHJvdyAncmVzdWx0ICdjYW5jZWwpKQorICAgICAgICAgIChlcnJvcgorICAgICAgICAg ICAobWVzc2FnZSAiRXJyb3IgZHVyaW5nIGlucHV0OiAlcyIgKGVycm9yLW1lc3NhZ2Utc3Ry aW5nIGVycikpCisgICAgICAgICAgIChzaXQtZm9yIDEpKSkpKSkpCisKKyhkZWZ1biBwYWNr YWdlLS1nZXQtaW5zdGFsbGVkLXBhY2thZ2UtZGlyIChwa2ctZGVzYykKKyAgIkdldCBkaXJl Y3Rvcnkgb2YgaW5zdGFsbGVkIFBLRy1ERVNDIHBhY2thZ2UuIgorICAoZXhwYW5kLWZpbGUt bmFtZSAocGFja2FnZS1kZXNjLWZ1bGwtbmFtZSBwa2ctZGVzYykgcGFja2FnZS11c2VyLWRp cikpCisKKyhkZWZ1biBwYWNrYWdlLWV4dHJhY3QgKHBrZy1kZXNjKQorICAiRXh0cmFjdCBw YWNrYWdlIFBLRy1ERVNDIGZpbGVzIHdpdGhvdXQgZ2VuZXJhdGluZyBhdXRvbG9hZHMgb3Ig ZGVzY3JpcHRvcnMuCitPbmx5IHBlcmZvcm1zIGZpbGUgZXh0cmFjdGlvbiBiYXNlZCBvbiBw YWNrYWdlIGtpbmQuICBSZXR1cm5zIHRoZSBwYWNrYWdlCitkaXJlY3RvcnkgcGF0aCB3aGVy ZSBmaWxlcyB3ZXJlIGV4dHJhY3RlZC4iCisgIChsZXQqICgobmFtZSAocGFja2FnZS1kZXNj LW5hbWUgcGtnLWRlc2MpKQorICAgICAgICAgKGRpcm5hbWUgKHBhY2thZ2UtZGVzYy1mdWxs LW5hbWUgcGtnLWRlc2MpKQorICAgICAgICAgKHBrZy1kaXIgKGV4cGFuZC1maWxlLW5hbWUg ZGlybmFtZSBwYWNrYWdlLXVzZXItZGlyKSkpCisgICAgOzsgRXh0cmFjdCBmaWxlcyBiYXNl ZCBvbiBwYWNrYWdlIGtpbmQKKyAgICAocGNhc2UgKHBhY2thZ2UtZGVzYy1raW5kIHBrZy1k ZXNjKQorICAgICAgKCdkaXIKKyAgICAgICAobWFrZS1kaXJlY3RvcnkgcGtnLWRpciB0KQor ICAgICAgIChsZXQgKChmaWxlLWxpc3QKKyAgICAgICAgICAgICAgKG9yIChhbmQgKGRlcml2 ZWQtbW9kZS1wICdkaXJlZC1tb2RlKQorICAgICAgICAgICAgICAgICAgICAgICAoZGlyZWQt Z2V0LW1hcmtlZC1maWxlcykpCisgICAgICAgICAgICAgICAgICAoZGlyZWN0b3J5LWZpbGVz LXJlY3Vyc2l2ZWx5IGRlZmF1bHQtZGlyZWN0b3J5ICIiIG5pbCkpKSkKKyAgICAgICAgIChk b2xpc3QgKHNvdXJjZS1maWxlIGZpbGUtbGlzdCkKKyAgICAgICAgICAgKGxldCAoKHRhcmdl dCAoZXhwYW5kLWZpbGUtbmFtZQorICAgICAgICAgICAgICAgICAgICAgICAgICAoZmlsZS1y ZWxhdGl2ZS1uYW1lIHNvdXJjZS1maWxlIGRlZmF1bHQtZGlyZWN0b3J5KQorICAgICAgICAg ICAgICAgICAgICAgICAgICBwa2ctZGlyKSkpCisgICAgICAgICAgICAgKG1ha2UtZGlyZWN0 b3J5IChmaWxlLW5hbWUtZGlyZWN0b3J5IHRhcmdldCkgdCkKKyAgICAgICAgICAgICAoY29w eS1maWxlIHNvdXJjZS1maWxlIHRhcmdldCB0KSkpCisgICAgICAgICA7OyBOb3cgdGhhdCB0 aGUgZmlsZXMgaGF2ZSBiZWVuIGluc3RhbGxlZCwgdGhpcyBwYWNrYWdlIGlzCisgICAgICAg ICA7OyBpbmRpc3Rpbmd1aXNoYWJsZSBmcm9tIGEgYHRhcicgb3IgYSBgc2luZ2xlJy4gTGV0 J3MgbWFrZQorICAgICAgICAgOzsgdGhpbmdzIHNpbXBsZSBieSBlbnN1cmluZyB3ZSdyZSBv bmUgb2YgdGhlbS4KKyAgICAgICAgIChzZXRmIChwYWNrYWdlLWRlc2Mta2luZCBwa2ctZGVz YykKKyAgICAgICAgICAgICAgIChpZiAobGVuZ3RoPiBmaWxlLWxpc3QgMSkgJ3RhciAnc2lu Z2xlKSkpKQorICAgICAgKCd0YXIKKyAgICAgICAobWFrZS1kaXJlY3RvcnkgcGFja2FnZS11 c2VyLWRpciB0KQorICAgICAgIChsZXQqICgoZGVmYXVsdC1kaXJlY3RvcnkgKGZpbGUtbmFt ZS1hcy1kaXJlY3RvcnkgcGFja2FnZS11c2VyLWRpcikpKQorICAgICAgICAgKHBhY2thZ2Ut dW50YXItYnVmZmVyIGRpcm5hbWUpKSkKKyAgICAgICgnc2luZ2xlCisgICAgICAgKGxldCAo KGVsLWZpbGUgKGV4cGFuZC1maWxlLW5hbWUgKGZvcm1hdCAiJXMuZWwiIG5hbWUpIHBrZy1k aXIpKSkKKyAgICAgICAgIChtYWtlLWRpcmVjdG9yeSBwa2ctZGlyIHQpCisgICAgICAgICAo cGFja2FnZS0td3JpdGUtZmlsZS1uby1jb2RpbmcgZWwtZmlsZSkpKQorICAgICAgKGtpbmQg KGVycm9yICJVbmtub3duIHBhY2thZ2Uga2luZDogJVMiIGtpbmQpKSkKKyAgICA7OyBSZXR1 cm4gdGhlIGRpcmVjdG9yeSBwYXRoIChubyBhdXRvbG9hZHMgZ2VuZXJhdGlvbiB5ZXQpCisg ICAgcGtnLWRpcikpCisKKyhkZWZ1biBwYWNrYWdlLS1kb3dubG9hZC1hbmQtZXh0cmFjdCAo bmV3LXBrZy1kZXNjKQorICAiRG93bmxvYWQgYW5kIGV4dHJhY3QgTkVXLVBLRy1ERVNDLiBS ZXR1cm4gZXh0cmFjdGlvbiBkaXJlY3RvcnkuIgorICAobGV0ICgobG9jYXRpb24gKHBhY2th Z2UtYXJjaGl2ZS1iYXNlIG5ldy1wa2ctZGVzYykpCisgICAgICAgIChmaWxlIChjb25jYXQg KHBhY2thZ2UtZGVzYy1mdWxsLW5hbWUgbmV3LXBrZy1kZXNjKQorICAgICAgICAgICAgICAg ICAgICAgIChwYWNrYWdlLWRlc2Mtc3VmZml4IG5ldy1wa2ctZGVzYykpKSkKKyAgICAocGFj a2FnZS0td2l0aC1yZXNwb25zZS1idWZmZXIgbG9jYXRpb24gOmZpbGUgZmlsZQorICAgICAg KHBhY2thZ2UtZXh0cmFjdCBuZXctcGtnLWRlc2MpKSkpCisKKyhkZWZ1biBwYWNrYWdlLS1j b25maXJtLXVwZ3JhZGUgKF9wa2ctZGVzYyBuZXctcGtnLWRlc2Mgb2xkLWRpciBuZXctZGly KQorICAiQXNrIHVzZXIgdG8gY29uZmlybSB1cGdyYWRlIGZyb20gX1BLRy1ERVNDIHRvIE5F Vy1QS0ctREVTQy4iCisgIChpZiAoZmlsZS1leGlzdHMtcCBvbGQtZGlyKQorICAgICAgKGxl dCAoKHJlc3VsdCAocGFja2FnZS0tdXBncmFkZS1pbnRlcmFjdGl2ZS1wcm9tcHQgbmV3LXBr Zy1kZXNjIG9sZC1kaXIgbmV3LWRpcikpKQorICAgICAgICAoY29uZAorICAgICAgICAgKChl cSByZXN1bHQgJ3VwZ3JhZGUpIHQpCisgICAgICAgICAoKGVxIHJlc3VsdCAncXVpdCkgKHVz ZXItZXJyb3IgIlBhY2thZ2UgdXBncmFkZSBjYW5jZWxsZWQgYnkgdXNlciIpKQorICAgICAg ICAgKHQgbmlsKSkpCisgICAgKHllcy1vci1uby1wIChmb3JtYXQgIk5ldyBwYWNrYWdlIGlu c3RhbGxhdGlvbjogJXMuIENvbnRpbnVlPyAiCisgICAgICAgICAgICAgICAgICAgICAgICAg KHBhY2thZ2UtZGVzYy1uYW1lIG5ldy1wa2ctZGVzYykpKSkpCisKKyhkZWZ1biBwYWNrYWdl LS1jb21wbGV0ZS11cGdyYWRlIChwa2ctZGVzYyBuZXctcGtnLWRlc2MgbmV3LWRpcikKKyAg IkNvbXBsZXRlIHRoZSB1cGdyYWRlIHByb2Nlc3MgZnJvbSBQS0ctREVTQyB0byBORVctUEtH LURFU0MuIgorICAod2hlbiBwa2ctZGVzYworICAgIChwYWNrYWdlLWRlbGV0ZSBwa2ctZGVz YyAnZm9yY2UgJ2RvbnQtdW5zZWxlY3QpKQorICAod2hlbiAoYW5kIG5ldy1kaXIgKGZpbGUt ZGlyZWN0b3J5LXAgbmV3LWRpcikpCisgICAgKGRlbGV0ZS1kaXJlY3RvcnkgbmV3LWRpciB0 KSkKKyAgKHBhY2thZ2UtaW5zdGFsbC1mcm9tLWFyY2hpdmUgbmV3LXBrZy1kZXNjKSkKKwor KGRlZnVuIHBhY2thZ2UtLWNvbmZpcm0tdGFyYmFsbC11cGdyYWRlIChwa2ctZGVzYyBuZXct cGtnLWRlc2MpCisgICJDb25maXJtIGFuZCBleGVjdXRlIHRhcmJhbGwgcGFja2FnZSB1cGdy YWRlLgorCitUaGlzIGZ1bmN0aW9uIGhhbmRsZXMgdGhlIGNvbXBsZXRlIHRhcmJhbGwgdXBn cmFkZSB3b3JrZmxvdzoKKzEuIENoZWNrIGlmIGRpZmYgZGlzcGxheSBpcyByZXF1aXJlZCBi YXNlZCBvbiB0cnVzdCBwb2xpY3kKKzIuIERvd25sb2FkIGFuZCBleHRyYWN0IG5ldyBwYWNr YWdlIGZvciBjb21wYXJpc29uCiszLiBTaG93IGRpZmYgYW5kIGdldCB1c2VyIGNvbmZpcm1h dGlvbgorNC4gQ29tcGxldGUgdXBncmFkZSBvciBjbGVhbiB1cCBvbiBjYW5jZWxsYXRpb24K KworQXJnczoKKyAgUEtHLURFU0M6IEN1cnJlbnQgaW5zdGFsbGVkIHBhY2thZ2UgZGVzY3Jp cHRvcgorICBORVctUEtHLURFU0M6IE5ldyBwYWNrYWdlIGRlc2NyaXB0b3IgdG8gdXBncmFk ZSB0bworCitSZXR1cm5zOgorICB0IGlmIHVwZ3JhZGUgd2FzIGNvbmZpcm1lZCBhbmQgY29t cGxldGVkLCBuaWwgb3RoZXJ3aXNlLiIKKyAgKGlmIChwYWNrYWdlLS1zaG91bGQtc2hvdy1k aWZmLXAgbmV3LXBrZy1kZXNjKQorICAgICAgKGxldCogKChvbGQtZGlyIChwYWNrYWdlLS1n ZXQtaW5zdGFsbGVkLXBhY2thZ2UtZGlyIHBrZy1kZXNjKSkKKyAgICAgICAgICAgICAobmV3 LWRpciBuaWwpCisgICAgICAgICAgICAgKGNvbmZpcm1lZCBuaWwpKQorICAgICAgICAodW53 aW5kLXByb3RlY3QKKyAgICAgICAgICAgIChwcm9nbgorICAgICAgICAgICAgICAoc2V0cSBu ZXctZGlyIChwYWNrYWdlLS1kb3dubG9hZC1hbmQtZXh0cmFjdCBuZXctcGtnLWRlc2MpKQor ICAgICAgICAgICAgICAoc2V0cSBjb25maXJtZWQgKHBhY2thZ2UtLWNvbmZpcm0tdXBncmFk ZSBwa2ctZGVzYyBuZXctcGtnLWRlc2Mgb2xkLWRpciBuZXctZGlyKSkKKyAgICAgICAgICAg ICAgKHdoZW4gY29uZmlybWVkCisgICAgICAgICAgICAgICAgKHBhY2thZ2UtLWNvbXBsZXRl LXVwZ3JhZGUgcGtnLWRlc2MgbmV3LXBrZy1kZXNjIG5ldy1kaXIpKSkKKyAgICAgICAgICA7 OyBDbGVhbnVwOiByZW1vdmUgdGVtcG9yYXJ5IGV4dHJhY3Rpb24gZGlyZWN0b3J5IGlmIHVw Z3JhZGUgd2FzIGNhbmNlbGxlZAorICAgICAgICAgICh3aGVuIChhbmQgbmV3LWRpciAobm90 IGNvbmZpcm1lZCkgKGZpbGUtZXhpc3RzLXAgbmV3LWRpcikpCisgICAgICAgICAgICAoaWdu b3JlLWVycm9ycyAoZGVsZXRlLWRpcmVjdG9yeSBuZXctZGlyIHQpKSkpCisgICAgICAgIGNv bmZpcm1lZCkKKyAgICA7OyBUcnVzdCBwb2xpY3kgc2F5cyBza2lwIGRpZmYgLSBwcm9jZWVk IGRpcmVjdGx5IHdpdGggdXBncmFkZQorICAgIChwcm9nbgorICAgICAgKHBhY2thZ2UtLWNv bXBsZXRlLXVwZ3JhZGUgcGtnLWRlc2MgbmV3LXBrZy1kZXNjIG5pbCkKKyAgICAgIHQpKSkK KwogKHByb3ZpZGUgJ3BhY2thZ2UtaW5zdGFsbCkKIDs7OyBwYWNrYWdlLWluc3RhbGwuZWwg ZW5kcyBoZXJlCmRpZmYgLS1naXQgYS9saXNwL3BhY2thZ2UvcGFja2FnZS1tZW51LmVsIGIv bGlzcC9wYWNrYWdlL3BhY2thZ2UtbWVudS5lbAppbmRleCBjNTcwODYxMTJjNC4uM2ZmZGI5 NDA1NTQgMTAwNjQ0Ci0tLSBhL2xpc3AvcGFja2FnZS9wYWNrYWdlLW1lbnUuZWwKKysrIGIv bGlzcC9wYWNrYWdlL3BhY2thZ2UtbWVudS5lbApAQCAtNjUzLDIyICs2NTMsMzggQEAgcGFj a2FnZS1tZW51LS1wZXJmb3JtLXRyYW5zYWN0aW9uCiAgICAgICAgICAgICAgICAgICAoZm9y bWF0IHN0YXR1cy1mb3JtYXQgKGluY2YgaSkpKQogICAgICAgICAgICAgKGZvcmNlLW1vZGUt bGluZS11cGRhdGUpCiAgICAgICAgICAgICAocmVkaXNwbGF5ICdmb3JjZSkKLSAgICAgICAg ICAgIDs7IERvbid0IG1hcmsgYXMgc2VsZWN0ZWQsIGBwYWNrYWdlLW1lbnUtZXhlY3V0ZScg YWxyZWFkeQotICAgICAgICAgICAgOzsgZG9lcyB0aGF0LgotICAgICAgICAgICAgKHBhY2th Z2UtaW5zdGFsbCBwa2cgJ2RvbnQtc2VsZWN0KSkpKQotICAgIChsZXQgKChwYWNrYWdlLW1l bnUtLXRyYW5zYWN0aW9uLXN0YXR1cyAiOkRlbGV0aW5nIikpCi0gICAgICAoZm9yY2UtbW9k ZS1saW5lLXVwZGF0ZSkKLSAgICAgIChyZWRpc3BsYXkgJ2ZvcmNlKQotICAgICAgKGRvbGlz dCAoZWx0IChwYWNrYWdlLS1zb3J0LWJ5LWRlcGVuZGVuY2UgZGVsZXRlLWxpc3QpKQotICAg ICAgICAoY29uZGl0aW9uLWNhc2UtdW5sZXNzLWRlYnVnIGVycgotICAgICAgICAgICAgKGxl dCAoKGluaGliaXQtbWVzc2FnZSAob3IgaW5oaWJpdC1tZXNzYWdlIHBhY2thZ2UtbWVudS1h c3luYykpKQotICAgICAgICAgICAgICAocGFja2FnZS1kZWxldGUgZWx0IG5pbCAnbm9zYXZl KSkKLSAgICAgICAgICAoZXJyb3IKLSAgICAgICAgICAgKHB1c2ggKHBhY2thZ2UtZGVzYy1m dWxsLW5hbWUgZWx0KSBlcnJvcnMpCi0gICAgICAgICAgIChtZXNzYWdlICJFcnJvciB0cnlp bmcgdG8gZGVsZXRlIGAlcyc6ICVzIgotICAgICAgICAgICAgICAgICAgICAocGFja2FnZS1k ZXNjLWZ1bGwtbmFtZSBlbHQpCi0gICAgICAgICAgICAgICAgICAgIChlcnJvci1tZXNzYWdl LXN0cmluZyBlcnIpKSkpKSkKLSAgICBlcnJvcnMpKQorICAgICAgICAgICAgOzsgQ2hlY2sg aWYgdGhpcyBpcyBhIHBhY2thZ2UgdXBncmFkZSBhbmQgbmVlZHMgY29uZmlybWF0aW9uCisg ICAgICAgICAgICAobGV0KiAoKHBrZy1uYW1lIChwYWNrYWdlLWRlc2MtbmFtZSBwa2cpKQor ICAgICAgICAgICAgICAgICAgIChvbGQtcGtnIChjbC1maW5kLWlmIChsYW1iZGEgKGRlbC1w a2cpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoZXEgKHBh Y2thZ2UtZGVzYy1uYW1lIGRlbC1wa2cpIHBrZy1uYW1lKSkKKyAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICBkZWxldGUtbGlzdCkpKQorICAgICAgICAgICAgICAo Y29uZAorICAgICAgICAgICAgICAgOzsgVGFyYmFsbCBwYWNrYWdlIHVwZ3JhZGUgLSB1c2Ug dGFyYmFsbCBjb25maXJtYXRpb24KKyAgICAgICAgICAgICAgICgoYW5kIG9sZC1wa2cgKGVx IChwYWNrYWdlLWRlc2Mta2luZCBwa2cpICd0YXIpKQorICAgICAgICAgICAgICAgIChpZiAo cGFja2FnZS0tY29uZmlybS10YXJiYWxsLXVwZ3JhZGUgb2xkLXBrZyBwa2cpCisgICAgICAg ICAgICAgICAgICAgIChwYWNrYWdlLWluc3RhbGwgcGtnICdkb250LXNlbGVjdCkKKyAgICAg ICAgICAgICAgICAgIChwdXNoIChwYWNrYWdlLWRlc2MtZnVsbC1uYW1lIHBrZykgZXJyb3Jz KSkpCisgICAgICAgICAgICAgICA7OyBWQyBwYWNrYWdlIHVwZ3JhZGUgLSB1c2UgVkMgY29u ZmlybWF0aW9uCisgICAgICAgICAgICAgICAoKGFuZCBvbGQtcGtnIChwYWNrYWdlLXZjLXAg b2xkLXBrZykpCisgICAgICAgICAgICAgICAgKGlmIChwYWNrYWdlLXZjLS1jb25maXJtLXVw Z3JhZGUgb2xkLXBrZykKKyAgICAgICAgICAgICAgICAgICAgKHBhY2thZ2UtaW5zdGFsbCBw a2cgJ2RvbnQtc2VsZWN0KQorICAgICAgICAgICAgICAgICAgKHB1c2ggKHBhY2thZ2UtZGVz Yy1mdWxsLW5hbWUgcGtnKSBlcnJvcnMpKSkKKyAgICAgICAgICAgICAgIDs7IE5vcm1hbCBp bnN0YWxsYXRpb24gb3IgdXBncmFkZQorICAgICAgICAgICAgICAgKHQKKyAgICAgICAgICAg ICAgICAocGFja2FnZS1pbnN0YWxsIHBrZyAnZG9udC1zZWxlY3QpKSkpKSkKKyAgICAgIChs ZXQgKChwYWNrYWdlLW1lbnUtLXRyYW5zYWN0aW9uLXN0YXR1cyAiOkRlbGV0aW5nIikpCisg ICAgICAgIChmb3JjZS1tb2RlLWxpbmUtdXBkYXRlKQorICAgICAgICAocmVkaXNwbGF5ICdm b3JjZSkKKyAgICAgICAgKGRvbGlzdCAoZWx0IChwYWNrYWdlLS1zb3J0LWJ5LWRlcGVuZGVu Y2UgZGVsZXRlLWxpc3QpKQorICAgICAgICAgIChjb25kaXRpb24tY2FzZS11bmxlc3MtZGVi dWcgZXJyCisgICAgICAgICAgICAgIChsZXQgKChpbmhpYml0LW1lc3NhZ2UgKG9yIGluaGli aXQtbWVzc2FnZSBwYWNrYWdlLW1lbnUtYXN5bmMpKSkKKyAgICAgICAgICAgICAgICAocGFj a2FnZS1kZWxldGUgZWx0IG5pbCAnbm9zYXZlKSkKKyAgICAgICAgICAgIChlcnJvcgorICAg ICAgICAgICAgIChwdXNoIChwYWNrYWdlLWRlc2MtZnVsbC1uYW1lIGVsdCkgZXJyb3JzKQor ICAgICAgICAgICAgIChtZXNzYWdlICJFcnJvciB0cnlpbmcgdG8gZGVsZXRlIGAlcyc6ICVz IgorICAgICAgICAgICAgICAgICAgICAgIChwYWNrYWdlLWRlc2MtZnVsbC1uYW1lIGVsdCkK KyAgICAgICAgICAgICAgICAgICAgICAoZXJyb3ItbWVzc2FnZS1zdHJpbmcgZXJyKSkpKSkp CisgICAgICBlcnJvcnMpKSkKIAogKGRlZnVuIHBhY2thZ2UtLXVwZGF0ZS1zZWxlY3RlZC1w YWNrYWdlcyAoYWRkIHJlbW92ZSkKICAgIlVwZGF0ZSB0aGUgYHBhY2thZ2Utc2VsZWN0ZWQt cGFja2FnZXMnIGxpc3QgYWNjb3JkaW5nIHRvIEFERCBhbmQgUkVNT1ZFLgpkaWZmIC0tZ2l0 IGEvbGlzcC9wYWNrYWdlL3BhY2thZ2UtdmMuZWwgYi9saXNwL3BhY2thZ2UvcGFja2FnZS12 Yy5lbAppbmRleCAwMzc2N2I5OTcyOS4uMzU3OWM5ZDY5YjUgMTAwNjQ0Ci0tLSBhL2xpc3Av cGFja2FnZS9wYWNrYWdlLXZjLmVsCisrKyBiL2xpc3AvcGFja2FnZS9wYWNrYWdlLXZjLmVs CkBAIC01Myw2ICs1Myw3IEBACiAocmVxdWlyZSAncGFja2FnZS1lbHBhKQogKHJlcXVpcmUg J2xpc3AtbW50KQogKHJlcXVpcmUgJ3ZjKQorKHJlcXVpcmUgJ3ZjLWdpdCkKIChyZXF1aXJl ICdzZXEpCiAKIChkZWZncm91cCBwYWNrYWdlLXZjIG5pbApAQCAtNzM3LDYgKzczOCw4IEBA IHBhY2thZ2UtdmMtdXBncmFkZS1hbGwKIAogKGRlY2xhcmUtZnVuY3Rpb24gdmMtZGlyLXBy ZXBhcmUtc3RhdHVzLWJ1ZmZlciAidmMtZGlyIgogICAgICAgICAgICAgICAgICAgKGJuYW1l IGRpciBiYWNrZW5kICZvcHRpb25hbCBjcmVhdGUtbmV3KSkKKyhkZWNsYXJlLWZ1bmN0aW9u IHZjLWRpZmYtaW5jb21pbmcgInZjIiAoJm9wdGlvbmFsIHJlbW90ZS1sb2NhdGlvbiBmaWxl c2V0KSkKKyhkZWNsYXJlLWZ1bmN0aW9uIHZjLWxvZy1pbmNvbWluZyAidmMiICgmb3B0aW9u YWwgcmVtb3RlLWxvY2F0aW9uKSkKIAogOzs7IyMjYXV0b2xvYWQKIChkZWZ1biBwYWNrYWdl LXZjLXVwZ3JhZGUgKHBrZy1kZXNjKQpAQCAtNzQ1LDQwICs3NDgsNDIgQEAgcGFja2FnZS12 Yy11cGdyYWRlCiBUaGlzIG1heSBmYWlsIGlmIHRoZSBsb2NhbCBWQ1Mgc3RhdGUgb2YgdGhl IHBhY2thZ2UgY29uZmxpY3RzCiB3aXRoIHRoZSByZW1vdGUgcmVwb3NpdG9yeSBzdGF0ZS4i CiAgIChpbnRlcmFjdGl2ZSAobGlzdCAocGFja2FnZS12Yy0tcmVhZC1wYWNrYWdlLWRlc2Mg IlVwZ3JhZGUgVkMgcGFja2FnZTogIiB0KSkpCi0gIDs7IEhBQ0s6IFRvIHJ1biBgcGFja2Fn ZS12Yy0tdW5wYWNrLTEnIGFmdGVyIGNoZWNraW5nIG91dCB0aGUgbmV3Ci0gIDs7IHJldmlz aW9uLCB3ZSBpbnNlcnQgYSBob29rIGludG8gYHZjLXBvc3QtY29tbWFuZC1mdW5jdGlvbnMn LCBhbmQKLSAgOzsgcmVtb3ZlIGl0IHJpZ2h0IGFmdGVyIGl0IHJhbi4gIFRvIGF2b2lkIHJ1 bm5pbmcgdGhlIGhvb2sgbXVsdGlwbGUKLSAgOzsgdGltZXMgb3IgZXZlbiBmb3IgdGhlIHdy b25nIHJlcG9zaXRvcnkgKGFzIGB2Yy1wdWxsJyBpcyBvZnRlbgotICA7OyBhc3luY2hyb25v dXMpLCB3ZSBleHRyYWN0IHRoZSByZWxldmFudCBhcmd1bWVudHMgdXNpbmcgYSBwc2V1ZG8K LSAgOzsgZmlsdGVyIGZvciBgdmMtZmlsdGVyLWNvbW1hbmQtZnVuY3Rpb24nLCBleGVjdXRl ZCBvbmx5IGZvciB0aGUKLSAgOzsgc2lkZSBlZmZlY3QsIGFuZCBzdG9yZSB0aGVtIGluIHRo ZSBsZXhpY2FsIHNjb3BlLiAgV2hlbiB0aGUgaG9vawotICA7OyBpcyBydW4sIHdlIGNoZWNr IGlmIHRoZSBhcmd1bWVudHMgYXJlIHRoZSBzYW1lIChgZXEnKSBhcyB0aGUgb25lcwotICA7 OyBwcmV2aW91c2x5IGV4dHJhY3RlZCwgYW5kIG9ubHkgaW4gdGhhdCBjYXNlIHdpbGwgYmUg Y2FsbAotICA7OyBgcGFja2FnZS12Yy0tdW5wYWNrLTEnLiAgVWdoLi4uCi0gIDs7Ci0gIDs7 IElmIHRoZXJlIGlzIGEgYmV0dGVyIHdheSB0byBkbyB0aGlzLCBpdCBzaG91bGQgYmUgZG9u ZS4KLSAgKGNsLWFzc2VydCAocGFja2FnZS12Yy1wIHBrZy1kZXNjKSkKLSAgKGxldHJlYyAo KHBrZy1kaXIgKHBhY2thZ2UtZGVzYy1kaXIgcGtnLWRlc2MpKQotICAgICAgICAgICAodmMt ZmxhZ3MpCi0gICAgICAgICAgICh2Yy1maWx0ZXItY29tbWFuZC1mdW5jdGlvbgotICAgICAg ICAgICAgKGxhbWJkYSAoY29tbWFuZCBmaWxlLW9yLWxpc3QgZmxhZ3MpCi0gICAgICAgICAg ICAgIChzZXRxIHZjLWZsYWdzIGZsYWdzKQotICAgICAgICAgICAgICAobGlzdCBjb21tYW5k IGZpbGUtb3ItbGlzdCBmbGFncykpKQotICAgICAgICAgICAocG9zdC11cGdyYWRlCi0gICAg ICAgICAgICAobGFtYmRhIChfY29tbWFuZCBfZmlsZS1vci1saXN0IGZsYWdzKQotICAgICAg ICAgICAgICAod2hlbiAoYW5kIChmaWxlLWVxdWFsLXAgcGtnLWRpciBkZWZhdWx0LWRpcmVj dG9yeSkKLSAgICAgICAgICAgICAgICAgICAgICAgICAoZXEgZmxhZ3MgdmMtZmxhZ3MpKQot ICAgICAgICAgICAgICAgICh1bndpbmQtcHJvdGVjdAotICAgICAgICAgICAgICAgICAgICAo d2l0aC1kZW1vdGVkLWVycm9ycyAiRmFpbGVkIHRvIGFjdGl2YXRlOiAlUyIKLSAgICAgICAg ICAgICAgICAgICAgICAocGFja2FnZS12Yy0tdW5wYWNrLTEgcGtnLWRlc2MgcGtnLWRpcikp Ci0gICAgICAgICAgICAgICAgICAocmVtb3ZlLWhvb2sgJ3ZjLXBvc3QtY29tbWFuZC1mdW5j dGlvbnMgcG9zdC11cGdyYWRlKSkpKSkpCi0gICAgKGFkZC1ob29rICd2Yy1wb3N0LWNvbW1h bmQtZnVuY3Rpb25zIHBvc3QtdXBncmFkZSkKLSAgICAod2l0aC1kZW1vdGVkLWVycm9ycyAi RmFpbGVkIHRvIGZldGNoOiAlUyIKLSAgICAgIChyZXF1aXJlICd2Yy1kaXIpCi0gICAgICAo d2l0aC1jdXJyZW50LWJ1ZmZlciAodmMtZGlyLXByZXBhcmUtc3RhdHVzLWJ1ZmZlcgotICAg ICAgICAgICAgICAgICAgICAgICAgICAgIChmb3JtYXQgIiAqcGFja2FnZS12Yy1kaXI6ICVz KiIgcGtnLWRpcikKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBwa2ctZGlyICh2Yy1y ZXNwb25zaWJsZS1iYWNrZW5kIHBrZy1kaXIpKQotICAgICAgICAodmMtcHVsbCkpKSkpCisg IDs7IENoZWNrIGlmIHVzZXIgd2FudHMgdG8gc2VlIGRpZmYgYW5kIGNvbmZpcm0gdXBncmFk ZQorICAod2hlbiAocGFja2FnZS12Yy0tY29uZmlybS11cGdyYWRlIHBrZy1kZXNjKQorICAg IDs7IEhBQ0s6IFRvIHJ1biBgcGFja2FnZS12Yy0tdW5wYWNrLTEnIGFmdGVyIGNoZWNraW5n IG91dCB0aGUgbmV3CisgICAgOzsgcmV2aXNpb24sIHdlIGluc2VydCBhIGhvb2sgaW50byBg dmMtcG9zdC1jb21tYW5kLWZ1bmN0aW9ucycsIGFuZAorICAgIDs7IHJlbW92ZSBpdCByaWdo dCBhZnRlciBpdCByYW4uICBUbyBhdm9pZCBydW5uaW5nIHRoZSBob29rIG11bHRpcGxlCisg ICAgOzsgdGltZXMgb3IgZXZlbiBmb3IgdGhlIHdyb25nIHJlcG9zaXRvcnkgKGFzIGB2Yy1w dWxsJyBpcyBvZnRlbgorICAgIDs7IGFzeW5jaHJvbm91cyksIHdlIGV4dHJhY3QgdGhlIHJl bGV2YW50IGFyZ3VtZW50cyB1c2luZyBhIHBzZXVkbworICAgIDs7IGZpbHRlciBmb3IgYHZj LWZpbHRlci1jb21tYW5kLWZ1bmN0aW9uJywgZXhlY3V0ZWQgb25seSBmb3IgdGhlCisgICAg Ozsgc2lkZSBlZmZlY3QsIGFuZCBzdG9yZSB0aGVtIGluIHRoZSBsZXhpY2FsIHNjb3BlLiAg V2hlbiB0aGUgaG9vaworICAgIDs7IGlzIHJ1biwgd2UgY2hlY2sgaWYgdGhlIGFyZ3VtZW50 cyBhcmUgdGhlIHNhbWUgKGBlcScpIGFzIHRoZSBvbmVzCisgICAgOzsgcHJldmlvdXNseSBl eHRyYWN0ZWQsIGFuZCBvbmx5IGluIHRoYXQgY2FzZSB3aWxsIGJlIGNhbGwKKyAgICA7OyBg cGFja2FnZS12Yy0tdW5wYWNrLTEnLiAgVWdoLi4uCisgICAgOzsKKyAgICA7OyBJZiB0aGVy ZSBpcyBhIGJldHRlciB3YXkgdG8gZG8gdGhpcywgaXQgc2hvdWxkIGJlIGRvbmUuCisgICAg KGNsLWFzc2VydCAocGFja2FnZS12Yy1wIHBrZy1kZXNjKSkKKyAgICAobGV0cmVjICgocGtn LWRpciAocGFja2FnZS1kZXNjLWRpciBwa2ctZGVzYykpCisgICAgICAgICAgICAgKHZjLWZs YWdzKQorICAgICAgICAgICAgICh2Yy1maWx0ZXItY29tbWFuZC1mdW5jdGlvbgorICAgICAg ICAgICAgICAobGFtYmRhIChjb21tYW5kIGZpbGUtb3ItbGlzdCBmbGFncykKKyAgICAgICAg ICAgICAgICAoc2V0cSB2Yy1mbGFncyBmbGFncykKKyAgICAgICAgICAgICAgICAobGlzdCBj b21tYW5kIGZpbGUtb3ItbGlzdCBmbGFncykpKQorICAgICAgICAgICAgIChwb3N0LXVwZ3Jh ZGUKKyAgICAgICAgICAgICAgKGxhbWJkYSAoX2NvbW1hbmQgX2ZpbGUtb3ItbGlzdCBmbGFn cykKKyAgICAgICAgICAgICAgICAod2hlbiAoYW5kIChmaWxlLWVxdWFsLXAgcGtnLWRpciBk ZWZhdWx0LWRpcmVjdG9yeSkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIChlcSBmbGFn cyB2Yy1mbGFncykpCisgICAgICAgICAgICAgICAgICAodW53aW5kLXByb3RlY3QKKyAgICAg ICAgICAgICAgICAgICAgICAod2l0aC1kZW1vdGVkLWVycm9ycyAiRmFpbGVkIHRvIGFjdGl2 YXRlOiAlUyIKKyAgICAgICAgICAgICAgICAgICAgICAgIChwYWNrYWdlLXZjLS11bnBhY2st MSBwa2ctZGVzYyBwa2ctZGlyKSkKKyAgICAgICAgICAgICAgICAgICAgKHJlbW92ZS1ob29r ICd2Yy1wb3N0LWNvbW1hbmQtZnVuY3Rpb25zIHBvc3QtdXBncmFkZSkpKSkpKQorICAgICAg KGFkZC1ob29rICd2Yy1wb3N0LWNvbW1hbmQtZnVuY3Rpb25zIHBvc3QtdXBncmFkZSkKKyAg ICAgICh3aXRoLWRlbW90ZWQtZXJyb3JzICJGYWlsZWQgdG8gZmV0Y2g6ICVTIgorICAgICAg ICAocmVxdWlyZSAndmMtZGlyKQorICAgICAgICAod2l0aC1jdXJyZW50LWJ1ZmZlciAodmMt ZGlyLXByZXBhcmUtc3RhdHVzLWJ1ZmZlcgorICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgKGZvcm1hdCAiICpwYWNrYWdlLXZjLWRpcjogJXMqIiBwa2ctZGlyKQorICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgcGtnLWRpciAodmMtcmVzcG9uc2libGUtYmFja2VuZCBw a2ctZGlyKSkKKyAgICAgICAgICAodmMtcHVsbCkpKSkpKQogCiAoZGVmdW4gcGFja2FnZS12 Yy0tYXJjaGl2ZXMtaW5pdGlhbGl6ZSAoKQogICAiSW5pdGlhbGl6ZSBwYWNrYWdlLmVsIGFu ZCBmZXRjaCBwYWNrYWdlIHNwZWNpZmljYXRpb25zLiIKQEAgLTk5Nyw3ICsxMDAyLDE1MCBA QCBwYWNrYWdlLXZjLWxvZy1pbmNvbWluZwogICAoaW50ZXJhY3RpdmUKICAgIChsaXN0IChw YWNrYWdlLXZjLS1yZWFkLXBhY2thZ2UtZGVzYyAiSW5jb21pbmcgbG9nIGZvciBwYWNrYWdl OiAiIHQpKSkKICAgKGxldCAoKGRlZmF1bHQtZGlyZWN0b3J5IChwYWNrYWdlLWRlc2MtZGly IHBrZy1kZXNjKSkpCi0gICAgKGNhbGwtaW50ZXJhY3RpdmVseSAjJ3ZjLWxvZy1pbmNvbWlu ZykpKQorICAgIDs7IENhbGwgdmMtbG9nLWluY29taW5nIGRpcmVjdGx5IHdpdGhvdXQgaW50 ZXJhY3RpdmUgcHJvbXB0aW5nCisgICAgKHZjLWxvZy1pbmNvbWluZyBuaWwpKSkKKworOzsg UGFja2FnZSB1cGdyYWRlIGRpZmYgdXRpbGl0aWVzIGZvciBWQyBwYWNrYWdlcworCisoZGVm dW4gcGFja2FnZS12Yy0tc2hvdy1jaGFuZ2Vsb2cgKHBrZy1kZXNjIGZyb20tcmV2IHRvLXJl dikKKyAgIlNob3cgZGlmZiBvZiBhbGwgY2hhbmdlbG9nIGZpbGVzIGJldHdlZW4gRlJPTS1S RVYgYW5kIFRPLVJFViBmb3IgUEtHLURFU0MuCitSZXR1cm5zIHQgaWYgYW55IGNoYW5nZWxv ZyBkaWZmIHdhcyBkaXNwbGF5ZWQsIG5pbCBvdGhlcndpc2UuIgorICAobGV0KiAoKHBrZy1k aXIgKHBhY2thZ2UtZGVzYy1kaXIgcGtnLWRlc2MpKQorICAgICAgICAgKGRlZmF1bHQtZGly ZWN0b3J5IHBrZy1kaXIpCisgICAgICAgICAoY2hhbmdlbG9nLWZpbGVzIChwYWNrYWdlLS1m aW5kLWNoYW5nZWxvZy1maWxlcyBwa2ctZGlyKSkpCisgICAgKGlmIGNoYW5nZWxvZy1maWxl cworICAgICAgICAocGFja2FnZS12Yy0tZGlzcGxheS1hbGwtY2hhbmdlbG9nLWRpZmZzIGNo YW5nZWxvZy1maWxlcyBmcm9tLXJldiB0by1yZXYpCisgICAgICAobWVzc2FnZSAiTm8gY2hh bmdlbG9nIGZpbGVzIGZvdW5kIGluIHJlcG9zaXRvcnkiKQorICAgICAgbmlsKSkpCisKKyhk ZWZ1biBwYWNrYWdlLXZjLS1kaXNwbGF5LWFsbC1jaGFuZ2Vsb2ctZGlmZnMgKGNoYW5nZWxv Zy1maWxlcyBmcm9tLXJldiB0by1yZXYpCisgICJEaXNwbGF5IGdpdCBkaWZmIGZvciBhbGwg Q0hBTkdFTE9HLUZJTEVTIGJldHdlZW4gRlJPTS1SRVYgYW5kIFRPLVJFVi4iCisgIChsZXQg KChkaWZmLWJ1ZmZlci1uYW1lICIqUGFja2FnZSBWQyBDaGFuZ2Vsb2cgRGlmZioiKQorICAg ICAgICAoZGlzcGxheWVkLWFueSBuaWwpKQorICAgIDs7IEtpbGwgZXhpc3RpbmcgYnVmZmVy CisgICAgKHdoZW4gKGdldC1idWZmZXIgZGlmZi1idWZmZXItbmFtZSkKKyAgICAgIChraWxs LWJ1ZmZlciBkaWZmLWJ1ZmZlci1uYW1lKSkKKworICAgICh3aXRoLWN1cnJlbnQtYnVmZmVy IChnZXQtYnVmZmVyLWNyZWF0ZSBkaWZmLWJ1ZmZlci1uYW1lKQorICAgICAgKGxldCAoKGlu aGliaXQtcmVhZC1vbmx5IHQpKQorICAgICAgICAoZXJhc2UtYnVmZmVyKQorICAgICAgICAo aW5zZXJ0IChmb3JtYXQgIkNoYW5nZWxvZyBkaWZmZXJlbmNlcyBiZXR3ZWVuICVzIGFuZCAl czpcbiIgZnJvbS1yZXYgdG8tcmV2KSkKKyAgICAgICAgKGluc2VydCAobWFrZS1zdHJpbmcg NjAgPz0pKQorICAgICAgICAoaW5zZXJ0ICJcblxuIikKKworICAgICAgICA7OyBQcm9jZXNz IGVhY2ggY2hhbmdlbG9nIGZpbGUKKyAgICAgICAgKGRvbGlzdCAoY2hhbmdlbG9nLWZpbGUg Y2hhbmdlbG9nLWZpbGVzKQorICAgICAgICAgIChsZXQgKChmaWxlbmFtZSAoZmlsZS1uYW1l LW5vbmRpcmVjdG9yeSBjaGFuZ2Vsb2ctZmlsZSkpKQorICAgICAgICAgICAgKGluc2VydCAo Zm9ybWF0ICItLS0gJXMgLS0tXG4iIGZpbGVuYW1lKSkKKyAgICAgICAgICAgIChjb25kaXRp b24tY2FzZSBlcnIKKyAgICAgICAgICAgICAgICAobGV0ICgoZGlmZi1vdXRwdXQKKyAgICAg ICAgICAgICAgICAgICAgICAgKHdpdGgtb3V0cHV0LXRvLXN0cmluZworICAgICAgICAgICAg ICAgICAgICAgICAgICh3aXRoLWN1cnJlbnQtYnVmZmVyIHN0YW5kYXJkLW91dHB1dAorICAg ICAgICAgICAgICAgICAgICAgICAgICAgKHZjLWdpdC1jb21tYW5kCisgICAgICAgICAgICAg ICAgICAgICAgICAgICAgKGN1cnJlbnQtYnVmZmVyKSAwIGNoYW5nZWxvZy1maWxlCisgICAg ICAgICAgICAgICAgICAgICAgICAgICAgImRpZmYiIGZyb20tcmV2IHRvLXJldgorICAgICAg ICAgICAgICAgICAgICAgICAgICAgIChmb3JtYXQgIi0tdW5pZmllZD0lZCIgcGFja2FnZS1k aWZmLWNvbnRleHQtbGluZXMpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIi0tIiAo ZmlsZS1yZWxhdGl2ZS1uYW1lIGNoYW5nZWxvZy1maWxlKSkpKSkpCisgICAgICAgICAgICAg ICAgICAoaWYgKD4gKGxlbmd0aCBkaWZmLW91dHB1dCkgMCkKKyAgICAgICAgICAgICAgICAg ICAgICAocHJvZ24KKyAgICAgICAgICAgICAgICAgICAgICAgIChpbnNlcnQgZGlmZi1vdXRw dXQpCisgICAgICAgICAgICAgICAgICAgICAgICAoc2V0cSBkaXNwbGF5ZWQtYW55IHQpKQor ICAgICAgICAgICAgICAgICAgICAoaW5zZXJ0ICJObyBjaGFuZ2VzIGZvdW5kIGluIHRoaXMg ZmlsZS5cbiIpKSkKKyAgICAgICAgICAgICAgKGVycm9yCisgICAgICAgICAgICAgICAoaW5z ZXJ0IChmb3JtYXQgIkVycm9yIHJ1bm5pbmcgZ2l0IGRpZmY6ICVzIiAoZXJyb3ItbWVzc2Fn ZS1zdHJpbmcgZXJyKSkpKSkKKyAgICAgICAgICAgIChpbnNlcnQgIlxuXG4iKSkpCisKKyAg ICAgICAgKGlmIGRpc3BsYXllZC1hbnkKKyAgICAgICAgICAgIChwcm9nbgorICAgICAgICAg ICAgICAocGFja2FnZS0tZm9ybWF0LWNoYW5nZWxvZy1kaWZmKQorICAgICAgICAgICAgICAo Z290by1jaGFyIChwb2ludC1taW4pKQorICAgICAgICAgICAgICAocmVhZC1vbmx5LW1vZGUg MSkpCisgICAgICAgICAgKGluc2VydCAiTm8gY2hhbmdlbG9nIGNoYW5nZXMgZm91bmQgYmV0 d2VlbiB0aGUgc3BlY2lmaWVkIHJldmlzaW9ucy5cbiIpCisgICAgICAgICAgKHJlYWQtb25s eS1tb2RlIDEpKSkKKworICAgICAgKGRpc3BsYXktYnVmZmVyIGRpZmYtYnVmZmVyLW5hbWUp CisgICAgICBkaXNwbGF5ZWQtYW55KSkpCisKKyhkZWZ1biBwYWNrYWdlLXZjLS11cGdyYWRl LWludGVyYWN0aXZlLXByb21wdCAocGtnLWRlc2MpCisgICJJbnRlcmFjdGl2ZSBwcm9tcHQg Zm9yIFZDIHBhY2thZ2UgdXBncmFkZSBjb25maXJtYXRpb24uCitQS0ctREVTQyBpcyB0aGUg VkMgcGFja2FnZSBkZXNjcmlwdG9yLgorUmV0dXJucyBcXD0ndXBncmFkZSB0byBwcm9jZWVk IHdpdGggdXBncmFkZSwgXFw9J2NhbmNlbCB0byBhYm9ydC4iCisgIChjb25kaXRpb24tY2Fz ZSBlcnIKKyAgICAgIChsZXQgKChwYWNrYWdlLW5hbWUgKHBhY2thZ2UtZGVzYy1uYW1lIHBr Zy1kZXNjKSkKKyAgICAgICAgICAgIChwcm9tcHQtY2hvaWNlcyAobWFwY2FyICMnY2FyIHBh Y2thZ2UtdXBncmFkZS1pbnRlcmFjdGl2ZS1jb21tYW5kcykpCisgICAgICAgICAgICAocmVz dWx0IG5pbCkKKyAgICAgICAgICAgIChwa2ctZGlyIChwYWNrYWdlLWRlc2MtZGlyIHBrZy1k ZXNjKSkKKyAgICAgICAgICAgIChjdXJyZW50LXJldiBuaWwpCisgICAgICAgICAgICAodGFy Z2V0LXJldiBuaWwpKQorCisgICAgICAgIDs7IEluaXRpYWxpemUgcmV2aXNpb25zIGZvciBj aGFuZ2Vsb2cgY29tcGFyaXNvbgorICAgICAgICAoY29uZGl0aW9uLWNhc2UgXworICAgICAg ICAgICAgKGxldCAoKGRlZmF1bHQtZGlyZWN0b3J5IHBrZy1kaXIpKQorICAgICAgICAgICAg ICAoc2V0cSBjdXJyZW50LXJldiAoc3RyaW5nLXRyaW0gKHNoZWxsLWNvbW1hbmQtdG8tc3Ry aW5nICJnaXQgcmV2LXBhcnNlIEhFQUQiKSkpCisgICAgICAgICAgICAgIChzZXRxIHRhcmdl dC1yZXYgIm9yaWdpbi9IRUFEIikpCisgICAgICAgICAgKGVycm9yCisgICAgICAgICAgIChz ZXRxIGN1cnJlbnQtcmV2ICJIRUFEfjEiKQorICAgICAgICAgICAoc2V0cSB0YXJnZXQtcmV2 ICJIRUFEIikpKQorCisgICAgICAgICh3aGlsZSAobm90IChtZW1xIHJlc3VsdCAnKHVwZ3Jh ZGUgY2FuY2VsIHF1aXQpKSkKKyAgICAgICAgICAoY29uZGl0aW9uLWNhc2UgaW5wdXQtZXJy CisgICAgICAgICAgICAgIChsZXQgKChjaG9pY2UgKHJlYWQtY2hhci1jaG9pY2UKKyAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgKGZvcm1hdCBwYWNrYWdlLXVwZ3JhZGUtcHJvbXB0 LW1lc3NhZ2UgcGFja2FnZS1uYW1lKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBw cm9tcHQtY2hvaWNlcykpKQorICAgICAgICAgICAgICAgIChwY2FzZSAoY2RyIChhc3NxIGNo b2ljZSBwYWNrYWdlLXVwZ3JhZGUtaW50ZXJhY3RpdmUtY29tbWFuZHMpKQorICAgICAgICAg ICAgICAgICAgKCd1cGdyYWRlCisgICAgICAgICAgICAgICAgICAgKHNldHEgcmVzdWx0ICd1 cGdyYWRlKSkKKyAgICAgICAgICAgICAgICAgICgnY2FuY2VsCisgICAgICAgICAgICAgICAg ICAgKHNldHEgcmVzdWx0ICdjYW5jZWwpKQorICAgICAgICAgICAgICAgICAgKCdxdWl0Cisg ICAgICAgICAgICAgICAgICAgKHNldHEgcmVzdWx0ICdxdWl0KSkKKyAgICAgICAgICAgICAg ICAgICgnc2hvdy1kaWZmCisgICAgICAgICAgICAgICAgICAgOzsgRm9yIFZDIHBhY2thZ2Vz LCBzaG93IGJvdGggbG9nIGFuZCBkaWZmIHVzaW5nIHNlcGFyYXRlIHN0YW5kYXJkIFZDIGZ1 bmN0aW9ucworICAgICAgICAgICAgICAgICAgIChjb25kaXRpb24tY2FzZSBsb2ctZXJyCisg ICAgICAgICAgICAgICAgICAgICAgIChsZXQgKChkZWZhdWx0LWRpcmVjdG9yeSAocGFja2Fn ZS1kZXNjLWRpciBwa2ctZGVzYykpKQorICAgICAgICAgICAgICAgICAgICAgICAgIDs7IFNo b3cgaW5jb21pbmcgbG9nCisgICAgICAgICAgICAgICAgICAgICAgICAgKHZjLWxvZy1pbmNv bWluZyBuaWwpCisgICAgICAgICAgICAgICAgICAgICAgICAgOzsgQWxzbyBzaG93IGluY29t aW5nIGRpZmYKKyAgICAgICAgICAgICAgICAgICAgICAgICAodmMtcm9vdC1kaWZmLWluY29t aW5nIG5pbCkpCisgICAgICAgICAgICAgICAgICAgICAoZXJyb3IKKyAgICAgICAgICAgICAg ICAgICAgICAobWVzc2FnZSAiRXJyb3Igc2hvd2luZyBpbmNvbWluZyBjaGFuZ2VzOiAlcyIg KGVycm9yLW1lc3NhZ2Utc3RyaW5nIGxvZy1lcnIpKSkpKQorICAgICAgICAgICAgICAgICAg KCdzaG93LWNoYW5nZWxvZworICAgICAgICAgICAgICAgICAgIChjb25kaXRpb24tY2FzZSBs b2ctZXJyCisgICAgICAgICAgICAgICAgICAgICAgIChwYWNrYWdlLXZjLS1zaG93LWNoYW5n ZWxvZyBwa2ctZGVzYyBjdXJyZW50LXJldiB0YXJnZXQtcmV2KQorICAgICAgICAgICAgICAg ICAgICAgKGVycm9yCisgICAgICAgICAgICAgICAgICAgICAgKG1lc3NhZ2UgIkVycm9yIHNo b3dpbmcgY2hhbmdlbG9nOiAlcyIgKGVycm9yLW1lc3NhZ2Utc3RyaW5nIGxvZy1lcnIpKSkp KQorICAgICAgICAgICAgICAgICAgKF8KKyAgICAgICAgICAgICAgICAgICA7OyBJbnZhbGlk IGNob2ljZSwgY29udGludWUgbG9vcAorICAgICAgICAgICAgICAgICAgIChtZXNzYWdlICJJ bnZhbGlkIGNob2ljZS4gUGxlYXNlIHByZXNzIHksIG4sIGQsIGMsIG9yIHEuIikKKyAgICAg ICAgICAgICAgICAgICAoc2l0LWZvciAxKSkpKQorICAgICAgICAgICAgKHF1aXQKKyAgICAg ICAgICAgICA7OyBIYW5kbGUgdXNlciBpbnRlcnJ1cHRpb24gKEMtZykKKyAgICAgICAgICAg ICAoc2V0cSByZXN1bHQgJ2NhbmNlbCkpCisgICAgICAgICAgICAoZXJyb3IKKyAgICAgICAg ICAgICAobWVzc2FnZSAiRXJyb3IgZHVyaW5nIGlucHV0OiAlcyIgKGVycm9yLW1lc3NhZ2Ut c3RyaW5nIGlucHV0LWVycikpCisgICAgICAgICAgICAgKHNpdC1mb3IgMSkpKSkKKworICAg ICAgICByZXN1bHQpCisgICAgKGVycm9yCisgICAgIChtZXNzYWdlICJDcml0aWNhbCBlcnJv ciBpbiBpbnRlcmFjdGl2ZSBwcm9tcHQgZm9yICVzOiAlcyIKKyAgICAgICAgICAgICAgKHBh Y2thZ2UtZGVzYy1uYW1lIHBrZy1kZXNjKSAoZXJyb3ItbWVzc2FnZS1zdHJpbmcgZXJyKSkK KyAgICAgJ2NhbmNlbCkpKQorCisoZGVmdW4gcGFja2FnZS12Yy0tY29uZmlybS11cGdyYWRl IChwa2ctZGVzYykKKyAgIlNob3cgaW5jb21pbmcgY2hhbmdlcyBmb3IgVkMgcGFja2FnZSB1 cGdyYWRlIGFuZCBhc2sgZm9yIGNvbmZpcm1hdGlvbi4KK1BLRy1ERVNDIGlzIHRoZSBwYWNr YWdlIGRlc2NyaXB0b3IgdG8gdXBncmFkZS4KK1JldHVybiB0IGlmIHVzZXIgd2FudHMgdG8g cHJvY2VlZCwgbmlsIG90aGVyd2lzZS4iCisgIDs7IENoZWNrIHRydXN0IHBvbGljeQorICAo bGV0ICgoc2hvdWxkLXNob3ctZGlmZiAocGFja2FnZS0tc2hvdWxkLXNob3ctZGlmZi1wIHBr Zy1kZXNjKSkpCisgICAgKGlmIHNob3VsZC1zaG93LWRpZmYKKyAgICAgICAgOzsgVXNlIGlu dGVyYWN0aXZlIHByb21wdCBmb3IgdXBncmFkZSBjb25maXJtYXRpb24KKyAgICAgICAgKGxl dCAoKHJlc3VsdCAocGFja2FnZS12Yy0tdXBncmFkZS1pbnRlcmFjdGl2ZS1wcm9tcHQgcGtn LWRlc2MpKSkKKyAgICAgICAgICAoY29uZAorICAgICAgICAgICAoKGVxIHJlc3VsdCAndXBn cmFkZSkgdCkKKyAgICAgICAgICAgKChlcSByZXN1bHQgJ3F1aXQpICh1c2VyLWVycm9yICJQ YWNrYWdlIHVwZ3JhZGUgY2FuY2VsbGVkIGJ5IHVzZXIiKSkKKyAgICAgICAgICAgKHQgbmls KSkpCisgICAgICA7OyBBdXRvLXVwZ3JhZGUgd2l0aG91dCBkaWZmCisgICAgICB0KSkpCiAK IChwcm92aWRlICdwYWNrYWdlLXZjKQogOzs7IHBhY2thZ2UtdmMuZWwgZW5kcyBoZXJlCi0t IAoyLjQzLjAKCg== --------------fbZRW2EvGyfUKUcjKcvjyeca-- From unknown Fri Sep 19 04:01:23 2025 X-Loop: help-debbugs@gnu.org Subject: bug#74604: [PATCH v1] package.el: Add diff display and confirmation for package upgrades (Bug#74604) Resent-From: Eli Zaretskii Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Sat, 13 Sep 2025 07:10:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 74604 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: To: Nobuyuki Kamimoto Cc: mail@daniel-mendler.de, philipk@posteo.net, 74604@debbugs.gnu.org Received: via spool by 74604-submit@debbugs.gnu.org id=B74604.175774735022372 (code B ref 74604); Sat, 13 Sep 2025 07:10:02 +0000 Received: (at 74604) by debbugs.gnu.org; 13 Sep 2025 07:09:10 +0000 Received: from localhost ([127.0.0.1]:52882 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1uxKNi-0005ok-Dy for submit@debbugs.gnu.org; Sat, 13 Sep 2025 03:09:10 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:53064) by debbugs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.84_2) (envelope-from ) id 1uxKNf-0005oA-Rh for 74604@debbugs.gnu.org; Sat, 13 Sep 2025 03:09:08 -0400 Received: from fencepost.gnu.org ([2001:470:142:3::e]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1uxKNY-0004w2-2z; Sat, 13 Sep 2025 03:09:00 -0400 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=gnu.org; s=fencepost-gnu-org; h=References:Subject:In-Reply-To:To:From:Date: mime-version; bh=VHGu1mdaMZ2IDyy1sqnXqDlOhs/mijqF2rWSvrvNKas=; b=YqFPbpVwY/KL fZuHOVSKMZAzi3Nwhpde76WlQmw8u+d5UIm1Ly/F6Iu1OuSip0ZtWUkSBWx0d8deiAEwcRWepIE9+ SQO9I6Phmwi8JTmfD6TZWlERWDBYjy5keX45dFFVtkbADnYmBwEBcIBv8NeBdv8YzODFerSlIzzIX LnE81yKQUoKE160W3dTziHZTArTZJ7o5TNJoEnzX6wlx34WOBu6oQD4L0qRU5yP28yoC+sNwQzHG+ /kjt50LCaGNNQdyt3lm3zNcdBT3LZmxDDh4jpKyhJzUbQGPnFSX+Y/Oen7tPylW+ukqWwGWNDSrdO wPV1l/QQHY718Vh05Mb03g==; Date: Sat, 13 Sep 2025 10:08:57 +0300 Message-Id: <86ldmisuba.fsf@gnu.org> From: Eli Zaretskii In-Reply-To: <312bce53-f1de-4dfb-8338-a71f4d7cebfb@gmail.com> (message from Nobuyuki Kamimoto on Sat, 13 Sep 2025 09:01:33 +0900) References: <87h67quk0g.fsf@daniel-mendler.de> <54fadfd1-21f6-48cb-a17e-8d0878a68f1d@gmail.com> <87ldmweuf2.fsf@posteo.net> <87ecsovdqp.fsf@daniel-mendler.de> <87seh4tptl.fsf@posteo.net> <312bce53-f1de-4dfb-8338-a71f4d7cebfb@gmail.com> X-Spam-Score: -2.3 (--) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -3.3 (---) > Cc: 74604@debbugs.gnu.org > Date: Sat, 13 Sep 2025 09:01:33 +0900 > From: Nobuyuki Kamimoto > > +(defcustom package-upgrade-confirmation-policy t The default value sounds problematic to me. For starters, it changes previous behavior, which already should have a good reason. Moreover, IME most people don't care about the changes, and consider any display that insists of showing them, let alone wants a confirmation, an annoyance. Consider the case that a user upgrades many packages at once, for example. So my suggestion is to leave the default at nil, preserving previous behavior. This option is a very good feature, but only for users who are actually interested in reviewing the changes when they upgrade. > +Possible values: > + > +\\=`t\\=' - Default > + Show diffs and prompt for all package upgrades. > + > +\\=`nil\\=' > + Automatically upgrade all packages without showing diffs. We don't quote t and nil in doc strings, so please don't. > + :type '(choice > + (const :tag "Always show diffs" t) > + (const :tag "Never show diffs" nil) > + (repeat :tag "Specific packages/archives to confirm" If we are going to request confirmation, the first two tags should also mention that. As written, the first two tags only talk about showing the diffs and never mention that showing changes also requires a confirmation. Thanks. From unknown Fri Sep 19 04:01:23 2025 X-Loop: help-debbugs@gnu.org Subject: bug#74604: [PATCH v1] package.el: Add diff display and confirmation for package upgrades (Bug#74604) Resent-From: =?UTF-8?Q?St=C3=A9phane?= Marks Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Sat, 13 Sep 2025 11:35:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 74604 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: To: Eli Zaretskii Cc: mail@daniel-mendler.de, philipk@posteo.net, Nobuyuki Kamimoto , 74604@debbugs.gnu.org Received: via spool by 74604-submit@debbugs.gnu.org id=B74604.175776327531901 (code B ref 74604); Sat, 13 Sep 2025 11:35:01 +0000 Received: (at 74604) by debbugs.gnu.org; 13 Sep 2025 11:34:35 +0000 Received: from localhost ([127.0.0.1]:54086 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1uxOWY-0008IO-9W for submit@debbugs.gnu.org; Sat, 13 Sep 2025 07:34:35 -0400 Received: from mail-vs1-xe2e.google.com ([2607:f8b0:4864:20::e2e]:42423) by debbugs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.84_2) (envelope-from ) id 1uxOWU-0008Hl-CH for 74604@debbugs.gnu.org; Sat, 13 Sep 2025 07:34:31 -0400 Received: by mail-vs1-xe2e.google.com with SMTP id ada2fe7eead31-5565a83f796so1359289137.1 for <74604@debbugs.gnu.org>; Sat, 13 Sep 2025 04:34:30 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1757763264; x=1758368064; darn=debbugs.gnu.org; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:from:to:cc:subject:date:message-id:reply-to; bh=sLEtQfXfLGmvMlvw4MUIrpcnDrzQTXhQJ2Cu8ALm7+Q=; b=UHuWBGnAvvHBjdeotQxz43lPOtw49J5iAzzXPtOlljaKthOrycHswtuNcaD5tv00Wb fiNPUaNkCbMLTWiu+sK7Sqzw0otS/yeqYsiz3DCjWFopVXa/AB8zacDzBGEV+h+RO/kO o6eFeQJ4HdwOSEURDjx7DK0Po2R1l5WoJsfeZC97MjcA+Ve8fpWDejiBk4d/Qo5vBy9q flbqwg3xwpclOHrLuzKBoewCNU+m9b3VBF52XJ+wshYMiRPHuLFwWyffcOUhGk04ZaVN rWtJwE2CM6OULEOHMc3e9Pu8GAORZQTMMfu6ttvLo4on0qhigw+l0g+t65JyMwJHTjPF mH+Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1757763264; x=1758368064; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=sLEtQfXfLGmvMlvw4MUIrpcnDrzQTXhQJ2Cu8ALm7+Q=; b=KUsdr1lBfFScmC4soTmakPJLO0QQ+tSinMACWVpAmhqQcSaZQsBhIuYV3xhupA3oin K+18k+9iJzAMWJat5/t/edeHfRFYSpYYEZ02dmMkKmdWCyT/6pm1IjKdi9FGSMzgwdZL chqWNKZGQ07Gut8dkVkmEci8j72EYWhmMIWj3yE5X1to6peMSr15JsWkgAjXWTjc98gQ 11Z727qATY49F0NpXp5qiL3Q8etb7Px1oRzCYQMhh0mr0tmXF8SFmTpAYUzcv+WEEHh3 sJCL8nsSd+d/wNxye0L2d7sHZRZYKO50T3TyyiZn3vPHv6ZNt1zYYHnWPAarBdHdQIhE GSpA== X-Forwarded-Encrypted: i=1; AJvYcCV21uUk1AakdyWQaRdf2FO39tjyldJgT5v+Q1VV7t8eL5nwsagKtjEmtlBJCme9lszQk5+ApA==@debbugs.gnu.org X-Gm-Message-State: AOJu0YygFf82nZdRHPk6vltDmMp3apnTKvePu3+M+IryP86+18l+V1Pd aWaE/XJJ00be8uiv1IpRtPEhZyy/xNLNuerS3oYOS8EAd8MfQgUJ3/uRlCFqa91+q3gyFwVBoEB UmOmRiquDJBZh5581kOYOfxsuyreTFeE= X-Gm-Gg: ASbGncuhuoP5dcgamapdnfzxRHGS2nhRa7Vqgpj660K9CqPHUAxrg9BCAEagINcFFai ypA6LT5kJDkyiJdu37Q33l1RjhCKXM3BMLThY7E6gJgTB/qS3rHXUbe86C4jvI8MEs1My02OpIo 7fV3bmyLvI+WERz0ykC7XZKzcSuwTVJLhkNoTn4mRAlOeZj/2cj9VdpslD9/2wlObKhAYjR+Cze xw+vgudWc7rs45IX1hTnEj4yZQrqUjD2fucGwlTXoQUstoyJHnaIZhMaMbhWNp7X4DDyBujKzhU N7INDPJKiD1c7tP3a+ckUfjBrhJGsPH+BfoHZfJKj9XxyMSRDV9jPSFfFO2ClktZ0ZZdPEfXL+M gmMr66+JKjXRMQt9KUVM= X-Google-Smtp-Source: AGHT+IGc6EJncQ/pc9iYpHZ9QrEy1effQalFos1nMF1glD04zyJ6+eOWbNAZnyp93jcIhwvWHLlWsJUqdPDhqzSA5QY= X-Received: by 2002:a05:6102:5805:b0:534:24ad:3596 with SMTP id ada2fe7eead31-556367927ebmr3069932137.3.1757763264387; Sat, 13 Sep 2025 04:34:24 -0700 (PDT) MIME-Version: 1.0 References: <87h67quk0g.fsf@daniel-mendler.de> <54fadfd1-21f6-48cb-a17e-8d0878a68f1d@gmail.com> <87ldmweuf2.fsf@posteo.net> <87ecsovdqp.fsf@daniel-mendler.de> <87seh4tptl.fsf@posteo.net> <312bce53-f1de-4dfb-8338-a71f4d7cebfb@gmail.com> <86ldmisuba.fsf@gnu.org> In-Reply-To: <86ldmisuba.fsf@gnu.org> From: =?UTF-8?Q?St=C3=A9phane?= Marks Date: Sat, 13 Sep 2025 07:34:13 -0400 X-Gm-Features: AS18NWDf5U5CUduwVeEujzybwwWRYK3eQZMPmNTcnC_hE20CKEP_icfKFAOFPAM Message-ID: Content-Type: multipart/alternative; boundary="000000000000f91ce8063ead2618" X-Spam-Score: 0.0 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) --000000000000f91ce8063ead2618 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable On Sat, Sep 13, 2025 at 3:10=E2=80=AFAM Eli Zaretskii wrote: > > Cc: 74604@debbugs.gnu.org > > Date: Sat, 13 Sep 2025 09:01:33 +0900 > > From: Nobuyuki Kamimoto > > > > +(defcustom package-upgrade-confirmation-policy t > > The default value sounds problematic to me. For starters, it changes > previous behavior, which already should have a good reason. Moreover, > IME most people don't care about the changes, and consider any display > that insists of showing them, let alone wants a confirmation, an > annoyance. Consider the case that a user upgrades many packages at > once, for example. > > So my suggestion is to leave the default at nil, preserving previous > behavior. This option is a very good feature, but only for users who > are actually interested in reviewing the changes when they upgrade. > > > +Possible values: > > + > > +\\=3D`t\\=3D' - Default > > + Show diffs and prompt for all package upgrades. > > + > > +\\=3D`nil\\=3D' > > + Automatically upgrade all packages without showing diffs. > > We don't quote t and nil in doc strings, so please don't. > > > + :type '(choice > > + (const :tag "Always show diffs" t) > > + (const :tag "Never show diffs" nil) > > + (repeat :tag "Specific packages/archives to confirm" > > If we are going to request confirmation, the first two tags should > also mention that. As written, the first two tags only talk about > showing the diffs and never mention that showing changes also requires > a confirmation. > I think I'd prefer a whitelist of packages I choose to trust vs. a blacklist of those I don't. I'm guessing that for the people who want this feature (like me), their blacklist would be much longer than the whitelist, and we will not want to maintain that blacklist by hand. Maintaining the whitelist will be easy, with so few packages to not warrant a review. --000000000000f91ce8063ead2618 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
= On Sat, Sep 13, 2025 at 3:10=E2=80=AFAM Eli Zaretskii <eliz@gnu.org> wrote:
> Cc: 74604@debbugs.gnu.org
> Date: Sat, 13 Sep 2025 09:01:33 +0900
> From: Nobuyuki Kamimoto <kamimoto527@gmail.com>
>
> +(defcustom package-upgrade-confirmation-policy t

The default value sounds problematic to me.=C2=A0 For starters, it changes<= br> previous behavior, which already should have a good reason.=C2=A0 Moreover,=
IME most people don't care about the changes, and consider any display<= br> that insists of showing them, let alone wants a confirmation, an
annoyance.=C2=A0 Consider the case that a user upgrades many packages at once, for example.

So my suggestion is to leave the default at nil, preserving previous
behavior.=C2=A0 This option is a very good feature, but only for users who<= br> are actually interested in reviewing the changes when they upgrade.

> +Possible values:
> +
> +\\=3D`t\\=3D' - Default
> +=C2=A0 =C2=A0 Show diffs and prompt for all package upgrades.
> +
> +\\=3D`nil\\=3D'
> +=C2=A0 =C2=A0 Automatically upgrade all packages without showing diff= s.

We don't quote t and nil in doc strings, so please don't.

> +=C2=A0 :type '(choice
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (const :tag "Always show diff= s" t)
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (const :tag "Never show diffs= " nil)
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (repeat :tag "Specific packag= es/archives to confirm"

If we are going to request confirmation, the first two tags should
also mention that.=C2=A0 As written, the first two tags only talk about
showing the diffs and never mention that showing changes also requires
a confirmation.

I think I'd prefer a whitelist of pack= ages I choose to trust vs. a blacklist of those I don't.=C2=A0 I'm = guessing that for the people who want this feature (like me), their blackli= st would be much longer than the whitelist, and we will not want to maintai= n=C2=A0that blacklist by hand.=C2=A0 Maintaining the whitelist will be easy= , with so few packages to not warrant a review.
--000000000000f91ce8063ead2618-- From unknown Fri Sep 19 04:01:23 2025 X-Loop: help-debbugs@gnu.org Subject: bug#74604: [PATCH v1] package.el: Add diff display and confirmation for package upgrades (Bug#74604) Resent-From: =?UTF-8?Q?St=C3=A9phane?= Marks Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Sat, 13 Sep 2025 12:18:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 74604 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: To: Eli Zaretskii Cc: mail@daniel-mendler.de, philipk@posteo.net, Nobuyuki Kamimoto , 74604@debbugs.gnu.org Received: via spool by 74604-submit@debbugs.gnu.org id=B74604.175776586011629 (code B ref 74604); Sat, 13 Sep 2025 12:18:02 +0000 Received: (at 74604) by debbugs.gnu.org; 13 Sep 2025 12:17:40 +0000 Received: from localhost ([127.0.0.1]:54275 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1uxPCF-00031V-Ad for submit@debbugs.gnu.org; Sat, 13 Sep 2025 08:17:39 -0400 Received: from mail-vk1-xa2e.google.com ([2607:f8b0:4864:20::a2e]:48206) by debbugs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.84_2) (envelope-from ) id 1uxPCC-000315-LY for 74604@debbugs.gnu.org; Sat, 13 Sep 2025 08:17:37 -0400 Received: by mail-vk1-xa2e.google.com with SMTP id 71dfb90a1353d-54a16081361so262843e0c.0 for <74604@debbugs.gnu.org>; Sat, 13 Sep 2025 05:17:36 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1757765850; x=1758370650; darn=debbugs.gnu.org; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:from:to:cc:subject:date:message-id:reply-to; bh=2QrmMwVmWhYcRYggIQpQFEaBsVy9i+vzfdvYwaALU2s=; b=NEiUJsMNqccxbmlWKklaclymlPFQ598J9q0+P1uSFZD/ckGBhD4DYR0f4OA0t6VsGL 3u/i3mleA3jvEb2x2VnGa2eGNnoGhue+Np+rY93fXPkrpVWIJy6/RN4VhApxn7pYYz4H InzGT10dwwL+Wnj5iO0wt9sckomN+BnLlLlNJsiNi8euxrJ60M7fKxKFYVAeXtSFX/iT vdXGaLsducb3uVPSteL36rJ+F6BWp8pLKHdiSz/B4jOjGhejVoX5E2pS9oIl4Ppy/xwB fIrCh8TretfbiKstj5iqPvQA8g8/LwXpZ+V6GRKPJUjkLtrFsOuOEcpYBk1M37uRNeTW he0Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1757765850; x=1758370650; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=2QrmMwVmWhYcRYggIQpQFEaBsVy9i+vzfdvYwaALU2s=; b=lKi6RKV4nwf7z1thTpJ+RcUFEoKcYeZGD2Bh3ASNE6W/L7BoD5wgMWShqhJjMjlRqR u6/E2svvGvea6+amAhzFVNGIxrV/iMAtdK4g+nGxyceEsiRsCc9nSY8f2h07xn/OaPVA hF/guodRDqOQVERjzrA52pzOaM4zxFaY5KuQhJjRAqbEjAE858nXmgLiNJnY6Gm3HKF4 qan9+4lO0inIlxsF9Rs/ix2HIWob2TLJgzo9tW5M4xa6HsMFfsw+l3+ag6KlZ6at95YD QrabYd1xEzS72l0PX/N6d41YFYHlYOaPUCRdgb3yWMrB9IhFxEk+KmVZq2UNQ4qeEJHr xJgg== X-Forwarded-Encrypted: i=1; AJvYcCX5XoT97ihfqjB5rSuqM60BqthJAVJxOiA0zbrBYW3Md5srCGET6u6z6Zil5Ara4HI32yRT/A==@debbugs.gnu.org X-Gm-Message-State: AOJu0YyC9mxH+Jm9fO7KDmT7xGMjhrDq20Z53ccjiV/OuQ1Z7XiApwFf wx8bX3psK5HZvPov/Uf8yDBJFiuxUe7zHSO6Zxg+TX1KlEDntsC8yJrigl+53oBrbZvGWYaNWOJ Ygsav8vGdPrIeHpv7iF06Q7DqFvSZXGI= X-Gm-Gg: ASbGncvAVyFhSEnQAA1uoZgtGw6ddW6A7fp2+YSwDPGDby6SnotUlI+NBkGVnXzWupH YDqu+JArsmEXbYNm6HcQo2TDLHrmmEZlcSOoovUZDiB/H0f7aJ9lmmbYRhuJwNwtig15Itn0XjL XTnS7bOSc8Nh5XhvfWjsz22ZlWkQW/yGQu5sl0em5HgPBMMpfZUFYDgdQdINksr1JcbQCLWsbIy 8rQtdmLM8eyJ80kE79646d8xMh+2hrr9PtqjGqkjFG0H/VK1mPNURI/xwdN7HRYTs5bM9sngq0j s3CUW9JOYTKMRz6ObGlRQDuSbfQrtaSdP2gRtxKXmCd4quOoYdsB1a50KpS3rSSFATFlICWpwJh 1Ouh1ggzCkYYDwcmpvkpwtAam6/UDFQ== X-Google-Smtp-Source: AGHT+IFDSQzIAqRoxs7ICnCEXrbjiwrmm+Ic3YpPBQDTEVAH229zNGGvYU3H+gH+frMmGAIIScF38pKz//T3V7ZRnBw= X-Received: by 2002:a05:6122:ca2:b0:545:df94:e613 with SMTP id 71dfb90a1353d-54a16b7dbc0mr2048092e0c.6.1757765850131; Sat, 13 Sep 2025 05:17:30 -0700 (PDT) MIME-Version: 1.0 References: <87h67quk0g.fsf@daniel-mendler.de> <54fadfd1-21f6-48cb-a17e-8d0878a68f1d@gmail.com> <87ldmweuf2.fsf@posteo.net> <87ecsovdqp.fsf@daniel-mendler.de> <87seh4tptl.fsf@posteo.net> <312bce53-f1de-4dfb-8338-a71f4d7cebfb@gmail.com> <86ldmisuba.fsf@gnu.org> In-Reply-To: From: =?UTF-8?Q?St=C3=A9phane?= Marks Date: Sat, 13 Sep 2025 08:17:18 -0400 X-Gm-Features: AS18NWA4F6xKqHVpwejJlNfqYaE09diixbA2sAsP-xkd9nBOuYFno-xBbQ5-Q88 Message-ID: Content-Type: multipart/alternative; boundary="00000000000018708e063eadc14b" X-Spam-Score: 0.0 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) --00000000000018708e063eadc14b Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable On Sat, Sep 13, 2025 at 7:34=E2=80=AFAM St=C3=A9phane Marks wrote: > On Sat, Sep 13, 2025 at 3:10=E2=80=AFAM Eli Zaretskii wrot= e: > >> > Cc: 74604@debbugs.gnu.org >> > Date: Sat, 13 Sep 2025 09:01:33 +0900 >> > From: Nobuyuki Kamimoto >> > >> > +(defcustom package-upgrade-confirmation-policy t >> >> The default value sounds problematic to me. For starters, it changes >> previous behavior, which already should have a good reason. Moreover, >> IME most people don't care about the changes, and consider any display >> that insists of showing them, let alone wants a confirmation, an >> annoyance. Consider the case that a user upgrades many packages at >> once, for example. >> >> So my suggestion is to leave the default at nil, preserving previous >> behavior. This option is a very good feature, but only for users who >> are actually interested in reviewing the changes when they upgrade. >> >> > +Possible values: >> > + >> > +\\=3D`t\\=3D' - Default >> > + Show diffs and prompt for all package upgrades. >> > + >> > +\\=3D`nil\\=3D' >> > + Automatically upgrade all packages without showing diffs. >> >> We don't quote t and nil in doc strings, so please don't. >> >> > + :type '(choice >> > + (const :tag "Always show diffs" t) >> > + (const :tag "Never show diffs" nil) >> > + (repeat :tag "Specific packages/archives to confirm" >> >> If we are going to request confirmation, the first two tags should >> also mention that. As written, the first two tags only talk about >> showing the diffs and never mention that showing changes also requires >> a confirmation. >> > > I think I'd prefer a whitelist of packages I choose to trust vs. a > blacklist of those I don't. I'm guessing that for the people who want th= is > feature (like me), their blacklist would be much longer than the whitelis= t, > and we will not want to maintain that blacklist by hand. Maintaining the > whitelist will be easy, with so few packages to not warrant a review. > An option to automatically whitelist built-ins might also be useful, as those are "core." --00000000000018708e063eadc14b Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
= On Sat, Sep 13, 2025 at 7:34=E2=80=AFAM St=C3=A9phane Marks <shipmints@gmail.com> wrote:
=
On Sat, Sep 13, 2025 at 3:10=E2=80=AFAM Eli Zaretskii <eliz@gnu.org> wrote:<= /div>
> Cc: 74604@debbugs.gnu.org
> Date: Sat, 13 Sep 2025 09:01:33 +0900
> From: Nobuyuki Kamimoto <kamimoto527@gmail.com>
>
> +(defcustom package-upgrade-confirmation-policy t

The default value sounds problematic to me.=C2=A0 For starters, it changes<= br> previous behavior, which already should have a good reason.=C2=A0 Moreover,=
IME most people don't care about the changes, and consider any display<= br> that insists of showing them, let alone wants a confirmation, an
annoyance.=C2=A0 Consider the case that a user upgrades many packages at once, for example.

So my suggestion is to leave the default at nil, preserving previous
behavior.=C2=A0 This option is a very good feature, but only for users who<= br> are actually interested in reviewing the changes when they upgrade.

> +Possible values:
> +
> +\\=3D`t\\=3D' - Default
> +=C2=A0 =C2=A0 Show diffs and prompt for all package upgrades.
> +
> +\\=3D`nil\\=3D'
> +=C2=A0 =C2=A0 Automatically upgrade all packages without showing diff= s.

We don't quote t and nil in doc strings, so please don't.

> +=C2=A0 :type '(choice
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (const :tag "Always show diff= s" t)
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (const :tag "Never show diffs= " nil)
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (repeat :tag "Specific packag= es/archives to confirm"

If we are going to request confirmation, the first two tags should
also mention that.=C2=A0 As written, the first two tags only talk about
showing the diffs and never mention that showing changes also requires
a confirmation.

I think I'd prefer a whitelist of packages I choose to trust v= s. a blacklist of those I don't.=C2=A0 I'm guessing that for the pe= ople who want this feature (like me), their blacklist would be much longer = than the whitelist, and we will not want to maintain=C2=A0that blacklist by= hand.=C2=A0 Maintaining the whitelist will be easy, with so few packages t= o not warrant a review.

An option to automat= ically whitelist built-ins might also be useful, as those are "core.&q= uot;
--00000000000018708e063eadc14b-- From unknown Fri Sep 19 04:01:23 2025 X-Loop: help-debbugs@gnu.org Subject: bug#74604: [PATCH v1] package.el: Add diff display and confirmation for package upgrades (Bug#74604) Resent-From: Philip Kaludercic Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Sat, 13 Sep 2025 12:19:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 74604 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: To: Nobuyuki Kamimoto Cc: Daniel Mendler , 74604@debbugs.gnu.org Received: via spool by 74604-submit@debbugs.gnu.org id=B74604.175776588411746 (code B ref 74604); Sat, 13 Sep 2025 12:19:02 +0000 Received: (at 74604) by debbugs.gnu.org; 13 Sep 2025 12:18:04 +0000 Received: from localhost ([127.0.0.1]:54278 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1uxPCZ-00032d-8V for submit@debbugs.gnu.org; Sat, 13 Sep 2025 08:18:04 -0400 Received: from mout01.posteo.de ([185.67.36.65]:36363) by debbugs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.84_2) (envelope-from ) id 1uxPCF-00031A-KU for 74604@debbugs.gnu.org; Sat, 13 Sep 2025 08:17:43 -0400 Received: from submission (posteo.de [185.67.36.169]) by mout01.posteo.de (Postfix) with ESMTPS id DB28A240027 for <74604@debbugs.gnu.org>; Sat, 13 Sep 2025 14:17:31 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=posteo.net; s=2017; t=1757765851; bh=ouHY0RCxA6RexC8RdwF3PjjAqhD9ufLOuYNc47IYOuc=; h=From:To:Cc:Subject:OpenPGP:Date:Message-ID:MIME-Version: Content-Type:Content-Transfer-Encoding:From; b=MSCj2UT3hNC7I4mpEUtKI91gkm0hD+9MFyEjngmjhQrtVSi7Bc9xqmM3FLCskm5CB 3VQRknzeo1KQzwCCeCQ60ZTTOswQl0k91FcOvoFpOMkA+jnTzozuSKOhZCZlOmEh// mVy3NYtFI3G9/HAauklV6DLeD9389ulh6jJKTYLf+DrM2pEJCn8fdmMi3W37DaJnR4 IVwTFNlgrUChWz/sui5HqF/snisStZ2l4MnEY//drPhsW1PsOidqISu1Q05Bxh1jz2 UHHI8OiDhkEUot01zyQsKF+ZKctRReNneBj24eiHAU+BEMB6hL8yEmUjaJfvxUi+8E ni/ftyUxrl6oA== Received: from customer (localhost [127.0.0.1]) by submission (posteo.de) with ESMTPSA id 4cP9KR0ZPxz6twv; Sat, 13 Sep 2025 14:17:30 +0200 (CEST) From: Philip Kaludercic In-Reply-To: <312bce53-f1de-4dfb-8338-a71f4d7cebfb@gmail.com> References: <87h67quk0g.fsf@daniel-mendler.de> <54fadfd1-21f6-48cb-a17e-8d0878a68f1d@gmail.com> <87ldmweuf2.fsf@posteo.net> <87ecsovdqp.fsf@daniel-mendler.de> <87seh4tptl.fsf@posteo.net> <312bce53-f1de-4dfb-8338-a71f4d7cebfb@gmail.com> OpenPGP: id=7126E1DE2F0CE35C770BED01F2C3CC513DB89F66; url="https://keys.openpgp.org/vks/v1/by-fingerprint/7126E1DE2F0CE35C770BED01F2C3CC513DB89F66"; preference=signencrypt Date: Sat, 13 Sep 2025 12:17:31 +0000 Message-ID: <87348qy2b0.fsf@posteo.net> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-Spam-Score: -2.3 (--) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -3.3 (---) Nobuyuki Kamimoto writes: > Hello Philip and Daniel, > > Thank you for your detailed feedback on the initial patch. You raised > excellent points about avoiding > duplication of existing VC functionality and improving the overall approa= ch. (Not to start a unrelated discussion, but parts of your message sound like they might have been written by generative AI. I don't mind that, but it might be an issue if you used GenAI to prepare the patch as well, as TTBOMK is not yet a resolved matter for the GNU project. Related to that, have you signed the FSF copyright assignment?) [...] > > From a41c934b9c39e99e9aaf379519f0d66a71b39966 Mon Sep 17 00:00:00 2001 > From: Nobuyuki Kamimoto > Date: Fri, 12 Sep 2025 21:12:53 +0900 > Subject: [PATCH] Enhance package upgrade UI with interactive y/n/d/c prom= pts > > Add interactive confirmation system for package upgrades with options for: > - Yes/No upgrade decisions > - Diff display between package versions > - Changelog viewing with file exclusion patterns > - Configurable confirmation policy per package/archive > > Includes comprehensive diff utilities for tarball packages and VC package= s, > with proper error handling and user-friendly display buffers. It would be nice if you could rewrite the commit message to align with the style described in the CONTRIBUTE file (see the section "Commit messages"). The main thing here is that you explicitly annotate how which functions have been changed in which files. > --- > doc/emacs/package.texi | 42 ++++ > etc/NEWS | 10 + > lisp/package/package-core.el | 158 ++++++++++++++ How much of these changes really have to be part of package-core? The idea behind the ongoing refactoring is to keep that file as small as possible, so that it contains just what is necessary to activate packages on startup. > lisp/package/package-install.el | 356 +++++++++++++++++++++++++++++++- > lisp/package/package-menu.el | 48 +++-- > lisp/package/package-vc.el | 218 +++++++++++++++---- > 6 files changed, 774 insertions(+), 58 deletions(-) > > diff --git a/doc/emacs/package.texi b/doc/emacs/package.texi > index 5aa9f9a74bf..3b2a59dda23 100644 > --- a/doc/emacs/package.texi > +++ b/doc/emacs/package.texi > @@ -389,6 +389,38 @@ Package Installation > use these bulk commands if you want to update only a small number of > built-in packages. >=20=20 > +@vindex package-upgrade-confirmation-policy > + By default, Emacs shows a diff of the changes when upgrading > +packages, allowing you to review what has changed between the current > +and new version before proceeding. This is controlled by the > +@code{package-upgrade-confirmation-policy} user option. When set to @co= de{t} (the > +default), package upgrades will display the differences and ask for > +confirmation before proceeding. You can disable this behavior by > +setting @code{package-upgrade-confirmation-policy} to @code{nil} to upgr= ade > +all packages automatically without showing diffs. > + > + You can also specify which packages or archives require confirmation by > +setting @code{package-upgrade-confirmation-policy} to a list of specific > +packages and archives. Only the packages and archives in the list will = show > +confirmation prompts, while all others will upgrade automatically. > + > +@noindent > +Examples of list-based configuration: > + > +@example > +;; Only confirm magit and helm upgrades, auto-upgrade everything else > +(setq package-upgrade-confirmation-policy > + '((package magit) (package helm))) > + > +;; Only confirm packages from melpa archive, auto-upgrade others > +(setq package-upgrade-confirmation-policy > + '((archive "melpa"))) > + > +;; Mixed: confirm org package and all melpa-stable packages > +(setq package-upgrade-confirmation-policy > + '((package org) (archive "melpa-stable"))) > +@end example > + > @cindex package requirements > A package may @dfn{require} certain other packages to be installed, > because it relies on functionality provided by them. When Emacs > @@ -655,6 +687,16 @@ Fetching Package Sources > Note that currently, built-in packages cannot be upgraded using > @code{package-vc-install}. >=20=20 > + Like regular package upgrades, VC package upgrades can also show > +diffs before proceeding. This behavior is controlled by the same > +@code{package-upgrade-confirmation-policy} user option that controls reg= ular > +package upgrades. When set to @code{t} (the default), upgrading VC > +packages will display the differences between the current and updated > +versions, allowing you to review the changes before confirming the upgra= de. > + > + VC packages use the same confirmation policy and file exclusion patter= ns > +as regular packages, ensuring consistent behavior across all package typ= es. > + > @findex package-report-bug > @findex package-vc-prepare-patch > With the source checkout, you might want to reproduce a bug against > diff --git a/etc/NEWS b/etc/NEWS > index ac8e56326bf..904592577a0 100644 > --- a/etc/NEWS > +++ b/etc/NEWS > @@ -74,6 +74,16 @@ done from early-init.el, such as adding to 'package-di= rectory-list'. > ** 'prettify-symbols-mode' attempts to ignore undisplayable characters. > Previously, such characters would be rendered as, e.g., white boxes. >=20=20 > ++++ > +** Package management now shows diffs before upgrades. > +Package upgrades will now display differences between the current and > +new version before proceeding. This applies to both regular packages > +and VC packages installed from version control repositories. > + > +Users will see a diff buffer showing changes and can choose whether to > +proceed with or cancel the upgrade. This behavior can be controlled > +through the 'package-upgrade-confirmation-policy' user option. > + > +++ > ** 'standard-display-table' now has more extra slots. > 'standard-display-table' has been extended to allow specifying glyphs > diff --git a/lisp/package/package-core.el b/lisp/package/package-core.el > index e52654aa53d..b0b1831e1ed 100644 > --- a/lisp/package/package-core.el > +++ b/lisp/package/package-core.el > @@ -284,6 +284,164 @@ package-selected-packages > :version "25.1" > :type '(repeat symbol)) >=20=20 > +;; Interactive upgrade prompt constants > +(defconst package-upgrade-interactive-commands > + '((?y . upgrade) > + (?n . cancel) > + (?d . show-diff) > + (?c . show-changelog) > + (?q . quit)) > + "Interactive commands for package upgrade confirmation.") > + > +(defconst package-upgrade-prompt-message > + "Upgrade %s? (y)es, (n)o, (d)iff, (c)hangelog, (q)uit: " > + "Prompt message format for package upgrade confirmation.") > + > +(defconst package-diff-context-lines 3 > + "Number of context lines to show in package and changelog diffs.") I don't think that we need these declarations as constants? > +(defconst package-changelog-max-size (* 1024 1024) > + "Maximum size in bytes for changelog files to process.") > + > +(defcustom package-upgrade-confirmation-policy t As Eli said, the default is probably too invasive. > + "Policy for confirming packages during upgrades. > +This determines which packages require user confirmation before upgradin= g. > + > +Possible values: > + > +\\=3D`t\\=3D' - Default > + Show diffs and prompt for all package upgrades. > + > +\\=3D`nil\\=3D' > + Automatically upgrade all packages without showing diffs. > + > +A list of specific packages/archives to confirm > + Only the packages and archives listed will show confirmation prompts. > + All others will be upgraded automatically. > + > + List format: > + (package PACKAGE-SYMBOL) - Show diff for this specific package Do you think that it would also be acceptable to have symbols interpreted as synonyms to (package ...)? > + (archive ARCHIVE-NAME) - Show diff for all packages in this archi= ve > + > +Examples: > + \\=3D'((package magit) (package helm)) > + - Only confirm magit and helm upgrades > + - All other packages upgrade automatically > + > + \\=3D'((archive \"melpa\") (package org)) > + - Confirm all melpa archive packages > + - Confirm org package upgrades > + - All other packages upgrade automatically > + > + \\=3D'((package magit)) > + - Only confirm magit upgrades > + - All other packages upgrade automatically" > + :type '(choice > + (const :tag "Always show diffs" t) > + (const :tag "Never show diffs" nil) > + (repeat :tag "Specific packages/archives to confirm" > + (choice > + (list :tag "Package rule" (const package) symbol) > + (list :tag "Archive rule" (const archive) string)))) > + :version "31.1") > + > +(defun package--match-rule-p (rule package-name package-archive) I think it would be cleaner to pass the package-desc object here, than to have to extract the information before invoking the function. > + "Check if RULE matches PACKAGE-NAME and PACKAGE-ARCHIVE." > + (pcase rule > + (`(package ,name) (eq name package-name)) > + (`(archive ,archive) (string=3D archive package-archive)) > + (_ nil))) > + > +(defun package--should-show-diff-p (pkg-desc) > + "Check if diff should be shown for PKG-DESC based on confirmation poli= cy." > + (let ((package-name (package-desc-name pkg-desc)) > + (package-archive (package-desc-archive pkg-desc)) > + (policy package-upgrade-confirmation-policy)) > + (cond Feel free to use `pcase' here as well, to avoid the trivial binding. > + ((eq policy t) t) > + ((eq policy nil) nil) This is redundant, as if the policy is nil, (listp nil) is true, and (seq-some ... nil) is always nil. > + ((listp policy) > + ;; List mode: only show diff for packages/archives in the list > + (seq-some (lambda (rule) > + (package--match-rule-p rule package-name package-archi= ve)) As the function is used only once, I would actually even inline it here. > + policy)) > + (t t)))) > + > +(defcustom package-changelog-patterns > + '("CHANGELOG*" "NEWS*" "ChangeLog*" "CHANGES*" "HISTORY*") > + "File patterns to match changelog files." > + :type '(repeat string) > + :version "31.1") > + > +(defvar package-changelog-file-regex > + (concat "\\(" (mapconcat (lambda (pattern) > + (replace-regexp-in-string "\\*" ".*" pattern)) > + package-changelog-patterns "\\|") "\\)") > + "Regular expression to match changelog files based on patterns.") I think it would be better to check for a designated "news" file, the way that `describe-package-1' does. > +;; Changelog file utilities > +(declare-function diff-no-select "diff" (old new &optional switches no-a= sync)) > + > +(defun package--find-changelog-files (directory) > + "Find all changelog files in DIRECTORY using regular expression matchi= ng. > +Returns a list of paths to all matching changelog files found, or nil if= none." > + (when (and directory (stringp directory) (file-directory-p directory)) > + (condition-case err > + (let ((files (directory-files directory t "^[^.]" t)) > + (candidates nil)) > + ;; Collect all matching files > + (dolist (file files) > + (when (and (file-regular-p file) > + (file-readable-p file) > + (let ((basename (file-name-nondirectory file))) > + (string-match-p package-changelog-file-regex > + (downcase basename)))) You can also just bind `case-fold-search' to nil, that way you don't have to allocate a new string. > + (push file candidates))) > + ;; Return all candidates sorted by name for consistent ordering > + (sort candidates #'string<)) > + (file-error > + (message "File access error searching for changelog files in %s: = %s" > + directory (error-message-string err)) > + nil) > + (error > + (message "Error searching for changelog files in %s: %s" > + directory (error-message-string err)) > + nil)))) I think that you can simplify this using `with-demoted-errors'. > + > +(defun package--diff-available-p () > + "Check if diff functionality is available. > +Since we use built-in Emacs diff functions, this always returns t." > + (require 'diff) > + t) Why do we need this? > +(defun package--diff-changelog-files (old-file new-file) > + "Generate unified diff between OLD-FILE and NEW-FILE. > +Returns diff output as string, or nil if diff is not available." > + (when (and old-file new-file > + (file-exists-p old-file) > + (file-exists-p new-file) > + (package--diff-available-p)) > + (let ((old-size (nth 7 (file-attributes old-file))) > + (new-size (nth 7 (file-attributes new-file)))) > + ;; Check file size limits > + (when (and (< old-size package-changelog-max-size) > + (< new-size package-changelog-max-size)) > + (let ((diff-buffer (diff-no-select old-file new-file > + (format "--unified=3D%d" pack= age-diff-context-lines) t))) > + (when diff-buffer > + (with-current-buffer diff-buffer > + (let ((diff-output (buffer-string))) > + (kill-buffer diff-buffer) > + (when (> (length diff-output) 0) > + diff-output))))))))) > + > +(defun package--format-changelog-diff () > + "Format and highlight diff output in current buffer. > +Uses diff-mode features for syntax highlighting." > + (when (fboundp 'diff-mode) > + (diff-mode) > + (font-lock-ensure))) > + > ;; Pseudo fields. > (defun package-version-join (vlist) > "Return the version string corresponding to the list VLIST. > diff --git a/lisp/package/package-install.el b/lisp/package/package-insta= ll.el > index 8401a7769b7..34468c109b5 100644 > --- a/lisp/package/package-install.el > +++ b/lisp/package/package-install.el > @@ -380,6 +380,7 @@ package-install > (message "`%s' is already installed" name)))) >=20=20 > (declare-function package-vc-upgrade "package-vc" (pkg)) > +(declare-function diff-no-select "diff" (old new &optional switches no-a= sync)) >=20=20 > ;;;###autoload > (defun package-upgrade (name) > @@ -392,16 +393,26 @@ package-upgrade > (package--upgradeable-packages t) nil t)))) > (cl-check-type name symbol) > (let* ((pkg-desc (cadr (assq name package-alist))) > - (package-install-upgrade-built-in (not pkg-desc))) > + (package-install-upgrade-built-in (not pkg-desc)) > + (new-pkg-desc (cadr (assq name package-archive-contents)))) > ;; `pkg-desc' will be nil when the package is an "active built-in". > (if (and pkg-desc (package-vc-p pkg-desc)) > (package-vc-upgrade pkg-desc) > - (when pkg-desc > - (package-delete pkg-desc 'force 'dont-unselect)) > - (package-install name > - ;; An active built-in has never been "selected" > - ;; before. Mark it as installed explicitly. > - (and pkg-desc 'dont-select))))) > + ;; Check if this is a tarball package upgrade that needs diff conf= irmation > + (if (and pkg-desc new-pkg-desc > + (eq (package-desc-kind new-pkg-desc) 'tar)) > + ;; For tarball packages, show diff and ask for confirmation > + ;; The function now handles the complete upgrade process inter= nally > + (unless (package--confirm-tarball-upgrade pkg-desc new-pkg-des= c) > + (message "Package upgrade cancelled")) > + ;; For non-tarball packages, proceed with normal upgrade > + (progn You can drop the `progn' here, Elisp's if has an implicit trailing progn. > + (when pkg-desc > + (package-delete pkg-desc 'force 'dont-unselect)) > + (package-install name > + ;; An active built-in has never been "selecte= d" > + ;; before. Mark it as installed explicitly. > + (and pkg-desc 'dont-select))))))) >=20=20 > (defun package--upgradeable-packages (&optional include-builtins) > ;; Initialize the package system to get the list of package > @@ -1108,5 +1119,336 @@ package-recompile-all > (with-demoted-errors "Error while recompiling: %S" > (package-recompile pkg-desc)))) >=20=20 > +;; Package upgrade diff utilities > + > +(defun package--safe-insert-file (file &optional error-msg) > + "Safely insert FILE contents, showing ERROR-MSG on failure." > + (condition-case err Same comment here as above. > + (when (and file (file-readable-p file)) > + (insert-file-contents file)) > + (file-error > + (insert (or error-msg > + (format "File access error: %s" (error-message-string e= rr))))) How can this happen, if we have established prior to `insert-file-contents' that the file is readable -- excluding the possibility of corrupted permissions due the involvement of multiple users or race conditions? > + (error > + (insert (or error-msg > + (format "Error reading file: %s" (error-message-string = err))))))) > + > +(defun package--show-changelog (old-dir new-dir) > + "Show diff of all changelog files between OLD-DIR and NEW-DIR. > +Displays unified diff showing what changed in all matched changelog file= s. > +Returns t if any changelog diff was displayed, nil otherwise." > + (let ((old-changelogs (when old-dir (package--find-changelog-files old= -dir))) > + (new-changelogs (when new-dir (package--find-changelog-files new= -dir))) > + (displayed-any nil)) > + (cond > + ;; Both directories have changelog files > + ((or old-changelogs new-changelogs) > + (setq displayed-any (package--display-all-changelog-diffs old-chan= gelogs new-changelogs))) > + ;; No changelog files found in either directory > + (t > + (message "No changelog files found") > + nil)) > + displayed-any)) > + > +(defun package--display-all-changelog-diffs (old-files new-files) > + "Display diffs for all changelog files between OLD-FILES and NEW-FILES. > +Returns t if any diff was displayed, nil otherwise." > + (let ((buffer-name "*Package Changelog Diff*") > + (displayed-any nil) > + (unique-filenames nil)) > + ;; Kill existing buffer if it exists > + (when (get-buffer buffer-name) > + (kill-buffer buffer-name)) > + > + ;; Get unique filenames from both lists > + (setq unique-filenames > + (delete-dups > + (append (mapcar #'file-name-nondirectory old-files) > + (mapcar #'file-name-nondirectory new-files)))) > + > + (with-current-buffer (get-buffer-create buffer-name) > + (let ((inhibit-read-only t)) > + (erase-buffer) > + (insert "Changelog differences between old and new versions:\n") > + (insert (make-string 55 ?=3D)) > + (insert "\n\n") > + > + ;; Process each unique filename > + (dolist (filename unique-filenames) > + (let ((old-file (car (seq-filter (lambda (f) > + (string=3D filename (file-n= ame-nondirectory f))) > + old-files))) > + (new-file (car (seq-filter (lambda (f) > + (string=3D filename (file-n= ame-nondirectory f))) > + new-files)))) > + (cond > + ;; Both old and new versions exist: show diff > + ((and old-file new-file) > + (package--insert-file-diff filename old-file new-file) > + (setq displayed-any t)) > + ;; Only new file exists: show as new addition > + ((and (not old-file) new-file) > + (package--insert-new-file filename new-file) > + (setq displayed-any t)) > + ;; Only old file exists: show as removal > + ((and old-file (not new-file)) > + (insert (format "--- %s (REMOVED in new version) ---\n\n" = filename)) > + (setq displayed-any t))))) > + > + (if displayed-any > + (progn > + (package--format-changelog-diff) > + (goto-char (point-min)) > + (read-only-mode 1)) > + (insert "No changelog differences found.\n") > + (read-only-mode 1))) > + > + (display-buffer buffer-name) > + displayed-any))) IMO it might be nicer if we could use an existing interface like tabulated-list-mode. But just generating a plain, recursive diff would also be fine. > +(defun package--insert-file-diff (filename old-file new-file) > + "Insert diff content for a single file into current buffer." > + (insert (format "--- %s ---\n" filename)) > + (let ((diff-output (package--diff-changelog-files old-file new-file))) > + (if diff-output > + (insert diff-output) > + ;; Fallback if diff is unavailable > + (insert "Diff unavailable. Showing full new content:\n") > + (package--safe-insert-file new-file)) > + (insert "\n\n"))) > + > +(defun package--insert-new-file (filename new-file) > + "Insert new file content into current buffer." > + (insert (format "--- %s (NEW in this version) ---\n" filename)) > + (package--safe-insert-file new-file) > + (insert "\n\n")) > + > +(defun package--show-package-diff (old-dir new-dir pkg-desc) > + "Show diff between OLD-DIR and NEW-DIR package directories for PKG-DES= C. > +This function only displays the diff without prompting for user confirma= tion." > + ;; Ensure diff is loaded and ready before proceeding > + (require 'diff) > + ;; Ensure diff feature is fully loaded on first run > + (unless (featurep 'diff) > + (sit-for 0.1)) require is not asynchronous! This is not an issue. > + ;; Additional safety: ensure diff functions are available > + (unless (fboundp 'diff-mode) > + (autoload 'diff-mode "diff" "Diff major mode" t)) This is als not necessary, diff-mode is part of Emacs and you can rely on the above require to do the right thing=E2=84=A2. > + (condition-case outer-err > + (let ((diff-buffer-name "*Package Diff*")) > + ;; Kill existing buffer to avoid read-only issues > + (when (get-buffer diff-buffer-name) > + (kill-buffer diff-buffer-name)) > + > + ;; Check if directories exist before proceeding > + (unless (and (file-directory-p old-dir) (file-directory-p new-di= r)) > + (error "One or both directories do not exist: %s, %s" old-dir = new-dir)) > + > + (condition-case diff-err > + ;; Use built-in diff-no-select instead of external commands Why? > + (let ((diff-buffer (diff-no-select old-dir new-dir "--unifie= d" t))) > + (if diff-buffer > + (progn > + ;; Safely configure diff buffer before renaming > + (with-current-buffer diff-buffer > + ;; Ensure diff-mode is properly initialized first > + (when (fboundp 'diff-mode) > + (diff-mode)) > + ;; Configure buffer for stable scrolling > + (setq buffer-read-only t) > + (setq truncate-lines nil) ; Allow line wrapping > + ;; Disable potentially problematic diff features > + (when (boundp 'diff-refine-hunk) > + (set (make-local-variable 'diff-refine-hunk) nil= )) Why disable this? This is a useful feature when reading the file. > + (goto-char (point-min)) > + ;; Now safely rename the buffer > + (rename-buffer diff-buffer-name t)) > + ;; Display the properly configured buffer > + (display-buffer diff-buffer-name)) > + ;; No differences found > + (with-current-buffer (get-buffer-create diff-buffer-name) > + (let ((inhibit-read-only t)) > + (erase-buffer) > + (insert (format "No significant differences found be= tween old and new versions of %s.\n" > + (package-desc-name pkg-desc))) > + (goto-char (point-min)) > + (read-only-mode 1)) > + (display-buffer diff-buffer-name)))) > + (error > + ;; If diff fails, create a simple error message > + (with-current-buffer (get-buffer-create diff-buffer-name) > + (let ((inhibit-read-only t)) > + (erase-buffer) > + (insert (format "Error running diff operation: %s\n\n" (e= rror-message-string diff-err))) > + (insert "This may be due to:\n") > + (insert "- File access permissions\n") > + (insert "- Directory structure issues\n") > + (insert "- Memory limitations for large diffs\n") > + (read-only-mode 1)) > + (display-buffer diff-buffer-name)))) > + ;; Return t to indicate success > + t) > + (error > + (message "Error showing package diff: %s (Retry may work)" (error-m= essage-string outer-err)) > + ;; Return nil to indicate failure but allow retry > + nil))) > + > +(defun package--handle-interactive-command (command pkg-desc old-dir new= -dir) > + "Handle interactive COMMAND for PKG-DESC upgrade." > + (pcase command > + ('upgrade 'upgrade) You don't need to quote upgrade here? > + ('cancel 'cancel) > + ('show-diff > + (condition-case err > + (if (and old-dir new-dir) > + (progn > + (let ((result (package--show-package-diff old-dir new-dir= pkg-desc))) > + (if result > + (message "Diff displayed. Press y to upgrade, n to = cancel, c for changelog.") > + (message "Diff display failed. Please try again or us= e changelog (c).")))) > + (message "Package directories not available for diff.")) > + (error > + (message "Error displaying diff: %s (Try again with 'd' or use c= hangelog with 'c')" > + (error-message-string err)))) > + ;; Always return nil to prevent process termination > + nil) > + ('show-changelog > + (condition-case err > + (if (package--show-changelog old-dir new-dir) > + (message "Changelog displayed. Press y to upgrade, n to can= cel, d for full diff.") > + (message "No changelog differences found. Press y to upgrade,= n to cancel.")) > + (error > + (message "Error displaying changelog: %s" (error-message-string = err)))) > + nil) > + ('quit 'quit) > + (_ > + (message "Invalid choice. Use: y=3Dupgrade, n=3Dcancel, d=3Ddiff, c= =3Dchangelog, q=3Dquit") > + (sit-for 1.5) > + nil))) > + > +(defun package--upgrade-interactive-prompt (pkg-desc &optional old-dir n= ew-dir) > + "Interactive prompt for package upgrade confirmation." > + (let ((package-name (package-desc-name pkg-desc)) > + (prompt-choices (mapcar #'car package-upgrade-interactive-comman= ds))) > + (catch 'result > + (while t > + (condition-case err > + (let* ((choice (read-char-choice > + (format package-upgrade-prompt-message packa= ge-name) > + prompt-choices)) > + (command (cdr (assq choice package-upgrade-interactiv= e-commands))) > + (result (package--handle-interactive-command command = pkg-desc old-dir new-dir))) > + (when result > + (throw 'result result))) > + (quit > + (message "Package upgrade cancelled by user") > + (throw 'result 'cancel)) > + (error > + (message "Error during input: %s" (error-message-string err)) > + (sit-for 1))))))) You have reimplemented `read-multiple-choice'... > + > +(defun package--get-installed-package-dir (pkg-desc) > + "Get directory of installed PKG-DESC package." > + (expand-file-name (package-desc-full-name pkg-desc) package-user-dir)) > + > +(defun package-extract (pkg-desc) > + "Extract package PKG-DESC files without generating autoloads or descri= ptors. > +Only performs file extraction based on package kind. Returns the package > +directory path where files were extracted." > + (let* ((name (package-desc-name pkg-desc)) > + (dirname (package-desc-full-name pkg-desc)) > + (pkg-dir (expand-file-name dirname package-user-dir))) > + ;; Extract files based on package kind > + (pcase (package-desc-kind pkg-desc) > + ('dir > + (make-directory pkg-dir t) > + (let ((file-list > + (or (and (derived-mode-p 'dired-mode) > + (dired-get-marked-files)) > + (directory-files-recursively default-directory "" nil)= ))) > + (dolist (source-file file-list) > + (let ((target (expand-file-name > + (file-relative-name source-file default-direct= ory) > + pkg-dir))) > + (make-directory (file-name-directory target) t) > + (copy-file source-file target t))) > + ;; Now that the files have been installed, this package is > + ;; indistinguishable from a `tar' or a `single'. Let's make > + ;; things simple by ensuring we're one of them. > + (setf (package-desc-kind pkg-desc) > + (if (length> file-list 1) 'tar 'single)))) > + ('tar > + (make-directory package-user-dir t) > + (let* ((default-directory (file-name-as-directory package-user-di= r))) > + (package-untar-buffer dirname))) > + ('single > + (let ((el-file (expand-file-name (format "%s.el" name) pkg-dir))) > + (make-directory pkg-dir t) > + (package--write-file-no-coding el-file))) > + (kind (error "Unknown package kind: %S" kind))) > + ;; Return the directory path (no autoloads generation yet) > + pkg-dir)) > + > +(defun package--download-and-extract (new-pkg-desc) > + "Download and extract NEW-PKG-DESC. Return extraction directory." > + (let ((location (package-archive-base new-pkg-desc)) > + (file (concat (package-desc-full-name new-pkg-desc) > + (package-desc-suffix new-pkg-desc)))) > + (package--with-response-buffer location :file file > + (package-extract new-pkg-desc)))) > + > +(defun package--confirm-upgrade (_pkg-desc new-pkg-desc old-dir new-dir) > + "Ask user to confirm upgrade from _PKG-DESC to NEW-PKG-DESC." > + (if (file-exists-p old-dir) > + (let ((result (package--upgrade-interactive-prompt new-pkg-desc ol= d-dir new-dir))) > + (cond > + ((eq result 'upgrade) t) > + ((eq result 'quit) (user-error "Package upgrade cancelled by us= er")) > + (t nil))) > + (yes-or-no-p (format "New package installation: %s. Continue? " > + (package-desc-name new-pkg-desc))))) > + > +(defun package--complete-upgrade (pkg-desc new-pkg-desc new-dir) > + "Complete the upgrade process from PKG-DESC to NEW-PKG-DESC." > + (when pkg-desc > + (package-delete pkg-desc 'force 'dont-unselect)) > + (when (and new-dir (file-directory-p new-dir)) > + (delete-directory new-dir t)) > + (package-install-from-archive new-pkg-desc)) > + > +(defun package--confirm-tarball-upgrade (pkg-desc new-pkg-desc) > + "Confirm and execute tarball package upgrade. > + > +This function handles the complete tarball upgrade workflow: > +1. Check if diff display is required based on trust policy > +2. Download and extract new package for comparison > +3. Show diff and get user confirmation > +4. Complete upgrade or clean up on cancellation > + > +Args: > + PKG-DESC: Current installed package descriptor > + NEW-PKG-DESC: New package descriptor to upgrade to > + > +Returns: > + t if upgrade was confirmed and completed, nil otherwise." > + (if (package--should-show-diff-p new-pkg-desc) > + (let* ((old-dir (package--get-installed-package-dir pkg-desc)) > + (new-dir nil) > + (confirmed nil)) > + (unwind-protect > + (progn > + (setq new-dir (package--download-and-extract new-pkg-desc)) > + (setq confirmed (package--confirm-upgrade pkg-desc new-pkg= -desc old-dir new-dir)) > + (when confirmed > + (package--complete-upgrade pkg-desc new-pkg-desc new-dir= ))) > + ;; Cleanup: remove temporary extraction directory if upgrade w= as cancelled > + (when (and new-dir (not confirmed) (file-exists-p new-dir)) > + (ignore-errors (delete-directory new-dir t)))) > + confirmed) > + ;; Trust policy says skip diff - proceed directly with upgrade > + (progn > + (package--complete-upgrade pkg-desc new-pkg-desc nil) > + t))) > + > (provide 'package-install) > ;;; package-install.el ends here > diff --git a/lisp/package/package-menu.el b/lisp/package/package-menu.el > index c57086112c4..3ffdb940554 100644 > --- a/lisp/package/package-menu.el > +++ b/lisp/package/package-menu.el > @@ -653,22 +653,38 @@ package-menu--perform-transaction > (format status-format (incf i))) > (force-mode-line-update) > (redisplay 'force) > - ;; Don't mark as selected, `package-menu-execute' already > - ;; does that. > - (package-install pkg 'dont-select)))) > - (let ((package-menu--transaction-status ":Deleting")) > - (force-mode-line-update) > - (redisplay 'force) > - (dolist (elt (package--sort-by-dependence delete-list)) > - (condition-case-unless-debug err > - (let ((inhibit-message (or inhibit-message package-menu-asyn= c))) > - (package-delete elt nil 'nosave)) > - (error > - (push (package-desc-full-name elt) errors) > - (message "Error trying to delete `%s': %s" > - (package-desc-full-name elt) > - (error-message-string err)))))) > - errors)) > + ;; Check if this is a package upgrade and needs confirmation > + (let* ((pkg-name (package-desc-name pkg)) > + (old-pkg (cl-find-if (lambda (del-pkg) > + (eq (package-desc-name del-pkg= ) pkg-name)) > + delete-list))) > + (cond > + ;; Tarball package upgrade - use tarball confirmation > + ((and old-pkg (eq (package-desc-kind pkg) 'tar)) > + (if (package--confirm-tarball-upgrade old-pkg pkg) > + (package-install pkg 'dont-select) > + (push (package-desc-full-name pkg) errors))) > + ;; VC package upgrade - use VC confirmation > + ((and old-pkg (package-vc-p old-pkg)) > + (if (package-vc--confirm-upgrade old-pkg) > + (package-install pkg 'dont-select) > + (push (package-desc-full-name pkg) errors))) > + ;; Normal installation or upgrade > + (t > + (package-install pkg 'dont-select)))))) > + (let ((package-menu--transaction-status ":Deleting")) > + (force-mode-line-update) > + (redisplay 'force) > + (dolist (elt (package--sort-by-dependence delete-list)) > + (condition-case-unless-debug err > + (let ((inhibit-message (or inhibit-message package-menu-as= ync))) > + (package-delete elt nil 'nosave)) > + (error > + (push (package-desc-full-name elt) errors) > + (message "Error trying to delete `%s': %s" > + (package-desc-full-name elt) > + (error-message-string err)))))) > + errors))) >=20=20 > (defun package--update-selected-packages (add remove) > "Update the `package-selected-packages' list according to ADD and REMO= VE. > diff --git a/lisp/package/package-vc.el b/lisp/package/package-vc.el > index 03767b99729..3579c9d69b5 100644 > --- a/lisp/package/package-vc.el > +++ b/lisp/package/package-vc.el > @@ -53,6 +53,7 @@ > (require 'package-elpa) > (require 'lisp-mnt) > (require 'vc) > +(require 'vc-git) Err, package-vc is intentionally vc agnostic, so we shouldn't depend on a specific backend, unless we are providing a speedup (in which case it would be better to implement the feature more generally in vc-git). > (require 'seq) >=20=20 > (defgroup package-vc nil > @@ -737,6 +738,8 @@ package-vc-upgrade-all >=20=20 > (declare-function vc-dir-prepare-status-buffer "vc-dir" > (bname dir backend &optional create-new)) > +(declare-function vc-diff-incoming "vc" (&optional remote-location files= et)) > +(declare-function vc-log-incoming "vc" (&optional remote-location)) You shouldn't need this, as we are requiring vc above! >=20=20 > ;;;###autoload > (defun package-vc-upgrade (pkg-desc) > @@ -745,40 +748,42 @@ package-vc-upgrade > This may fail if the local VCS state of the package conflicts > with the remote repository state." > (interactive (list (package-vc--read-package-desc "Upgrade VC package:= " t))) > - ;; HACK: To run `package-vc--unpack-1' after checking out the new > - ;; revision, we insert a hook into `vc-post-command-functions', and > - ;; remove it right after it ran. To avoid running the hook multiple > - ;; times or even for the wrong repository (as `vc-pull' is often > - ;; asynchronous), we extract the relevant arguments using a pseudo > - ;; filter for `vc-filter-command-function', executed only for the > - ;; side effect, and store them in the lexical scope. When the hook > - ;; is run, we check if the arguments are the same (`eq') as the ones > - ;; previously extracted, and only in that case will be call > - ;; `package-vc--unpack-1'. Ugh... > - ;; > - ;; If there is a better way to do this, it should be done. > - (cl-assert (package-vc-p pkg-desc)) > - (letrec ((pkg-dir (package-desc-dir pkg-desc)) > - (vc-flags) > - (vc-filter-command-function > - (lambda (command file-or-list flags) > - (setq vc-flags flags) > - (list command file-or-list flags))) > - (post-upgrade > - (lambda (_command _file-or-list flags) > - (when (and (file-equal-p pkg-dir default-directory) > - (eq flags vc-flags)) > - (unwind-protect > - (with-demoted-errors "Failed to activate: %S" > - (package-vc--unpack-1 pkg-desc pkg-dir)) > - (remove-hook 'vc-post-command-functions post-upgrade))= )))) > - (add-hook 'vc-post-command-functions post-upgrade) > - (with-demoted-errors "Failed to fetch: %S" > - (require 'vc-dir) > - (with-current-buffer (vc-dir-prepare-status-buffer > - (format " *package-vc-dir: %s*" pkg-dir) > - pkg-dir (vc-responsible-backend pkg-dir)) > - (vc-pull))))) > + ;; Check if user wants to see diff and confirm upgrade > + (when (package-vc--confirm-upgrade pkg-desc) > + ;; HACK: To run `package-vc--unpack-1' after checking out the new > + ;; revision, we insert a hook into `vc-post-command-functions', and > + ;; remove it right after it ran. To avoid running the hook multiple > + ;; times or even for the wrong repository (as `vc-pull' is often > + ;; asynchronous), we extract the relevant arguments using a pseudo > + ;; filter for `vc-filter-command-function', executed only for the > + ;; side effect, and store them in the lexical scope. When the hook > + ;; is run, we check if the arguments are the same (`eq') as the ones > + ;; previously extracted, and only in that case will be call > + ;; `package-vc--unpack-1'. Ugh... > + ;; > + ;; If there is a better way to do this, it should be done. > + (cl-assert (package-vc-p pkg-desc)) This assertion should remain at the beginning of the function. > + (letrec ((pkg-dir (package-desc-dir pkg-desc)) > + (vc-flags) > + (vc-filter-command-function > + (lambda (command file-or-list flags) > + (setq vc-flags flags) > + (list command file-or-list flags))) > + (post-upgrade > + (lambda (_command _file-or-list flags) > + (when (and (file-equal-p pkg-dir default-directory) > + (eq flags vc-flags)) > + (unwind-protect > + (with-demoted-errors "Failed to activate: %S" > + (package-vc--unpack-1 pkg-desc pkg-dir)) > + (remove-hook 'vc-post-command-functions post-upgrade= )))))) > + (add-hook 'vc-post-command-functions post-upgrade) > + (with-demoted-errors "Failed to fetch: %S" > + (require 'vc-dir) > + (with-current-buffer (vc-dir-prepare-status-buffer > + (format " *package-vc-dir: %s*" pkg-dir) > + pkg-dir (vc-responsible-backend pkg-dir)) > + (vc-pull)))))) >=20=20 > (defun package-vc--archives-initialize () > "Initialize package.el and fetch package specifications." > @@ -997,7 +1002,150 @@ package-vc-log-incoming > (interactive > (list (package-vc--read-package-desc "Incoming log for package: " t))) > (let ((default-directory (package-desc-dir pkg-desc))) > - (call-interactively #'vc-log-incoming))) > + ;; Call vc-log-incoming directly without interactive prompting > + (vc-log-incoming nil))) > + > +;; Package upgrade diff utilities for VC packages > + > +(defun package-vc--show-changelog (pkg-desc from-rev to-rev) > + "Show diff of all changelog files between FROM-REV and TO-REV for PKG-= DESC. > +Returns t if any changelog diff was displayed, nil otherwise." > + (let* ((pkg-dir (package-desc-dir pkg-desc)) > + (default-directory pkg-dir) > + (changelog-files (package--find-changelog-files pkg-dir))) > + (if changelog-files > + (package-vc--display-all-changelog-diffs changelog-files from-re= v to-rev) > + (message "No changelog files found in repository") > + nil))) > + > +(defun package-vc--display-all-changelog-diffs (changelog-files from-rev= to-rev) > + "Display git diff for all CHANGELOG-FILES between FROM-REV and TO-REV." > + (let ((diff-buffer-name "*Package VC Changelog Diff*") > + (displayed-any nil)) > + ;; Kill existing buffer > + (when (get-buffer diff-buffer-name) > + (kill-buffer diff-buffer-name)) > + > + (with-current-buffer (get-buffer-create diff-buffer-name) > + (let ((inhibit-read-only t)) > + (erase-buffer) > + (insert (format "Changelog differences between %s and %s:\n" fro= m-rev to-rev)) > + (insert (make-string 60 ?=3D)) > + (insert "\n\n") > + > + ;; Process each changelog file > + (dolist (changelog-file changelog-files) > + (let ((filename (file-name-nondirectory changelog-file))) > + (insert (format "--- %s ---\n" filename)) > + (condition-case err > + (let ((diff-output > + (with-output-to-string > + (with-current-buffer standard-output > + (vc-git-command This is not acceptable. > + (current-buffer) 0 changelog-file > + "diff" from-rev to-rev > + (format "--unified=3D%d" package-diff-contex= t-lines) > + "--" (file-relative-name changelog-file)))))) > + (if (> (length diff-output) 0) > + (progn > + (insert diff-output) > + (setq displayed-any t)) > + (insert "No changes found in this file.\n"))) > + (error > + (insert (format "Error running git diff: %s" (error-messa= ge-string err))))) > + (insert "\n\n"))) > + > + (if displayed-any > + (progn > + (package--format-changelog-diff) > + (goto-char (point-min)) > + (read-only-mode 1)) > + (insert "No changelog changes found between the specified revi= sions.\n") > + (read-only-mode 1))) > + > + (display-buffer diff-buffer-name) > + displayed-any))) > + > +(defun package-vc--upgrade-interactive-prompt (pkg-desc) > + "Interactive prompt for VC package upgrade confirmation. > +PKG-DESC is the VC package descriptor. > +Returns \\=3D'upgrade to proceed with upgrade, \\=3D'cancel to abort." > + (condition-case err > + (let ((package-name (package-desc-name pkg-desc)) > + (prompt-choices (mapcar #'car package-upgrade-interactive-co= mmands)) > + (result nil) > + (pkg-dir (package-desc-dir pkg-desc)) > + (current-rev nil) > + (target-rev nil)) > + > + ;; Initialize revisions for changelog comparison > + (condition-case _ > + (let ((default-directory pkg-dir)) > + (setq current-rev (string-trim (shell-command-to-string "g= it rev-parse HEAD"))) > + (setq target-rev "origin/HEAD")) > + (error > + (setq current-rev "HEAD~1") > + (setq target-rev "HEAD"))) > + > + (while (not (memq result '(upgrade cancel quit))) > + (condition-case input-err > + (let ((choice (read-char-choice > + (format package-upgrade-prompt-message pack= age-name) > + prompt-choices))) > + (pcase (cdr (assq choice package-upgrade-interactive-com= mands)) > + ('upgrade > + (setq result 'upgrade)) > + ('cancel > + (setq result 'cancel)) > + ('quit > + (setq result 'quit)) > + ('show-diff > + ;; For VC packages, show both log and diff using sepa= rate standard VC functions > + (condition-case log-err > + (let ((default-directory (package-desc-dir pkg-de= sc))) > + ;; Show incoming log > + (vc-log-incoming nil) > + ;; Also show incoming diff > + (vc-root-diff-incoming nil)) > + (error > + (message "Error showing incoming changes: %s" (err= or-message-string log-err))))) > + ('show-changelog > + (condition-case log-err > + (package-vc--show-changelog pkg-desc current-rev = target-rev) > + (error > + (message "Error showing changelog: %s" (error-mess= age-string log-err))))) > + (_ > + ;; Invalid choice, continue loop > + (message "Invalid choice. Please press y, n, d, c, or= q.") > + (sit-for 1)))) > + (quit > + ;; Handle user interruption (C-g) > + (setq result 'cancel)) > + (error > + (message "Error during input: %s" (error-message-string inp= ut-err)) > + (sit-for 1)))) > + > + result) > + (error > + (message "Critical error in interactive prompt for %s: %s" > + (package-desc-name pkg-desc) (error-message-string err)) > + 'cancel))) > + > +(defun package-vc--confirm-upgrade (pkg-desc) > + "Show incoming changes for VC package upgrade and ask for confirmation. > +PKG-DESC is the package descriptor to upgrade. > +Return t if user wants to proceed, nil otherwise." > + ;; Check trust policy > + (let ((should-show-diff (package--should-show-diff-p pkg-desc))) > + (if should-show-diff > + ;; Use interactive prompt for upgrade confirmation > + (let ((result (package-vc--upgrade-interactive-prompt pkg-desc))) > + (cond > + ((eq result 'upgrade) t) > + ((eq result 'quit) (user-error "Package upgrade cancelled by = user")) > + (t nil))) > + ;; Auto-upgrade without diff > + t))) I am sorry to say, but I am not convinced by the current approach. My suggestion would be to first focus on upgrading tarball packages, and then we can consider the matter again for vc-packages. > (provide 'package-vc) > ;;; package-vc.el ends here From unknown Fri Sep 19 04:01:23 2025 X-Loop: help-debbugs@gnu.org Subject: bug#74604: [PATCH v1] package.el: Add diff display and confirmation for package upgrades (Bug#74604) Resent-From: Nobuyuki Kamimoto Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Sat, 13 Sep 2025 13:08:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 74604 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: To: Philip Kaludercic Cc: Daniel Mendler , 74604@debbugs.gnu.org Received: via spool by 74604-submit@debbugs.gnu.org id=B74604.175776883327334 (code B ref 74604); Sat, 13 Sep 2025 13:08:02 +0000 Received: (at 74604) by debbugs.gnu.org; 13 Sep 2025 13:07:13 +0000 Received: from localhost ([127.0.0.1]:54484 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1uxPy9-00076g-K9 for submit@debbugs.gnu.org; Sat, 13 Sep 2025 09:07:12 -0400 Received: from mail-pl1-x62d.google.com ([2607:f8b0:4864:20::62d]:59765) by debbugs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.84_2) (envelope-from ) id 1uxPy3-00075b-Da for 74604@debbugs.gnu.org; Sat, 13 Sep 2025 09:07:07 -0400 Received: by mail-pl1-x62d.google.com with SMTP id d9443c01a7336-2445826fd9dso33546145ad.3 for <74604@debbugs.gnu.org>; Sat, 13 Sep 2025 06:07:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1757768816; x=1758373616; darn=debbugs.gnu.org; h=content-transfer-encoding:in-reply-to:from:content-language :references:cc:to:subject:user-agent:mime-version:date:message-id :from:to:cc:subject:date:message-id:reply-to; bh=7HnX6Lswdzw/gYbtk7JqArNGxq48E3R7C8O+b63yEtA=; b=EfRFmhxJhVcusGFZHXq1qOm01OiTYi+6ZaaYANF15gZKaw5yLLH9uwhW4zVnGU7fBn uabtBlSNx+u/yRI2BhLz7TKlFRsdLB+Evk7h9/3PQxDribKex6fKTr4pU5QbTrmT7XHz ebxvhOnv+l/fp+tHjpRJIQzrNqy2RYOLJwyVqGYLum1gOcAVPx3z8+Hz9vfGlj3Uc/rn 3uLmHSRPrWonGBje468ByxyUWavSSKFMxJax74DGV+Y6cSHdeRA4Giv7uu1Y6kqb1kxM SwfXZTFdGBNHH8nbU4dNQWN/i1eyikGy0Ftm/95drAjqij+Z0hIsiWOVGbUunrBrd6M/ cDDw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1757768816; x=1758373616; h=content-transfer-encoding:in-reply-to:from:content-language :references:cc:to:subject:user-agent:mime-version:date:message-id :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=7HnX6Lswdzw/gYbtk7JqArNGxq48E3R7C8O+b63yEtA=; b=FyT8gdsjo/PAfS6JCP9hFmVZX4WrYNPDoBQUSghu7sMR/Bv9R9ErjVzGBL05QBsfdA iRQ+tc+CS72sHZT1tjQaepI3xZP5I4sMlrPmlJqRJXq4bFPiyKoyOjDPoVo1st4FMqKJ aPSU5lmezT1k3ZuFZMr24EdxecdLJOx9fC++a54o13Ae2aqrIwsnt7zOt8eBxB0Py7XJ LhmymwFVoNlWwb6gGZMsRoHo3DY4v00lDxj0QB96JosKnk3Ys+PAfR8zcwGQAnEGHTOJ j7zx5nPqHwiraiec9qYgo9/STKueOM1kPakdCxcUpUbPEqnT95vpm64PLK2USp70zCIK d+8A== X-Forwarded-Encrypted: i=1; AJvYcCVz6Ajtbo4AznnpXY98bdWLrijdqyxoU7Y026Apw/IXHWcp74DE0X+KyLWiyelDSfr68FTCVg==@debbugs.gnu.org X-Gm-Message-State: AOJu0Yzbr+dC7EwY+Dzf6ZgWiKz0UnWENwTSCRX5LWFKAYGPIc6/R7TN DLzs8txloJvwNbw4zaedWiTJRW6LULMadpGTozma7YFUj/Nghvhga5IB X-Gm-Gg: ASbGncvL8hVn1u/a4HuNhNGRalkW0MIGlyxd/B4zA9Qh+Kjttqkq0/2WRjn6S4596EQ Lk5GXgQFbVZ91YkJGEsEKo9U46bCYaFehtVK2f0dQFMErfS1mVvf9lyPLrOqCk0A7RdRjdEfO5R +5U3B0lC2TkKbfw8M7FlxZ1oHZx+GawHhsr96Ir2G5LkS2c8xNKeaFDyfekCB8R4222ZUnc4CVM HM/cvjKnW4b7pdGolrGVTy+84MeE41iDdP5fVvQrPM8bobullaHxk9/VRXFL1bkz57yuCBM3Z7Y aRgCsCxcWrdZwHfVTULNwqEBzWcqPaq08ybLBZw2msWGwoKpWISBApKGfW9jQRBqvEPCMQQPpg5 vyuZxfhL9ldU0zaBpb3j8iyh8VSpJx99eLmzK7lQxi4SmfVPfNOGwEhrzDtOtOqw2ClB+qIFEAK cVeINd6FGqXva3vg== X-Google-Smtp-Source: AGHT+IHVQk7ym/bomAK7a/2sDsIzSzxDHpyxt8sJh4h/LwIFjF3ocqsGX4BykW5jiBVGqnKLW7D7Uw== X-Received: by 2002:a17:903:3503:b0:263:57e7:8950 with SMTP id d9443c01a7336-26357e78ae5mr5098205ad.19.1757768815614; Sat, 13 Sep 2025 06:06:55 -0700 (PDT) Received: from ?IPV6:240b:c020:633:378e:45c6:32e8:9518:829f? ([240b:c020:633:378e:45c6:32e8:9518:829f]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-25f4935db09sm32453475ad.61.2025.09.13.06.06.53 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Sat, 13 Sep 2025 06:06:55 -0700 (PDT) Message-ID: Date: Sat, 13 Sep 2025 22:05:56 +0900 MIME-Version: 1.0 User-Agent: Mozilla Thunderbird References: <87h67quk0g.fsf@daniel-mendler.de> <54fadfd1-21f6-48cb-a17e-8d0878a68f1d@gmail.com> <87ldmweuf2.fsf@posteo.net> <87ecsovdqp.fsf@daniel-mendler.de> <87seh4tptl.fsf@posteo.net> <312bce53-f1de-4dfb-8338-a71f4d7cebfb@gmail.com> <87348qy2b0.fsf@posteo.net> Content-Language: en-US From: Nobuyuki Kamimoto In-Reply-To: <87348qy2b0.fsf@posteo.net> Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit X-Spam-Score: 0.3 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -0.7 (/) Thank you for reviewing my patch. I will go through your comments and apply the suggested changes. > (Not to start a unrelated discussion, but parts of your message sound > like they might have been written by generative AI. I don't mind that, > but it might be an issue if you used GenAI to prepare the patch as well, > as TTBOMK is not yet a resolved matter for the GNU project. Related to > that, have you signed the FSF copyright assignment?) I am aware of the complexities surrounding FSF copyright from what I have seen online, so I write the actual code by hand. (However, I do ask for advice on refactoring methods and best practices.) Since English is not my native language, I write commit messages and emails in my native language, then translate them with AI and double-check them using Google Translate. As a result, some nuances or expressions may not always be appropriate. Would such a development workflow be acceptable? In addition, I have already received the copyright assignment form for the FSF and plan to complete and submit it. On 2025/09/13 21:17, Philip Kaludercic wrote: > Nobuyuki Kamimoto writes: > >> Hello Philip and Daniel, >> >> Thank you for your detailed feedback on the initial patch. You raised >> excellent points about avoiding >> duplication of existing VC functionality and improving the overall approach. > (Not to start a unrelated discussion, but parts of your message sound > like they might have been written by generative AI. I don't mind that, > but it might be an issue if you used GenAI to prepare the patch as well, > as TTBOMK is not yet a resolved matter for the GNU project. Related to > that, have you signed the FSF copyright assignment?) > > [...] > >> From a41c934b9c39e99e9aaf379519f0d66a71b39966 Mon Sep 17 00:00:00 2001 >> From: Nobuyuki Kamimoto >> Date: Fri, 12 Sep 2025 21:12:53 +0900 >> Subject: [PATCH] Enhance package upgrade UI with interactive y/n/d/c prompts >> >> Add interactive confirmation system for package upgrades with options for: >> - Yes/No upgrade decisions >> - Diff display between package versions >> - Changelog viewing with file exclusion patterns >> - Configurable confirmation policy per package/archive >> >> Includes comprehensive diff utilities for tarball packages and VC packages, >> with proper error handling and user-friendly display buffers. > It would be nice if you could rewrite the commit message to align with > the style described in the CONTRIBUTE file (see the section "Commit > messages"). The main thing here is that you explicitly annotate how > which functions have been changed in which files. > >> --- >> doc/emacs/package.texi | 42 ++++ >> etc/NEWS | 10 + >> lisp/package/package-core.el | 158 ++++++++++++++ > How much of these changes really have to be part of package-core? The > idea behind the ongoing refactoring is to keep that file as small as > possible, so that it contains just what is necessary to activate > packages on startup. > >> lisp/package/package-install.el | 356 +++++++++++++++++++++++++++++++- >> lisp/package/package-menu.el | 48 +++-- >> lisp/package/package-vc.el | 218 +++++++++++++++---- >> 6 files changed, 774 insertions(+), 58 deletions(-) >> >> diff --git a/doc/emacs/package.texi b/doc/emacs/package.texi >> index 5aa9f9a74bf..3b2a59dda23 100644 >> --- a/doc/emacs/package.texi >> +++ b/doc/emacs/package.texi >> @@ -389,6 +389,38 @@ Package Installation >> use these bulk commands if you want to update only a small number of >> built-in packages. >> >> +@vindex package-upgrade-confirmation-policy >> + By default, Emacs shows a diff of the changes when upgrading >> +packages, allowing you to review what has changed between the current >> +and new version before proceeding. This is controlled by the >> +@code{package-upgrade-confirmation-policy} user option. When set to @code{t} (the >> +default), package upgrades will display the differences and ask for >> +confirmation before proceeding. You can disable this behavior by >> +setting @code{package-upgrade-confirmation-policy} to @code{nil} to upgrade >> +all packages automatically without showing diffs. >> + >> + You can also specify which packages or archives require confirmation by >> +setting @code{package-upgrade-confirmation-policy} to a list of specific >> +packages and archives. Only the packages and archives in the list will show >> +confirmation prompts, while all others will upgrade automatically. >> + >> +@noindent >> +Examples of list-based configuration: >> + >> +@example >> +;; Only confirm magit and helm upgrades, auto-upgrade everything else >> +(setq package-upgrade-confirmation-policy >> + '((package magit) (package helm))) >> + >> +;; Only confirm packages from melpa archive, auto-upgrade others >> +(setq package-upgrade-confirmation-policy >> + '((archive "melpa"))) >> + >> +;; Mixed: confirm org package and all melpa-stable packages >> +(setq package-upgrade-confirmation-policy >> + '((package org) (archive "melpa-stable"))) >> +@end example >> + >> @cindex package requirements >> A package may @dfn{require} certain other packages to be installed, >> because it relies on functionality provided by them. When Emacs >> @@ -655,6 +687,16 @@ Fetching Package Sources >> Note that currently, built-in packages cannot be upgraded using >> @code{package-vc-install}. >> >> + Like regular package upgrades, VC package upgrades can also show >> +diffs before proceeding. This behavior is controlled by the same >> +@code{package-upgrade-confirmation-policy} user option that controls regular >> +package upgrades. When set to @code{t} (the default), upgrading VC >> +packages will display the differences between the current and updated >> +versions, allowing you to review the changes before confirming the upgrade. >> + >> + VC packages use the same confirmation policy and file exclusion patterns >> +as regular packages, ensuring consistent behavior across all package types. >> + >> @findex package-report-bug >> @findex package-vc-prepare-patch >> With the source checkout, you might want to reproduce a bug against >> diff --git a/etc/NEWS b/etc/NEWS >> index ac8e56326bf..904592577a0 100644 >> --- a/etc/NEWS >> +++ b/etc/NEWS >> @@ -74,6 +74,16 @@ done from early-init.el, such as adding to 'package-directory-list'. >> ** 'prettify-symbols-mode' attempts to ignore undisplayable characters. >> Previously, such characters would be rendered as, e.g., white boxes. >> >> ++++ >> +** Package management now shows diffs before upgrades. >> +Package upgrades will now display differences between the current and >> +new version before proceeding. This applies to both regular packages >> +and VC packages installed from version control repositories. >> + >> +Users will see a diff buffer showing changes and can choose whether to >> +proceed with or cancel the upgrade. This behavior can be controlled >> +through the 'package-upgrade-confirmation-policy' user option. >> + >> +++ >> ** 'standard-display-table' now has more extra slots. >> 'standard-display-table' has been extended to allow specifying glyphs >> diff --git a/lisp/package/package-core.el b/lisp/package/package-core.el >> index e52654aa53d..b0b1831e1ed 100644 >> --- a/lisp/package/package-core.el >> +++ b/lisp/package/package-core.el >> @@ -284,6 +284,164 @@ package-selected-packages >> :version "25.1" >> :type '(repeat symbol)) >> >> +;; Interactive upgrade prompt constants >> +(defconst package-upgrade-interactive-commands >> + '((?y . upgrade) >> + (?n . cancel) >> + (?d . show-diff) >> + (?c . show-changelog) >> + (?q . quit)) >> + "Interactive commands for package upgrade confirmation.") >> + >> +(defconst package-upgrade-prompt-message >> + "Upgrade %s? (y)es, (n)o, (d)iff, (c)hangelog, (q)uit: " >> + "Prompt message format for package upgrade confirmation.") >> + >> +(defconst package-diff-context-lines 3 >> + "Number of context lines to show in package and changelog diffs.") > I don't think that we need these declarations as constants? > >> +(defconst package-changelog-max-size (* 1024 1024) >> + "Maximum size in bytes for changelog files to process.") >> + >> +(defcustom package-upgrade-confirmation-policy t > As Eli said, the default is probably too invasive. > >> + "Policy for confirming packages during upgrades. >> +This determines which packages require user confirmation before upgrading. >> + >> +Possible values: >> + >> +\\=`t\\=' - Default >> + Show diffs and prompt for all package upgrades. >> + >> +\\=`nil\\=' >> + Automatically upgrade all packages without showing diffs. >> + >> +A list of specific packages/archives to confirm >> + Only the packages and archives listed will show confirmation prompts. >> + All others will be upgraded automatically. >> + >> + List format: >> + (package PACKAGE-SYMBOL) - Show diff for this specific package > Do you think that it would also be acceptable to have symbols > interpreted as synonyms to (package ...)? > >> + (archive ARCHIVE-NAME) - Show diff for all packages in this archive >> + >> +Examples: >> + \\='((package magit) (package helm)) >> + - Only confirm magit and helm upgrades >> + - All other packages upgrade automatically >> + >> + \\='((archive \"melpa\") (package org)) >> + - Confirm all melpa archive packages >> + - Confirm org package upgrades >> + - All other packages upgrade automatically >> + >> + \\='((package magit)) >> + - Only confirm magit upgrades >> + - All other packages upgrade automatically" >> + :type '(choice >> + (const :tag "Always show diffs" t) >> + (const :tag "Never show diffs" nil) >> + (repeat :tag "Specific packages/archives to confirm" >> + (choice >> + (list :tag "Package rule" (const package) symbol) >> + (list :tag "Archive rule" (const archive) string)))) >> + :version "31.1") >> + >> +(defun package--match-rule-p (rule package-name package-archive) > I think it would be cleaner to pass the package-desc object here, than > to have to extract the information before invoking the function. > >> + "Check if RULE matches PACKAGE-NAME and PACKAGE-ARCHIVE." >> + (pcase rule >> + (`(package ,name) (eq name package-name)) >> + (`(archive ,archive) (string= archive package-archive)) >> + (_ nil))) >> + >> +(defun package--should-show-diff-p (pkg-desc) >> + "Check if diff should be shown for PKG-DESC based on confirmation policy." >> + (let ((package-name (package-desc-name pkg-desc)) >> + (package-archive (package-desc-archive pkg-desc)) >> + (policy package-upgrade-confirmation-policy)) >> + (cond > Feel free to use `pcase' here as well, to avoid the trivial binding. > >> + ((eq policy t) t) >> + ((eq policy nil) nil) > This is redundant, as if the policy is nil, (listp nil) is true, and > (seq-some ... nil) is always nil. > >> + ((listp policy) >> + ;; List mode: only show diff for packages/archives in the list >> + (seq-some (lambda (rule) >> + (package--match-rule-p rule package-name package-archive)) > As the function is used only once, I would actually even inline it here. > >> + policy)) >> + (t t)))) >> + >> +(defcustom package-changelog-patterns >> + '("CHANGELOG*" "NEWS*" "ChangeLog*" "CHANGES*" "HISTORY*") >> + "File patterns to match changelog files." >> + :type '(repeat string) >> + :version "31.1") >> + >> +(defvar package-changelog-file-regex >> + (concat "\\(" (mapconcat (lambda (pattern) >> + (replace-regexp-in-string "\\*" ".*" pattern)) >> + package-changelog-patterns "\\|") "\\)") >> + "Regular expression to match changelog files based on patterns.") > I think it would be better to check for a designated "news" file, the > way that `describe-package-1' does. > >> +;; Changelog file utilities >> +(declare-function diff-no-select "diff" (old new &optional switches no-async)) >> + >> +(defun package--find-changelog-files (directory) >> + "Find all changelog files in DIRECTORY using regular expression matching. >> +Returns a list of paths to all matching changelog files found, or nil if none." >> + (when (and directory (stringp directory) (file-directory-p directory)) >> + (condition-case err >> + (let ((files (directory-files directory t "^[^.]" t)) >> + (candidates nil)) >> + ;; Collect all matching files >> + (dolist (file files) >> + (when (and (file-regular-p file) >> + (file-readable-p file) >> + (let ((basename (file-name-nondirectory file))) >> + (string-match-p package-changelog-file-regex >> + (downcase basename)))) > You can also just bind `case-fold-search' to nil, that way you don't > have to allocate a new string. > >> + (push file candidates))) >> + ;; Return all candidates sorted by name for consistent ordering >> + (sort candidates #'string<)) >> + (file-error >> + (message "File access error searching for changelog files in %s: %s" >> + directory (error-message-string err)) >> + nil) >> + (error >> + (message "Error searching for changelog files in %s: %s" >> + directory (error-message-string err)) >> + nil)))) > I think that you can simplify this using `with-demoted-errors'. > >> + >> +(defun package--diff-available-p () >> + "Check if diff functionality is available. >> +Since we use built-in Emacs diff functions, this always returns t." >> + (require 'diff) >> + t) > Why do we need this? > >> +(defun package--diff-changelog-files (old-file new-file) >> + "Generate unified diff between OLD-FILE and NEW-FILE. >> +Returns diff output as string, or nil if diff is not available." >> + (when (and old-file new-file >> + (file-exists-p old-file) >> + (file-exists-p new-file) >> + (package--diff-available-p)) >> + (let ((old-size (nth 7 (file-attributes old-file))) >> + (new-size (nth 7 (file-attributes new-file)))) >> + ;; Check file size limits >> + (when (and (< old-size package-changelog-max-size) >> + (< new-size package-changelog-max-size)) >> + (let ((diff-buffer (diff-no-select old-file new-file >> + (format "--unified=%d" package-diff-context-lines) t))) >> + (when diff-buffer >> + (with-current-buffer diff-buffer >> + (let ((diff-output (buffer-string))) >> + (kill-buffer diff-buffer) >> + (when (> (length diff-output) 0) >> + diff-output))))))))) >> + >> +(defun package--format-changelog-diff () >> + "Format and highlight diff output in current buffer. >> +Uses diff-mode features for syntax highlighting." >> + (when (fboundp 'diff-mode) >> + (diff-mode) >> + (font-lock-ensure))) >> + >> ;; Pseudo fields. >> (defun package-version-join (vlist) >> "Return the version string corresponding to the list VLIST. >> diff --git a/lisp/package/package-install.el b/lisp/package/package-install.el >> index 8401a7769b7..34468c109b5 100644 >> --- a/lisp/package/package-install.el >> +++ b/lisp/package/package-install.el >> @@ -380,6 +380,7 @@ package-install >> (message "`%s' is already installed" name)))) >> >> (declare-function package-vc-upgrade "package-vc" (pkg)) >> +(declare-function diff-no-select "diff" (old new &optional switches no-async)) >> >> ;;;###autoload >> (defun package-upgrade (name) >> @@ -392,16 +393,26 @@ package-upgrade >> (package--upgradeable-packages t) nil t)))) >> (cl-check-type name symbol) >> (let* ((pkg-desc (cadr (assq name package-alist))) >> - (package-install-upgrade-built-in (not pkg-desc))) >> + (package-install-upgrade-built-in (not pkg-desc)) >> + (new-pkg-desc (cadr (assq name package-archive-contents)))) >> ;; `pkg-desc' will be nil when the package is an "active built-in". >> (if (and pkg-desc (package-vc-p pkg-desc)) >> (package-vc-upgrade pkg-desc) >> - (when pkg-desc >> - (package-delete pkg-desc 'force 'dont-unselect)) >> - (package-install name >> - ;; An active built-in has never been "selected" >> - ;; before. Mark it as installed explicitly. >> - (and pkg-desc 'dont-select))))) >> + ;; Check if this is a tarball package upgrade that needs diff confirmation >> + (if (and pkg-desc new-pkg-desc >> + (eq (package-desc-kind new-pkg-desc) 'tar)) >> + ;; For tarball packages, show diff and ask for confirmation >> + ;; The function now handles the complete upgrade process internally >> + (unless (package--confirm-tarball-upgrade pkg-desc new-pkg-desc) >> + (message "Package upgrade cancelled")) >> + ;; For non-tarball packages, proceed with normal upgrade >> + (progn > You can drop the `progn' here, Elisp's if has an implicit trailing progn. > >> + (when pkg-desc >> + (package-delete pkg-desc 'force 'dont-unselect)) >> + (package-install name >> + ;; An active built-in has never been "selected" >> + ;; before. Mark it as installed explicitly. >> + (and pkg-desc 'dont-select))))))) >> >> (defun package--upgradeable-packages (&optional include-builtins) >> ;; Initialize the package system to get the list of package >> @@ -1108,5 +1119,336 @@ package-recompile-all >> (with-demoted-errors "Error while recompiling: %S" >> (package-recompile pkg-desc)))) >> >> +;; Package upgrade diff utilities >> + >> +(defun package--safe-insert-file (file &optional error-msg) >> + "Safely insert FILE contents, showing ERROR-MSG on failure." >> + (condition-case err > Same comment here as above. > >> + (when (and file (file-readable-p file)) >> + (insert-file-contents file)) >> + (file-error >> + (insert (or error-msg >> + (format "File access error: %s" (error-message-string err))))) > How can this happen, if we have established prior to > `insert-file-contents' that the file is readable -- excluding the > possibility of corrupted permissions due the involvement of multiple > users or race conditions? > >> + (error >> + (insert (or error-msg >> + (format "Error reading file: %s" (error-message-string err))))))) >> + >> +(defun package--show-changelog (old-dir new-dir) >> + "Show diff of all changelog files between OLD-DIR and NEW-DIR. >> +Displays unified diff showing what changed in all matched changelog files. >> +Returns t if any changelog diff was displayed, nil otherwise." >> + (let ((old-changelogs (when old-dir (package--find-changelog-files old-dir))) >> + (new-changelogs (when new-dir (package--find-changelog-files new-dir))) >> + (displayed-any nil)) >> + (cond >> + ;; Both directories have changelog files >> + ((or old-changelogs new-changelogs) >> + (setq displayed-any (package--display-all-changelog-diffs old-changelogs new-changelogs))) >> + ;; No changelog files found in either directory >> + (t >> + (message "No changelog files found") >> + nil)) >> + displayed-any)) >> + >> +(defun package--display-all-changelog-diffs (old-files new-files) >> + "Display diffs for all changelog files between OLD-FILES and NEW-FILES. >> +Returns t if any diff was displayed, nil otherwise." >> + (let ((buffer-name "*Package Changelog Diff*") >> + (displayed-any nil) >> + (unique-filenames nil)) >> + ;; Kill existing buffer if it exists >> + (when (get-buffer buffer-name) >> + (kill-buffer buffer-name)) >> + >> + ;; Get unique filenames from both lists >> + (setq unique-filenames >> + (delete-dups >> + (append (mapcar #'file-name-nondirectory old-files) >> + (mapcar #'file-name-nondirectory new-files)))) >> + >> + (with-current-buffer (get-buffer-create buffer-name) >> + (let ((inhibit-read-only t)) >> + (erase-buffer) >> + (insert "Changelog differences between old and new versions:\n") >> + (insert (make-string 55 ?=)) >> + (insert "\n\n") >> + >> + ;; Process each unique filename >> + (dolist (filename unique-filenames) >> + (let ((old-file (car (seq-filter (lambda (f) >> + (string= filename (file-name-nondirectory f))) >> + old-files))) >> + (new-file (car (seq-filter (lambda (f) >> + (string= filename (file-name-nondirectory f))) >> + new-files)))) >> + (cond >> + ;; Both old and new versions exist: show diff >> + ((and old-file new-file) >> + (package--insert-file-diff filename old-file new-file) >> + (setq displayed-any t)) >> + ;; Only new file exists: show as new addition >> + ((and (not old-file) new-file) >> + (package--insert-new-file filename new-file) >> + (setq displayed-any t)) >> + ;; Only old file exists: show as removal >> + ((and old-file (not new-file)) >> + (insert (format "--- %s (REMOVED in new version) ---\n\n" filename)) >> + (setq displayed-any t))))) >> + >> + (if displayed-any >> + (progn >> + (package--format-changelog-diff) >> + (goto-char (point-min)) >> + (read-only-mode 1)) >> + (insert "No changelog differences found.\n") >> + (read-only-mode 1))) >> + >> + (display-buffer buffer-name) >> + displayed-any))) > IMO it might be nicer if we could use an existing interface like > tabulated-list-mode. But just generating a plain, recursive diff would > also be fine. > >> +(defun package--insert-file-diff (filename old-file new-file) >> + "Insert diff content for a single file into current buffer." >> + (insert (format "--- %s ---\n" filename)) >> + (let ((diff-output (package--diff-changelog-files old-file new-file))) >> + (if diff-output >> + (insert diff-output) >> + ;; Fallback if diff is unavailable >> + (insert "Diff unavailable. Showing full new content:\n") >> + (package--safe-insert-file new-file)) >> + (insert "\n\n"))) >> + >> +(defun package--insert-new-file (filename new-file) >> + "Insert new file content into current buffer." >> + (insert (format "--- %s (NEW in this version) ---\n" filename)) >> + (package--safe-insert-file new-file) >> + (insert "\n\n")) >> + >> +(defun package--show-package-diff (old-dir new-dir pkg-desc) >> + "Show diff between OLD-DIR and NEW-DIR package directories for PKG-DESC. >> +This function only displays the diff without prompting for user confirmation." >> + ;; Ensure diff is loaded and ready before proceeding >> + (require 'diff) >> + ;; Ensure diff feature is fully loaded on first run >> + (unless (featurep 'diff) >> + (sit-for 0.1)) > require is not asynchronous! This is not an issue. > >> + ;; Additional safety: ensure diff functions are available >> + (unless (fboundp 'diff-mode) >> + (autoload 'diff-mode "diff" "Diff major mode" t)) > This is als not necessary, diff-mode is part of Emacs and you can rely > on the above require to do the right thing™. > >> + (condition-case outer-err >> + (let ((diff-buffer-name "*Package Diff*")) >> + ;; Kill existing buffer to avoid read-only issues >> + (when (get-buffer diff-buffer-name) >> + (kill-buffer diff-buffer-name)) >> + >> + ;; Check if directories exist before proceeding >> + (unless (and (file-directory-p old-dir) (file-directory-p new-dir)) >> + (error "One or both directories do not exist: %s, %s" old-dir new-dir)) >> + >> + (condition-case diff-err >> + ;; Use built-in diff-no-select instead of external commands > Why? > >> + (let ((diff-buffer (diff-no-select old-dir new-dir "--unified" t))) >> + (if diff-buffer >> + (progn >> + ;; Safely configure diff buffer before renaming >> + (with-current-buffer diff-buffer >> + ;; Ensure diff-mode is properly initialized first >> + (when (fboundp 'diff-mode) >> + (diff-mode)) >> + ;; Configure buffer for stable scrolling >> + (setq buffer-read-only t) >> + (setq truncate-lines nil) ; Allow line wrapping >> + ;; Disable potentially problematic diff features >> + (when (boundp 'diff-refine-hunk) >> + (set (make-local-variable 'diff-refine-hunk) nil)) > Why disable this? This is a useful feature when reading the file. > >> + (goto-char (point-min)) >> + ;; Now safely rename the buffer >> + (rename-buffer diff-buffer-name t)) >> + ;; Display the properly configured buffer >> + (display-buffer diff-buffer-name)) >> + ;; No differences found >> + (with-current-buffer (get-buffer-create diff-buffer-name) >> + (let ((inhibit-read-only t)) >> + (erase-buffer) >> + (insert (format "No significant differences found between old and new versions of %s.\n" >> + (package-desc-name pkg-desc))) >> + (goto-char (point-min)) >> + (read-only-mode 1)) >> + (display-buffer diff-buffer-name)))) >> + (error >> + ;; If diff fails, create a simple error message >> + (with-current-buffer (get-buffer-create diff-buffer-name) >> + (let ((inhibit-read-only t)) >> + (erase-buffer) >> + (insert (format "Error running diff operation: %s\n\n" (error-message-string diff-err))) >> + (insert "This may be due to:\n") >> + (insert "- File access permissions\n") >> + (insert "- Directory structure issues\n") >> + (insert "- Memory limitations for large diffs\n") >> + (read-only-mode 1)) >> + (display-buffer diff-buffer-name)))) >> + ;; Return t to indicate success >> + t) >> + (error >> + (message "Error showing package diff: %s (Retry may work)" (error-message-string outer-err)) >> + ;; Return nil to indicate failure but allow retry >> + nil))) >> + >> +(defun package--handle-interactive-command (command pkg-desc old-dir new-dir) >> + "Handle interactive COMMAND for PKG-DESC upgrade." >> + (pcase command >> + ('upgrade 'upgrade) > You don't need to quote upgrade here? > >> + ('cancel 'cancel) >> + ('show-diff >> + (condition-case err >> + (if (and old-dir new-dir) >> + (progn >> + (let ((result (package--show-package-diff old-dir new-dir pkg-desc))) >> + (if result >> + (message "Diff displayed. Press y to upgrade, n to cancel, c for changelog.") >> + (message "Diff display failed. Please try again or use changelog (c).")))) >> + (message "Package directories not available for diff.")) >> + (error >> + (message "Error displaying diff: %s (Try again with 'd' or use changelog with 'c')" >> + (error-message-string err)))) >> + ;; Always return nil to prevent process termination >> + nil) >> + ('show-changelog >> + (condition-case err >> + (if (package--show-changelog old-dir new-dir) >> + (message "Changelog displayed. Press y to upgrade, n to cancel, d for full diff.") >> + (message "No changelog differences found. Press y to upgrade, n to cancel.")) >> + (error >> + (message "Error displaying changelog: %s" (error-message-string err)))) >> + nil) >> + ('quit 'quit) >> + (_ >> + (message "Invalid choice. Use: y=upgrade, n=cancel, d=diff, c=changelog, q=quit") >> + (sit-for 1.5) >> + nil))) >> + >> +(defun package--upgrade-interactive-prompt (pkg-desc &optional old-dir new-dir) >> + "Interactive prompt for package upgrade confirmation." >> + (let ((package-name (package-desc-name pkg-desc)) >> + (prompt-choices (mapcar #'car package-upgrade-interactive-commands))) >> + (catch 'result >> + (while t >> + (condition-case err >> + (let* ((choice (read-char-choice >> + (format package-upgrade-prompt-message package-name) >> + prompt-choices)) >> + (command (cdr (assq choice package-upgrade-interactive-commands))) >> + (result (package--handle-interactive-command command pkg-desc old-dir new-dir))) >> + (when result >> + (throw 'result result))) >> + (quit >> + (message "Package upgrade cancelled by user") >> + (throw 'result 'cancel)) >> + (error >> + (message "Error during input: %s" (error-message-string err)) >> + (sit-for 1))))))) > You have reimplemented `read-multiple-choice'... > >> + >> +(defun package--get-installed-package-dir (pkg-desc) >> + "Get directory of installed PKG-DESC package." >> + (expand-file-name (package-desc-full-name pkg-desc) package-user-dir)) >> + >> +(defun package-extract (pkg-desc) >> + "Extract package PKG-DESC files without generating autoloads or descriptors. >> +Only performs file extraction based on package kind. Returns the package >> +directory path where files were extracted." >> + (let* ((name (package-desc-name pkg-desc)) >> + (dirname (package-desc-full-name pkg-desc)) >> + (pkg-dir (expand-file-name dirname package-user-dir))) >> + ;; Extract files based on package kind >> + (pcase (package-desc-kind pkg-desc) >> + ('dir >> + (make-directory pkg-dir t) >> + (let ((file-list >> + (or (and (derived-mode-p 'dired-mode) >> + (dired-get-marked-files)) >> + (directory-files-recursively default-directory "" nil)))) >> + (dolist (source-file file-list) >> + (let ((target (expand-file-name >> + (file-relative-name source-file default-directory) >> + pkg-dir))) >> + (make-directory (file-name-directory target) t) >> + (copy-file source-file target t))) >> + ;; Now that the files have been installed, this package is >> + ;; indistinguishable from a `tar' or a `single'. Let's make >> + ;; things simple by ensuring we're one of them. >> + (setf (package-desc-kind pkg-desc) >> + (if (length> file-list 1) 'tar 'single)))) >> + ('tar >> + (make-directory package-user-dir t) >> + (let* ((default-directory (file-name-as-directory package-user-dir))) >> + (package-untar-buffer dirname))) >> + ('single >> + (let ((el-file (expand-file-name (format "%s.el" name) pkg-dir))) >> + (make-directory pkg-dir t) >> + (package--write-file-no-coding el-file))) >> + (kind (error "Unknown package kind: %S" kind))) >> + ;; Return the directory path (no autoloads generation yet) >> + pkg-dir)) >> + >> +(defun package--download-and-extract (new-pkg-desc) >> + "Download and extract NEW-PKG-DESC. Return extraction directory." >> + (let ((location (package-archive-base new-pkg-desc)) >> + (file (concat (package-desc-full-name new-pkg-desc) >> + (package-desc-suffix new-pkg-desc)))) >> + (package--with-response-buffer location :file file >> + (package-extract new-pkg-desc)))) >> + >> +(defun package--confirm-upgrade (_pkg-desc new-pkg-desc old-dir new-dir) >> + "Ask user to confirm upgrade from _PKG-DESC to NEW-PKG-DESC." >> + (if (file-exists-p old-dir) >> + (let ((result (package--upgrade-interactive-prompt new-pkg-desc old-dir new-dir))) >> + (cond >> + ((eq result 'upgrade) t) >> + ((eq result 'quit) (user-error "Package upgrade cancelled by user")) >> + (t nil))) >> + (yes-or-no-p (format "New package installation: %s. Continue? " >> + (package-desc-name new-pkg-desc))))) >> + >> +(defun package--complete-upgrade (pkg-desc new-pkg-desc new-dir) >> + "Complete the upgrade process from PKG-DESC to NEW-PKG-DESC." >> + (when pkg-desc >> + (package-delete pkg-desc 'force 'dont-unselect)) >> + (when (and new-dir (file-directory-p new-dir)) >> + (delete-directory new-dir t)) >> + (package-install-from-archive new-pkg-desc)) >> + >> +(defun package--confirm-tarball-upgrade (pkg-desc new-pkg-desc) >> + "Confirm and execute tarball package upgrade. >> + >> +This function handles the complete tarball upgrade workflow: >> +1. Check if diff display is required based on trust policy >> +2. Download and extract new package for comparison >> +3. Show diff and get user confirmation >> +4. Complete upgrade or clean up on cancellation >> + >> +Args: >> + PKG-DESC: Current installed package descriptor >> + NEW-PKG-DESC: New package descriptor to upgrade to >> + >> +Returns: >> + t if upgrade was confirmed and completed, nil otherwise." >> + (if (package--should-show-diff-p new-pkg-desc) >> + (let* ((old-dir (package--get-installed-package-dir pkg-desc)) >> + (new-dir nil) >> + (confirmed nil)) >> + (unwind-protect >> + (progn >> + (setq new-dir (package--download-and-extract new-pkg-desc)) >> + (setq confirmed (package--confirm-upgrade pkg-desc new-pkg-desc old-dir new-dir)) >> + (when confirmed >> + (package--complete-upgrade pkg-desc new-pkg-desc new-dir))) >> + ;; Cleanup: remove temporary extraction directory if upgrade was cancelled >> + (when (and new-dir (not confirmed) (file-exists-p new-dir)) >> + (ignore-errors (delete-directory new-dir t)))) >> + confirmed) >> + ;; Trust policy says skip diff - proceed directly with upgrade >> + (progn >> + (package--complete-upgrade pkg-desc new-pkg-desc nil) >> + t))) >> + >> (provide 'package-install) >> ;;; package-install.el ends here >> diff --git a/lisp/package/package-menu.el b/lisp/package/package-menu.el >> index c57086112c4..3ffdb940554 100644 >> --- a/lisp/package/package-menu.el >> +++ b/lisp/package/package-menu.el >> @@ -653,22 +653,38 @@ package-menu--perform-transaction >> (format status-format (incf i))) >> (force-mode-line-update) >> (redisplay 'force) >> - ;; Don't mark as selected, `package-menu-execute' already >> - ;; does that. >> - (package-install pkg 'dont-select)))) >> - (let ((package-menu--transaction-status ":Deleting")) >> - (force-mode-line-update) >> - (redisplay 'force) >> - (dolist (elt (package--sort-by-dependence delete-list)) >> - (condition-case-unless-debug err >> - (let ((inhibit-message (or inhibit-message package-menu-async))) >> - (package-delete elt nil 'nosave)) >> - (error >> - (push (package-desc-full-name elt) errors) >> - (message "Error trying to delete `%s': %s" >> - (package-desc-full-name elt) >> - (error-message-string err)))))) >> - errors)) >> + ;; Check if this is a package upgrade and needs confirmation >> + (let* ((pkg-name (package-desc-name pkg)) >> + (old-pkg (cl-find-if (lambda (del-pkg) >> + (eq (package-desc-name del-pkg) pkg-name)) >> + delete-list))) >> + (cond >> + ;; Tarball package upgrade - use tarball confirmation >> + ((and old-pkg (eq (package-desc-kind pkg) 'tar)) >> + (if (package--confirm-tarball-upgrade old-pkg pkg) >> + (package-install pkg 'dont-select) >> + (push (package-desc-full-name pkg) errors))) >> + ;; VC package upgrade - use VC confirmation >> + ((and old-pkg (package-vc-p old-pkg)) >> + (if (package-vc--confirm-upgrade old-pkg) >> + (package-install pkg 'dont-select) >> + (push (package-desc-full-name pkg) errors))) >> + ;; Normal installation or upgrade >> + (t >> + (package-install pkg 'dont-select)))))) >> + (let ((package-menu--transaction-status ":Deleting")) >> + (force-mode-line-update) >> + (redisplay 'force) >> + (dolist (elt (package--sort-by-dependence delete-list)) >> + (condition-case-unless-debug err >> + (let ((inhibit-message (or inhibit-message package-menu-async))) >> + (package-delete elt nil 'nosave)) >> + (error >> + (push (package-desc-full-name elt) errors) >> + (message "Error trying to delete `%s': %s" >> + (package-desc-full-name elt) >> + (error-message-string err)))))) >> + errors))) >> >> (defun package--update-selected-packages (add remove) >> "Update the `package-selected-packages' list according to ADD and REMOVE. >> diff --git a/lisp/package/package-vc.el b/lisp/package/package-vc.el >> index 03767b99729..3579c9d69b5 100644 >> --- a/lisp/package/package-vc.el >> +++ b/lisp/package/package-vc.el >> @@ -53,6 +53,7 @@ >> (require 'package-elpa) >> (require 'lisp-mnt) >> (require 'vc) >> +(require 'vc-git) > Err, package-vc is intentionally vc agnostic, so we shouldn't depend on > a specific backend, unless we are providing a speedup (in which case it > would be better to implement the feature more generally in vc-git). > >> (require 'seq) >> >> (defgroup package-vc nil >> @@ -737,6 +738,8 @@ package-vc-upgrade-all >> >> (declare-function vc-dir-prepare-status-buffer "vc-dir" >> (bname dir backend &optional create-new)) >> +(declare-function vc-diff-incoming "vc" (&optional remote-location fileset)) >> +(declare-function vc-log-incoming "vc" (&optional remote-location)) > You shouldn't need this, as we are requiring vc above! > >> >> ;;;###autoload >> (defun package-vc-upgrade (pkg-desc) >> @@ -745,40 +748,42 @@ package-vc-upgrade >> This may fail if the local VCS state of the package conflicts >> with the remote repository state." >> (interactive (list (package-vc--read-package-desc "Upgrade VC package: " t))) >> - ;; HACK: To run `package-vc--unpack-1' after checking out the new >> - ;; revision, we insert a hook into `vc-post-command-functions', and >> - ;; remove it right after it ran. To avoid running the hook multiple >> - ;; times or even for the wrong repository (as `vc-pull' is often >> - ;; asynchronous), we extract the relevant arguments using a pseudo >> - ;; filter for `vc-filter-command-function', executed only for the >> - ;; side effect, and store them in the lexical scope. When the hook >> - ;; is run, we check if the arguments are the same (`eq') as the ones >> - ;; previously extracted, and only in that case will be call >> - ;; `package-vc--unpack-1'. Ugh... >> - ;; >> - ;; If there is a better way to do this, it should be done. >> - (cl-assert (package-vc-p pkg-desc)) >> - (letrec ((pkg-dir (package-desc-dir pkg-desc)) >> - (vc-flags) >> - (vc-filter-command-function >> - (lambda (command file-or-list flags) >> - (setq vc-flags flags) >> - (list command file-or-list flags))) >> - (post-upgrade >> - (lambda (_command _file-or-list flags) >> - (when (and (file-equal-p pkg-dir default-directory) >> - (eq flags vc-flags)) >> - (unwind-protect >> - (with-demoted-errors "Failed to activate: %S" >> - (package-vc--unpack-1 pkg-desc pkg-dir)) >> - (remove-hook 'vc-post-command-functions post-upgrade)))))) >> - (add-hook 'vc-post-command-functions post-upgrade) >> - (with-demoted-errors "Failed to fetch: %S" >> - (require 'vc-dir) >> - (with-current-buffer (vc-dir-prepare-status-buffer >> - (format " *package-vc-dir: %s*" pkg-dir) >> - pkg-dir (vc-responsible-backend pkg-dir)) >> - (vc-pull))))) >> + ;; Check if user wants to see diff and confirm upgrade >> + (when (package-vc--confirm-upgrade pkg-desc) >> + ;; HACK: To run `package-vc--unpack-1' after checking out the new >> + ;; revision, we insert a hook into `vc-post-command-functions', and >> + ;; remove it right after it ran. To avoid running the hook multiple >> + ;; times or even for the wrong repository (as `vc-pull' is often >> + ;; asynchronous), we extract the relevant arguments using a pseudo >> + ;; filter for `vc-filter-command-function', executed only for the >> + ;; side effect, and store them in the lexical scope. When the hook >> + ;; is run, we check if the arguments are the same (`eq') as the ones >> + ;; previously extracted, and only in that case will be call >> + ;; `package-vc--unpack-1'. Ugh... >> + ;; >> + ;; If there is a better way to do this, it should be done. >> + (cl-assert (package-vc-p pkg-desc)) > This assertion should remain at the beginning of the function. > >> + (letrec ((pkg-dir (package-desc-dir pkg-desc)) >> + (vc-flags) >> + (vc-filter-command-function >> + (lambda (command file-or-list flags) >> + (setq vc-flags flags) >> + (list command file-or-list flags))) >> + (post-upgrade >> + (lambda (_command _file-or-list flags) >> + (when (and (file-equal-p pkg-dir default-directory) >> + (eq flags vc-flags)) >> + (unwind-protect >> + (with-demoted-errors "Failed to activate: %S" >> + (package-vc--unpack-1 pkg-desc pkg-dir)) >> + (remove-hook 'vc-post-command-functions post-upgrade)))))) >> + (add-hook 'vc-post-command-functions post-upgrade) >> + (with-demoted-errors "Failed to fetch: %S" >> + (require 'vc-dir) >> + (with-current-buffer (vc-dir-prepare-status-buffer >> + (format " *package-vc-dir: %s*" pkg-dir) >> + pkg-dir (vc-responsible-backend pkg-dir)) >> + (vc-pull)))))) >> >> (defun package-vc--archives-initialize () >> "Initialize package.el and fetch package specifications." >> @@ -997,7 +1002,150 @@ package-vc-log-incoming >> (interactive >> (list (package-vc--read-package-desc "Incoming log for package: " t))) >> (let ((default-directory (package-desc-dir pkg-desc))) >> - (call-interactively #'vc-log-incoming))) >> + ;; Call vc-log-incoming directly without interactive prompting >> + (vc-log-incoming nil))) >> + >> +;; Package upgrade diff utilities for VC packages >> + >> +(defun package-vc--show-changelog (pkg-desc from-rev to-rev) >> + "Show diff of all changelog files between FROM-REV and TO-REV for PKG-DESC. >> +Returns t if any changelog diff was displayed, nil otherwise." >> + (let* ((pkg-dir (package-desc-dir pkg-desc)) >> + (default-directory pkg-dir) >> + (changelog-files (package--find-changelog-files pkg-dir))) >> + (if changelog-files >> + (package-vc--display-all-changelog-diffs changelog-files from-rev to-rev) >> + (message "No changelog files found in repository") >> + nil))) >> + >> +(defun package-vc--display-all-changelog-diffs (changelog-files from-rev to-rev) >> + "Display git diff for all CHANGELOG-FILES between FROM-REV and TO-REV." >> + (let ((diff-buffer-name "*Package VC Changelog Diff*") >> + (displayed-any nil)) >> + ;; Kill existing buffer >> + (when (get-buffer diff-buffer-name) >> + (kill-buffer diff-buffer-name)) >> + >> + (with-current-buffer (get-buffer-create diff-buffer-name) >> + (let ((inhibit-read-only t)) >> + (erase-buffer) >> + (insert (format "Changelog differences between %s and %s:\n" from-rev to-rev)) >> + (insert (make-string 60 ?=)) >> + (insert "\n\n") >> + >> + ;; Process each changelog file >> + (dolist (changelog-file changelog-files) >> + (let ((filename (file-name-nondirectory changelog-file))) >> + (insert (format "--- %s ---\n" filename)) >> + (condition-case err >> + (let ((diff-output >> + (with-output-to-string >> + (with-current-buffer standard-output >> + (vc-git-command > This is not acceptable. > >> + (current-buffer) 0 changelog-file >> + "diff" from-rev to-rev >> + (format "--unified=%d" package-diff-context-lines) >> + "--" (file-relative-name changelog-file)))))) >> + (if (> (length diff-output) 0) >> + (progn >> + (insert diff-output) >> + (setq displayed-any t)) >> + (insert "No changes found in this file.\n"))) >> + (error >> + (insert (format "Error running git diff: %s" (error-message-string err))))) >> + (insert "\n\n"))) >> + >> + (if displayed-any >> + (progn >> + (package--format-changelog-diff) >> + (goto-char (point-min)) >> + (read-only-mode 1)) >> + (insert "No changelog changes found between the specified revisions.\n") >> + (read-only-mode 1))) >> + >> + (display-buffer diff-buffer-name) >> + displayed-any))) >> + >> +(defun package-vc--upgrade-interactive-prompt (pkg-desc) >> + "Interactive prompt for VC package upgrade confirmation. >> +PKG-DESC is the VC package descriptor. >> +Returns \\='upgrade to proceed with upgrade, \\='cancel to abort." >> + (condition-case err >> + (let ((package-name (package-desc-name pkg-desc)) >> + (prompt-choices (mapcar #'car package-upgrade-interactive-commands)) >> + (result nil) >> + (pkg-dir (package-desc-dir pkg-desc)) >> + (current-rev nil) >> + (target-rev nil)) >> + >> + ;; Initialize revisions for changelog comparison >> + (condition-case _ >> + (let ((default-directory pkg-dir)) >> + (setq current-rev (string-trim (shell-command-to-string "git rev-parse HEAD"))) >> + (setq target-rev "origin/HEAD")) >> + (error >> + (setq current-rev "HEAD~1") >> + (setq target-rev "HEAD"))) >> + >> + (while (not (memq result '(upgrade cancel quit))) >> + (condition-case input-err >> + (let ((choice (read-char-choice >> + (format package-upgrade-prompt-message package-name) >> + prompt-choices))) >> + (pcase (cdr (assq choice package-upgrade-interactive-commands)) >> + ('upgrade >> + (setq result 'upgrade)) >> + ('cancel >> + (setq result 'cancel)) >> + ('quit >> + (setq result 'quit)) >> + ('show-diff >> + ;; For VC packages, show both log and diff using separate standard VC functions >> + (condition-case log-err >> + (let ((default-directory (package-desc-dir pkg-desc))) >> + ;; Show incoming log >> + (vc-log-incoming nil) >> + ;; Also show incoming diff >> + (vc-root-diff-incoming nil)) >> + (error >> + (message "Error showing incoming changes: %s" (error-message-string log-err))))) >> + ('show-changelog >> + (condition-case log-err >> + (package-vc--show-changelog pkg-desc current-rev target-rev) >> + (error >> + (message "Error showing changelog: %s" (error-message-string log-err))))) >> + (_ >> + ;; Invalid choice, continue loop >> + (message "Invalid choice. Please press y, n, d, c, or q.") >> + (sit-for 1)))) >> + (quit >> + ;; Handle user interruption (C-g) >> + (setq result 'cancel)) >> + (error >> + (message "Error during input: %s" (error-message-string input-err)) >> + (sit-for 1)))) >> + >> + result) >> + (error >> + (message "Critical error in interactive prompt for %s: %s" >> + (package-desc-name pkg-desc) (error-message-string err)) >> + 'cancel))) >> + >> +(defun package-vc--confirm-upgrade (pkg-desc) >> + "Show incoming changes for VC package upgrade and ask for confirmation. >> +PKG-DESC is the package descriptor to upgrade. >> +Return t if user wants to proceed, nil otherwise." >> + ;; Check trust policy >> + (let ((should-show-diff (package--should-show-diff-p pkg-desc))) >> + (if should-show-diff >> + ;; Use interactive prompt for upgrade confirmation >> + (let ((result (package-vc--upgrade-interactive-prompt pkg-desc))) >> + (cond >> + ((eq result 'upgrade) t) >> + ((eq result 'quit) (user-error "Package upgrade cancelled by user")) >> + (t nil))) >> + ;; Auto-upgrade without diff >> + t))) > I am sorry to say, but I am not convinced by the current approach. My > suggestion would be to first focus on upgrading tarball packages, and > then we can consider the matter again for vc-packages. > >> (provide 'package-vc) >> ;;; package-vc.el ends here From unknown Fri Sep 19 04:01:23 2025 X-Loop: help-debbugs@gnu.org Subject: bug#74604: [PATCH v1] package.el: Add diff display and confirmation for package upgrades (Bug#74604) Resent-From: Philip Kaludercic Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Sat, 13 Sep 2025 22:15:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 74604 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: To: Nobuyuki Kamimoto Cc: Daniel Mendler , 74604@debbugs.gnu.org Received: via spool by 74604-submit@debbugs.gnu.org id=B74604.175780165312205 (code B ref 74604); Sat, 13 Sep 2025 22:15:02 +0000 Received: (at 74604) by debbugs.gnu.org; 13 Sep 2025 22:14:13 +0000 Received: from localhost ([127.0.0.1]:57582 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1uxYVY-0003Al-AZ for submit@debbugs.gnu.org; Sat, 13 Sep 2025 18:14:12 -0400 Received: from mout02.posteo.de ([185.67.36.66]:39841) by debbugs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.84_2) (envelope-from ) id 1uxYVQ-00039B-VQ for 74604@debbugs.gnu.org; Sat, 13 Sep 2025 18:14:06 -0400 Received: from submission (posteo.de [185.67.36.169]) by mout02.posteo.de (Postfix) with ESMTPS id A90FD240101 for <74604@debbugs.gnu.org>; Sun, 14 Sep 2025 00:13:57 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=posteo.net; s=2017; t=1757801637; bh=AAIt+hCUbeBRTWfdM5fLV1fZ3I6hVuGt76Q0HGQ05Qw=; h=From:To:Cc:Subject:OpenPGP:Date:Message-ID:MIME-Version: Content-Type:From; b=q07Y1aug5XsNTIT3C+o+fKEJIOxs/5yMO7zIVR9wNksQF4xwpPRl/wkXAtGr4ri85 Dtjzm717jTeytzsxdBR168t//p4x2z4IGkk5w8dxJBJanZ7EZlabPtQXFr1XtImVTg nkTfrElbQfmVXtFasFkON5g7P5rSUqoqFSHNTD/9FOMn2avF1do3IcySX23T2azh7G UnOWyEMwnAtqJe6Oi7anCQd+YBXHjsc7tfSK4Tdn75A/6bdZ58wEk6MYRMkVDvSwey +3cNFtsX7TwE06Gxa0IS9jaYzBJ5Gp/B6s/y/kPzPJpNJYMWyp7dKoBzkCnfpG/FGk +mzyGHOm0cPtw== Received: from customer (localhost [127.0.0.1]) by submission (posteo.de) with ESMTPSA id 4cPQYd05HCz9rxB; Sun, 14 Sep 2025 00:13:56 +0200 (CEST) From: Philip Kaludercic In-Reply-To: References: <87h67quk0g.fsf@daniel-mendler.de> <54fadfd1-21f6-48cb-a17e-8d0878a68f1d@gmail.com> <87ldmweuf2.fsf@posteo.net> <87ecsovdqp.fsf@daniel-mendler.de> <87seh4tptl.fsf@posteo.net> <312bce53-f1de-4dfb-8338-a71f4d7cebfb@gmail.com> <87348qy2b0.fsf@posteo.net> OpenPGP: id=7126E1DE2F0CE35C770BED01F2C3CC513DB89F66; url="https://keys.openpgp.org/vks/v1/by-fingerprint/7126E1DE2F0CE35C770BED01F2C3CC513DB89F66"; preference=signencrypt Date: Sat, 13 Sep 2025 22:13:57 +0000 Message-ID: <87y0qivw4d.fsf@posteo.net> MIME-Version: 1.0 Content-Type: text/plain X-Spam-Score: -2.3 (--) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -3.3 (---) Nobuyuki Kamimoto writes: > Thank you for reviewing my patch. > I will go through your comments and apply the suggested changes. > >> (Not to start a unrelated discussion, but parts of your message sound >> like they might have been written by generative AI. I don't mind that, >> but it might be an issue if you used GenAI to prepare the patch as well, >> as TTBOMK is not yet a resolved matter for the GNU project. Related to >> that, have you signed the FSF copyright assignment?) > > I am aware of the complexities surrounding FSF copyright from what I > have seen online, > so I write the actual code by hand. (However, I do ask for advice on > refactoring methods and best practices.) > Since English is not my native language, I write commit messages and > emails in my native language, then translate them with AI and > double-check them using Google Translate. As a result, some nuances or > expressions may not always be appropriate. > Would such a development workflow be acceptable? I cannot claim that nobody will complain, but I have no issue with you using generative AI as a spell/grammar checker. The only thing were we have to watch out is with generated code. But feel free to ask question here (or if you don't want it to end up on the mailing list I'd gladly give you my input as well in personal correspondence) if you want to learn more about best practice. As you might have seen in my review of your last patch, you ended up writing a lot more code than is actually necessary, and I feel that humans are still a bit better at recognising patterns like these in niche languages like Elisp :) > In addition, I have already received the copyright assignment form for > the FSF and plan to complete and submit it. OK, so we will have to wait on that anyway. But we can continue the discussion here so that the one doesn't block the other, and vice versa.