1

Package foo description is stored inside a file foo-VERSION/foo-pkg.el with a cl-defstruct definition that complies to package.el package-desc structure type with a package-desc-from-define constructor. Something like this (for the package ace-link):

(define-package
  "ace-link"
  "20210121.923"
  "Quickly follow links"
  '((avy "0.4.0"))
  :commit "e1b1c91b280d85fce2194fea861a9ae29e8b03dd"
  :authors '(("Oleh Krehel" . "ohwoeowho@gmail.com"))
  :maintainer '("Oleh Krehel" . "ohwoeowho@gmail.com")
  :keywords '("convenience" "links" "avy")
  :url "https://github.com/abo-abo/ace-link")

Inside package.el, the define-package function is not meant to be called. I'd like to dynamically extract the information from all the -pkg.el files and process them further.

What is the best way to create a structure instance of that?

To circumvent the package.el definition of define-package I temporary re-defined define-package to the constructor and then applied the code once manually like this:

(defalias 'define-package 'package-desc-from-define) 
(setq instance-value (define-package
                       "ace-link"
                       "20210121.923"
                       "Quickly follow links"
                       '((avy "0.4.0"))
                       :commit "e1b1c91b280d85fce2194fea861a9ae29e8b03dd"
                       :authors '(("Oleh Krehel" . "ohwoeowho@gmail.com"))
                       :maintainer '("Oleh Krehel" . "ohwoeowho@gmail.com")
                       :keywords '("convenience" "links" "avy")
                       :url "https://github.com/abo-abo/ace-link"))

That works, but its I'd like to do the same thing just using the file name: being able to create an instance-value but processing the content of the -pkg.el file.

So I wrote another alias that creates a global variable instance my-struct-instance:

(defun my-def (n v &optional s r &rest pl)                                                                                                                                                                                                                                                 
         "Replaces package-desc-from-define."                                                                                                                                                                                                                                                                                        
         (setq my-struct-instance (apply 'package-desc-from-define n v s r pl)))
(defalias 'define-package 'my-def) 

Then I load the file with something like:

(load "~/.emacs.d/elpa/ace-link-xxx/ace-link-pkg.el")

And that creates an instance of the structure inside the variable my-struct-instance.

I get the feeling it should be easy and I'm missing something in the handling of cl-defstruct. Is there a better, more obvious way to extract the structure information from these -pkg.el files?

PRouleau
  • 744
  • 3
  • 10
  • `(package-load-descriptor DIRECTORY)` ? – phils Jul 08 '21 at 04:08
  • Yes. Thanks. I knew there ought to be something simpler! I looked at its code and it essentially reads the content of the -pkg.el file in a buffer and then reads it into the argument of package-process-define-package. That's exactly what I wanted to know! – PRouleau Jul 08 '21 at 11:26
  • Cool. I'll add it as a proper answer. – phils Jul 08 '21 at 12:28

1 Answers1

1

(package-load-descriptor DIRECTORY) will read the *-pkg.el file in the given directory, create a new package-desc structure object, add it to package-alist and return the object.

That seems to cover what you need, with the possible exception of it modifying package-alist (which you may or may not want to happen). It's actually the call to package-process-define-package which does this. If you wanted to avoid that modification, you could use:

(let (package-alist)
  (package-load-descriptor DIRECTORY))
phils
  • 48,657
  • 3
  • 76
  • 115