2010-08-24 23:30:32 +08:00
|
|
|
|
;;; el-get.el --- Manage the external elisp bits and pieces you depend upon
|
2010-06-19 04:21:02 +08:00
|
|
|
|
;;
|
2011-09-20 21:15:52 +08:00
|
|
|
|
;; Copyright (C) 2010-2011 Dimitri Fontaine
|
2010-06-19 04:21:02 +08:00
|
|
|
|
;;
|
|
|
|
|
;; Author: Dimitri Fontaine <dim@tapoueh.org>
|
2011-09-16 04:07:54 +08:00
|
|
|
|
;; URL: http://www.emacswiki.org/emacs/el-get
|
|
|
|
|
;; GIT: https://github.com/dimitri/el-get
|
2011-09-19 16:55:20 +08:00
|
|
|
|
;; Version: 4.0
|
2010-06-19 04:21:02 +08:00
|
|
|
|
;; Created: 2010-06-17
|
2010-11-15 03:40:53 +08:00
|
|
|
|
;; Keywords: emacs package elisp install elpa git git-svn bzr cvs svn darcs hg
|
|
|
|
|
;; apt-get fink pacman http http-tar emacswiki
|
2010-06-19 04:21:02 +08:00
|
|
|
|
;; Licence: WTFPL, grab your copy here: http://sam.zoy.org/wtfpl/
|
|
|
|
|
;;
|
|
|
|
|
;; This file is NOT part of GNU Emacs.
|
|
|
|
|
;;
|
2010-09-01 23:52:53 +08:00
|
|
|
|
;; Install
|
|
|
|
|
;; Please see the README.asciidoc file from the same distribution
|
2011-03-11 04:15:12 +08:00
|
|
|
|
|
|
|
|
|
;;; Commentary:
|
|
|
|
|
;;
|
|
|
|
|
;; Version String are now inspired by how Emacs itself numbers its version.
|
|
|
|
|
;; First is the major version number, then a dot, then the minor version
|
|
|
|
|
;; number. The minor version number is 0 when still developping the next
|
|
|
|
|
;; major version.
|
|
|
|
|
;;
|
|
|
|
|
;; So 2.0 is a developer release while 2.1 will be the next stable release.
|
2010-08-05 04:10:34 +08:00
|
|
|
|
;;
|
2011-05-26 03:59:32 +08:00
|
|
|
|
;; Please note that this versioning policy has been picked while backing
|
2011-03-11 04:15:12 +08:00
|
|
|
|
;; 1.2~dev, so 1.0 was a "stable" release in fact. Ah, history.
|
2012-02-02 08:25:17 +08:00
|
|
|
|
;;
|
|
|
|
|
;; In addition to the version, you can also get the exact git revision
|
|
|
|
|
;; by running M-x `el-get-self-checksum'. You should provide this
|
|
|
|
|
;; checksum when seeking support or reporting a bug, so that the
|
|
|
|
|
;; developers will know exactly which version you are using.
|
2011-03-11 04:15:12 +08:00
|
|
|
|
|
|
|
|
|
;;; Change Log:
|
2010-08-05 04:10:34 +08:00
|
|
|
|
;;
|
2011-09-16 04:40:30 +08:00
|
|
|
|
;; 4.0 - WIP - To infinity, and beyond!
|
|
|
|
|
;;
|
2011-09-24 05:05:02 +08:00
|
|
|
|
;; - code refactoring
|
|
|
|
|
;; - fix dependency tracking at install and init times
|
|
|
|
|
;; - fix autoloading so that it happens before notifying install is done
|
|
|
|
|
;; - add some tests
|
2011-10-01 02:55:40 +08:00
|
|
|
|
;; - deprecate package.el from the old days, only include the Emacs24 one
|
2011-10-02 04:31:07 +08:00
|
|
|
|
;; - implement :builtin property (useful for dealing with package.el)
|
2011-10-08 04:57:08 +08:00
|
|
|
|
;; - fix recipes :build commands, must be either lists of strings or expr
|
2011-10-11 16:37:52 +08:00
|
|
|
|
;; - add support for el-get-reload and do that at update time
|
2011-10-29 00:02:38 +08:00
|
|
|
|
;; - implement :checksum property for http kinds of files
|
2012-01-30 14:11:44 +08:00
|
|
|
|
;; - Add new command el-get-reinstall
|
2012-01-30 14:19:43 +08:00
|
|
|
|
;; - implement :checkout property for git packages
|
2012-02-13 04:59:14 +08:00
|
|
|
|
;; - implement :shallow property for git packages
|
2012-02-19 04:34:24 +08:00
|
|
|
|
;; - add support for auto-building of ELPA recipes
|
2012-02-19 05:03:19 +08:00
|
|
|
|
;; - implement :submodule property for git packages (allow bypassing them)
|
2012-01-30 13:14:23 +08:00
|
|
|
|
;; - New package types: github, emacsmirror
|
2011-09-24 05:05:02 +08:00
|
|
|
|
;;
|
2011-09-16 04:07:54 +08:00
|
|
|
|
;; 3.1 - 2011-09-15 - Get a fix
|
2011-05-26 04:07:37 +08:00
|
|
|
|
;;
|
2011-09-16 04:07:54 +08:00
|
|
|
|
;; - support for package dependencies
|
2011-06-22 18:00:30 +08:00
|
|
|
|
;; - rely on package status for `el-get' to install and init them
|
2011-08-18 00:17:22 +08:00
|
|
|
|
;; - M-x el-get-list-packages
|
2011-08-19 21:14:06 +08:00
|
|
|
|
;; - support for :branch in git
|
2011-08-18 00:17:22 +08:00
|
|
|
|
;; - new recipes, galore
|
|
|
|
|
;; - bug fixes, byte compiling, windows compatibility, etc
|
2011-09-07 03:22:46 +08:00
|
|
|
|
;; - recipe files are now *.rcp rather than *.el (el still supported)
|
2011-09-12 01:55:09 +08:00
|
|
|
|
;; - el-get-user-package-directory allows to setup init-<package>.el files
|
2011-09-16 04:07:54 +08:00
|
|
|
|
;; - remove M-x el-get-sync, now obsolete
|
2011-05-26 04:07:37 +08:00
|
|
|
|
;;
|
2011-05-26 16:46:05 +08:00
|
|
|
|
;; 2.2 - 2011-05-26 - Fix the merge
|
|
|
|
|
;;
|
|
|
|
|
;; - Revert changes introduced by a merge done by mistake
|
|
|
|
|
;;
|
|
|
|
|
;; 2.1 - 2011-05-25 - Still growing, getting lazy
|
2011-01-03 01:22:51 +08:00
|
|
|
|
;;
|
2011-01-05 05:10:35 +08:00
|
|
|
|
;; - Add support for autoloads, per Dave Abrahams
|
2011-01-03 01:22:51 +08:00
|
|
|
|
;; - fix 'wait support for http (using sync retrieval)
|
2011-01-05 05:10:35 +08:00
|
|
|
|
;; - code cleanup per Dave Abrahams, lots of it
|
2011-01-07 20:30:47 +08:00
|
|
|
|
;; - add function M-x el-get-update-all
|
2011-01-11 05:39:17 +08:00
|
|
|
|
;; - Implement M-x el-get-make-recipes
|
2011-01-30 06:10:47 +08:00
|
|
|
|
;; - byte-compile at build time rather than at init time
|
|
|
|
|
;; - and use a "clean room" external emacs -Q for byte compiling
|
2011-02-02 00:09:25 +08:00
|
|
|
|
;; - allow to skip autoloads either globally or per-package
|
2011-02-05 02:48:15 +08:00
|
|
|
|
;; - better checks and errors for commands used when installing packages
|
2011-02-20 04:24:19 +08:00
|
|
|
|
;; - register `el-get-sources' against the custom interface
|
2011-02-22 05:20:57 +08:00
|
|
|
|
;; - el-get will now accept a list of sources to install or init
|
2011-02-22 05:55:45 +08:00
|
|
|
|
;; - open el-get-{install,init,remove,update} from `el-get-sources' only
|
2011-02-25 05:03:47 +08:00
|
|
|
|
;; - add :prepare and :post-init and :lazy, and `el-get-is-lazy'
|
2011-03-17 05:31:00 +08:00
|
|
|
|
;; - add support for :repo for ELPA packages
|
2011-01-03 01:22:51 +08:00
|
|
|
|
;;
|
2010-12-20 22:37:13 +08:00
|
|
|
|
;; 1.1 - 2010-12-20 - Nobody's testing until the release
|
2010-10-08 18:37:50 +08:00
|
|
|
|
;;
|
|
|
|
|
;; - Adapt to package.el from Emacs24 by using relative symlinks to ELPA
|
|
|
|
|
;; packages ((package-user-dir) is "~/.emacs.d/elpa" now, so needs to
|
|
|
|
|
;; get expanded at least)
|
2010-10-09 20:41:02 +08:00
|
|
|
|
;; - Allow to bypass byte compiling entirely with a single global var
|
2010-10-09 21:10:22 +08:00
|
|
|
|
;; - Have http local file default to something sane, not package.el
|
2010-10-10 03:19:57 +08:00
|
|
|
|
;; - Implement support for svn and darcs too
|
2010-10-09 21:10:22 +08:00
|
|
|
|
;; - Still more recipes
|
2010-11-08 20:45:04 +08:00
|
|
|
|
;; - Add support for the `pacman' package manager (ARCH Linux)
|
2010-11-15 03:40:53 +08:00
|
|
|
|
;; - Add support for mercurial
|
2010-11-13 05:22:19 +08:00
|
|
|
|
;; - (el-get 'sync) now really means synchronous, and serialized too
|
|
|
|
|
;; - el-get-start-process-list implements :sync, defaults to nil (async)
|
2010-11-26 23:32:23 +08:00
|
|
|
|
;; - Implement a :localname package property to help with some kind of URLs
|
2010-11-27 05:07:02 +08:00
|
|
|
|
;; - Add el-get-post-init-hooks
|
2010-11-28 23:37:18 +08:00
|
|
|
|
;; - Allow build commands to be evaluated, hence using some emacs variables
|
2010-11-30 00:41:21 +08:00
|
|
|
|
;; - Finaly walk the extra mile and remove "required" packages at install
|
2010-11-30 01:02:25 +08:00
|
|
|
|
;; - Implement support for the "Do you want to continue" apt-get prompt
|
2010-12-01 20:32:39 +08:00
|
|
|
|
;; - implement :before user defined function to run before init
|
2010-10-08 18:37:50 +08:00
|
|
|
|
;;
|
2010-10-07 18:18:04 +08:00
|
|
|
|
;; 1.0 - 2010-10-07 - Can I haz your recipes?
|
2010-08-31 04:59:05 +08:00
|
|
|
|
;;
|
|
|
|
|
;; - Implement el-get recipes so that el-get-sources can be a simple list
|
|
|
|
|
;; of symbols. Now that there's an authoritative git repository, where
|
2010-09-01 23:52:53 +08:00
|
|
|
|
;; to share the recipes is easy.
|
2010-09-02 03:48:50 +08:00
|
|
|
|
;; - Add support for emacswiki directly, save from having to enter the URL
|
2010-09-02 05:39:39 +08:00
|
|
|
|
;; - Implement package status on-disk saving so that installing over a
|
|
|
|
|
;; previously failed install is in theory possible. Currently `el-get'
|
|
|
|
|
;; will refrain from removing your package automatically, though.
|
2010-09-03 21:02:49 +08:00
|
|
|
|
;; - Fix ELPA remove method, adding a "removed" state too.
|
2010-09-06 05:23:15 +08:00
|
|
|
|
;; - Implement CVS login support.
|
2010-09-10 03:54:18 +08:00
|
|
|
|
;; - Add lots of recipes
|
|
|
|
|
;; - Add support for `system-type' specific build commands
|
2010-09-15 23:34:37 +08:00
|
|
|
|
;; - Byte compile files from the load-path entries or :compile files
|
2010-09-20 03:28:07 +08:00
|
|
|
|
;; - Implement support for git submodules with the command
|
|
|
|
|
;; `git submodule update --init --recursive`
|
2010-09-22 16:38:52 +08:00
|
|
|
|
;; - Add catch-all post-install and post-update hooks
|
2010-09-22 16:56:33 +08:00
|
|
|
|
;; - Add desktop notification on install/update.
|
2010-08-31 04:59:05 +08:00
|
|
|
|
;;
|
2010-08-24 23:37:06 +08:00
|
|
|
|
;; 0.9 - 2010-08-24 - build me a shell
|
|
|
|
|
;;
|
|
|
|
|
;; - have `el-get-build' use start-process-shell-command so that you can
|
|
|
|
|
;; pass-in shell commands. Beware of poor command argument "parsing"
|
|
|
|
|
;; though, done with a simple `split-string'.
|
|
|
|
|
;;
|
2010-08-23 21:12:30 +08:00
|
|
|
|
;; 0.8 - 2010-08-23 - listen to the users
|
|
|
|
|
;;
|
|
|
|
|
;; - implement :after user defined function to run at the end of init
|
2010-08-24 23:30:32 +08:00
|
|
|
|
;; - add CVS support (no login support)
|
2010-08-23 22:55:36 +08:00
|
|
|
|
;; - improve el-get-build to use async building
|
|
|
|
|
;; - fix el-get-update doing so
|
2010-08-23 21:12:30 +08:00
|
|
|
|
;;
|
2010-08-23 06:19:47 +08:00
|
|
|
|
;; 0.7 - 2010-08-23 - archive
|
|
|
|
|
;;
|
|
|
|
|
;; - http support is extended to `tar' archives, via the http-tar type
|
|
|
|
|
;;
|
2010-08-13 03:00:15 +08:00
|
|
|
|
;; 0.6 - 2010-08-12 - towards a stable version
|
|
|
|
|
;;
|
|
|
|
|
;; - fix when asynchronous http support call post-install-fun
|
|
|
|
|
;; - fix el-get-remove calling convention
|
|
|
|
|
;; - add support for bzr, thanks to Kevin Fletcher
|
|
|
|
|
;;
|
2010-08-06 18:19:39 +08:00
|
|
|
|
;; 0.5 - 2010-08-06 - release early, fix often
|
|
|
|
|
;;
|
|
|
|
|
;; - fix apt-get and fink install hooks to call el-get-dpkg-symlink
|
|
|
|
|
;; - fix elpa and http support to follow the new call convention
|
|
|
|
|
;; - use asynchronous url-retrieve facility so that http is async too
|
|
|
|
|
;;
|
2010-08-05 04:10:34 +08:00
|
|
|
|
;; 0.4 - 2010-08-04 - foxy release
|
|
|
|
|
;;
|
|
|
|
|
;; - support asynchronous processes for system commands
|
|
|
|
|
;; apt-get, fink, git and git-svn are run in background
|
|
|
|
|
;; - support `sudo' password prompts (classic and ubuntu variants)
|
|
|
|
|
;; - fix fink support
|
|
|
|
|
;; - ELPA support is an option so that you can install ELPA from el-get
|
|
|
|
|
;; - implement el-get-rmdir
|
2010-06-19 04:21:02 +08:00
|
|
|
|
|
2011-03-11 04:15:12 +08:00
|
|
|
|
;;; Code:
|
2011-09-16 04:07:54 +08:00
|
|
|
|
|
2011-09-23 03:48:11 +08:00
|
|
|
|
;; first some essential variables, used in other parts of the code.
|
2010-06-19 04:21:02 +08:00
|
|
|
|
(defgroup el-get nil "el-get customization group"
|
|
|
|
|
:group 'convenience)
|
|
|
|
|
|
2012-02-12 18:41:20 +08:00
|
|
|
|
(defconst el-get-version "4.0.7" "el-get version number")
|
2011-09-20 21:15:52 +08:00
|
|
|
|
|
2011-09-23 03:48:11 +08:00
|
|
|
|
(defconst el-get-script (or load-file-name buffer-file-name))
|
|
|
|
|
|
|
|
|
|
(defcustom el-get-dir "~/.emacs.d/el-get/"
|
|
|
|
|
"Path where to install the packages."
|
|
|
|
|
:group 'el-get
|
|
|
|
|
:type 'directory)
|
|
|
|
|
|
|
|
|
|
(defcustom el-get-status-file
|
|
|
|
|
(concat (file-name-as-directory el-get-dir) ".status.el")
|
|
|
|
|
"Define where to store and read the package statuses")
|
|
|
|
|
|
|
|
|
|
(defvar el-get-autoload-file
|
|
|
|
|
(concat (file-name-as-directory el-get-dir) ".loaddefs.el")
|
|
|
|
|
"Where generated autoloads are saved")
|
|
|
|
|
|
|
|
|
|
(defvar el-get-emacs (concat invocation-directory invocation-name)
|
|
|
|
|
"Where to find the currently running emacs, a facility for :build commands")
|
2010-10-07 20:27:28 +08:00
|
|
|
|
|
2011-09-23 03:48:11 +08:00
|
|
|
|
;;
|
|
|
|
|
;; Now load the rest of the el-get code
|
|
|
|
|
;;
|
2011-09-21 22:06:18 +08:00
|
|
|
|
(require 'el-get-core) ; core facilities used everywhere
|
|
|
|
|
(require 'el-get-custom) ; user tweaks and `el-get-sources'
|
|
|
|
|
(require 'el-get-methods) ; support for `el-get-methods', backends
|
|
|
|
|
(require 'el-get-recipes) ; support for dealing with recipes
|
|
|
|
|
(require 'el-get-status) ; support for dealing with status
|
|
|
|
|
(require 'el-get-build) ; building packages
|
|
|
|
|
(require 'el-get-byte-compile) ; byte compiling in a subprocess
|
|
|
|
|
(require 'el-get-dependencies) ; topological-sort of package dep graph
|
|
|
|
|
(require 'el-get-notify) ; notification support (dbus, growl...)
|
|
|
|
|
(require 'el-get-list-packages) ; menu and `el-get-describe' facilities
|
2011-09-23 17:41:24 +08:00
|
|
|
|
(require 'el-get-autoloads) ; manages updating el-get's loaddefs.el
|
2011-06-25 23:07:14 +08:00
|
|
|
|
|
2011-09-23 03:48:11 +08:00
|
|
|
|
;;
|
|
|
|
|
;; And then define some more code-level customs. They stay here so that
|
|
|
|
|
;; it's easier for elisp programmers to find them and know about them. If
|
|
|
|
|
;; that is too lame of an excuse, let's move them to el-get-custom.el.
|
|
|
|
|
;;
|
2010-11-27 05:07:02 +08:00
|
|
|
|
(defcustom el-get-post-init-hooks nil
|
|
|
|
|
"Hooks to run after a package init.
|
2011-05-23 08:08:36 +08:00
|
|
|
|
Each hook is a unary function accepting a package"
|
2010-11-27 05:07:02 +08:00
|
|
|
|
:group 'el-get
|
|
|
|
|
:type 'hook)
|
|
|
|
|
|
2010-09-22 14:36:43 +08:00
|
|
|
|
(defcustom el-get-post-install-hooks nil
|
|
|
|
|
"Hooks to run after installing a package.
|
2011-05-26 21:49:30 +08:00
|
|
|
|
Each hook is a unary function accepting a package"
|
2010-09-22 14:36:43 +08:00
|
|
|
|
:group 'el-get
|
|
|
|
|
:type 'hook)
|
|
|
|
|
|
|
|
|
|
(defcustom el-get-post-update-hooks nil
|
2010-09-22 16:38:52 +08:00
|
|
|
|
"Hooks to run after updating a package.
|
2011-05-26 21:49:30 +08:00
|
|
|
|
Each hook is a unary function accepting a package"
|
|
|
|
|
:group 'el-get
|
|
|
|
|
:type 'hook)
|
2011-05-26 22:11:01 +08:00
|
|
|
|
|
|
|
|
|
(defcustom el-get-post-error-hooks nil
|
|
|
|
|
"Hooks to run after package installation fails.
|
|
|
|
|
Each hook is a binay function accepting a package and error data"
|
2010-09-22 14:36:43 +08:00
|
|
|
|
:group 'el-get
|
|
|
|
|
:type 'hook)
|
|
|
|
|
|
2010-10-08 21:00:38 +08:00
|
|
|
|
(defcustom el-get-byte-compile t
|
2011-03-28 18:43:48 +08:00
|
|
|
|
"Whether or not to byte-compile packages. Can be used to
|
2011-08-14 23:49:46 +08:00
|
|
|
|
disable byte-compilation globally, unless this process is not
|
|
|
|
|
controlled by `el-get' itself.
|
|
|
|
|
|
|
|
|
|
The cases when `el-get' loses control are with \"advanced\"
|
|
|
|
|
packaging systems (apt-get, fink, pacman, elpa) or when the
|
|
|
|
|
recipe contains a :build rule (using a Makefile for example)."
|
2010-10-08 21:00:38 +08:00
|
|
|
|
:group 'el-get
|
|
|
|
|
:type 'boolean)
|
|
|
|
|
|
2011-05-22 12:06:45 +08:00
|
|
|
|
(defcustom el-get-verbose nil
|
|
|
|
|
"Non-nil means print messages describing progress of el-get even for fast operations."
|
|
|
|
|
:group 'el-get
|
|
|
|
|
:type 'boolean)
|
|
|
|
|
|
2011-03-28 18:43:48 +08:00
|
|
|
|
(defcustom el-get-byte-compile-at-init nil
|
|
|
|
|
"Whether or not to byte-compile packages at init.
|
|
|
|
|
|
|
|
|
|
Turn this to t if you happen to update your packages from under
|
|
|
|
|
`el-get', e.g. doing `cd el-get-dir/package && git pull`
|
|
|
|
|
directly."
|
|
|
|
|
:group 'el-get
|
|
|
|
|
:type 'boolean)
|
|
|
|
|
|
2011-01-31 23:50:41 +08:00
|
|
|
|
(defcustom el-get-generate-autoloads t
|
|
|
|
|
"Whether or not to generate autoloads for packages. Can be used
|
|
|
|
|
to disable autoloads globally."
|
|
|
|
|
:group 'el-get
|
|
|
|
|
:type 'boolean)
|
|
|
|
|
|
2011-02-25 05:03:47 +08:00
|
|
|
|
(defcustom el-get-is-lazy nil
|
|
|
|
|
"Whether or not to defer evaluation of :post-init and :after
|
|
|
|
|
functions until libraries are required. Will also have el-get
|
|
|
|
|
skip the :load and :features properties when set. See :lazy to
|
|
|
|
|
force their evaluation on some packages only."
|
2011-02-23 04:39:37 +08:00
|
|
|
|
:group 'el-get
|
|
|
|
|
:type 'boolean)
|
|
|
|
|
|
2011-09-21 22:06:18 +08:00
|
|
|
|
(defvar el-get-next-packages nil
|
|
|
|
|
"List of packages to install next, used when dealing with dependencies.")
|
2011-05-26 22:37:28 +08:00
|
|
|
|
|
2011-05-26 22:11:01 +08:00
|
|
|
|
(defun el-get-installation-failed (package signal-data)
|
|
|
|
|
"Run all the failure hooks for PACKAGE and `signal' the car and cdr of SIGNAL-DATA."
|
|
|
|
|
(run-hook-with-args 'el-get-post-error-hooks package signal-data)
|
|
|
|
|
(signal (car signal-data) (cdr signal-data)))
|
|
|
|
|
|
2010-07-30 17:16:56 +08:00
|
|
|
|
|
2010-06-29 00:35:15 +08:00
|
|
|
|
;;
|
|
|
|
|
;; User Interface, Interactive part
|
|
|
|
|
;;
|
2011-10-14 22:28:52 +08:00
|
|
|
|
;;;###autoload
|
2010-10-07 20:27:28 +08:00
|
|
|
|
(defun el-get-version ()
|
|
|
|
|
"Message the current el-get version"
|
|
|
|
|
(interactive)
|
2012-02-19 04:46:32 +08:00
|
|
|
|
(let ((version
|
|
|
|
|
(if (string= (cadr (split-string el-get-version "\\.")) "0")
|
|
|
|
|
;; devel version, add the current git sha1 (short form)
|
|
|
|
|
(let ((default-directory (file-name-directory el-get-script)))
|
|
|
|
|
(concat el-get-version "."
|
|
|
|
|
(shell-command-to-string
|
|
|
|
|
"git --no-pager log -n1 --format=format:%h")))
|
|
|
|
|
el-get-version)))
|
|
|
|
|
(kill-new version)
|
|
|
|
|
(message "el-get version %s" version)))
|
2010-10-07 20:27:28 +08:00
|
|
|
|
|
2011-06-22 05:13:48 +08:00
|
|
|
|
(defun el-get-read-all-recipe-names ()
|
2011-03-17 05:21:52 +08:00
|
|
|
|
"Return the list of all known recipe names.
|
|
|
|
|
|
|
|
|
|
This is useful to use for providing completion candidates for
|
2011-06-22 05:13:48 +08:00
|
|
|
|
package names."
|
|
|
|
|
(mapcar 'el-get-source-name (el-get-read-all-recipes)))
|
2011-03-17 05:21:52 +08:00
|
|
|
|
|
2010-09-02 02:00:49 +08:00
|
|
|
|
(defun el-get-error-unless-package-p (package)
|
2011-02-22 05:55:45 +08:00
|
|
|
|
"Raise an error if PACKAGE does not name a package that has a valid recipe."
|
|
|
|
|
;; check for recipe
|
2010-11-29 21:03:37 +08:00
|
|
|
|
(let ((recipe (el-get-package-def package)))
|
|
|
|
|
(unless recipe
|
|
|
|
|
(error "el-get: package `%s' has no recipe" package))
|
|
|
|
|
(unless (plist-member recipe :type)
|
|
|
|
|
(error "el-get: package `%s' has incomplete recipe (no :type)" package))))
|
2010-09-02 02:00:49 +08:00
|
|
|
|
|
2011-06-22 06:33:33 +08:00
|
|
|
|
(defun el-get-package-is-installed (package)
|
2011-06-22 06:01:53 +08:00
|
|
|
|
"Raise an error if PACKAGE is already installed"
|
2011-06-22 06:33:33 +08:00
|
|
|
|
(string= "installed" (el-get-package-status (el-get-as-string package))))
|
2011-06-22 06:01:53 +08:00
|
|
|
|
|
2011-06-06 03:28:59 +08:00
|
|
|
|
(defun el-get-read-package-name (action &optional filtered)
|
2011-03-17 05:21:52 +08:00
|
|
|
|
"Ask user for a package name in minibuffer, with completion.
|
|
|
|
|
|
2011-06-06 03:28:59 +08:00
|
|
|
|
Completions are offered from all known package names, after
|
|
|
|
|
removing any packages in FILTERED."
|
2011-06-22 05:13:48 +08:00
|
|
|
|
(let ((packages (el-get-read-all-recipe-names)))
|
2011-02-22 05:55:45 +08:00
|
|
|
|
(completing-read (format "%s package: " action)
|
2011-05-24 23:46:42 +08:00
|
|
|
|
(set-difference packages filtered :test 'string=) nil t)))
|
2010-09-02 02:00:49 +08:00
|
|
|
|
|
2011-05-24 23:46:42 +08:00
|
|
|
|
(defun el-get-read-recipe-name (action)
|
2011-03-17 05:21:52 +08:00
|
|
|
|
"Ask user for a recipe name, with completion from the list of known recipe files.
|
|
|
|
|
|
|
|
|
|
This function does not deal with `el-get-sources' at all."
|
|
|
|
|
(completing-read (format "%s recipe: " action)
|
2011-06-22 05:13:48 +08:00
|
|
|
|
(el-get-read-all-recipe-names) nil))
|
2011-03-17 05:21:52 +08:00
|
|
|
|
|
|
|
|
|
(defun el-get-find-recipe-file (package &optional dir)
|
|
|
|
|
"Find recipe file for PACKAGE.
|
|
|
|
|
|
|
|
|
|
If no recipe file exists for PACKAGE, create a new one in DIR,
|
|
|
|
|
which defaults to the first element in `el-get-recipe-path'."
|
|
|
|
|
(interactive (list (el-get-read-recipe-name "Find or create")))
|
2011-09-07 03:22:46 +08:00
|
|
|
|
(let* ((package-el (concat (el-get-as-string package) ".rcp"))
|
2011-03-17 05:21:52 +08:00
|
|
|
|
(recipe-file (or
|
|
|
|
|
;; If dir was specified, open or create the
|
|
|
|
|
;; recipe file in that directory.
|
2011-05-23 09:33:32 +08:00
|
|
|
|
(when dir (expand-file-name package-el dir))
|
2011-03-17 05:21:52 +08:00
|
|
|
|
;; Next, try to find an existing recipe file anywhere.
|
|
|
|
|
(el-get-recipe-filename package)
|
|
|
|
|
;; Lastly, create a new recipe file in the first
|
|
|
|
|
;; directory in `el-get-recipe-path'
|
2011-06-20 05:47:42 +08:00
|
|
|
|
(expand-file-name package-el
|
2011-05-23 09:33:32 +08:00
|
|
|
|
(car el-get-recipe-path)))))
|
2011-03-17 05:21:52 +08:00
|
|
|
|
(find-file recipe-file)))
|
|
|
|
|
|
2011-05-22 12:06:45 +08:00
|
|
|
|
(defun el-get-funcall (func fname package)
|
2011-06-20 03:30:51 +08:00
|
|
|
|
"`funcal' FUNC for PACKAGE and report about FNAME when `el-get-verbose'"
|
2011-05-22 12:06:45 +08:00
|
|
|
|
(when (and func (functionp func))
|
2011-06-20 03:30:51 +08:00
|
|
|
|
(el-get-verbose-message "el-get: Calling :%s function for package %s"
|
|
|
|
|
fname package)
|
|
|
|
|
;; don't forget to make some variables available
|
2011-11-30 23:58:26 +08:00
|
|
|
|
(let ((pdir (el-get-package-directory package)))
|
2011-06-20 03:30:51 +08:00
|
|
|
|
(funcall func))))
|
2011-05-22 12:06:45 +08:00
|
|
|
|
|
2011-09-21 22:06:18 +08:00
|
|
|
|
|
2011-03-01 17:59:17 +08:00
|
|
|
|
(defun el-get-init (package)
|
2010-12-29 16:43:46 +08:00
|
|
|
|
"Make the named PACKAGE available for use.
|
|
|
|
|
|
|
|
|
|
Add PACKAGE's directory (or `:load-path' if specified) to the
|
|
|
|
|
`load-path', add any its `:info' directory to
|
|
|
|
|
`Info-directory-list', and `require' its `:features'. Will be
|
2011-06-22 06:01:53 +08:00
|
|
|
|
called by `el-get' (usually at startup) for each installed package."
|
2010-09-02 02:00:49 +08:00
|
|
|
|
(interactive (list (el-get-read-package-name "Init")))
|
2011-06-26 04:56:29 +08:00
|
|
|
|
(el-get-verbose-message "el-get-init: %s" package)
|
2011-05-26 22:11:01 +08:00
|
|
|
|
(condition-case err
|
|
|
|
|
(let* ((source (el-get-package-def package))
|
2011-06-22 04:28:58 +08:00
|
|
|
|
(method (el-get-package-method source))
|
2011-05-26 22:11:01 +08:00
|
|
|
|
(loads (el-get-as-list (plist-get source :load)))
|
|
|
|
|
(autoloads (plist-get source :autoloads))
|
|
|
|
|
(feats (el-get-as-list (plist-get source :features)))
|
|
|
|
|
(el-path (el-get-as-list (el-get-load-path package)))
|
|
|
|
|
(lazy (plist-get source :lazy))
|
|
|
|
|
(prepare (plist-get source :prepare))
|
|
|
|
|
(before (plist-get source :before))
|
|
|
|
|
(postinit (plist-get source :post-init))
|
|
|
|
|
(after (plist-get source :after))
|
|
|
|
|
(pkgname (plist-get source :pkgname))
|
|
|
|
|
(library (or (plist-get source :library) pkgname package))
|
2012-02-14 13:03:00 +08:00
|
|
|
|
(pdir (el-get-package-directory package))
|
|
|
|
|
(default-directory pdir))
|
2011-05-26 22:11:01 +08:00
|
|
|
|
|
2011-10-03 01:50:17 +08:00
|
|
|
|
;; a builtin package initialisation is about calling recipe and user
|
|
|
|
|
;; code only, no load-path nor byte-compiling support needed here.
|
2011-10-04 17:53:35 +08:00
|
|
|
|
(unless (eq method 'builtin)
|
2011-10-03 01:48:21 +08:00
|
|
|
|
;; append entries to load-path and Info-directory-list
|
2011-11-23 16:45:07 +08:00
|
|
|
|
(unless (member method '(apt-get fink pacman))
|
2011-10-03 01:48:21 +08:00
|
|
|
|
;; append entries to load-path
|
|
|
|
|
(dolist (path el-path)
|
|
|
|
|
(el-get-add-path-to-list package 'load-path path))
|
|
|
|
|
;; and Info-directory-list
|
|
|
|
|
(el-get-install-or-init-info package 'init))
|
|
|
|
|
|
|
|
|
|
(when el-get-byte-compile-at-init
|
|
|
|
|
;; If the package has been updated outside el-get, the .el files will be
|
|
|
|
|
;; out of date, so just check if we need to recompile them.
|
|
|
|
|
;;
|
|
|
|
|
;; when using el-get-update to update packages, though, there's no
|
|
|
|
|
;; need to byte compile at init.
|
|
|
|
|
(el-get-byte-compile package))
|
|
|
|
|
|
|
|
|
|
;; load any autoloads file if needed
|
|
|
|
|
(unless (eq autoloads t)
|
|
|
|
|
(dolist (file (el-get-as-list autoloads))
|
|
|
|
|
(el-get-load-fast file))))
|
2011-05-26 22:11:01 +08:00
|
|
|
|
|
|
|
|
|
;; first, the :prepare function, usually defined in the recipe
|
|
|
|
|
(el-get-funcall prepare "prepare" package)
|
|
|
|
|
|
|
|
|
|
;; now call the :before user function
|
|
|
|
|
(el-get-funcall before "before" package)
|
|
|
|
|
|
|
|
|
|
;; loads and feature are skipped when el-get-is-lazy
|
|
|
|
|
(unless (or lazy el-get-is-lazy)
|
|
|
|
|
;; loads
|
|
|
|
|
(dolist (file loads)
|
|
|
|
|
(let ((pfile (concat pdir file)))
|
|
|
|
|
(unless (file-exists-p pfile)
|
|
|
|
|
(error "el-get could not find file '%s'" pfile))
|
|
|
|
|
(el-get-verbose-message "el-get: load '%s'" pfile)
|
|
|
|
|
(el-get-load-fast pfile)))
|
|
|
|
|
|
|
|
|
|
;; features, only ELPA will handle them on its own
|
|
|
|
|
(unless (eq method 'elpa)
|
|
|
|
|
;; if a feature is provided, require it now
|
|
|
|
|
(dolist (feat feats)
|
|
|
|
|
(let ((feature (el-get-as-symbol feat)))
|
|
|
|
|
(el-get-verbose-message "require '%s" feature)
|
|
|
|
|
(require feature)))))
|
|
|
|
|
|
2011-10-20 20:47:04 +08:00
|
|
|
|
(el-get-funcall postinit "post-init" package)
|
|
|
|
|
|
|
|
|
|
;; now handle the user configs and :after functions
|
2011-05-26 22:11:01 +08:00
|
|
|
|
(if (or lazy el-get-is-lazy)
|
2011-09-12 01:55:09 +08:00
|
|
|
|
(let ((lazy-form
|
2011-10-20 20:47:04 +08:00
|
|
|
|
`(progn (el-get-load-package-user-init-file ',package)
|
2011-09-12 01:55:09 +08:00
|
|
|
|
,(when after (list 'funcall after)))))
|
2011-05-26 22:11:01 +08:00
|
|
|
|
(eval-after-load library lazy-form))
|
|
|
|
|
|
|
|
|
|
;; el-get is not lazy here
|
2011-09-12 01:55:09 +08:00
|
|
|
|
(el-get-load-package-user-init-file package)
|
2011-05-26 22:11:01 +08:00
|
|
|
|
(el-get-funcall after "after" package))
|
|
|
|
|
|
|
|
|
|
;; and call the global init hooks
|
|
|
|
|
(run-hook-with-args 'el-get-post-init-hooks package)
|
|
|
|
|
|
|
|
|
|
;; return the package
|
|
|
|
|
package)
|
2011-06-20 05:47:42 +08:00
|
|
|
|
(debug error
|
2011-05-26 22:11:01 +08:00
|
|
|
|
(el-get-installation-failed package err))))
|
2010-06-28 23:03:42 +08:00
|
|
|
|
|
2011-09-21 22:06:18 +08:00
|
|
|
|
|
|
|
|
|
(defun el-get-install (package)
|
|
|
|
|
"Cause the named PACKAGE to be installed after all of its
|
|
|
|
|
dependencies (if any).
|
|
|
|
|
|
|
|
|
|
PACKAGE may be either a string or the corresponding symbol."
|
|
|
|
|
(interactive (list (el-get-read-package-name "Install")))
|
2011-10-09 03:27:55 +08:00
|
|
|
|
(let ((packages (el-get-dependencies (el-get-as-symbol package))))
|
|
|
|
|
(when (cdr packages)
|
|
|
|
|
;; tweak el-get-post-install-hooks to install remaining packages
|
|
|
|
|
;; once the first is installed
|
|
|
|
|
(el-get-verbose-message "el-get-install %s: %S" package packages)
|
|
|
|
|
(setq el-get-next-packages (cdr packages))
|
2012-02-19 08:36:45 +08:00
|
|
|
|
(add-hook 'el-get-post-init-hooks 'el-get-install-next-packages))
|
2011-10-09 03:27:55 +08:00
|
|
|
|
|
|
|
|
|
(let ((package (car packages)))
|
|
|
|
|
(if (not (el-get-package-is-installed package))
|
|
|
|
|
(el-get-do-install package)
|
|
|
|
|
;; if package is already installed, skip to the next
|
|
|
|
|
(message "el-get: `%s' package is already installed" package)
|
2012-02-21 04:58:45 +08:00
|
|
|
|
(el-get-init package)))))
|
2011-09-21 22:06:18 +08:00
|
|
|
|
|
2012-02-19 08:39:48 +08:00
|
|
|
|
(defun el-get-install-next-packages (&rest ignored)
|
2011-09-21 22:06:18 +08:00
|
|
|
|
"Run as part of `el-get-post-init-hooks' when dealing with dependencies."
|
|
|
|
|
(let ((package (pop el-get-next-packages)))
|
2011-09-23 03:48:11 +08:00
|
|
|
|
(el-get-verbose-message "el-get-install-next-packages: %s" package)
|
2011-09-21 22:06:18 +08:00
|
|
|
|
(if package
|
2011-10-12 02:27:01 +08:00
|
|
|
|
;; el-get-do-install will either init the package, installing it
|
|
|
|
|
;; first only when necessary to do so
|
|
|
|
|
(el-get-do-install (el-get-as-string package))
|
2011-09-21 22:06:18 +08:00
|
|
|
|
;; no more packages to install in the dependency walk, clean up
|
|
|
|
|
(remove-hook 'el-get-post-init-hooks 'el-get-install-next-packages))))
|
|
|
|
|
|
2011-06-26 05:13:06 +08:00
|
|
|
|
(defun el-get-post-install-build (package)
|
|
|
|
|
"Function to call after building the package while installing it."
|
2011-09-23 20:06:29 +08:00
|
|
|
|
(el-get-save-package-status package "installed")
|
|
|
|
|
(el-get-invalidate-autoloads package) ; that will also update them
|
|
|
|
|
(el-get-init package))
|
2011-06-25 12:49:17 +08:00
|
|
|
|
|
2011-03-01 17:59:17 +08:00
|
|
|
|
(defun el-get-post-install (package)
|
|
|
|
|
"Post install PACKAGE. This will get run by a sentinel."
|
2011-10-28 00:27:10 +08:00
|
|
|
|
(let* ((sync el-get-default-process-sync)
|
|
|
|
|
(type (el-get-package-type package))
|
|
|
|
|
(hooks (el-get-method type :install-hook))
|
|
|
|
|
(commands (el-get-build-commands package))
|
|
|
|
|
(checksum (plist-get (el-get-package-def package) :checksum))
|
|
|
|
|
(compute-checksum (el-get-method type :compute-checksum)))
|
|
|
|
|
|
|
|
|
|
;; check the checksum of the package here, as early as possible
|
2011-10-29 00:02:38 +08:00
|
|
|
|
(when (and checksum (not compute-checksum))
|
|
|
|
|
(error
|
|
|
|
|
"Checksum verification of package %s is not supported with method %s."
|
|
|
|
|
package type))
|
2011-10-28 00:27:10 +08:00
|
|
|
|
(when compute-checksum
|
|
|
|
|
(let ((computed (funcall compute-checksum package)))
|
|
|
|
|
(if checksum
|
2011-10-31 17:58:12 +08:00
|
|
|
|
(if (equal computed (el-get-as-string checksum))
|
|
|
|
|
(el-get-verbose-message "el-get: package %s passed checksum with \"%s\"."
|
|
|
|
|
package computed)
|
|
|
|
|
(error "Checksum verification failed. Required: \"%s\", actual: \"%s\"."
|
2011-10-28 00:27:10 +08:00
|
|
|
|
checksum computed))
|
2011-10-29 00:02:38 +08:00
|
|
|
|
(el-get-verbose-message "el-get: pakage %s checksum is %s."
|
|
|
|
|
package computed))))
|
2010-12-27 17:33:14 +08:00
|
|
|
|
|
2010-08-04 03:35:04 +08:00
|
|
|
|
;; post-install is the right place to run install-hook
|
2010-09-04 03:38:53 +08:00
|
|
|
|
(run-hook-with-args hooks package)
|
2010-12-27 17:33:14 +08:00
|
|
|
|
|
2011-06-26 05:13:06 +08:00
|
|
|
|
;; el-get-post-build will care about autoloads and initializing the
|
|
|
|
|
;; package, and will change the status to "installed"
|
|
|
|
|
(el-get-build package commands nil sync 'el-get-post-install-build))
|
2010-09-22 16:56:32 +08:00
|
|
|
|
(run-hook-with-args 'el-get-post-install-hooks package))
|
2010-08-04 03:35:04 +08:00
|
|
|
|
|
2011-06-06 03:28:59 +08:00
|
|
|
|
(defun el-get-do-install (package)
|
2011-06-05 07:15:54 +08:00
|
|
|
|
"Install any PACKAGE for which you have a recipe."
|
2011-06-22 06:01:53 +08:00
|
|
|
|
(el-get-error-unless-package-p package)
|
2011-09-20 23:55:14 +08:00
|
|
|
|
(if (string= (el-get-package-status package) "installed")
|
2011-10-08 03:46:34 +08:00
|
|
|
|
(el-get-init package)
|
2011-09-20 23:55:14 +08:00
|
|
|
|
(let* ((status (el-get-read-package-status package))
|
|
|
|
|
(source (el-get-package-def package))
|
|
|
|
|
(method (el-get-package-method source))
|
|
|
|
|
(install (el-get-method method :install))
|
2011-10-08 06:43:55 +08:00
|
|
|
|
(url (plist-get source :url))
|
|
|
|
|
(pdir (el-get-package-directory package)))
|
|
|
|
|
|
|
|
|
|
(cond ((string= "installed" status)
|
|
|
|
|
(error "Package %s is already installed." package))
|
|
|
|
|
((string= "required" status)
|
|
|
|
|
(message "Package %s failed to install, removing it first." package)
|
|
|
|
|
(el-get-remove package))
|
|
|
|
|
((file-exists-p pdir)
|
|
|
|
|
(message "Package %s has an install dir but is not known to be installed. Removing it so we can install a known version." package)
|
|
|
|
|
(el-get-remove package)))
|
2011-09-20 23:55:14 +08:00
|
|
|
|
|
2011-10-04 05:13:07 +08:00
|
|
|
|
;; check we can install the package and save to "required" status
|
|
|
|
|
(el-get-check-init)
|
|
|
|
|
(el-get-save-package-status package "required")
|
2011-09-20 23:55:14 +08:00
|
|
|
|
|
2011-10-04 05:13:07 +08:00
|
|
|
|
;; and install the package now, *then* message about it
|
|
|
|
|
(funcall install package url 'el-get-post-install)
|
|
|
|
|
(message "el-get install %s" package))))
|
2010-06-28 23:03:42 +08:00
|
|
|
|
|
2011-10-11 16:37:52 +08:00
|
|
|
|
(defun el-get-reload (package)
|
|
|
|
|
"Reload PACKAGE."
|
|
|
|
|
(interactive
|
|
|
|
|
(list (el-get-read-package-with-status "Update" "installed")))
|
|
|
|
|
(el-get-verbose-message "el-get-reload: %s" package)
|
|
|
|
|
(let* ((all-features features)
|
|
|
|
|
(package-features (el-get-package-features package))
|
|
|
|
|
(package-files (el-get-package-files package))
|
|
|
|
|
(other-features
|
|
|
|
|
(remove-if (lambda (x) (memq x package-features)) all-features)))
|
|
|
|
|
(unwind-protect
|
|
|
|
|
(progn
|
|
|
|
|
;; We cannot let-bind `features' here, becauses the changes
|
|
|
|
|
;; made by `el-get-init' must persist.
|
|
|
|
|
(setq features other-features)
|
|
|
|
|
;; Reload all loaded files in package dir if they still
|
|
|
|
|
;; exist.
|
|
|
|
|
(loop for file in package-files
|
|
|
|
|
do (load file 'noerror))
|
|
|
|
|
;; Redo package initialization
|
|
|
|
|
(el-get-init package)
|
|
|
|
|
;; Reload all features provided by the package. This ensures
|
|
|
|
|
;; that autoloaded packages (which normally don't load
|
|
|
|
|
;; anything until one of their entry points is called) are
|
|
|
|
|
;; forced to reload immediately if they were already loaded.
|
|
|
|
|
(loop for f in package-features
|
|
|
|
|
do (require f nil 'noerror)))
|
|
|
|
|
;; We have to add all the removed features back in no matter
|
|
|
|
|
;; what, or else we would be lying about what has been loaded.
|
|
|
|
|
;; This covers the corner case where an updated package no
|
|
|
|
|
;; longer provides a certain feature. Technically that feature
|
|
|
|
|
;; is still provided, so not adding it back would be wrong.
|
|
|
|
|
(let ((missing-features
|
|
|
|
|
(remove-if (lambda (x) (memq x features)) package-features)))
|
|
|
|
|
(when missing-features
|
|
|
|
|
(warn "Adding %S back onto features, because the reloaded package did not provide them."
|
|
|
|
|
missing-features)
|
|
|
|
|
(setq features (append missing-features features)))))))
|
|
|
|
|
|
2011-09-21 22:06:18 +08:00
|
|
|
|
|
2010-08-04 03:35:04 +08:00
|
|
|
|
(defun el-get-post-update (package)
|
2010-09-02 02:00:49 +08:00
|
|
|
|
"Post update PACKAGE. This will get run by a sentinel."
|
2010-08-04 03:35:04 +08:00
|
|
|
|
(let* ((source (el-get-package-def package))
|
2011-01-07 20:08:14 +08:00
|
|
|
|
(commands (el-get-build-commands package)))
|
2011-01-29 06:12:32 +08:00
|
|
|
|
(el-get-build package commands nil el-get-default-process-sync
|
2011-01-07 20:08:14 +08:00
|
|
|
|
(lambda (package)
|
|
|
|
|
(el-get-init package)
|
|
|
|
|
;; fix trailing failed installs
|
|
|
|
|
(when (string= (el-get-read-package-status package) "required")
|
|
|
|
|
(el-get-save-package-status package "installed"))
|
2011-10-11 16:37:52 +08:00
|
|
|
|
(el-get-reload package)
|
2010-09-28 02:24:39 +08:00
|
|
|
|
(run-hook-with-args 'el-get-post-update-hooks package)))))
|
2010-06-28 23:03:42 +08:00
|
|
|
|
|
2010-09-02 02:00:49 +08:00
|
|
|
|
(defun el-get-update (package)
|
|
|
|
|
"Update PACKAGE."
|
2011-02-22 05:55:45 +08:00
|
|
|
|
(interactive
|
|
|
|
|
(list (el-get-read-package-with-status "Update" "required" "installed")))
|
2010-09-02 02:00:49 +08:00
|
|
|
|
(el-get-error-unless-package-p package)
|
|
|
|
|
(let* ((source (el-get-package-def package))
|
2011-06-22 04:28:58 +08:00
|
|
|
|
(method (el-get-package-method source))
|
2011-01-07 20:08:14 +08:00
|
|
|
|
(update (el-get-method method :update))
|
|
|
|
|
(url (plist-get source :url))
|
|
|
|
|
(commands (plist-get source :build)))
|
2010-06-28 23:03:42 +08:00
|
|
|
|
;; update the package now
|
2011-10-31 17:41:25 +08:00
|
|
|
|
(if (plist-get source :checksum)
|
2011-10-31 17:58:12 +08:00
|
|
|
|
(error "el-get: remove checksum from package %s to update it." package)
|
2011-10-31 17:41:25 +08:00
|
|
|
|
(funcall update package url 'el-get-post-update)
|
|
|
|
|
(message "el-get update %s" package))))
|
2010-06-28 23:03:42 +08:00
|
|
|
|
|
2011-10-14 22:28:52 +08:00
|
|
|
|
;;;###autoload
|
2011-01-07 20:09:06 +08:00
|
|
|
|
(defun el-get-update-all ()
|
2011-06-22 17:50:49 +08:00
|
|
|
|
"Performs update of all installed packages."
|
2011-06-16 03:46:09 +08:00
|
|
|
|
(interactive)
|
2011-06-22 17:50:49 +08:00
|
|
|
|
(mapc 'el-get-update (el-get-list-package-names-with-status "installed")))
|
2011-01-07 20:09:06 +08:00
|
|
|
|
|
2011-10-14 22:28:52 +08:00
|
|
|
|
;;;###autoload
|
2011-06-16 03:46:09 +08:00
|
|
|
|
(defun el-get-self-update ()
|
|
|
|
|
"Update el-get itself. The standard recipe takes care of reloading the code."
|
|
|
|
|
(interactive)
|
2011-08-16 21:51:04 +08:00
|
|
|
|
(let ((el-get-default-process-sync t)
|
|
|
|
|
(el-get-dir
|
|
|
|
|
(expand-file-name ".." (file-name-directory el-get-script))))
|
2011-06-22 03:56:07 +08:00
|
|
|
|
(el-get-update "el-get")))
|
2011-06-16 03:46:09 +08:00
|
|
|
|
|
2011-09-21 22:06:18 +08:00
|
|
|
|
|
2010-08-05 03:57:42 +08:00
|
|
|
|
(defun el-get-post-remove (package)
|
2010-09-02 02:00:49 +08:00
|
|
|
|
"Run the post-remove hooks for PACKAGE."
|
2011-06-22 04:28:58 +08:00
|
|
|
|
(let* ((hooks (el-get-method (el-get-package-method package) :remove-hook)))
|
2011-06-17 17:36:41 +08:00
|
|
|
|
(run-hook-with-args hooks package)
|
|
|
|
|
(run-hook-with-args 'el-get-post-remove-hooks package)))
|
2010-08-05 03:57:42 +08:00
|
|
|
|
|
2010-09-04 06:42:12 +08:00
|
|
|
|
(defun el-get-remove (package)
|
2011-02-22 05:55:45 +08:00
|
|
|
|
"Remove any PACKAGE that is know to be installed or required."
|
|
|
|
|
(interactive
|
|
|
|
|
(list (el-get-read-package-with-status "Remove" "required" "installed")))
|
2011-06-22 06:01:53 +08:00
|
|
|
|
(el-get-error-unless-package-p package)
|
2011-06-20 05:47:42 +08:00
|
|
|
|
|
2011-06-22 06:01:53 +08:00
|
|
|
|
(let* ((source (el-get-package-def package))
|
|
|
|
|
(method (el-get-package-method source))
|
|
|
|
|
(remove (el-get-method method :remove))
|
|
|
|
|
(url (plist-get source :url)))
|
|
|
|
|
;; remove the package now
|
|
|
|
|
(el-get-remove-autoloads package)
|
|
|
|
|
(funcall remove package url 'el-get-post-remove)
|
|
|
|
|
(el-get-save-package-status package "removed")
|
|
|
|
|
(message "el-get remove %s" package)))
|
2010-06-28 23:03:42 +08:00
|
|
|
|
|
2012-02-19 08:39:48 +08:00
|
|
|
|
(defun el-get-reinstall (package)
|
|
|
|
|
"Remove PACKAGE and then install it again."
|
|
|
|
|
(interactive (list (el-get-read-package-name "Reinstall")))
|
|
|
|
|
(el-get-remove package)
|
|
|
|
|
(el-get-install package))
|
|
|
|
|
|
2011-10-14 22:28:52 +08:00
|
|
|
|
;;;###autoload
|
2010-09-02 02:00:49 +08:00
|
|
|
|
(defun el-get-cd (package)
|
2010-08-04 03:44:29 +08:00
|
|
|
|
"Open dired in the package directory."
|
2011-02-22 05:55:45 +08:00
|
|
|
|
(interactive
|
|
|
|
|
(list (el-get-read-package-with-status "cd to" "required" "installed")))
|
2010-09-02 02:00:49 +08:00
|
|
|
|
(el-get-error-unless-package-p package)
|
|
|
|
|
(dired (el-get-package-directory package)))
|
2010-08-04 03:44:29 +08:00
|
|
|
|
|
2011-03-17 05:21:52 +08:00
|
|
|
|
(defun el-get-write-recipe (source dir &optional filename)
|
|
|
|
|
"Given an SOURCE entry, write it to FILENAME"
|
|
|
|
|
(let* (;; Replace a package name with its definition
|
|
|
|
|
(source (if (symbolp source) (el-get-read-recipe source) source))
|
|
|
|
|
;; Autogenerate filename if unspecified
|
2011-09-07 03:22:46 +08:00
|
|
|
|
(filename (or filename (format "%s.rcp" (el-get-source-name source)))))
|
2011-03-17 05:21:52 +08:00
|
|
|
|
;; Filepath is dir/file
|
|
|
|
|
(let ((filepath (format "%s/%s" dir filename)))
|
|
|
|
|
(with-temp-file filepath
|
|
|
|
|
(insert (prin1-to-string source))))))
|
|
|
|
|
|
2011-10-14 22:28:52 +08:00
|
|
|
|
;;;###autoload
|
2011-01-11 05:36:55 +08:00
|
|
|
|
(defun el-get-make-recipes (&optional dir)
|
2011-01-11 05:44:56 +08:00
|
|
|
|
"Loop over `el-get-sources' and write a recipe file for each
|
2011-01-11 05:36:55 +08:00
|
|
|
|
entry which is not a symbol and is not already a known recipe."
|
|
|
|
|
(interactive "Dsave recipes in directory: ")
|
|
|
|
|
(let* ((all (mapcar 'el-get-source-name (el-get-read-all-recipes)))
|
|
|
|
|
(new (loop for r in el-get-sources
|
|
|
|
|
when (and (not (symbolp r))
|
|
|
|
|
(not (member (el-get-source-name r) all)))
|
|
|
|
|
collect r)))
|
|
|
|
|
(dolist (r new)
|
|
|
|
|
(message "el-get: preparing recipe file for %s" (el-get-source-name r))
|
2011-03-17 05:21:52 +08:00
|
|
|
|
(el-get-write-recipe r dir)))
|
2011-01-11 05:36:55 +08:00
|
|
|
|
(dired dir))
|
|
|
|
|
|
2011-10-29 00:02:38 +08:00
|
|
|
|
;;;###autoload
|
|
|
|
|
(defun el-get-checksum (package)
|
|
|
|
|
"Compute the checksum of the given package, and put it in the kill-ring"
|
|
|
|
|
(interactive
|
|
|
|
|
(list (el-get-read-package-with-status "Checksum" "installed")))
|
|
|
|
|
(let* ((type (el-get-package-type package))
|
|
|
|
|
(checksum (plist-get (el-get-package-def package) :checksum))
|
|
|
|
|
(compute-checksum (el-get-method type :compute-checksum)))
|
|
|
|
|
(when (and checksum (not compute-checksum))
|
|
|
|
|
(error "package method %s does not support checksums" type))
|
|
|
|
|
(when compute-checksum
|
|
|
|
|
(let ((checksum (funcall compute-checksum package)))
|
2012-02-02 08:25:17 +08:00
|
|
|
|
(message "Checksum for package %s is: %s. It has been copied to the kill-ring."
|
|
|
|
|
package checksum)
|
|
|
|
|
(kill-new checksum)))))
|
2011-10-29 00:02:38 +08:00
|
|
|
|
|
2012-02-02 08:20:39 +08:00
|
|
|
|
(defun el-get-self-checksum ()
|
|
|
|
|
"Compute the checksum of the running version of el-get itself.
|
|
|
|
|
|
|
|
|
|
Also put the checksum in the kill-ring."
|
|
|
|
|
(interactive)
|
|
|
|
|
(el-get-checksum 'el-get))
|
|
|
|
|
|
2010-07-30 17:16:56 +08:00
|
|
|
|
|
2010-06-29 00:35:15 +08:00
|
|
|
|
;;
|
|
|
|
|
;; User Interface, Non Interactive part
|
|
|
|
|
;;
|
2011-06-22 17:38:40 +08:00
|
|
|
|
(defun el-get-init-and-install (&optional packages)
|
|
|
|
|
"Install \"required\" packages, init \"installed\" packages.
|
|
|
|
|
|
|
|
|
|
When PACKAGES is non-nil, only process entries from this list.
|
|
|
|
|
Those packages from the list we don't know the status of are
|
|
|
|
|
considered \"required\"."
|
|
|
|
|
(let* ((required (el-get-list-package-names-with-status "required"))
|
|
|
|
|
(installed (el-get-list-package-names-with-status "installed"))
|
|
|
|
|
(to-init (if packages
|
|
|
|
|
(loop for p in packages
|
|
|
|
|
when (member (el-get-as-string p) installed)
|
2011-09-23 17:39:12 +08:00
|
|
|
|
collect p)
|
|
|
|
|
(mapcar 'el-get-as-symbol installed)))
|
|
|
|
|
(init-deps (el-get-dependencies to-init))
|
2011-06-22 17:38:40 +08:00
|
|
|
|
(to-install (if packages
|
|
|
|
|
(loop for p in packages
|
2011-09-23 17:39:12 +08:00
|
|
|
|
unless (member p init-deps)
|
|
|
|
|
collect p)
|
|
|
|
|
(mapcar 'el-get-as-symbol required)))
|
|
|
|
|
(install-deps (el-get-dependencies to-install))
|
2011-06-26 06:16:25 +08:00
|
|
|
|
done)
|
2011-09-23 17:39:12 +08:00
|
|
|
|
(el-get-verbose-message "el-get-init-and-install: install %S" install-deps)
|
|
|
|
|
(el-get-verbose-message "el-get-init-and-install: init %S" init-deps)
|
|
|
|
|
|
|
|
|
|
(loop for p in install-deps do (el-get-do-install p) collect p into done)
|
|
|
|
|
(loop for p in init-deps do (el-get-init p) collect p into done)
|
2011-06-26 06:16:25 +08:00
|
|
|
|
done))
|
2011-06-22 17:38:40 +08:00
|
|
|
|
|
|
|
|
|
(defun el-get (&optional sync &rest packages)
|
2011-05-26 22:15:00 +08:00
|
|
|
|
"Ensure that packages have been downloaded once and init them as needed.
|
2010-06-28 03:13:22 +08:00
|
|
|
|
|
|
|
|
|
This will not update the sources by using `apt-get install' or
|
2011-05-26 22:15:00 +08:00
|
|
|
|
`git pull', but it will ensure that:
|
2010-06-28 03:13:22 +08:00
|
|
|
|
|
2011-05-26 22:15:00 +08:00
|
|
|
|
* the packages have been installed
|
|
|
|
|
* load-path is set so their elisp files can be found
|
|
|
|
|
* Info-directory-list is set so their info files can be found
|
|
|
|
|
* Autoloads have been prepared and evaluated for each package
|
|
|
|
|
* Any post-installation setup (e.g. `(require 'feature)') happens
|
2010-09-20 03:49:00 +08:00
|
|
|
|
|
2011-05-26 22:15:00 +08:00
|
|
|
|
When SYNC is nil (the default), all installations run
|
|
|
|
|
concurrently, in the background.
|
2010-11-13 05:22:19 +08:00
|
|
|
|
|
2011-05-26 22:15:00 +08:00
|
|
|
|
When SYNC is 'sync, each package will be installed synchronously,
|
|
|
|
|
and any error will stop it all.
|
2010-11-13 05:22:19 +08:00
|
|
|
|
|
|
|
|
|
When SYNC is 'wait, then `el-get' will enter a wait-loop and only
|
|
|
|
|
let you use Emacs once it has finished with its job. That's
|
|
|
|
|
useful an option to use in your `user-init-file'. Note that each
|
|
|
|
|
package in the list gets installed in parallel with this option.
|
2010-09-20 03:49:00 +08:00
|
|
|
|
|
|
|
|
|
Please note that the `el-get-init' part of `el-get' is always
|
|
|
|
|
done synchronously, so you will have to wait here. There's
|
|
|
|
|
`byte-compile' support though, and the packages you use are
|
2011-02-22 05:20:57 +08:00
|
|
|
|
welcome to use `autoload' too.
|
|
|
|
|
|
2011-06-22 17:38:40 +08:00
|
|
|
|
PACKAGES is expected to be a list of packages you want to install
|
|
|
|
|
or init. When PACKAGES is omited (the default), the list of
|
|
|
|
|
already installed packages is considered."
|
2010-11-13 05:22:19 +08:00
|
|
|
|
(unless (or (null sync)
|
2011-01-07 20:08:14 +08:00
|
|
|
|
(member sync '(sync wait)))
|
2011-01-03 01:22:51 +08:00
|
|
|
|
(error "el-get sync parameter should be either nil, sync or wait"))
|
2011-06-17 00:27:58 +08:00
|
|
|
|
|
2010-12-27 17:33:14 +08:00
|
|
|
|
;; If there's no autoload file, everything needs to be regenerated.
|
2011-09-23 17:41:24 +08:00
|
|
|
|
(unless (file-exists-p el-get-autoload-file) (el-get-invalidate-autoloads))
|
2010-12-27 17:33:14 +08:00
|
|
|
|
|
2011-02-25 06:57:27 +08:00
|
|
|
|
;; Autoloads path are relative to el-get-dir, so add it to load-path
|
|
|
|
|
(add-to-list 'load-path (file-name-as-directory el-get-dir))
|
|
|
|
|
|
2011-09-23 03:48:11 +08:00
|
|
|
|
(let* ((packages
|
|
|
|
|
;; (el-get 'sync 'a 'b my-package-list)
|
|
|
|
|
(loop for p in packages when (listp p) append p else collect p))
|
|
|
|
|
(p-status (el-get-read-all-packages-status))
|
|
|
|
|
(total (length packages))
|
|
|
|
|
(installed (el-get-count-packages-with-status packages "installed"))
|
|
|
|
|
(progress (and (eq sync 'wait)
|
2010-11-13 05:22:19 +08:00
|
|
|
|
(make-progress-reporter
|
2011-09-04 03:57:56 +08:00
|
|
|
|
"Waiting for `el-get' to complete... "
|
2011-09-23 03:48:11 +08:00
|
|
|
|
0 (- total installed) 0)))
|
2010-12-25 15:27:58 +08:00
|
|
|
|
(el-get-default-process-sync sync))
|
2011-05-26 22:37:28 +08:00
|
|
|
|
|
2011-06-22 17:38:40 +08:00
|
|
|
|
;; keep the result of `el-get-init-and-install' to return it even in the
|
|
|
|
|
;; 'wait case
|
2010-11-10 19:15:30 +08:00
|
|
|
|
(prog1
|
2011-09-23 17:39:12 +08:00
|
|
|
|
(el-get-init-and-install (mapcar 'el-get-as-symbol packages))
|
2010-11-10 19:15:30 +08:00
|
|
|
|
|
2011-09-23 03:48:11 +08:00
|
|
|
|
;; el-get-install is async, that's now ongoing.
|
2010-11-10 19:15:30 +08:00
|
|
|
|
(when progress
|
2011-09-23 03:48:11 +08:00
|
|
|
|
(while (> (- total installed) 0)
|
|
|
|
|
(sleep-for 0.2)
|
|
|
|
|
;; don't forget to account for installation failure
|
|
|
|
|
(setq installed (el-get-count-packages-with-status packages "installed" "required"))
|
|
|
|
|
(progress-reporter-update progress (- total installed)))
|
2011-10-12 00:02:20 +08:00
|
|
|
|
(progress-reporter-done progress))
|
|
|
|
|
|
|
|
|
|
;; now is a good time to care about autoloads
|
|
|
|
|
(el-get-eval-autoloads))))
|
2010-11-10 19:15:30 +08:00
|
|
|
|
|
2010-06-28 03:13:22 +08:00
|
|
|
|
(provide 'el-get)
|
2011-03-11 04:15:12 +08:00
|
|
|
|
|
|
|
|
|
;;; el-get.el ends here
|