Sean Whitton <[email protected]> writes:

> Hello,
>
> On Mon 16 Jun 2025 at 05:59pm -07, Xiyue Deng wrote:
>
>> Sean Whitton <[email protected]> writes:
>>
>>> control: reassign -1 src:emacs
>>> control: retitle -1 emacs: generate versioned Provides for all :core 
>>> packages
>>>
>>> Hello,
>>>
>>> On Sun 13 Apr 2025 at 08:55pm -07, Xiyue Deng wrote:
>>>
>>>> Option 1 also sounds good to me.
>>>
>>> Cool.  I'm not planning to work on it but I can review patches.
>>>
>>
>> I have made proof-of-concept patches as a pseudo-MR at [1] (this MR is
>> against my own fork just for illustration).  Basically, it uses an Emacs
>> script to generate Debian compatible versions from the builtin package
>> list, which is integrated with `debian-sync' in debian/rules (similar to
>> the handling of debian/copyright.in).  I'm currently making the provide
>> list in emacs-common package which ships the compiled elisp files.
>>
>> Please review and comment.
>
> Very interesting.
>
> Have you considered using debhelper substvars for this?  Like how we
> have ${elpa:Depends}.  It avoids needing a control.in.  A control.in
> isn't the end of the world but it might be cleaner not to have one.
>

Ah didn't think about that.  I think it's better than using control.in
in general, though there are the "unused" warning on other packages
(using "?=" doesn't seem to help).

One advantage of generating d/control that I like is that we can see the
provide list directly and can inspect the diff on regeneration.  To get
something similar, I have each package version pair as one line of
comment in the substvars file before setting emacs:Provides (the
substitute variable I'm using for now).  This way we get something
similar.

Somehow I cannot use debian/substvars or debian/<package>.substvars
(which probably got removed by "clean") and need to use
override_dh_gencontrol to pass the generated substvars file (I'm using
debian/emacs-substvars).  Let me know if there is a better way.

> Don't sharpquote lambdas; unlike in CL, doing so will mean they don't
> get compiled (I think).
>

Ack.  TIL.

> You can rewrite the cond using cl-case or pcase.
>

Done

> Use cl-incf (just incf in Emacs 31) instead of setq and 1+.
>

Done

> I see you're using package--builtin-versions.  I'm not happy to be using
> an internal variable -- it got us in trouble before!
>

Current there seems to be no way to get the builtin package info
otherwise.  Fortunately we can easily verify whether it still works by
running "debian/rules debian-sync" and inspect the diff in
debian/emacs-substvars.

Meanwhile I'll try to file a wishlist bug upstream and migrate in
future.

> -- 
> Sean Whitton

I have updated my branch accordingly.  Also attached the formatted patch
in case it's preferred.

PTAL.

-- 
Regards,
Xiyue Deng
From 611a450a5e8f528a146e3ae7c6ca8a372a398484 Mon Sep 17 00:00:00 2001
From: Xiyue Deng <[email protected]>
Date: Mon, 16 Jun 2025 17:09:48 -0700
Subject: [PATCH 1/4] Add script to generate a package provide list

---
 .../generate-bundled-package-provide-list.el  | 66 +++++++++++++++++++
 1 file changed, 66 insertions(+)
 create mode 100644 debian/generate-bundled-package-provide-list.el

diff --git a/debian/generate-bundled-package-provide-list.el b/debian/generate-bundled-package-provide-list.el
new file mode 100644
index 00000000000..d07752ccda9
--- /dev/null
+++ b/debian/generate-bundled-package-provide-list.el
@@ -0,0 +1,66 @@
+;; Emacs script to generate a package provide list -*- lexical-binding:t -*-
+
+(defvar package-skip-list
+  '("elpa-emacs")
+  "A list of package that should be skipped in the provide list")
+
+(defun package-version-list-to-string (package-version-list)
+  "Convert a package version list to version string acceptable in Debian."
+  (let ((count 0)
+        (version-list nil))
+    (dolist (item package-version-list)
+      (progn
+        (if (< item 0)
+            (progn
+              ;; This roughly matches the mapping in
+              ;; version-regexp-alist.
+              (cl-case item
+               (-1 (push "~rc" version-list))
+               (-2 (push "~beta" version-list))
+               (-3 (push "~alpha" version-list))
+               (-4 (push "~snapshot" version-list))
+               (t (error "Unknown version: %d" item)))
+              ;; no "." between prerelease name and number
+              (setq count 0))
+          (when (> count 0)
+            (push "." version-list))
+          (push (number-to-string item) version-list)
+          (cl-incf count))))
+    (push nil version-list)
+    (string-join (nreverse version-list))))
+
+(defvar emacs-provided-package-versions nil
+  "An alist of Debian package name to version.
+You should call the function version to get the values instead.")
+
+(defun emacs-provided-package-versions ()
+  "Returns the calculated EMACS-PROVIDED-PACKAGE-VERSIONS."
+  (if emacs-provided-package-versions
+      emacs-provided-package-versions
+    (mapc (lambda (package-info)
+            (let* ((debian-package-name (concat "elpa-"
+                                                (symbol-name (car package-info))))
+                   (debian-package-version (package-version-list-to-string
+                                            (cdr package-info))))
+              (when (not (member debian-package-name package-skip-list))
+                (push `(,debian-package-name . ,debian-package-version)
+                      emacs-provided-package-versions))))
+          (sort package--builtin-versions
+                :key (lambda (item) (symbol-name (car item)))))
+    (nreverse emacs-provided-package-versions)))
+
+(princ "# Package name and version on each line in comments for tracking.\n")
+(let ((substvar-list nil)
+      (count 0))
+  (mapc (lambda (package-version)
+          (let ((name (car package-version))
+                (version (cdr package-version)))
+            (princ (format "# %s (= %s),\n" name version))
+            (when (> count 0)
+              (push " " substvar-list))
+            (push (format "%s (= %s)," name version)
+                  substvar-list)
+            (cl-incf count)))
+        (emacs-provided-package-versions))
+  (let ((debian-substvar-string (string-join (nreverse substvar-list))))
+    (princ (format "emacs:Provides=%s\n" debian-substvar-string))))
-- 
2.47.2

