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" . "[email protected]"))
  :maintainer '("Oleh Krehel" . "[email protected]")
  :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" . "[email protected]"))
                       :maintainer '("Oleh Krehel" . "[email protected]")
                       :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?

3
  • (package-load-descriptor DIRECTORY) ?
    – phils
    Jul 8, 2021 at 4: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 8, 2021 at 11:26
  • Cool. I'll add it as a proper answer.
    – phils
    Jul 8, 2021 at 12:28

1 Answer 1

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))

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.