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
|
|
|
|
;;
|
|
|
|
|
;; Copyright (C) 2010 Dimitri Fontaine
|
|
|
|
|
;;
|
|
|
|
|
;; Author: Dimitri Fontaine <dim@tapoueh.org>
|
|
|
|
|
;; URL: http://www.emacswiki.org/emacs/el-get.el
|
2010-09-01 23:52:53 +08:00
|
|
|
|
;; Version: 0.9
|
2010-06-19 04:21:02 +08:00
|
|
|
|
;; Created: 2010-06-17
|
2010-09-02 03:48:50 +08:00
|
|
|
|
;; Keywords: emacs package elisp install elpa git git-svn bzr cvs apt-get fink 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
|
2010-08-05 04:10:34 +08:00
|
|
|
|
;;
|
|
|
|
|
;; Changelog
|
|
|
|
|
;;
|
2010-08-31 04:59:05 +08:00
|
|
|
|
;; 0.10 - <WIP> - Can I haz your recipes?
|
|
|
|
|
;;
|
|
|
|
|
;; - 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-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
|
|
|
|
|
2010-08-04 00:04:01 +08:00
|
|
|
|
(require 'dired)
|
2010-07-30 17:16:56 +08:00
|
|
|
|
(require 'package nil t) ; that's ELPA, but you can use el-get to install it
|
2010-06-19 04:21:02 +08:00
|
|
|
|
|
2010-09-02 03:30:27 +08:00
|
|
|
|
(eval-when-compile
|
2010-08-31 04:59:05 +08:00
|
|
|
|
;; yes we do need the loop facility, for merging 2 property lists
|
|
|
|
|
(require 'cl))
|
|
|
|
|
|
2010-06-19 04:21:02 +08:00
|
|
|
|
(defgroup el-get nil "el-get customization group"
|
|
|
|
|
:group 'convenience)
|
|
|
|
|
|
2010-08-23 06:19:47 +08:00
|
|
|
|
(defvar el-get-git-clone-hook nil "Hook run after git clone.")
|
|
|
|
|
(defvar el-get-git-svn-clone-hook nil "Hook run after git svn clone.")
|
|
|
|
|
(defvar el-get-bzr-branch-hook nil "Hook run after bzr branch.")
|
2010-08-23 21:52:15 +08:00
|
|
|
|
(defvar el-get-cvs-checkout-hook nil "Hook run after cvs checkout.")
|
2010-08-23 06:19:47 +08:00
|
|
|
|
(defvar el-get-apt-get-install-hook nil "Hook run after apt-get install.")
|
|
|
|
|
(defvar el-get-apt-get-remove-hook nil "Hook run after apt-get remove.")
|
|
|
|
|
(defvar el-get-fink-install-hook nil "Hook run after fink install.")
|
|
|
|
|
(defvar el-get-fink-remove-hook nil "Hook run after fink remove.")
|
|
|
|
|
(defvar el-get-elpa-install-hook nil "Hook run after ELPA package install.")
|
|
|
|
|
(defvar el-get-http-install-hook nil "Hook run after http retrieve.")
|
|
|
|
|
(defvar el-get-http-tar-install-hook nil "Hook run after http-tar package install.")
|
2010-06-28 03:13:22 +08:00
|
|
|
|
|
2010-06-19 04:21:02 +08:00
|
|
|
|
(defcustom el-get-methods
|
2010-09-02 03:30:27 +08:00
|
|
|
|
'(:git (:install el-get-git-clone
|
2010-06-28 03:13:22 +08:00
|
|
|
|
:install-hook el-get-git-clone-hook
|
2010-09-02 03:30:27 +08:00
|
|
|
|
:update el-get-git-pull
|
2010-06-28 03:13:22 +08:00
|
|
|
|
:remove el-get-rmdir)
|
2010-08-02 19:32:59 +08:00
|
|
|
|
:git-svn (:install el-get-git-svn-clone
|
|
|
|
|
:install-hook el-get-git-svn-clone-hook
|
|
|
|
|
:update el-get-git-svn-update
|
|
|
|
|
:remove el-get-rmdir)
|
2010-08-13 03:00:15 +08:00
|
|
|
|
:bzr (:install el-get-bzr-branch
|
|
|
|
|
:install-hook el-get-bzr-branch-hook
|
|
|
|
|
:update el-get-bzr-pull
|
|
|
|
|
:remove el-get-rmdir)
|
2010-08-23 21:52:15 +08:00
|
|
|
|
:cvs (:install el-get-cvs-checkout
|
|
|
|
|
:install-hook el-get-cvs-checkout-hook
|
|
|
|
|
:update el-get-cvs-update
|
|
|
|
|
:remove el-get-rmdir)
|
2010-09-02 03:30:27 +08:00
|
|
|
|
:apt-get (:install el-get-apt-get-install
|
2010-06-28 03:13:22 +08:00
|
|
|
|
:install-hook el-get-apt-get-install-hook
|
|
|
|
|
:update el-get-apt-get-install
|
2010-08-05 03:57:42 +08:00
|
|
|
|
:remove el-get-apt-get-remove
|
|
|
|
|
:remove-hook el-get-apt-get-remove-hook)
|
2010-09-02 03:30:27 +08:00
|
|
|
|
:fink (:install el-get-fink-install
|
2010-06-29 17:23:46 +08:00
|
|
|
|
:install-hook el-get-fink-install-hook
|
|
|
|
|
:update el-get-fink-install
|
2010-08-05 03:57:42 +08:00
|
|
|
|
:remove el-get-fink-remove
|
|
|
|
|
:remove-hook el-get-fink-remove-hook)
|
2010-09-02 03:30:27 +08:00
|
|
|
|
:elpa (:install el-get-elpa-install
|
2010-06-28 03:13:22 +08:00
|
|
|
|
:install-hook el-get-elpa-install-hook
|
2010-06-29 00:35:15 +08:00
|
|
|
|
:update el-get-elpa-update
|
2010-06-28 03:13:22 +08:00
|
|
|
|
:remove el-get-rmdir)
|
|
|
|
|
:http (:install el-get-http-install
|
|
|
|
|
:install-hook el-get-http-install-hook
|
|
|
|
|
:update el-get-http-install
|
2010-08-23 06:19:47 +08:00
|
|
|
|
:remove el-get-rmdir)
|
2010-09-02 03:48:50 +08:00
|
|
|
|
:emacswiki (:install el-get-emacswiki-install
|
|
|
|
|
:install-hook el-get-http-install-hook
|
|
|
|
|
:update el-get-emacswiki-install
|
|
|
|
|
:remove el-get-rmdir)
|
2010-08-23 06:19:47 +08:00
|
|
|
|
:http-tar (:install el-get-http-tar-install
|
|
|
|
|
:install-hook el-get-http-tar-install-hook
|
|
|
|
|
:update el-get-http-tar-install
|
2010-06-28 03:13:22 +08:00
|
|
|
|
:remove el-get-rmdir))
|
2010-06-29 17:12:58 +08:00
|
|
|
|
"Register methods that el-get can use to fetch and update a given package.
|
2010-06-19 04:21:02 +08:00
|
|
|
|
|
2010-06-29 17:12:58 +08:00
|
|
|
|
The methods list is a PLIST, each entry has a method name
|
|
|
|
|
property which value is another PLIST, which must contain values
|
|
|
|
|
for :install, :install-hook, :update and :remove
|
|
|
|
|
properties. Those should be the elisp functions to call for doing
|
|
|
|
|
the named package action in the given method."
|
2010-06-19 04:21:02 +08:00
|
|
|
|
:type '(repeat (cons symbol function))
|
|
|
|
|
:group 'el-get)
|
|
|
|
|
|
|
|
|
|
(defvar el-get-dir "~/.emacs.d/el-get/"
|
|
|
|
|
"Define where to fetch the packages.")
|
|
|
|
|
|
2010-09-01 23:39:38 +08:00
|
|
|
|
(defvar el-get-recipe-path '("~/.emacs.d/el-get/el-get/recipes")
|
2010-08-31 04:59:05 +08:00
|
|
|
|
"Define where to look for the recipes")
|
|
|
|
|
|
2010-09-02 05:39:39 +08:00
|
|
|
|
(defvar el-get-status-file
|
|
|
|
|
(concat (file-name-as-directory el-get-dir) ".status.el")
|
|
|
|
|
"Define where to store and read the package statuses")
|
|
|
|
|
|
2010-06-29 17:23:46 +08:00
|
|
|
|
(defvar el-get-apt-get (executable-find "apt-get")
|
2010-06-19 04:21:02 +08:00
|
|
|
|
"The apt-get executable.")
|
|
|
|
|
|
2010-07-08 02:11:45 +08:00
|
|
|
|
(defvar el-get-apt-get-base "/usr/share/emacs/site-lisp"
|
|
|
|
|
"Where to link the el-get symlink to, /<package> will get appended.")
|
|
|
|
|
|
2010-06-29 17:23:46 +08:00
|
|
|
|
(defvar el-get-fink (executable-find "fink")
|
|
|
|
|
"The fink executable.")
|
|
|
|
|
|
2010-07-08 02:11:45 +08:00
|
|
|
|
(defvar el-get-fink-base "/sw/share/doc"
|
|
|
|
|
"Where to link the el-get symlink to, /<package> will get appended.")
|
|
|
|
|
|
2010-09-02 03:48:50 +08:00
|
|
|
|
(defvar el-get-emacswiki-base-url
|
|
|
|
|
"http://www.emacswiki.org/emacs/download/%s.el"
|
|
|
|
|
"The base URL where to fetch :emacswiki packages")
|
|
|
|
|
|
2010-06-29 22:57:13 +08:00
|
|
|
|
;; debian uses ginstall-info and it's compatible to fink's install-info on
|
|
|
|
|
;; MacOSX, so:
|
|
|
|
|
(defvar el-get-install-info (or (executable-find "ginstall-info")
|
|
|
|
|
(executable-find "install-info")))
|
|
|
|
|
|
2010-06-19 04:21:02 +08:00
|
|
|
|
(defvar el-get-sources nil
|
|
|
|
|
"List of sources for packages.
|
|
|
|
|
|
2010-09-01 23:44:31 +08:00
|
|
|
|
Each source entry is either a symbol, in which case the first
|
|
|
|
|
recipe found in `el-get-recipe-path' directories named after the
|
|
|
|
|
symbol with a \".el\" extension will get used, or a PLIST where
|
|
|
|
|
the following properties are supported.
|
|
|
|
|
|
|
|
|
|
If your property list is missing the :type property, then it's
|
|
|
|
|
merged with the recipe one, so that you can override any
|
|
|
|
|
definition provided by `el-get' recipes locally.
|
2010-06-28 03:13:22 +08:00
|
|
|
|
|
2010-09-02 02:06:49 +08:00
|
|
|
|
:name
|
2010-06-29 17:12:58 +08:00
|
|
|
|
|
|
|
|
|
The name of the package. It can be different from the name of
|
|
|
|
|
the directory where the package is stored (after a `git
|
|
|
|
|
clone' for example, in which case a symlink will be created.
|
|
|
|
|
|
2010-09-02 02:06:49 +08:00
|
|
|
|
:type
|
2010-06-29 17:12:58 +08:00
|
|
|
|
|
|
|
|
|
The type of the package, currently el-get offers support for
|
|
|
|
|
`apt-get', `elpa', `git' and `http'. You can easily support
|
|
|
|
|
your own types here, see the variable `el-get-methods'.
|
|
|
|
|
|
2010-09-02 02:06:49 +08:00
|
|
|
|
:url
|
2010-06-29 17:12:58 +08:00
|
|
|
|
|
|
|
|
|
Where to fetch the package, only meaningful for `git' and `http' types.
|
|
|
|
|
|
2010-09-02 02:06:49 +08:00
|
|
|
|
:build
|
2010-06-29 17:12:58 +08:00
|
|
|
|
|
|
|
|
|
Your build recipe gets there, often it looks like (\"./configure\" \"make\")
|
|
|
|
|
|
2010-09-02 02:06:49 +08:00
|
|
|
|
:load-path
|
2010-06-29 17:12:58 +08:00
|
|
|
|
|
|
|
|
|
This should be a list of directories you want `el-get' to add
|
|
|
|
|
to your `load-path'.
|
|
|
|
|
|
2010-09-02 02:06:49 +08:00
|
|
|
|
:info
|
2010-06-29 17:12:58 +08:00
|
|
|
|
|
|
|
|
|
This string allows you to setup a directory where to find a
|
2010-07-28 18:36:53 +08:00
|
|
|
|
'package.info' file, or a path/to/whatever.info file. It will
|
|
|
|
|
even run `ginstall-info' for you to create the `dir' entry so
|
|
|
|
|
that C-h i will be able to list the newly installed
|
|
|
|
|
documentation. Note that you might need to kill (C-x k) your
|
|
|
|
|
info buffer then C-h i again to be able to see the new menu
|
|
|
|
|
entry.
|
2010-06-29 17:12:58 +08:00
|
|
|
|
|
2010-09-02 02:06:49 +08:00
|
|
|
|
:load
|
2010-06-30 05:16:13 +08:00
|
|
|
|
|
|
|
|
|
List of files to load, or a single file to load after having
|
|
|
|
|
installed the source but before `require'ing its features.
|
|
|
|
|
|
2010-09-02 02:06:49 +08:00
|
|
|
|
:features
|
2010-06-29 17:12:58 +08:00
|
|
|
|
|
|
|
|
|
List of features el-get will `require' for you.
|
2010-08-23 21:12:30 +08:00
|
|
|
|
|
2010-09-02 02:06:49 +08:00
|
|
|
|
:options
|
2010-08-23 21:12:30 +08:00
|
|
|
|
|
|
|
|
|
Currently only used by the http-tar support for you to give
|
|
|
|
|
the tar options you want to use. Typically would be \"xzf\",
|
|
|
|
|
but you might want to choose \"xjf\" for handling .tar.bz
|
|
|
|
|
files e.g.
|
|
|
|
|
|
2010-09-02 02:06:49 +08:00
|
|
|
|
:module
|
2010-08-23 21:52:15 +08:00
|
|
|
|
|
|
|
|
|
Currently only used by the `csv' support, allow you to
|
|
|
|
|
configure the module you want to checkout in the given URL.
|
|
|
|
|
|
2010-09-02 02:06:49 +08:00
|
|
|
|
:after
|
2010-08-23 21:12:30 +08:00
|
|
|
|
|
|
|
|
|
A function to run once `el-get' is done with `el-get-init',
|
|
|
|
|
can be a lambda.
|
2010-06-29 17:12:58 +08:00
|
|
|
|
")
|
2010-06-28 03:13:22 +08:00
|
|
|
|
|
2010-07-30 17:16:56 +08:00
|
|
|
|
|
2010-06-28 03:13:22 +08:00
|
|
|
|
(defun el-get-method (method-name action)
|
2010-09-02 02:00:49 +08:00
|
|
|
|
"Return the function to call for doing action (e.g. install) in
|
|
|
|
|
given method."
|
2010-06-28 03:13:22 +08:00
|
|
|
|
(let* ((method (intern-soft (concat ":" (format "%s" method-name))))
|
|
|
|
|
(actions (plist-get el-get-methods method)))
|
|
|
|
|
(plist-get actions action)))
|
2010-06-19 04:21:02 +08:00
|
|
|
|
|
|
|
|
|
(defun el-get-check-init ()
|
2010-09-02 02:00:49 +08:00
|
|
|
|
"Check that we can run el-get."
|
2010-06-19 04:21:02 +08:00
|
|
|
|
(unless (file-directory-p el-get-dir)
|
|
|
|
|
(make-directory el-get-dir)))
|
|
|
|
|
|
2010-06-28 03:13:22 +08:00
|
|
|
|
(defun el-get-package-directory (package)
|
2010-09-02 02:00:49 +08:00
|
|
|
|
"Returns the package installation directory absolute name."
|
2010-06-28 03:13:22 +08:00
|
|
|
|
(concat (file-name-as-directory el-get-dir) package))
|
|
|
|
|
|
|
|
|
|
(defun el-get-add-path-to-list (package list path)
|
2010-09-02 02:00:49 +08:00
|
|
|
|
"(add-to-list LIST PATH) checking for path existence within
|
2010-06-28 03:13:22 +08:00
|
|
|
|
given package directory."
|
2010-06-28 23:03:42 +08:00
|
|
|
|
(let* ((pdir (el-get-package-directory package))
|
2010-08-02 22:42:52 +08:00
|
|
|
|
(fullpath (expand-file-name (concat (file-name-as-directory pdir) path))))
|
2010-06-28 03:13:22 +08:00
|
|
|
|
(unless (file-directory-p fullpath)
|
2010-08-27 05:32:00 +08:00
|
|
|
|
(error "el-get could not find directory `%s' for package %s, at %s" path package fullpath))
|
2010-06-28 03:13:22 +08:00
|
|
|
|
(add-to-list list fullpath)))
|
|
|
|
|
|
2010-06-19 04:21:02 +08:00
|
|
|
|
(defun el-get-package-exists-p (package)
|
2010-09-02 02:00:49 +08:00
|
|
|
|
"Return true only when the given package name is either a
|
|
|
|
|
directory or a symlink in el-get-dir."
|
2010-06-29 00:35:15 +08:00
|
|
|
|
(let ((pdir (el-get-package-directory package)))
|
2010-06-19 04:21:02 +08:00
|
|
|
|
;; seems overkill as file-directory-p will always be true
|
|
|
|
|
(or (file-directory-p pdir)
|
|
|
|
|
(file-symlink-p pdir))))
|
|
|
|
|
|
2010-08-02 23:23:55 +08:00
|
|
|
|
|
|
|
|
|
;;
|
|
|
|
|
;; call-process-list utility, to do same as bash && feature
|
|
|
|
|
;;
|
2010-08-04 16:11:35 +08:00
|
|
|
|
(defun el-get-start-process-list-sentinel (proc change)
|
2010-09-02 02:00:49 +08:00
|
|
|
|
"When proc has exited and was successful, chain next command."
|
2010-08-02 23:23:55 +08:00
|
|
|
|
(when (eq (process-status proc) 'exit)
|
|
|
|
|
(let ((status (process-exit-status proc))
|
|
|
|
|
(cname (process-get proc :command-name))
|
2010-08-04 00:07:17 +08:00
|
|
|
|
(cbuf (process-get proc :buffer-name))
|
2010-08-02 23:23:55 +08:00
|
|
|
|
(message (process-get proc :message))
|
|
|
|
|
(errorm (process-get proc :error))
|
2010-08-04 03:35:04 +08:00
|
|
|
|
(package (process-get proc :el-get-package))
|
|
|
|
|
(final-f (process-get proc :el-get-final-func))
|
2010-08-04 16:11:35 +08:00
|
|
|
|
(next (process-get proc :el-get-start-process-list)))
|
2010-08-02 23:23:55 +08:00
|
|
|
|
(if (not (eq 0 status))
|
2010-08-04 00:17:42 +08:00
|
|
|
|
(progn
|
2010-08-05 00:25:52 +08:00
|
|
|
|
(when (process-buffer proc)
|
|
|
|
|
(set-window-buffer (selected-window) cbuf))
|
2010-08-04 03:35:04 +08:00
|
|
|
|
(error "el-get: %s" cname errorm))
|
|
|
|
|
(message "el-get: %s" message))
|
2010-09-02 03:30:27 +08:00
|
|
|
|
|
2010-08-04 00:07:17 +08:00
|
|
|
|
(when cbuf (kill-buffer cbuf))
|
2010-08-04 03:35:04 +08:00
|
|
|
|
(if next
|
2010-08-04 16:11:35 +08:00
|
|
|
|
(el-get-start-process-list package next final-f)
|
2010-08-23 22:54:12 +08:00
|
|
|
|
(when (functionp final-f)
|
|
|
|
|
(funcall final-f package))))))
|
2010-08-02 23:23:55 +08:00
|
|
|
|
|
2010-08-04 16:11:35 +08:00
|
|
|
|
(defun el-get-start-process-list (package commands final-func)
|
2010-09-02 02:00:49 +08:00
|
|
|
|
"Run each command one after the other, in order, stopping at
|
2010-08-02 23:23:55 +08:00
|
|
|
|
first error.
|
|
|
|
|
|
2010-09-02 02:00:49 +08:00
|
|
|
|
Commands should be a list of plists with at least the following
|
2010-08-02 23:23:55 +08:00
|
|
|
|
properties:
|
|
|
|
|
|
|
|
|
|
:default-directory
|
|
|
|
|
|
|
|
|
|
default-directory from where to start the command
|
|
|
|
|
|
|
|
|
|
:command-name
|
|
|
|
|
|
|
|
|
|
Name of the command to start, gives the name of the Emacs subprocess.
|
|
|
|
|
|
|
|
|
|
:buffer-name
|
|
|
|
|
|
|
|
|
|
Name of the buffer associated with the command.
|
|
|
|
|
|
2010-08-05 00:27:14 +08:00
|
|
|
|
:process-filter
|
|
|
|
|
|
|
|
|
|
Function to use as a process filter.
|
|
|
|
|
|
2010-08-24 23:37:06 +08:00
|
|
|
|
:shell
|
|
|
|
|
|
|
|
|
|
When set to a non-nil value, use start-process-shell-command
|
|
|
|
|
rather than the default start-process.
|
|
|
|
|
|
2010-08-02 23:23:55 +08:00
|
|
|
|
:program
|
|
|
|
|
|
|
|
|
|
The program to start
|
|
|
|
|
|
|
|
|
|
:args
|
|
|
|
|
|
|
|
|
|
The list of arguments for the program to start
|
|
|
|
|
|
|
|
|
|
:message
|
|
|
|
|
|
|
|
|
|
The message to send upon success
|
|
|
|
|
|
|
|
|
|
:error
|
|
|
|
|
|
|
|
|
|
The error to send upon failure
|
|
|
|
|
|
|
|
|
|
Any other property will get put into the process object.
|
|
|
|
|
"
|
2010-08-23 22:53:31 +08:00
|
|
|
|
(when commands
|
|
|
|
|
(let* ((c (car commands))
|
|
|
|
|
(cdir (plist-get c :default-directory))
|
|
|
|
|
(cname (plist-get c :command-name))
|
|
|
|
|
(cbuf (plist-get c :buffer-name))
|
|
|
|
|
(killed (when (get-buffer cbuf) (kill-buffer cbuf)))
|
|
|
|
|
(filter (plist-get c :process-filter))
|
|
|
|
|
(program (plist-get c :program))
|
|
|
|
|
(args (plist-get c :args))
|
2010-08-24 23:37:06 +08:00
|
|
|
|
(shell (plist-get c :shell))
|
|
|
|
|
(startf (if shell #'start-process-shell-command #'start-process))
|
2010-09-02 03:30:27 +08:00
|
|
|
|
(default-directory (if cdir
|
|
|
|
|
(file-name-as-directory
|
2010-09-01 04:17:52 +08:00
|
|
|
|
(expand-file-name cdir))
|
2010-08-23 22:53:31 +08:00
|
|
|
|
default-directory))
|
2010-08-24 23:37:06 +08:00
|
|
|
|
(proc (apply startf cname cbuf program args)))
|
2010-08-23 22:53:31 +08:00
|
|
|
|
|
|
|
|
|
;; add the properties to the process, then set the sentinel
|
|
|
|
|
(mapc (lambda (x) (process-put proc x (plist-get c x))) c)
|
|
|
|
|
(process-put proc :el-get-package package)
|
|
|
|
|
(process-put proc :el-get-final-func final-func)
|
|
|
|
|
(process-put proc :el-get-start-process-list (cdr commands))
|
|
|
|
|
(set-process-sentinel proc 'el-get-start-process-list-sentinel)
|
|
|
|
|
(when filter (set-process-filter proc filter)))))
|
2010-08-02 23:23:55 +08:00
|
|
|
|
|
2010-07-30 17:16:56 +08:00
|
|
|
|
|
2010-06-29 00:35:15 +08:00
|
|
|
|
;;
|
|
|
|
|
;; git support
|
|
|
|
|
;;
|
2010-08-02 23:23:55 +08:00
|
|
|
|
(defun el-get-git-executable ()
|
2010-09-02 02:00:49 +08:00
|
|
|
|
"Return git executable to use, or signal an error when not
|
|
|
|
|
found."
|
2010-08-04 17:21:53 +08:00
|
|
|
|
(let ((git-executable (if (and (boundp 'magit-git-executable)
|
|
|
|
|
(file-executable-p magit-git-executable))
|
2010-06-29 16:39:02 +08:00
|
|
|
|
magit-git-executable
|
|
|
|
|
(executable-find "git"))))
|
|
|
|
|
(unless (file-executable-p git-executable)
|
2010-09-02 03:30:27 +08:00
|
|
|
|
(error
|
2010-08-04 03:23:26 +08:00
|
|
|
|
(concat "el-get-git-clone requires `magit-git-executable' to be set, "
|
|
|
|
|
"or the binary `git' to be found in your PATH")))
|
2010-08-02 23:23:55 +08:00
|
|
|
|
git-executable))
|
2010-06-19 04:21:02 +08:00
|
|
|
|
|
2010-08-04 04:01:45 +08:00
|
|
|
|
(defun el-get-git-clone (package url post-install-fun)
|
2010-09-02 02:00:49 +08:00
|
|
|
|
"Clone the given package following the URL."
|
2010-08-02 23:23:55 +08:00
|
|
|
|
(let* ((git-executable (el-get-git-executable))
|
2010-08-04 04:01:45 +08:00
|
|
|
|
(name (format "*git clone %s*" package))
|
|
|
|
|
(ok (format "Package %s installed." package))
|
|
|
|
|
(ko (format "Could not install package %s." package)))
|
|
|
|
|
|
2010-09-02 03:30:27 +08:00
|
|
|
|
(el-get-start-process-list
|
2010-08-04 04:01:45 +08:00
|
|
|
|
package
|
|
|
|
|
`((:command-name ,name
|
|
|
|
|
:buffer-name ,name
|
|
|
|
|
:default-directory ,el-get-dir
|
|
|
|
|
:program ,git-executable
|
|
|
|
|
:args ( "--no-pager" "clone" ,url ,package)
|
|
|
|
|
:message ,ok
|
|
|
|
|
:error ,ko))
|
|
|
|
|
post-install-fun)))
|
|
|
|
|
|
|
|
|
|
(defun el-get-git-pull (package url post-update-fun)
|
2010-09-02 02:00:49 +08:00
|
|
|
|
"git pull the package."
|
2010-08-04 04:01:45 +08:00
|
|
|
|
(let* ((git-executable (el-get-git-executable))
|
|
|
|
|
(pdir (el-get-package-directory package))
|
|
|
|
|
(name (format "*git pull %s*" package))
|
|
|
|
|
(ok (format "Pulled package %s." package))
|
|
|
|
|
(ko (format "Could not update package %s." package)))
|
|
|
|
|
|
2010-09-02 03:30:27 +08:00
|
|
|
|
(el-get-start-process-list
|
2010-08-04 04:01:45 +08:00
|
|
|
|
package
|
|
|
|
|
`((:command-name ,name
|
|
|
|
|
:buffer-name ,name
|
|
|
|
|
:default-directory ,pdir
|
|
|
|
|
:program ,git-executable
|
|
|
|
|
:args ( "--no-pager" "pull")
|
|
|
|
|
:message ,ok
|
|
|
|
|
:error ,ko))
|
|
|
|
|
post-update-fun)))
|
2010-06-19 04:21:02 +08:00
|
|
|
|
|
2010-08-02 19:32:59 +08:00
|
|
|
|
|
|
|
|
|
;;
|
|
|
|
|
;; git-svn support
|
|
|
|
|
;;
|
2010-08-04 03:35:04 +08:00
|
|
|
|
(defun el-get-git-svn-clone (package url post-install-fun)
|
2010-08-02 19:32:59 +08:00
|
|
|
|
"Clone the given svn PACKAGE following the URL using git."
|
2010-08-02 23:23:55 +08:00
|
|
|
|
(let ((git-executable (el-get-git-executable))
|
|
|
|
|
(name (format "*git svn clone %s*" package))
|
|
|
|
|
(ok (format "Package %s installed." package))
|
|
|
|
|
(ko (format "Could not install package %s." package)))
|
|
|
|
|
|
2010-09-02 03:30:27 +08:00
|
|
|
|
(el-get-start-process-list
|
2010-08-04 03:35:04 +08:00
|
|
|
|
package
|
2010-08-04 00:07:17 +08:00
|
|
|
|
`((:command-name ,name
|
|
|
|
|
:buffer-name ,name
|
2010-08-04 03:35:04 +08:00
|
|
|
|
:default-directory ,el-get-dir
|
2010-08-04 00:07:17 +08:00
|
|
|
|
:program ,git-executable
|
|
|
|
|
:args ( "--no-pager" "svn" "clone" ,url ,package)
|
|
|
|
|
:message ,ok
|
2010-08-04 03:35:04 +08:00
|
|
|
|
:error ,ko))
|
|
|
|
|
post-install-fun)))
|
2010-08-02 19:32:59 +08:00
|
|
|
|
|
2010-08-04 03:35:04 +08:00
|
|
|
|
(defun el-get-git-svn-update (package url post-update-fun)
|
2010-08-02 19:32:59 +08:00
|
|
|
|
"Update PACKAGE using git-svn. URL is given for compatibility reasons."
|
2010-08-04 00:07:17 +08:00
|
|
|
|
(let ((git-executable (el-get-git-executable))
|
|
|
|
|
(pdir (el-get-package-directory package))
|
2010-08-02 23:23:55 +08:00
|
|
|
|
(f-name (format "*git svn fetch %s*" package))
|
|
|
|
|
(f-ok (format "Fetched package %s." package))
|
|
|
|
|
(f-ko (format "Could not fetch package %s." package))
|
|
|
|
|
(r-name (format "*git svn rebase %s*" package))
|
|
|
|
|
(r-ok (format "Rebased package %s." package))
|
|
|
|
|
(r-ko (format "Could not rebase package %s." package)))
|
|
|
|
|
|
2010-08-04 16:11:35 +08:00
|
|
|
|
(el-get-start-process-list
|
2010-08-04 03:35:04 +08:00
|
|
|
|
package
|
2010-08-02 23:23:55 +08:00
|
|
|
|
`((:command-name ,f-name
|
|
|
|
|
:buffer-name ,f-name
|
2010-08-04 00:07:17 +08:00
|
|
|
|
:default-directory ,pdir
|
2010-08-02 23:23:55 +08:00
|
|
|
|
:program ,git-executable
|
|
|
|
|
:args ("--no-pager" "svn" "fetch")
|
|
|
|
|
:message ,f-ok
|
|
|
|
|
:error ,f-ko)
|
2010-09-02 03:30:27 +08:00
|
|
|
|
|
2010-08-02 23:23:55 +08:00
|
|
|
|
(:command-name ,r-name
|
|
|
|
|
:buffer-name ,r-name
|
2010-08-04 00:07:17 +08:00
|
|
|
|
:default-directory ,pdir
|
2010-08-02 23:23:55 +08:00
|
|
|
|
:program ,git-executable
|
|
|
|
|
:args ("--no-pager" "svn" "rebase")
|
|
|
|
|
:message ,r-ok
|
2010-08-04 03:35:04 +08:00
|
|
|
|
:error ,r-ko))
|
|
|
|
|
post-update-fun)))
|
|
|
|
|
|
2010-08-13 03:00:15 +08:00
|
|
|
|
|
|
|
|
|
;;
|
|
|
|
|
;; bzr support
|
|
|
|
|
;;
|
|
|
|
|
(defun el-get-bzr-branch (package url post-install-fun)
|
|
|
|
|
"Branch a given bzr PACKAGE following the URL using bzr."
|
|
|
|
|
(let* ((bzr-executable "bzr")
|
|
|
|
|
(name (format "*bzr branch %s*" package))
|
|
|
|
|
(ok (format "Package %s installed" package))
|
|
|
|
|
(ko (format "Could not install package %s." package)))
|
|
|
|
|
(el-get-start-process-list
|
|
|
|
|
package
|
|
|
|
|
`((:command-name ,name
|
|
|
|
|
:buffer-name ,name
|
|
|
|
|
:default-directory ,el-get-dir
|
|
|
|
|
:program ,bzr-executable
|
|
|
|
|
:args ("branch" ,url ,package)
|
|
|
|
|
:message ,ok
|
|
|
|
|
:error ,ko))
|
|
|
|
|
post-install-fun)))
|
|
|
|
|
|
|
|
|
|
(defun el-get-bzr-pull (package url post-update-fun)
|
2010-09-02 02:00:49 +08:00
|
|
|
|
"bzr pull the package."
|
2010-08-13 03:00:15 +08:00
|
|
|
|
(let* ((bzr-executable "bzr")
|
|
|
|
|
(pdir (el-get-package-directory package))
|
|
|
|
|
(name (format "*bzr pull %s*" package))
|
|
|
|
|
(ok (format "Pulled package %s." package))
|
|
|
|
|
(ko (format "Could not update package %s." package)))
|
|
|
|
|
|
|
|
|
|
(el-get-start-process-list
|
|
|
|
|
package
|
|
|
|
|
`((:command-name ,name
|
|
|
|
|
:buffer-name ,name
|
|
|
|
|
:default-directory ,pdir
|
|
|
|
|
:program ,bzr-executable
|
|
|
|
|
:args ( "pull" )
|
|
|
|
|
:message ,ok
|
|
|
|
|
:error ,ko))
|
|
|
|
|
post-update-fun)))
|
|
|
|
|
|
2010-08-23 21:52:15 +08:00
|
|
|
|
|
|
|
|
|
(defun el-get-cvs-checkout (package url post-install-fun)
|
2010-09-02 02:00:49 +08:00
|
|
|
|
"cvs checkout the package."
|
2010-08-23 21:52:15 +08:00
|
|
|
|
(let* ((cvs-executable (executable-find "cvs"))
|
|
|
|
|
(source (el-get-package-def package))
|
|
|
|
|
(module (plist-get source :module))
|
|
|
|
|
(name (format "*cvs checkout %s*" package))
|
|
|
|
|
(ok (format "Checked out package %s." package))
|
|
|
|
|
(ko (format "Could not checkout package %s." package)))
|
|
|
|
|
|
|
|
|
|
(message "%S" `(:args ("-d" ,url "checkout" "-d" ,package ,module)))
|
|
|
|
|
|
|
|
|
|
(el-get-start-process-list
|
|
|
|
|
package
|
|
|
|
|
`((:command-name ,name
|
|
|
|
|
:buffer-name ,name
|
|
|
|
|
:default-directory ,el-get-dir
|
|
|
|
|
:program ,cvs-executable
|
|
|
|
|
:args ("-d" ,url "checkout" "-d" ,package ,module)
|
|
|
|
|
:message ,ok
|
|
|
|
|
:error ,ko))
|
|
|
|
|
post-install-fun)))
|
|
|
|
|
|
|
|
|
|
(defun el-get-cvs-update (package url post-update-fun)
|
2010-09-02 02:00:49 +08:00
|
|
|
|
"cvs checkout the package."
|
2010-08-23 21:52:15 +08:00
|
|
|
|
(let* ((cvs-executable (executable-find "cvs"))
|
|
|
|
|
(pdir (el-get-package-directory package))
|
|
|
|
|
(name (format "*cvs update %s*" package))
|
|
|
|
|
(ok (format "Updated package %s." package))
|
|
|
|
|
(ko (format "Could not update package %s." package)))
|
|
|
|
|
|
|
|
|
|
(el-get-start-process-list
|
|
|
|
|
package
|
|
|
|
|
`((:command-name ,name
|
|
|
|
|
:buffer-name ,name
|
|
|
|
|
:default-directory ,pdir
|
|
|
|
|
:program ,cvs-executable
|
|
|
|
|
:args ("update" "-dP")
|
|
|
|
|
:message ,ok
|
|
|
|
|
:error ,ko))
|
|
|
|
|
post-update-fun)))
|
2010-08-13 03:00:15 +08:00
|
|
|
|
|
2010-07-30 17:16:56 +08:00
|
|
|
|
|
2010-06-29 00:35:15 +08:00
|
|
|
|
;;
|
2010-08-05 03:57:42 +08:00
|
|
|
|
;; utilities for both apt-get and fink support (dpkg based)
|
2010-06-29 00:35:15 +08:00
|
|
|
|
;;
|
2010-08-05 03:57:42 +08:00
|
|
|
|
(defun el-get-dpkg-package-status (package)
|
2010-09-02 02:00:49 +08:00
|
|
|
|
"Return the package status from dpkg --get-selections."
|
2010-09-02 03:30:27 +08:00
|
|
|
|
(substring
|
|
|
|
|
(shell-command-to-string
|
2010-08-05 03:57:42 +08:00
|
|
|
|
(format
|
|
|
|
|
"dpkg -l %s| awk '/^ii/ && $2 = \"%s\" {print \"ok\"}'" package package)) 0 -1))
|
|
|
|
|
|
|
|
|
|
;;
|
|
|
|
|
;; those functions are meant as hooks at install and remove, and they will
|
|
|
|
|
;; get the global value of package, which has been set before calling
|
|
|
|
|
;; run-hooks.
|
|
|
|
|
;;
|
|
|
|
|
(defun el-get-dpkg-symlink ()
|
2010-06-29 19:35:32 +08:00
|
|
|
|
"ln -s /usr/share/emacs/site-lisp/package ~/.emacs.d/el-get/package"
|
2010-08-05 00:28:28 +08:00
|
|
|
|
(let* ((pdir (el-get-package-directory package))
|
2010-08-05 03:57:42 +08:00
|
|
|
|
(method (plist-get source :type))
|
|
|
|
|
(basedir (cond ((eq method 'apt-get) el-get-apt-get-base)
|
|
|
|
|
((eq method 'fink) el-get-fink-base)))
|
|
|
|
|
(debdir (concat (file-name-as-directory basedir) package)))
|
2010-08-05 00:28:28 +08:00
|
|
|
|
(unless (file-directory-p pdir)
|
2010-09-02 04:20:58 +08:00
|
|
|
|
(shell-command
|
2010-08-05 00:28:28 +08:00
|
|
|
|
(concat "cd " el-get-dir " && ln -s " debdir " " package)))))
|
|
|
|
|
|
2010-08-05 03:57:42 +08:00
|
|
|
|
(defun el-get-dpkg-remove-symlink ()
|
|
|
|
|
"rm -f ~/.emacs.d/el-get/package"
|
|
|
|
|
(let* ((pdir (el-get-package-directory package)))
|
|
|
|
|
(message "PHOQUE %S" pdir)
|
|
|
|
|
(when (file-symlink-p pdir)
|
|
|
|
|
(message (concat "cd " el-get-dir " && rm -f " package))
|
2010-09-02 04:20:58 +08:00
|
|
|
|
(shell-command
|
2010-08-05 03:57:42 +08:00
|
|
|
|
(concat "cd " el-get-dir " && rm -f " package)))))
|
2010-06-29 19:35:32 +08:00
|
|
|
|
|
2010-08-05 03:57:42 +08:00
|
|
|
|
|
|
|
|
|
;;
|
|
|
|
|
;; apt-get support
|
|
|
|
|
;;
|
2010-08-05 19:41:29 +08:00
|
|
|
|
(add-hook 'el-get-apt-get-install-hook 'el-get-dpkg-symlink)
|
2010-06-29 20:04:35 +08:00
|
|
|
|
|
2010-08-05 00:27:14 +08:00
|
|
|
|
(defun el-get-sudo-password-process-filter (proc string)
|
2010-09-02 02:00:49 +08:00
|
|
|
|
"Filter function that fills the process buffer's and matches a
|
|
|
|
|
password prompt."
|
2010-08-05 00:27:14 +08:00
|
|
|
|
(unless (eq (process-status proc) 'exit)
|
|
|
|
|
(with-current-buffer (process-buffer proc)
|
|
|
|
|
;; arrange to remember already seen content
|
|
|
|
|
(unless (boundp 'el-get-sudo-password-process-filter-pos)
|
|
|
|
|
(make-local-variable 'el-get-sudo-password-process-filter-pos)
|
|
|
|
|
(setq el-get-sudo-password-process-filter-pos (point-min)))
|
|
|
|
|
|
|
|
|
|
(save-excursion
|
|
|
|
|
(goto-char (point-max))
|
|
|
|
|
(insert string)
|
|
|
|
|
;; redirect the subprocess sudo prompt to the user face, and answer it
|
|
|
|
|
(goto-char el-get-sudo-password-process-filter-pos)
|
2010-08-25 17:13:55 +08:00
|
|
|
|
(while (re-search-forward "password" nil t)
|
2010-08-05 00:27:14 +08:00
|
|
|
|
(let* ((prompt (thing-at-point 'line))
|
|
|
|
|
(pass (read-passwd prompt)))
|
|
|
|
|
(process-send-string proc (concat pass "\n"))))
|
|
|
|
|
(setq el-get-sudo-password-process-filter-pos (point-max))))))
|
|
|
|
|
|
|
|
|
|
(defun el-get-apt-get-install (package url post-install-fun)
|
2010-09-02 02:00:49 +08:00
|
|
|
|
"echo $pass | sudo -S apt-get install PACKAGE"
|
2010-08-05 00:27:14 +08:00
|
|
|
|
(let* ((name (format "*apt-get install %s*" package))
|
|
|
|
|
(ok (format "Package %s installed." package))
|
|
|
|
|
(ko (format "Could not install package %s." package)))
|
2010-09-02 03:30:27 +08:00
|
|
|
|
|
2010-08-05 00:27:14 +08:00
|
|
|
|
(el-get-start-process-list
|
|
|
|
|
package
|
|
|
|
|
`((:command-name ,name
|
|
|
|
|
:buffer-name ,name
|
|
|
|
|
:process-filter ,(function el-get-sudo-password-process-filter)
|
|
|
|
|
:program ,(executable-find "sudo")
|
|
|
|
|
:args ("-S" ,(executable-find "apt-get") "install" ,package)
|
|
|
|
|
:message ,ok
|
|
|
|
|
:error ,ko))
|
|
|
|
|
post-install-fun)))
|
2010-06-19 04:21:02 +08:00
|
|
|
|
|
2010-08-05 03:56:40 +08:00
|
|
|
|
(defun el-get-apt-get-remove (package url post-remove-fun)
|
2010-09-02 02:00:49 +08:00
|
|
|
|
"apt-get remove PACKAGE, URL is there for API compliance"
|
2010-08-05 00:27:14 +08:00
|
|
|
|
(let* ((name (format "*apt-get remove %s*" package))
|
|
|
|
|
(ok (format "Package %s removed." package))
|
|
|
|
|
(ko (format "Could not remove package %s." package)))
|
2010-09-02 03:30:27 +08:00
|
|
|
|
|
2010-08-05 00:27:14 +08:00
|
|
|
|
(el-get-start-process-list
|
|
|
|
|
package
|
|
|
|
|
`((:command-name ,name
|
|
|
|
|
:buffer-name ,name
|
|
|
|
|
:process-filter ,(function el-get-sudo-password-process-filter)
|
|
|
|
|
:program ,(executable-find "sudo")
|
|
|
|
|
:args ("-S" ,(executable-find "apt-get") "remove" "-y" ,package)
|
|
|
|
|
:message ,ok
|
|
|
|
|
:error ,ko))
|
2010-08-05 03:57:42 +08:00
|
|
|
|
post-remove-fun)))
|
|
|
|
|
|
|
|
|
|
(add-hook 'el-get-apt-get-remove-hook 'el-get-dpkg-remove-symlink)
|
2010-06-19 04:21:02 +08:00
|
|
|
|
|
2010-07-30 17:16:56 +08:00
|
|
|
|
|
2010-06-29 17:23:46 +08:00
|
|
|
|
;;
|
|
|
|
|
;; fink support
|
|
|
|
|
;;
|
2010-08-05 03:57:42 +08:00
|
|
|
|
(defun el-get-fink-install (package url post-install-fun)
|
2010-09-02 02:00:49 +08:00
|
|
|
|
"sudo -S fink install PACKAGE"
|
2010-08-05 03:57:42 +08:00
|
|
|
|
(let* ((name (format "*fink install %s*" package))
|
|
|
|
|
(ok (format "Package %s installed." package))
|
|
|
|
|
(ko (format "Could not install package %s." package)))
|
2010-09-02 03:30:27 +08:00
|
|
|
|
|
2010-08-05 03:57:42 +08:00
|
|
|
|
(el-get-start-process-list
|
|
|
|
|
package
|
|
|
|
|
`((:command-name ,name
|
|
|
|
|
:buffer-name ,name
|
|
|
|
|
:process-filter ,(function el-get-sudo-password-process-filter)
|
|
|
|
|
:program ,(executable-find "sudo")
|
|
|
|
|
:args ("-S" ,(executable-find "fink") "install" ,package)
|
|
|
|
|
:message ,ok
|
|
|
|
|
:error ,ko))
|
|
|
|
|
post-install-fun)))
|
|
|
|
|
|
2010-08-05 19:41:29 +08:00
|
|
|
|
(add-hook 'el-get-fink-install-hook 'el-get-dpkg-symlink)
|
2010-08-05 03:57:42 +08:00
|
|
|
|
|
|
|
|
|
(defun el-get-fink-remove (package url post-remove-fun)
|
2010-09-02 02:00:49 +08:00
|
|
|
|
"apt-get remove PACKAGE. URL is there for API compliance."
|
2010-08-05 03:57:42 +08:00
|
|
|
|
(let* ((name (format "*fink remove %s*" package))
|
|
|
|
|
(ok (format "Package %s removed." package))
|
|
|
|
|
(ko (format "Could not remove package %s." package)))
|
2010-09-02 03:30:27 +08:00
|
|
|
|
|
2010-08-05 03:57:42 +08:00
|
|
|
|
(el-get-start-process-list
|
|
|
|
|
package
|
|
|
|
|
`((:command-name ,name
|
|
|
|
|
:buffer-name ,name
|
|
|
|
|
:process-filter ,(function el-get-sudo-password-process-filter)
|
|
|
|
|
:program ,(executable-find "sudo")
|
|
|
|
|
:args ("-S" ,(executable-find "fink") "-y" "remove" ,package)
|
|
|
|
|
:message ,ok
|
|
|
|
|
:error ,ko))
|
|
|
|
|
post-remove-fun)))
|
|
|
|
|
|
|
|
|
|
(add-hook 'el-get-fink-remove-hook 'el-get-dpkg-remove-symlink)
|
2010-06-29 17:23:46 +08:00
|
|
|
|
|
2010-07-30 17:16:56 +08:00
|
|
|
|
|
2010-06-29 00:35:15 +08:00
|
|
|
|
;;
|
|
|
|
|
;; ELPA support
|
|
|
|
|
;;
|
2010-06-29 03:57:59 +08:00
|
|
|
|
(defun el-get-elpa-package-directory (package)
|
2010-09-02 02:00:49 +08:00
|
|
|
|
"Return the directory where ELPA stores PACKAGE, or nil if
|
|
|
|
|
PACKAGE isn't currently installed by ELPA."
|
2010-06-29 03:57:59 +08:00
|
|
|
|
(let* ((pname (format "%s" package)) ; easy way to cope with symbols etc.
|
|
|
|
|
|
|
|
|
|
(l
|
2010-06-29 00:35:15 +08:00
|
|
|
|
;; we use try-completion to find the realname of the directory
|
|
|
|
|
;; ELPA used, and this wants an alist, we trick ls -i -1 into
|
|
|
|
|
;; that.
|
|
|
|
|
(mapcar 'split-string
|
|
|
|
|
(split-string
|
|
|
|
|
(shell-command-to-string
|
|
|
|
|
(concat "ls -i1 "
|
|
|
|
|
(file-name-as-directory package-user-dir))))))
|
|
|
|
|
|
2010-06-29 03:57:59 +08:00
|
|
|
|
(realname (try-completion pname l)))
|
|
|
|
|
|
2010-09-02 03:30:27 +08:00
|
|
|
|
(if realname (concat (file-name-as-directory package-user-dir) realname)
|
2010-06-29 03:57:59 +08:00
|
|
|
|
realname)))
|
2010-06-29 00:35:15 +08:00
|
|
|
|
|
2010-06-29 03:57:59 +08:00
|
|
|
|
(defun el-get-elpa-symlink-package (package)
|
|
|
|
|
"ln -s ~/.emacs.d/elpa/<package> ~/.emacs.d/el-get/<package>"
|
|
|
|
|
(let ((elpa-dir (el-get-elpa-package-directory package)))
|
2010-06-29 00:35:15 +08:00
|
|
|
|
(unless (el-get-package-exists-p package)
|
|
|
|
|
(shell-command
|
2010-09-02 03:30:27 +08:00
|
|
|
|
(concat "cd " el-get-dir
|
2010-06-29 03:57:59 +08:00
|
|
|
|
" && ln -s \"" elpa-dir "\" \"" package "\"")))))
|
2010-06-29 00:35:15 +08:00
|
|
|
|
|
2010-08-06 18:19:39 +08:00
|
|
|
|
(defun el-get-elpa-install (package url post-install-fun)
|
2010-09-02 02:00:49 +08:00
|
|
|
|
"Ask elpa to install given PACKAGE."
|
2010-06-29 03:57:59 +08:00
|
|
|
|
(let ((elpa-dir (el-get-elpa-package-directory package)))
|
|
|
|
|
(unless (and elpa-dir (file-directory-p elpa-dir))
|
|
|
|
|
(package-install (intern-soft package)))
|
|
|
|
|
;; we symlink even when the package already is installed because it's
|
|
|
|
|
;; not an error to have installed ELPA packages before using el-get, and
|
|
|
|
|
;; that will register them
|
2010-08-06 18:19:39 +08:00
|
|
|
|
(el-get-elpa-symlink-package package))
|
|
|
|
|
(funcall post-install-fun package))
|
|
|
|
|
|
|
|
|
|
(defun el-get-elpa-update (package url post-update-fun)
|
2010-09-02 02:00:49 +08:00
|
|
|
|
"Ask elpa to update given PACKAGE."
|
2010-08-12 20:40:32 +08:00
|
|
|
|
(el-get-rmdir (concat (file-name-as-directory package-user-dir) package nil))
|
2010-08-06 18:19:39 +08:00
|
|
|
|
(package-install (intern-soft package))
|
|
|
|
|
(funcall post-install-fun package))
|
2010-06-19 04:21:02 +08:00
|
|
|
|
|
2010-07-30 17:16:56 +08:00
|
|
|
|
|
2010-06-29 00:35:15 +08:00
|
|
|
|
;;
|
|
|
|
|
;; http support
|
|
|
|
|
;;
|
2010-08-31 19:57:07 +08:00
|
|
|
|
(defun el-get-http-retrieve-callback (url-arg package post-install-fun &optional dest)
|
2010-09-02 02:00:49 +08:00
|
|
|
|
"Callback function for `url-retrieve', store the emacs lisp file for the package.
|
2010-06-28 03:13:22 +08:00
|
|
|
|
|
2010-09-02 02:00:49 +08:00
|
|
|
|
URL-ARG is nil in my tests but `url-retrieve' seems to insist on
|
2010-08-06 18:19:39 +08:00
|
|
|
|
passing it the the callback function nonetheless."
|
2010-06-28 03:13:22 +08:00
|
|
|
|
(let* ((pdir (el-get-package-directory package))
|
2010-08-31 19:57:07 +08:00
|
|
|
|
(dest (or dest (concat (file-name-as-directory pdir) package ".el")))
|
|
|
|
|
(part (concat dest ".part")))
|
2010-08-06 18:19:39 +08:00
|
|
|
|
;; prune HTTP headers before save
|
|
|
|
|
(beginning-of-buffer)
|
|
|
|
|
(re-search-forward "^$" nil 'move)
|
|
|
|
|
(forward-char)
|
|
|
|
|
(delete-region (point-min) (point))
|
2010-08-31 19:57:07 +08:00
|
|
|
|
(write-file part)
|
|
|
|
|
(rename-file part dest)
|
|
|
|
|
(message "Renamed to %s" dest))
|
2010-08-12 20:40:15 +08:00
|
|
|
|
(funcall post-install-fun package))
|
2010-08-06 18:19:39 +08:00
|
|
|
|
|
2010-08-31 19:57:07 +08:00
|
|
|
|
(defun el-get-http-install (package url post-install-fun &optional dest)
|
2010-09-02 02:00:49 +08:00
|
|
|
|
"Dowload a single-file PACKAGE over HTTP and store it in DEST, or in PACKAGE.el"
|
2010-06-28 03:13:22 +08:00
|
|
|
|
(let ((pdir (el-get-package-directory package)))
|
2010-06-28 23:03:42 +08:00
|
|
|
|
(unless (file-directory-p pdir)
|
|
|
|
|
(make-directory pdir))
|
2010-09-02 03:30:27 +08:00
|
|
|
|
(url-retrieve
|
2010-08-31 19:57:07 +08:00
|
|
|
|
url 'el-get-http-retrieve-callback `(,package ,post-install-fun ,dest))))
|
2010-06-28 03:13:22 +08:00
|
|
|
|
|
2010-09-02 03:48:50 +08:00
|
|
|
|
|
|
|
|
|
;;
|
|
|
|
|
;; EmacsWiki support, which is http but with a known URL
|
|
|
|
|
;;
|
|
|
|
|
(defun el-get-emacswiki-install (package url post-install-fun)
|
|
|
|
|
"Download a single-file PACKAGE over HTTP from emacswiki."
|
|
|
|
|
(let ((url (or url (format el-get-emacswiki-base-url package))))
|
|
|
|
|
(el-get-http-install package url post-install-fun)))
|
|
|
|
|
|
2010-08-23 06:19:47 +08:00
|
|
|
|
|
|
|
|
|
;;
|
|
|
|
|
;; http-tar support (archive)
|
|
|
|
|
;;
|
|
|
|
|
(defun el-get-http-tar-cleanup-extract-hook ()
|
2010-09-02 02:00:49 +08:00
|
|
|
|
"Cleanup after tar xzf: if there's only one subdir, move all
|
|
|
|
|
the files up."
|
2010-08-23 06:19:47 +08:00
|
|
|
|
(let* ((pdir (el-get-package-directory package))
|
|
|
|
|
(url (plist-get source :url))
|
|
|
|
|
(tarfile (file-name-nondirectory url))
|
|
|
|
|
(files (directory-files pdir nil "[^.]$")))
|
|
|
|
|
;; if there's only one directory, move its content up and get rid of it
|
|
|
|
|
(message "%S" (remove tarfile files))
|
|
|
|
|
(when (null (cdr (remove tarfile files)))
|
|
|
|
|
(let ((move (format "cd %s && mv \"%s\"/* ." pdir (car files)))
|
|
|
|
|
(rmdir (format "cd %s && rmdir \"%s\"" pdir (car files))))
|
2010-08-23 21:10:12 +08:00
|
|
|
|
;; (message "%s: %s" package move)
|
|
|
|
|
;; (message "%s: %s" package rmdir)
|
2010-08-23 06:19:47 +08:00
|
|
|
|
(shell-command move)
|
|
|
|
|
(shell-command rmdir)))))
|
|
|
|
|
|
|
|
|
|
(defun el-get-http-tar-install (package url post-install-fun)
|
2010-09-02 02:00:49 +08:00
|
|
|
|
"Dowload a tar archive package over HTTP."
|
2010-08-23 06:19:47 +08:00
|
|
|
|
(let* ((source (el-get-package-def package))
|
|
|
|
|
(options (plist-get source :options))
|
|
|
|
|
(pdir (el-get-package-directory package))
|
|
|
|
|
(tarfile (file-name-nondirectory url))
|
2010-08-31 19:57:07 +08:00
|
|
|
|
(dest (concat (file-name-as-directory pdir) tarfile))
|
2010-08-23 06:19:47 +08:00
|
|
|
|
(name (format "*tar %s %s*" options url))
|
|
|
|
|
(ok (format "Package %s installed." package))
|
|
|
|
|
(ko (format "Could not install package %s." package))
|
|
|
|
|
(post `(lambda (package)
|
|
|
|
|
;; tar xzf `basename url`
|
|
|
|
|
(el-get-start-process-list
|
|
|
|
|
package
|
|
|
|
|
'((:command-name ,name
|
|
|
|
|
:buffer-name ,name
|
|
|
|
|
:default-directory ,pdir
|
|
|
|
|
:program ,(executable-find "tar")
|
|
|
|
|
:args (,@options ,tarfile)
|
|
|
|
|
:message ,ok
|
|
|
|
|
:error ,ko))
|
|
|
|
|
,(symbol-function post-install-fun)))))
|
2010-08-31 19:57:07 +08:00
|
|
|
|
(el-get-http-install package url post dest)))
|
2010-08-23 06:19:47 +08:00
|
|
|
|
|
|
|
|
|
(add-hook 'el-get-http-tar-install-hook 'el-get-http-tar-cleanup-extract-hook)
|
|
|
|
|
|
|
|
|
|
|
2010-06-29 00:35:15 +08:00
|
|
|
|
;;
|
|
|
|
|
;; Common support bits
|
|
|
|
|
;;
|
2010-08-12 20:40:15 +08:00
|
|
|
|
(defun el-get-rmdir (package url post-remove-fun)
|
2010-06-29 00:35:15 +08:00
|
|
|
|
"Just rm -rf the package directory. Follow symlinks."
|
2010-08-12 20:40:15 +08:00
|
|
|
|
(dired-delete-file (el-get-package-directory package) 'always)
|
|
|
|
|
(funcall post-remove-fun package))
|
2010-06-19 04:21:02 +08:00
|
|
|
|
|
2010-08-23 22:55:36 +08:00
|
|
|
|
(defun el-get-build (package commands &optional subdir sync post-build-fun)
|
2010-09-02 02:00:49 +08:00
|
|
|
|
"Run each command from the package directory."
|
2010-06-29 17:12:58 +08:00
|
|
|
|
(let* ((pdir (el-get-package-directory package))
|
2010-08-23 22:55:36 +08:00
|
|
|
|
(wdir (if subdir (concat (file-name-as-directory pdir) subdir) pdir))
|
2010-09-02 03:30:27 +08:00
|
|
|
|
(buf (format "*el-get-build: %s*" package))
|
2010-08-23 22:55:36 +08:00
|
|
|
|
(default-directory wdir))
|
|
|
|
|
(if sync
|
|
|
|
|
(progn
|
|
|
|
|
(dolist (c commands)
|
|
|
|
|
(message "el-get %s: cd %s && %s" package wdir c)
|
2010-09-02 03:30:27 +08:00
|
|
|
|
(message "%S" (shell-command-to-string
|
2010-08-23 22:55:36 +08:00
|
|
|
|
(concat "cd " wdir " && " c))))
|
|
|
|
|
(when (and post-build-fun (functionp post-build-fun))
|
|
|
|
|
(funcall post-build-fun)))
|
|
|
|
|
|
|
|
|
|
;; async
|
|
|
|
|
(let ((process-list
|
|
|
|
|
(mapcar (lambda (c)
|
|
|
|
|
(let* ((split (split-string c))
|
|
|
|
|
(name (car split))
|
|
|
|
|
(program (if (file-executable-p (expand-file-name name))
|
|
|
|
|
(expand-file-name name)
|
|
|
|
|
(executable-find name)))
|
|
|
|
|
(args (cdr split)))
|
2010-09-02 03:30:27 +08:00
|
|
|
|
|
2010-08-23 22:55:36 +08:00
|
|
|
|
`(:command-name ,name
|
|
|
|
|
:buffer-name ,buf
|
|
|
|
|
:default-directory ,wdir
|
2010-08-24 23:37:06 +08:00
|
|
|
|
:shell t
|
2010-08-23 22:55:36 +08:00
|
|
|
|
:program ,program
|
|
|
|
|
:args (,@args)
|
|
|
|
|
:message ,(format "el-get-build %s: %s ok." package c)
|
2010-09-02 03:30:27 +08:00
|
|
|
|
:error ,(format
|
2010-08-23 22:55:36 +08:00
|
|
|
|
"el-get could not build %s [%s]" package c))))
|
|
|
|
|
commands)))
|
|
|
|
|
(el-get-start-process-list package process-list post-build-fun)))))
|
2010-06-28 03:13:22 +08:00
|
|
|
|
|
2010-09-02 05:39:39 +08:00
|
|
|
|
|
|
|
|
|
;;
|
|
|
|
|
;; recipes
|
|
|
|
|
;;
|
2010-08-31 04:59:05 +08:00
|
|
|
|
(defun el-get-read-recipe (package)
|
2010-09-02 02:00:49 +08:00
|
|
|
|
"Return the source definition for PACKAGE, from the recipes."
|
2010-08-31 05:34:00 +08:00
|
|
|
|
(loop for dir in el-get-recipe-path
|
|
|
|
|
for recipe = (concat (file-name-as-directory dir) package ".el")
|
|
|
|
|
if (file-exists-p recipe)
|
2010-09-02 03:30:27 +08:00
|
|
|
|
return (car (with-temp-buffer
|
2010-08-31 05:34:00 +08:00
|
|
|
|
(insert-file-contents-literally recipe)
|
|
|
|
|
(read-from-string (buffer-string))))))
|
2010-08-31 04:59:05 +08:00
|
|
|
|
|
2010-09-01 02:46:12 +08:00
|
|
|
|
(defun el-get-source-name (source)
|
2010-09-02 02:00:49 +08:00
|
|
|
|
"Return the package name (stringp) given an `el-get-sources'
|
|
|
|
|
entry."
|
2010-09-01 02:46:12 +08:00
|
|
|
|
(if (symbolp source) (symbol-name source)
|
|
|
|
|
(format "%s" (plist-get source :name))))
|
|
|
|
|
|
2010-06-28 23:03:42 +08:00
|
|
|
|
(defun el-get-package-def (package)
|
2010-09-02 02:00:49 +08:00
|
|
|
|
"Return a single `el-get-sources' entry for PACKAGE."
|
2010-09-01 02:46:12 +08:00
|
|
|
|
(let ((source (loop for src in el-get-sources
|
|
|
|
|
when (string= package (el-get-source-name src))
|
|
|
|
|
return src)))
|
2010-08-31 04:59:05 +08:00
|
|
|
|
|
|
|
|
|
(cond ((symbolp source)
|
|
|
|
|
;; we did find only its name, load its definition in the recipes
|
|
|
|
|
(el-get-read-recipe package))
|
2010-09-02 03:30:27 +08:00
|
|
|
|
|
2010-08-31 04:59:05 +08:00
|
|
|
|
((null (plist-get source :type))
|
|
|
|
|
;; we got a list with no :type, that's an override plist
|
|
|
|
|
(loop with def = (el-get-read-recipe package)
|
2010-09-02 03:30:27 +08:00
|
|
|
|
for (prop override) on source by 'cddr
|
2010-08-31 04:59:05 +08:00
|
|
|
|
do (plist-put def prop override)
|
|
|
|
|
finally return def))
|
2010-09-02 03:30:27 +08:00
|
|
|
|
|
2010-08-31 04:59:05 +08:00
|
|
|
|
;; none of the previous, must be a full definition
|
|
|
|
|
;; definition
|
|
|
|
|
(t source))))
|
2010-06-28 23:03:42 +08:00
|
|
|
|
|
2010-09-02 05:39:39 +08:00
|
|
|
|
|
|
|
|
|
;;
|
|
|
|
|
;; package status --- a plist saved on a file, using symbols
|
|
|
|
|
;;
|
|
|
|
|
;; it should be possible to use strings instead, but in my tests it failed
|
|
|
|
|
;; miserably.
|
|
|
|
|
;;
|
|
|
|
|
(defun el-get-package-symbol (package-name)
|
|
|
|
|
"Returns a symbol :package."
|
|
|
|
|
(if (symbolp package-name) package-name
|
|
|
|
|
(intern (format ":%s" package-name))))
|
|
|
|
|
|
|
|
|
|
(defun el-get-read-all-packages-status ()
|
|
|
|
|
"Return the current plist of packages status"
|
|
|
|
|
(when (file-exists-p el-get-status-file)
|
|
|
|
|
(car (with-temp-buffer
|
|
|
|
|
(insert-file-contents-literally el-get-status-file)
|
|
|
|
|
(read-from-string (buffer-string))))))
|
|
|
|
|
|
|
|
|
|
(defun el-get-read-package-status (package)
|
|
|
|
|
"Return the current known status for given package."
|
|
|
|
|
(plist-get (el-get-read-all-packages-status)
|
|
|
|
|
(el-get-package-symbol package)))
|
|
|
|
|
|
|
|
|
|
(defun el-get-save-package-status (package status)
|
|
|
|
|
"Save given package status"
|
|
|
|
|
(let ((p (el-get-package-symbol package))
|
|
|
|
|
(s (el-get-read-all-packages-status)))
|
|
|
|
|
(with-temp-file el-get-status-file
|
|
|
|
|
(insert
|
|
|
|
|
(format "%S" (if s (plist-put s p status)
|
|
|
|
|
`(,p ,status)))))))
|
|
|
|
|
|
2010-09-02 23:15:47 +08:00
|
|
|
|
(defun el-get-count-package-with-status (status)
|
|
|
|
|
"Return how many packages are currently in given status"
|
|
|
|
|
(loop for (p s) on (el-get-read-all-packages-status) by 'cddr
|
|
|
|
|
if (string= status s) sum 1))
|
|
|
|
|
|
|
|
|
|
(defun el-get-package-status (package &optional package-status-plist)
|
|
|
|
|
"Return current status of package from given list"
|
|
|
|
|
(let ((status-plist (or package-status-plist (el-get-read-all-packages-status))))
|
|
|
|
|
(plist-get status-plist (el-get-package-symbol package))))
|
|
|
|
|
|
2010-07-30 17:16:56 +08:00
|
|
|
|
|
2010-06-29 00:35:15 +08:00
|
|
|
|
;;
|
|
|
|
|
;; User Interface, Interactive part
|
|
|
|
|
;;
|
2010-09-02 02:00:49 +08:00
|
|
|
|
|
|
|
|
|
(defun el-get-package-name-list ()
|
|
|
|
|
"Return package a list of all package names from
|
|
|
|
|
`el-get-sources'."
|
2010-09-02 23:15:47 +08:00
|
|
|
|
(let* ((package-name-list
|
|
|
|
|
(mapcar (lambda (x)
|
|
|
|
|
(if (symbolp x) (format "%S" x)
|
|
|
|
|
(format "%s" (plist-get x :name))))
|
|
|
|
|
el-get-sources))
|
|
|
|
|
(dedup (remove-duplicates package-name-list :test 'string=)))
|
|
|
|
|
(unless (= (length dedup) (length package-name-list))
|
2010-09-03 02:30:20 +08:00
|
|
|
|
(error "You have duplicates in `el-get-sources', time to choose."))
|
2010-09-02 23:15:47 +08:00
|
|
|
|
package-name-list))
|
2010-09-02 02:00:49 +08:00
|
|
|
|
|
|
|
|
|
(defun el-get-package-p (package)
|
|
|
|
|
"Check that PACKAGE is actually a valid package according to
|
|
|
|
|
`el-get-sources'."
|
|
|
|
|
(member package (el-get-package-name-list)))
|
|
|
|
|
|
|
|
|
|
(defun el-get-error-unless-package-p (package)
|
|
|
|
|
"Raise en error if PACKAGE is not a valid package according to
|
|
|
|
|
`el-get-package-p'."
|
|
|
|
|
(unless (el-get-package-p package)
|
|
|
|
|
(error "el-get: can not find package name `%s' in `el-get-sources'" package)))
|
|
|
|
|
|
|
|
|
|
(defun el-get-read-package-name (action)
|
|
|
|
|
"Ask user for a package name in minibuffer, with completion."
|
|
|
|
|
(completing-read (format "%s package: " action)
|
|
|
|
|
(el-get-package-name-list) nil t))
|
|
|
|
|
|
|
|
|
|
(defun el-get-init (package)
|
|
|
|
|
"Care about `load-path', `Info-directory-list', and (require 'features)."
|
|
|
|
|
(interactive (list (el-get-read-package-name "Init")))
|
|
|
|
|
(el-get-error-unless-package-p package)
|
|
|
|
|
(let* ((source (el-get-package-def package))
|
2010-06-28 23:16:01 +08:00
|
|
|
|
(method (plist-get source :type))
|
2010-06-30 05:16:13 +08:00
|
|
|
|
(loads (plist-get source :load))
|
2010-06-28 23:03:42 +08:00
|
|
|
|
(feats (plist-get source :features))
|
|
|
|
|
(el-path (or (plist-get source :load-path) '(".")))
|
2010-06-29 17:12:58 +08:00
|
|
|
|
(infodir (plist-get source :info))
|
2010-08-23 21:12:30 +08:00
|
|
|
|
(after (plist-get source :after))
|
2010-06-29 17:12:58 +08:00
|
|
|
|
(pdir (el-get-package-directory package)))
|
2010-06-28 23:03:42 +08:00
|
|
|
|
|
2010-06-29 16:39:02 +08:00
|
|
|
|
;; apt-get and ELPA will take care of load-path, Info-directory-list
|
2010-08-05 03:57:42 +08:00
|
|
|
|
(unless (member method '(elpa apt-get fink))
|
2010-06-28 23:16:01 +08:00
|
|
|
|
;; append entries to load-path and Info-directory-list
|
2010-09-02 03:30:27 +08:00
|
|
|
|
(mapc (lambda (path)
|
2010-06-28 23:16:01 +08:00
|
|
|
|
(el-get-add-path-to-list package 'load-path path))
|
|
|
|
|
(if (stringp el-path) (list el-path) el-path))
|
2010-06-28 23:03:42 +08:00
|
|
|
|
|
2010-07-28 18:33:26 +08:00
|
|
|
|
(let* ((infodir-abs-conf (concat (file-name-as-directory pdir) infodir))
|
|
|
|
|
(infodir-abs (if (file-directory-p infodir-abs-conf)
|
|
|
|
|
infodir-abs-conf
|
|
|
|
|
(file-name-directory infodir-abs-conf)))
|
|
|
|
|
(infodir-rel (if (file-directory-p infodir-abs-conf)
|
|
|
|
|
infodir
|
|
|
|
|
(file-name-directory infodir)))
|
2010-09-02 02:16:01 +08:00
|
|
|
|
(info-dir (concat (file-name-as-directory infodir-abs) "dir"))
|
2010-07-28 18:33:26 +08:00
|
|
|
|
(infofile (if (and (file-exists-p infodir-abs-conf)
|
|
|
|
|
(not (file-directory-p infodir-abs-conf)))
|
|
|
|
|
infodir-abs-conf
|
|
|
|
|
(concat (file-name-as-directory infodir-abs) package))))
|
|
|
|
|
|
2010-09-02 02:16:01 +08:00
|
|
|
|
(when (and infodir
|
|
|
|
|
(file-directory-p infodir-abs)
|
|
|
|
|
(not (file-exists-p info-dir)))
|
2010-07-28 18:33:26 +08:00
|
|
|
|
(require 'info)
|
|
|
|
|
(info-initialize)
|
|
|
|
|
;; add to Info-directory-list
|
|
|
|
|
(el-get-add-path-to-list package 'Info-directory-list infodir-rel)
|
|
|
|
|
;; build the infodir entry, too
|
|
|
|
|
(el-get-build
|
|
|
|
|
package
|
2010-08-23 22:55:36 +08:00
|
|
|
|
`(,(format "%s %s.info dir" el-get-install-info infofile)) infodir-rel t))))
|
2010-06-28 23:03:42 +08:00
|
|
|
|
|
2010-06-30 05:16:13 +08:00
|
|
|
|
;; loads
|
|
|
|
|
(when loads
|
2010-09-02 03:30:27 +08:00
|
|
|
|
(mapc (lambda (file)
|
2010-06-30 05:16:13 +08:00
|
|
|
|
(let ((pfile (concat (file-name-as-directory pdir) file)))
|
|
|
|
|
(unless (file-exists-p pfile)
|
|
|
|
|
(error "el-get could not find file '%s'" pfile))
|
2010-08-23 21:10:12 +08:00
|
|
|
|
(message "el-get: load '%s'" pfile)
|
2010-06-30 05:16:13 +08:00
|
|
|
|
(load pfile)))
|
|
|
|
|
(if (stringp loads) (list loads) loads)))
|
|
|
|
|
|
2010-06-29 16:39:02 +08:00
|
|
|
|
;; features, only ELPA will handle them on its own
|
|
|
|
|
(unless (eq method 'elpa)
|
2010-06-28 23:16:01 +08:00
|
|
|
|
;; if a feature is provided, require it now
|
2010-09-02 03:46:54 +08:00
|
|
|
|
(when feats
|
2010-09-02 02:07:16 +08:00
|
|
|
|
(mapc (lambda (feat)
|
|
|
|
|
(let ((feature (if (stringp feat) (intern-soft feat) feat)))
|
|
|
|
|
(message "require '%s" (require feature))))
|
|
|
|
|
(cond ((symbolp feats) (list feats))
|
|
|
|
|
((stringp feats) (list (intern-soft feats)))
|
|
|
|
|
(t feats)))))
|
2010-06-28 23:03:42 +08:00
|
|
|
|
|
2010-08-23 21:12:30 +08:00
|
|
|
|
;; call the "after" user function
|
|
|
|
|
(when (and after (functionp after))
|
|
|
|
|
(message "el-get: Calling init user function for package %s" package)
|
|
|
|
|
(funcall after))
|
|
|
|
|
|
|
|
|
|
;; return the package
|
|
|
|
|
package))
|
2010-06-28 23:03:42 +08:00
|
|
|
|
|
2010-08-04 03:35:04 +08:00
|
|
|
|
(defun el-get-post-install (package)
|
2010-09-02 02:00:49 +08:00
|
|
|
|
"Post install PACKAGE. This will get run by a sentinel."
|
2010-08-04 03:35:04 +08:00
|
|
|
|
(let* ((source (el-get-package-def package))
|
|
|
|
|
(hooks (el-get-method (plist-get source :type) :install-hook))
|
|
|
|
|
(commands (plist-get source :build)))
|
|
|
|
|
;; post-install is the right place to run install-hook
|
|
|
|
|
(run-hooks hooks)
|
2010-09-02 05:39:39 +08:00
|
|
|
|
(if commands
|
|
|
|
|
;; build then init
|
|
|
|
|
(el-get-build package commands nil nil
|
|
|
|
|
(lambda (package)
|
2010-09-03 02:15:40 +08:00
|
|
|
|
(el-get-init package)
|
|
|
|
|
(el-get-save-package-status package "installed")))
|
|
|
|
|
;; if there's no commands, just init and mark as installed
|
|
|
|
|
(el-get-init package)
|
2010-09-02 05:39:39 +08:00
|
|
|
|
(el-get-save-package-status package "installed"))))
|
2010-08-04 03:35:04 +08:00
|
|
|
|
|
2010-09-02 02:00:49 +08:00
|
|
|
|
(defun el-get-install (package)
|
|
|
|
|
"Install PACKAGE."
|
|
|
|
|
(interactive (list (el-get-read-package-name "Install")))
|
2010-09-02 03:12:29 +08:00
|
|
|
|
(el-get-error-unless-package-p package)
|
2010-09-02 05:39:39 +08:00
|
|
|
|
|
|
|
|
|
(let ((status (el-get-read-package-status package)))
|
|
|
|
|
(when (string= "installed" status)
|
|
|
|
|
(error "Package %s is already installed." package))
|
|
|
|
|
(when (string= "required" status)
|
|
|
|
|
(error "Package %s failed to install, remove it first." package)))
|
|
|
|
|
|
2010-09-02 02:00:49 +08:00
|
|
|
|
(let* ((source (el-get-package-def package))
|
2010-06-28 23:03:42 +08:00
|
|
|
|
(method (plist-get source :type))
|
|
|
|
|
(install (el-get-method method :install))
|
2010-08-04 03:35:04 +08:00
|
|
|
|
(url (plist-get source :url)))
|
2010-06-28 23:03:42 +08:00
|
|
|
|
|
2010-09-02 05:39:39 +08:00
|
|
|
|
;; check we can install the package and save to "required" status
|
2010-06-28 23:03:42 +08:00
|
|
|
|
(el-get-check-init)
|
2010-09-02 05:39:39 +08:00
|
|
|
|
(el-get-save-package-status package "required")
|
2010-06-28 23:03:42 +08:00
|
|
|
|
|
|
|
|
|
;; and install the package now
|
|
|
|
|
(message "el-get install %s" package)
|
2010-08-04 03:35:04 +08:00
|
|
|
|
(funcall install package url 'el-get-post-install)))
|
2010-06-28 23:03:42 +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))
|
2010-08-23 22:55:36 +08:00
|
|
|
|
(commands (plist-get source :build)))
|
2010-09-02 03:30:27 +08:00
|
|
|
|
(el-get-build package commands nil nil
|
2010-08-23 22:55:36 +08:00
|
|
|
|
(lambda (package) (message "el-get-post-update %s: done" package)))))
|
2010-06-28 23:03:42 +08:00
|
|
|
|
|
2010-09-02 02:00:49 +08:00
|
|
|
|
(defun el-get-update (package)
|
|
|
|
|
"Update PACKAGE."
|
|
|
|
|
(interactive (list (el-get-read-package-name "Update")))
|
|
|
|
|
(el-get-error-unless-package-p package)
|
|
|
|
|
(let* ((source (el-get-package-def package))
|
2010-06-28 23:03:42 +08:00
|
|
|
|
(method (plist-get source :type))
|
|
|
|
|
(update (el-get-method method :update))
|
|
|
|
|
(url (plist-get source :url))
|
|
|
|
|
(commands (plist-get source :build)))
|
|
|
|
|
;; update the package now
|
|
|
|
|
(message "el-get update %s" package)
|
2010-08-04 03:35:04 +08:00
|
|
|
|
(funcall update package url 'el-get-post-update)))
|
2010-06-28 23:03:42 +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."
|
2010-08-05 03:57:42 +08:00
|
|
|
|
(let* ((source (el-get-package-def package))
|
|
|
|
|
(hooks (el-get-method (plist-get source :type) :remove-hook)))
|
|
|
|
|
(when hooks
|
|
|
|
|
(run-hooks hooks))))
|
|
|
|
|
|
2010-06-28 23:03:42 +08:00
|
|
|
|
(defun el-get-remove (&optional package)
|
2010-09-02 02:00:49 +08:00
|
|
|
|
"Remove PACKAGE."
|
|
|
|
|
(interactive (list (el-get-read-package-name "Remove")))
|
|
|
|
|
(el-get-error-unless-package-p package)
|
|
|
|
|
(let* ((source (el-get-package-def package))
|
2010-06-28 23:03:42 +08:00
|
|
|
|
(method (plist-get source :type))
|
|
|
|
|
(remove (el-get-method method :remove))
|
|
|
|
|
(url (plist-get source :url)))
|
|
|
|
|
;; remove the package now
|
|
|
|
|
(message "el-get remove %s" package)
|
2010-08-05 03:57:42 +08:00
|
|
|
|
(funcall remove package url 'el-get-post-remove)))
|
2010-06-28 23:03:42 +08:00
|
|
|
|
|
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."
|
2010-09-02 02:00:49 +08:00
|
|
|
|
(interactive (list (el-get-read-package-name "cd to")))
|
|
|
|
|
(el-get-error-unless-package-p package)
|
|
|
|
|
(dired (el-get-package-directory package)))
|
2010-08-04 03:44:29 +08:00
|
|
|
|
|
2010-07-30 17:16:56 +08:00
|
|
|
|
|
2010-06-29 00:35:15 +08:00
|
|
|
|
;;
|
|
|
|
|
;; User Interface, Non Interactive part
|
|
|
|
|
;;
|
2010-09-02 23:15:47 +08:00
|
|
|
|
(defun el-get (&optional sync)
|
2010-06-28 03:13:22 +08:00
|
|
|
|
"Check that all sources have been downloaded once, and init them as needed.
|
|
|
|
|
|
|
|
|
|
This will not update the sources by using `apt-get install' or
|
|
|
|
|
`git pull', but it will ensure the sources have been installed
|
|
|
|
|
and will set the load-path and Info-directory-list depending on
|
2010-06-28 23:03:42 +08:00
|
|
|
|
the el-get-sources setup.
|
2010-06-28 03:13:22 +08:00
|
|
|
|
|
2010-06-28 23:03:42 +08:00
|
|
|
|
el-get is also responsible for doing (require 'feature) for each
|
|
|
|
|
and every feature declared in `el-get-sources', so that it's
|
|
|
|
|
suitable for use in your emacs init script.
|
|
|
|
|
"
|
2010-09-02 23:15:47 +08:00
|
|
|
|
(let* ((p-status (el-get-read-all-packages-status))
|
|
|
|
|
(total (length (el-get-package-name-list)))
|
|
|
|
|
(installed (el-get-count-package-with-status "installed"))
|
|
|
|
|
progress ret)
|
|
|
|
|
(when sync
|
|
|
|
|
(setq progress
|
|
|
|
|
(make-progress-reporter
|
|
|
|
|
"Waiting for `el-get' to complete… " 0 (- total installed) 0)))
|
|
|
|
|
;; keep the result of mapcar to return it even in the 'sync case
|
|
|
|
|
(setq
|
|
|
|
|
ret
|
|
|
|
|
(mapcar
|
|
|
|
|
(lambda (source)
|
|
|
|
|
(let* ((package (el-get-source-name source))
|
|
|
|
|
(status (el-get-package-status package p-status)))
|
|
|
|
|
;; check if the package needs to be fetched (and built)
|
|
|
|
|
(if (el-get-package-exists-p package)
|
|
|
|
|
(if (and status (string= "installed" status))
|
|
|
|
|
(el-get-init package)
|
|
|
|
|
(error "Package %s failed to install, remove it first." package))
|
|
|
|
|
(el-get-install package))))
|
|
|
|
|
el-get-sources))
|
|
|
|
|
|
|
|
|
|
;; el-get-install is async, that's now ongoing.
|
|
|
|
|
(when sync
|
|
|
|
|
(while (> (- total installed) 0)
|
|
|
|
|
(sleep-for 0.2)
|
|
|
|
|
(setq installed (el-get-count-package-with-status "installed"))
|
|
|
|
|
(progress-reporter-update progress (- total installed)))
|
|
|
|
|
(progress-reporter-done progress))
|
|
|
|
|
|
|
|
|
|
;; return the list of packages
|
|
|
|
|
ret))
|
|
|
|
|
|
2010-06-19 04:21:02 +08:00
|
|
|
|
|
2010-06-28 03:13:22 +08:00
|
|
|
|
(provide 'el-get)
|