From 3e24a71780b72ff9dffa8effd4d94392c860bc15 Mon Sep 17 00:00:00 2001
From: Xiyue Deng <[email protected]>
Date: Wed, 18 Jun 2025 13:28:04 -0700
Subject: [PATCH 2/4] Add rule to generate debian/emacs-substvars in
 debian/rules

---
 debian/rules | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/debian/rules b/debian/rules
index 18de17ac996..a99df656955 100755
--- a/debian/rules
+++ b/debian/rules
@@ -221,7 +221,10 @@ check-vars:
 .PHONY: check-autogen
 check-autogen: $(persistent_autogen_files) $(nonpersistent_autogen_files)
 
-debian-sync: $(persistent_autogen_files)
+debian/emacs-substvars:
+	/usr/bin/emacs -Q --script debian/generate-bundled-package-provide-list.el > debian/emacs-substvars
+
+debian-sync: $(persistent_autogen_files) debian/emacs-substvars
         # so dh pattern rule doesn't try to handle this target
 	true
 
@@ -613,6 +616,9 @@ override_dh_auto_install: $(autogen_install_files)
 	rm -rf $(install_dir_nox)
 	rm -rf $(install_dir_lucid)
 
+override_dh_gencontrol:
+	dh_gencontrol -- -Tdebian/emacs-substvars
+
 # Install the per-user systemd unit in a disabled state by default.
 override_dh_installsystemduser:
 	dh_installsystemduser --no-enable
-- 
2.47.2

From a615fe8b8d20fe177b5f721f4d1edb991d9ab317 Mon Sep 17 00:00:00 2001
From: Xiyue Deng <[email protected]>
Date: Wed, 18 Jun 2025 16:05:43 -0700
Subject: [PATCH 3/4] Generate debian/emacs-substvars

