4

In my .emacs, I would like to ensure that the s package, version 1.10.0 or newer, is installed. If I use (use-package s :ensure t) it will not upgrade the installation on systems with older versions of s. How do I ensure that the minimum version is present?

  • 2
    I do not think that use-package supports this. It's rather unusual to have minimum version bounds in a personal configuration, because most people update regularly anyway. And with MELPA version bounds don't really work anyway. – lunaryorn May 6 '16 at 20:31
  • I looked in the use-package source and there doesn't seem to be an obvious way to do it with use-package. Is there another way to do it? – Michael Hoffman May 6 '16 at 20:39
  • Well, sure, there's always the package.el API which you can use to update a package programmatically. That's not a nice API though so consider whether it's really worth the effort. – lunaryorn May 6 '16 at 20:43
  • I am assuming that mass updating all the packages from Melpa/GNU Elpa does not apply to your use case? – Kaushal Modi May 6 '16 at 20:51
  • I have a single .emacs which I share among many environments. They all already have an old version of s installed. When I load Emacs next in each of these environments I will get errors due to missing functions in the old version that I would rather avoid. Yes, I can fix them by doing a mass update from the package-list-packages interface one environment at a time. Just like before I had use-package I would have installed the packages one environment at a time. – Michael Hoffman May 6 '16 at 21:10
3

This solution does not invoke use-package, but instead uses the included package.el functionality. Either way it should get the job done:

;; (source: http://emacs.stackexchange.com/a/22174/93)
(defun package-update (package &optional version)
  "Update a package from the package archives.
If VERSION is nil, update the package to the most recent version
available.  Otherwise, VERSION should be a version string, or a
list of the type returned by `version-to-list'. The package will
be updated only if the currently installed version is less than
the version specified, even if a newer version is available."
  (unless package--initialized
    (package-initialize t))
  (unless package-archive-contents
    (package-refresh-contents))
  (let* ((current (cadr (assoc package package-alist)))
         (current-version (if current (package-desc-version current) '(-1)))
         (pkg-desc (cadr (assoc package package-archive-contents)))
         (pkg-version (and pkg-desc (package-desc-version pkg-desc)))
         (target-version (or (and (stringp version) (version-to-list version))
                             version
                             pkg-version)))
    (when (version-list-< current-version target-version)
      (if (null pkg-desc)
        (error "Package `%s' not found in package archives" package))
      (if (version-list-< pkg-version target-version)
        (error "A suitable version of `%s' is not available" package))
      (package-install pkg-desc)
      (if current
          (package-delete current)))
    nil))

With that function defined, you could add the following to your init

(package-update 's '(1 10 0))

to ensure that your currently-installed version of the s package is at least version 1.10.0

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.