Subject: [PATCH emacs-team WIP 1/4] build-system: emacs: Define package-with-explicit-emacs.

From: Liliana Marie Prikler <[email-masked]>
Date: Wed, 31 Jul 2024 21:57:54 +0200

* guix/build-system/emacs.scm (package-with-explicit-emacs): New procedure.
---
 guix/build-system/emacs.scm | 51 +++++++++++++++++++++++++++++++++++++
 1 file changed, 51 insertions(+)

diff --git a/guix/build-system/emacs.scm b/guix/build-system/emacs.scm
index ebf97a5344..3a11738496 100644
--- a/guix/build-system/emacs.scm
+++ b/guix/build-system/emacs.scm
@@ -1,6 +1,7 @@
 ;;; GNU Guix --- Functional package management for GNU
 ;;; Copyright © 2015 Federico Beffa <[email-masked]>
 ;;; Copyright © 2020 Morgan Smith <[email-masked]>
+;;; Copyright © 2024 Liliana Marie Prikler <[email-masked]>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -128,4 +129,54 @@ (define emacs-build-system
     (description "The build system for Emacs packages")
     (lower lower)))
 
+(define* (package-with-explicit-emacs emacs old-prefix new-prefix
+                                      #:key variant-property)
+  "Return a procedure of one argument, P.  The procedure creates a package with
+the same fields as P, which is assumed to use EMACS-BUILD-SYSTEM, such that
+it is compiled with EMACS instead.  The inputs are changed recursively
+accordingly.  If the name of P starts with OLD-PREFIX, this is replaced by
+NEW-PREFIX; otherwise, NEW-PREFIX is prepended to the name.
+
+When VARIANT-PROPERTY is present, it is used as a key to search for
+pre-defined variants of this transformation recorded in the 'properties' field
+of packages.  The property value must be the promise of a package.  This is a
+convenient way for package writers to force the transformation to use
+pre-defined variants."
+  (define package-variant
+    (if variant-property
+        (lambda (package)
+          (assq-ref (package-properties package)
+                    variant-property))
+        (const #f)))
+
+  (define (transform pkg)
+    (cond
+     ;; If VARIANT-PROPERTY is present, use that.
+     ((package-variant pkg)
+      => force)
+
+     ;; Otherwise build the new package object graph.
+     ((eq? (package-build-system pkg) emacs-build-system)
+      (package/inherit pkg
+        (location (package-location pkg))
+        (name (let ((name (package-name pkg)))
+                (string-append new-prefix
+                               (if (string-prefix? old-prefix name)
+                                   (substring name
+                                              (string-length old-prefix))
+                                   name))))
+        (arguments
+         (let ((emacs (if (promise? emacs)
+                          (force emacs)
+                          emacs)))
+           (ensure-keyword-arguments (package-arguments pkg)
+                                     `(#:emacs ,emacs))))))
+     (else pkg)))
+
+  (define (cut? pkg)
+    (or (not (eq? (package-build-system pkg) emacs-build-system))
+        (package-variant pkg)))
+
+  (package-mapping transform cut?))
+
 ;;; emacs.scm ends here
-- 
2.45.2