---
 debian/emacs-substvars | 78 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 78 insertions(+)
 create mode 100644 debian/emacs-substvars

diff --git a/debian/emacs-substvars b/debian/emacs-substvars
new file mode 100644
index 00000000000..b31a4459bcb
--- /dev/null
+++ b/debian/emacs-substvars
@@ -0,0 +1,78 @@
+# Package name and version on each line in comments for tracking.
+# elpa-allout (= 2.3),
+# elpa-allout-widgets (= 1.0),
+# elpa-ansi-color (= 3.4.2),
+# elpa-antlr-mode (= 2.2.3),
+# elpa-auth-source-pass (= 5.0.0),
+# elpa-backtrace (= 1.0),
+# elpa-bind-key (= 2.4.1),
+# elpa-cc-mode (= 5.33.1),
+# elpa-cedet (= 2.0),
+# elpa-cfengine (= 1.4),
+# elpa-cl-generic (= 1.0),
+# elpa-cl-lib (= 1.0),
+# elpa-cl-print (= 1.0),
+# elpa-compat (= 30.1.9999),
+# elpa-ede (= 2.0),
+# elpa-ediff (= 2.81.6),
+# elpa-editorconfig (= 0.11.0),
+# elpa-eglot (= 1.17.30),
+# elpa-eieio (= 1.4),
+# elpa-eieio-core (= 1.4),
+# elpa-eldoc (= 1.15.0),
+# elpa-epg (= 1.0.0),
+# elpa-erc (= 5.6.0.30.1),
+# elpa-eshell (= 2.4.2),
+# elpa-external-completion (= 0.1),
+# elpa-faceup (= 0.0.6),
+# elpa-feedmail (= 11),
+# elpa-find-cmd (= 0.6),
+# elpa-flymake (= 1.3.7),
+# elpa-flymake-proc (= 1.0),
+# elpa-foldout (= 1.10),
+# elpa-gnus (= 5.13),
+# elpa-idlwave (= 6.1.22),
+# elpa-image-dired (= 0.5),
+# elpa-info-xref (= 3),
+# elpa-isearchb (= 1.5),
+# elpa-js (= 9),
+# elpa-json (= 1.5),
+# elpa-jsonrpc (= 1.0.25),
+# elpa-let-alist (= 1.0.6),
+# elpa-map (= 3.3.1),
+# elpa-meta-mode (= 1.0),
+# elpa-mh-e (= 8.6~snapshot),
+# elpa-mixal-mode (= 0.4),
+# elpa-nadvice (= 1.0),
+# elpa-ntlm (= 2.1.0),
+# elpa-org (= 9.7.11),
+# elpa-package (= 1.1.0),
+# elpa-peg (= 1.0.1),
+# elpa-project (= 0.11.1),
+# elpa-ps-mode (= 1.1.9),
+# elpa-pulse (= 1.0),
+# elpa-python (= 0.28),
+# elpa-ruby-mode (= 1.2),
+# elpa-ruby-ts-mode (= 0.2),
+# elpa-semantic (= 2.2),
+# elpa-seq (= 2.24),
+# elpa-so-long (= 1.1.2),
+# elpa-soap-client (= 3.2.3),
+# elpa-sql (= 3.6),
+# elpa-srecode (= 1.2),
+# elpa-svg (= 1.1),
+# elpa-tabulated-list (= 1.0),
+# elpa-thunk (= 1.0),
+# elpa-tildify (= 4.6.1),
+# elpa-track-changes (= 1.2),
+# elpa-tramp (= 2.7.1.30.1),
+# elpa-transient (= 0.7.2.2),
+# elpa-use-package (= 2.4.6),
+# elpa-vera-mode (= 2.28),
+# elpa-verilog-mode (= 2024.3.1.121933719),
+# elpa-viper (= 3.14.2),
+# elpa-which-key (= 3.6.0),
+# elpa-whitespace (= 13.2.2),
+# elpa-window-tool-bar (= 0.2.1),
+# elpa-xref (= 1.7.0),
+emacs:Provides=elpa-allout (= 2.3), elpa-allout-widgets (= 1.0), elpa-ansi-color (= 3.4.2), elpa-antlr-mode (= 2.2.3), elpa-auth-source-pass (= 5.0.0), elpa-backtrace (= 1.0), elpa-bind-key (= 2.4.1), elpa-cc-mode (= 5.33.1), elpa-cedet (= 2.0), elpa-cfengine (= 1.4), elpa-cl-generic (= 1.0), elpa-cl-lib (= 1.0), elpa-cl-print (= 1.0), elpa-compat (= 30.1.9999), elpa-ede (= 2.0), elpa-ediff (= 2.81.6), elpa-editorconfig (= 0.11.0), elpa-eglot (= 1.17.30), elpa-eieio (= 1.4), elpa-eieio-core (= 1.4), elpa-eldoc (= 1.15.0), elpa-epg (= 1.0.0), elpa-erc (= 5.6.0.30.1), elpa-eshell (= 2.4.2), elpa-external-completion (= 0.1), elpa-faceup (= 0.0.6), elpa-feedmail (= 11), elpa-find-cmd (= 0.6), elpa-flymake (= 1.3.7), elpa-flymake-proc (= 1.0), elpa-foldout (= 1.10), elpa-gnus (= 5.13), elpa-idlwave (= 6.1.22), elpa-image-dired (= 0.5), elpa-info-xref (= 3), elpa-isearchb (= 1.5), elpa-js (= 9), elpa-json (= 1.5), elpa-jsonrpc (= 1.0.25), elpa-let-alist (= 1.0.6), elpa-map (= 3.3.1), elpa-meta-mode (= 1.0), elpa-mh-e (= 8.6~snapshot), elpa-mixal-mode (= 0.4), elpa-nadvice (= 1.0), elpa-ntlm (= 2.1.0), elpa-org (= 9.7.11), elpa-package (= 1.1.0), elpa-peg (= 1.0.1), elpa-project (= 0.11.1), elpa-ps-mode (= 1.1.9), elpa-pulse (= 1.0), elpa-python (= 0.28), elpa-ruby-mode (= 1.2), elpa-ruby-ts-mode (= 0.2), elpa-semantic (= 2.2), elpa-seq (= 2.24), elpa-so-long (= 1.1.2), elpa-soap-client (= 3.2.3), elpa-sql (= 3.6), elpa-srecode (= 1.2), elpa-svg (= 1.1), elpa-tabulated-list (= 1.0), elpa-thunk (= 1.0), elpa-tildify (= 4.6.1), elpa-track-changes (= 1.2), elpa-tramp (= 2.7.1.30.1), elpa-transient (= 0.7.2.2), elpa-use-package (= 2.4.6), elpa-vera-mode (= 2.28), elpa-verilog-mode (= 2024.3.1.121933719), elpa-viper (= 3.14.2), elpa-which-key (= 3.6.0), elpa-whitespace (= 13.2.2), elpa-window-tool-bar (= 0.2.1), elpa-xref (= 1.7.0),
-- 
2.47.2

From 842cc6a23786e5d95298d1e84f523791284effb7 Mon Sep 17 00:00:00 2001
From: Xiyue Deng <[email protected]>
Date: Wed, 18 Jun 2025 13:29:16 -0700
Subject: [PATCH 4/4] Add "Provides: ${emacs:Provides}" to emacs-common in
 debian/control

---
 debian/control | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/debian/control b/debian/control
index 86cd8976b46..d0f09d402b3 100644
--- a/debian/control
+++ b/debian/control
@@ -193,6 +193,8 @@ Breaks:
  emacs-nox (<< 1:25),
 Replaces:
  emacs-bin-common (<< 1:28)
+Provides:
+ ${emacs:Provides}
 Description: GNU Emacs editor's shared, architecture independent infrastructure
  GNU Emacs is the extensible self-documenting text editor.
  This package contains the architecture independent infrastructure
-- 
2.47.2

i

Attachment: signature.asc
Description: PGP signature

Reply via email to