5

I manage packages in Emacs using Cask and Pallet. Yesterday I upgraded to Emacs 24.4; it went well enough, but all of a sudden all my packages were missing. Cask installs packages in separate directories by Emacs version, so everything was in .cask/24.3.1; there was nothing in .cask/24.4.1, and in fact the directory didn't exist. Once I figured this out, I was able to run cask and install everything again -- but is there a way to make this happpen automagically, from within Emacs itself, when upgrading?

  • 1
    Is there an advantage of using Cask+Pallet instead of plain packages-install? I have all my packages installed automatically with packages-install, see github.com/rekado/.emacs.d/blob/master/lisp/init-package.el . – rekado Nov 1 '14 at 15:00
  • @rekado I think some people don't want to install/update packages every time they start emacs, and they don't want to manually upgrade every individual package either. Cask is also good for managing dependencies when you write your own packages. – caisah Nov 1 '14 at 18:51
  • 1
    Cask is an external program that you have to run independently of Emacs. You could create a script file which runs cask on every startup. – caisah Nov 1 '14 at 19:00
  • cask and pallet can be called from Emacs, but you have a bit of a bootstrap issue if you setup Cask in the recommended way to load from ~/.emacs.d/.cask/emacs-version. Could you maybe install Pallet at every startup using the default package.el method and run pallet-install? Then Pallet would be in ~/.emacs.d/elpa as usual (and discoverable by default after an Emacs upgrade) and Pallet would do the rest. – Sam Brightman Dec 24 '14 at 0:00
6

Without using cask or pallet, you can achieve this with code such as the following:

(setq package-user-dir (expand-file-name (concat "elpa/" emacs-version) user-emacs-directory))
(setq package-enable-at-startup nil)
(package-initialize)

(defun require-package (package &optional min-version no-refresh)
  "Install given PACKAGE, optionally requiring MIN-VERSION.
If NO-REFRESH is non-nil, the available package lists will not be
re-downloaded in order to locate PACKAGE."
  (if (package-installed-p package min-version)
      t
    (if (or (assoc package package-archive-contents) no-refresh)
        (package-install package)
      (progn
        (package-refresh-contents)
        (require-package package min-version t)))))

Then you can sprinkle (require-package ...) calls throughout your config:

(require-package 'flycheck)

The packages will be installed into a version-specific package directory at startup, unless they're already there. (Disclaimer: I haven't tried the modification to package-user-dir above, so YMMV.)

This won't "lock" package versions, but I don't personally care about that. To upgrade packages, you'd go through the usual M-x package-list-packages procedure.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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