Skip to content

Instantly share code, notes, and snippets.

@aaron-em
Created July 25, 2015 11:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save aaron-em/e2b7096075d1e2f47edc to your computer and use it in GitHub Desktop.
Save aaron-em/e2b7096075d1e2f47edc to your computer and use it in GitHub Desktop.
(defcustom *expected-packages*
package-activated-list
"The list of packages which should be installed in any Emacs
using this init system."
:risky t
:type '(repeat (symbol)))
;; detect and (offer to) install missing packages
(defun package-install-missing nil
"If the current Emacs install lacks packages in
`*expected-packages*', offer to install them."
;; identify missing packages
(package-refresh-contents)
(let (missing-packages package-errors)
(dolist (package *expected-packages*)
(unless (package-installed-p package)
(setq missing-packages
(push package missing-packages))))
;; offer to install; if accepted, try to do so
(and (> (length missing-packages) 0)
(yes-or-no-p (format "Install missing packages? %s "
missing-packages))
(dolist (package missing-packages)
(condition-case err
(package-install package)
(error
(add-to-list 'package-errors (cadr err))))))
;; report any errors encountered during install
(and (> (length package-errors) 0)
(message "While installing packages: %s"
(mapconcat #'identity package-errors "; ")))))
(defun package-update-expected-list (&optional with)
"Apply the current value of `package-activated-list'
to `*expected-packages*'.
Intended as after-advice for `package-install' and
`package-delete', but can be called manually if you like.
This function takes an optional argument WITH; if given, its
value will be used in place of `package-activated-list'. This is
provided to support removal of packages from the expected list on
deletion (since a deleted package isn't unloaded)."
(and (null with)
(setq with package-activated-list))
(customize-save-variable '*expected-packages* with))
(defadvice package-install (after update-expected last nil activate)
"Update `*expected-packages*' after installing packages."
(package-update-expected-list))
(defadvice package-delete (around update-expected last nil activate)
"Update `*expected-packages*' after deleting packages."
ad-do-it
(let ((with nil)
(victim (intern (ad-get-arg 0))))
(dolist (package package-activated-list)
(and (not (eq package victim))
(setq with (push package with))))
(package-update-expected-list (sort with #'string-lessp))))
(package-install-missing)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment