Subject: [PATCH] build-system: emacs: Add generation of -pkg.el files.
From: Andrew Tropin <[email-masked]>
To: [email-masked], Liliana Marie Prikler <[email-masked]>
Cc: Ivan Sokolov <[email-masked]>
Date: Thu, 9 Dec 2021 12:01:46 +0300
List-Id: <debbugs-submit.debbugs.gnu.org>

* guix/build/emacs-build-system.scm (%default-exclude): Add generation of
-pkg.el files for packages, which do not provide them.
---
Implemented phase, which generates -pkg.el from comments in library file.  The
solution for finding main el file of the package is a little hacky, because
package name isn't available build time.

I took a part of the elisp implementation from melpa source code.
https://github.com/melpa/melpa/blob/master/package-build/package-build.el#L553

 guix/build/emacs-build-system.scm | 71 ++++++++++++++++++++++++++++++-
 1 file changed, 70 insertions(+), 1 deletion(-)

diff --git a/guix/build/emacs-build-system.scm b/guix/build/emacs-build-system.scm
index f13162d6c4..ee934f4bde 100644
--- a/guix/build/emacs-build-system.scm
+++ b/guix/build/emacs-build-system.scm
@@ -154,6 +154,74 @@ (define (substitute-program-names)
           (substitute-program-names))))
     #t))
 
+(define* (find-root-library-file name)
+  (let lp ((subnames (string-split
+                      (package-name-version->elpa-name-version name) #\-))
+           (possible-name ""))
+    (cond
+     ((file-exists? (string-append possible-name ".el")) possible-name)
+     ((null? subnames) #f)
+     (#t (lp (cdr subnames) (string-append
+                             possible-name
+                             (if (string-null? possible-name) "" "-")
+                             (car subnames)))))))
+
+(define (add-pkg-expr name)
+  `(progn
+    (require 'lisp-mnt)
+    (require 'package)
+
+    (defun build-package-desc-from-library (name)
+      (package-desc-from-define
+       name
+       ;; Workaround for malformed version string (for example "24 (beta)" in
+       ;; paredit.el), try to parse version obtained by lm-version, before
+       ;; trying to create package-desc.  Otherwis the whole process of
+       ;; generation -pkg.el will fail.
+       (condition-case
+        nil
+        (version-to-list (lm-version))
+        (lm-version)
+        (error "0.0.0"))
+       (or (save-excursion
+            (goto-char (point-min))
+            (and (re-search-forward
+                  "^;;; [^ ]*\\.el ---[ \t]*\\(.*?\\)[ \t]*\\(-\\*-.*-\\*-[ \t]*\\)?$"
+                  nil t)
+                 (match-string-no-properties 1)))
+           "No description available.")
+       (when-let ((require-lines (lm-header-multiline "package-requires")))
+                 (package--prepare-dependencies
+                  (package-read-from-string
+                   (mapconcat 'identity require-lines " "))))
+       :kind       'single
+       :url        (lm-homepage)
+       :keywords   (lm-keywords-list)
+       :maintainer (lm-maintainer)
+       :authors    (lm-authors)))
+
+    (defun generate-package-description-file (name)
+      (package-generate-description-file
+       (build-package-desc-from-library name)
+       (concat name "-pkg.el")))
+
+    (condition-case err
+     (generate-package-description-file ,name)
+     (message (concat ,name "-pkg.el file generated."))
+     (error
+      (message "There are some errors during generation of -pkg.el file:")
+      (message "%s" (error-message-string err))))))
+
+(define* (add-pkg-file #:key name outputs #:allow-other-keys)
+  (define source (getcwd))
+  (chdir (elpa-directory (assoc-ref outputs "out")))
+  (let ((el-lib (find-root-library-file name)))
+    (when (and el-lib (not (file-exists? (string-append el-lib "-pkg.el"))))
+      (emacs-batch-edit-file (string-append el-lib ".el")
+        (add-pkg-expr el-lib))))
+  (chdir source)
+  #t)
+
 (define* (check #:key tests? (test-command '("make" "check"))
                 (parallel-tests? #t) #:allow-other-keys)
   "Run the tests by invoking TEST-COMMAND.
@@ -294,7 +362,8 @@ (define %standard-phases
       enable-autoloads-compilation)
     (add-after 'enable-autoloads-compilation 'patch-el-files patch-el-files)
     ;; The .el files are byte compiled directly in the store.
-    (add-after 'patch-el-files 'build build)
+    (add-after 'patch-el-files 'add-pkg-file add-pkg-file)
+    (add-after 'add-pkg-file 'build build)
     (add-after 'build 'validate-compiled-autoloads validate-compiled-autoloads)
     (add-after 'validate-compiled-autoloads 'move-doc move-doc)))
 
-- 
2.34.0