Commit 8db0c4d4 authored by Dimitri Fontaine's avatar Dimitri Fontaine

Fix the refactoring so that it actually works.

This includes teaching methods that they now work with a symbolp PACKAGE,
some more cleaning up, and some load-path adjustments now that a part of the
code is in a subdirectory (methods).

Also include some of the tests used to convince oneself that the refactoring
didn't break any and all use cases for el-get, with some rough documentation
about how to use them.
parent 7a4a744d
......@@ -13,6 +13,12 @@
;; Please see the README.asciidoc file from the same distribution
(require 'el-get-core)
(require 'el-get-byte-compile)
;; 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")))
(defun el-get-build-commands (package)
"Return a list of build commands for the named PACKAGE.
......@@ -113,7 +119,6 @@ recursion.
;; it must be a lambda, just inline its value
post-build-fun)
package)))))
(el-get-start-process-list
package full-process-list build-info-then-post-build-fun)))
......@@ -129,6 +134,7 @@ recursion.
(let* ((source (el-get-package-def package))
(method (el-get-package-method source))
(infodir (plist-get source :info))
(pname (el-get-as-string package))
(pdir (el-get-package-directory package)))
;; apt-get, pacman and ELPA will set up Info-directory-list
......@@ -145,7 +151,7 @@ recursion.
(infofile (if (and (file-exists-p infodir-abs-conf)
(not (file-directory-p infodir-abs-conf)))
infodir-abs-conf
(concat infodir-abs package))))
(concat infodir-abs pname))))
(cond
((eq build-or-init 'init)
......
......@@ -12,7 +12,7 @@
;; Install
;; Please see the README.asciidoc file from the same distribution
(require 'el-get-core)
(require 'cl) ; yes I like loop
(require 'bytecomp)
;; Emacs < 24
......
......@@ -27,6 +27,10 @@
(defun el-get-verbose-message (format &rest arguments)
(when el-get-verbose (apply 'message format arguments)))
;;
;; el-get-methods support, those are like backends.
;;
(defvar el-get-methods nil
"Register methods that el-get can use to fetch and update a given package.
......@@ -108,7 +112,8 @@ given method."
(defun el-get-package-directory (package)
"Return the absolute directory name of the named PACKAGE."
(file-name-as-directory
(expand-file-name package (expand-file-name el-get-dir))))
(expand-file-name (el-get-as-string package)
(expand-file-name el-get-dir))))
(defun el-get-add-path-to-list (package list path)
"(add-to-list LIST PATH) checking for path existence within
......
......@@ -17,6 +17,10 @@
;;
;; NOTE: this will probably benefit from some autoloading magic, later.
;;
(add-to-list 'load-path
(expand-file-name
"methods"
(file-name-directory (or load-file-name buffer-file-name))))
(require 'el-get-apt-get)
(require 'el-get-bzr)
......
......@@ -68,6 +68,13 @@
(loop for (p s) on (el-get-read-all-packages-status) by 'cddr
if (member s status) sum 1))
(defun el-get-count-packages-with-status (packages &rest status)
"Return how many packages are currently in given status in PACKAGES"
(loop for (p s) on (el-get-read-all-packages-status) by 'cddr
when (and (member (el-get-as-symbol p) packages)
(member s status))
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))))
......
......@@ -144,8 +144,33 @@
;;; Code:
(require 'el-get-core)
;; first some essential variables, used in other parts of the code.
(defgroup el-get nil "el-get customization group"
:group 'convenience)
(defconst el-get-version "4.0.0" "el-get version number")
(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")
;;
;; Now load the rest of the el-get code
;;
(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
......@@ -159,11 +184,11 @@
(require 'el-get-autoloads) ; to be removed^W cleaned up next
(defgroup el-get nil "el-get customization group"
:group 'convenience)
(defconst el-get-version "4.0.0" "el-get version number")
;;
;; 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.
;;
(defcustom el-get-post-init-hooks nil
"Hooks to run after a package init.
Each hook is a unary function accepting a package"
......@@ -227,29 +252,6 @@ force their evaluation on some packages only."
:group 'el-get
:type 'boolean)
(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")
;; 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")))
(defvar el-get-next-packages nil
"List of packages to install next, used when dealing with dependencies.")
......@@ -433,21 +435,23 @@ PACKAGE may be either a string or the corresponding symbol."
(if (el-get-package-is-installed package)
(message "el-get: `%s' package is already installed" package)
(let* ((packages (el-get-dependencies package)))
(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))
(add-hook 'el-get-post-install-hooks 'el-get-install-next-packages))
(el-get-do-install package))))
(el-get-do-install (car packages)))))
(defun el-get-install-next-packages ()
(defun el-get-install-next-packages (current-package)
"Run as part of `el-get-post-init-hooks' when dealing with dependencies."
(let ((package (pop el-get-next-packages)))
(el-get-verbose-message "el-get-install-next-packages: %s" package)
(if package
(if (el-get-package-is-installed package)
(message "el-get: `%s' package is already installed" package)
(el-get-do-install package))
(el-get-do-install (el-get-as-string package)))
;; no more packages to install in the dependency walk, clean up
(remove-hook 'el-get-post-init-hooks 'el-get-install-next-packages))))
......@@ -670,35 +674,31 @@ already installed packages is considered."
;; 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))
(let ((previously-installing (el-get-currently-installing-packages))
(progress (and (eq sync 'wait)
(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)
(make-progress-reporter
"Waiting for `el-get' to complete... "
0 100 0)))
0 (- total installed) 0)))
(el-get-default-process-sync sync))
;; keep the result of `el-get-init-and-install' to return it even in the
;; 'wait case
(prog1
(let ((packages
;; (el-get 'sync 'a 'b my-package-list)
(loop for p in packages when (listp p) append p else collect p)))
(el-get-init-and-install packages))
(el-get-init-and-install packages)
;; el-get-do-install is async, that's now ongoing.
;; el-get-install is async, that's now ongoing.
(when progress
(let* ((newly-installing
(set-difference (el-get-currently-installing-packages)
previously-installing))
(still-installing newly-installing))
(while (> (length still-installing) 0)
(sleep-for 0.2)
(setq still-installing (delete-if-not 'el-get-currently-installing-p still-installing))
(progress-reporter-update
progress
(/ (* 100.0 (- newly-installing still-installing)) newly-installing)))
(progress-reporter-done progress)))
(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)))
(progress-reporter-done progress))
;; unless we have autoloads to update, just load them now
(unless el-get-outdated-autoloads
......
......@@ -53,19 +53,20 @@
"ln -s /usr/share/emacs/site-lisp/package ~/.emacs.d/el-get/package"
(let* ((pdir (el-get-package-directory package))
(method (el-get-package-method package))
(pname (el-get-as-string package))
(basedir (cond ((eq method 'apt-get) el-get-apt-get-base)
((eq method 'fink) el-get-fink-base)
((eq method 'pacman) el-get-pacman-base)))
(debdir (concat (file-name-as-directory basedir) package)))
(debdir (concat (file-name-as-directory basedir) pname)))
(unless (file-directory-p pdir)
(shell-command
(concat "cd " el-get-dir " && ln -s " debdir " " package)))))
(concat "cd " el-get-dir " && ln -s " debdir " " pname)))))
(defun el-get-dpkg-remove-symlink (package)
"rm -f ~/.emacs.d/el-get/package"
(let* ((pdir (el-get-package-directory package)))
(when (file-symlink-p pdir)
(let ((command (concat "cd " el-get-dir " && rm -f " package)))
(let ((command (concat "cd " el-get-dir " && rm -f " pname)))
(message command)
(shell-command command)))))
......@@ -111,7 +112,7 @@ password prompt."
(defun el-get-apt-get-install (package url post-install-fun)
"echo $pass | sudo -S apt-get install PACKAGE"
(let* ((source (el-get-package-def package))
(pkgname (or (plist-get source :pkgname) package))
(pkgname (or (plist-get source :pkgname) (el-get-as-string package)))
(name (format "*apt-get install %s*" package))
(ok (format "Package %s installed." package))
(ko (format "Could not install package %s." package)))
......@@ -130,7 +131,7 @@ password prompt."
(defun el-get-apt-get-remove (package url post-remove-fun)
"apt-get remove PACKAGE, URL is there for API compliance"
(let* ((source (el-get-package-def package))
(pkgname (or (plist-get source :pkgname) package))
(pkgname (or (plist-get source :pkgname) (el-get-as-string package)))
(name (format "*apt-get remove %s*" package))
(ok (format "Package %s removed." package))
(ko (format "Could not remove package %s." package)))
......
......@@ -22,16 +22,17 @@
(defun el-get-bzr-branch (package url post-install-fun)
"Branch a given bzr PACKAGE following the URL using bzr."
(let* ((bzr-executable (el-get-executable-find "bzr"))
(name (format "*bzr branch %s*" package))
(ok (format "Package %s installed" package))
(ko (format "Could not install package %s." package)))
(pname (el-get-as-string package))
(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)
:args ("branch" ,url ,pname)
:message ,ok
:error ,ko))
post-install-fun)))
......@@ -56,7 +57,7 @@
post-update-fun)))
(el-get-register-method
:bzr #'el-get-bzr-branch el-get-bzr-pull el-get-rmdir
:bzr #'el-get-bzr-branch #'el-get-bzr-pull #'el-get-rmdir
el-get-bzr-branch-hook)
(provide 'el-get-bzr)
......@@ -25,6 +25,7 @@
(source (el-get-package-def package))
(module (plist-get source :module))
(options (plist-get source :options))
(pname (el-get-as-string package))
(name (format "*cvs checkout %s*" package))
(ok (format "Checked out package %s." package))
(ko (format "Could not checkout package %s." package)))
......@@ -48,7 +49,7 @@
:buffer-name ,name
:default-directory ,el-get-dir
:program ,cvs-executable
:args ("-d" ,url "checkout" "-d" ,package ,module)
:args ("-d" ,url "checkout" "-d" ,pname ,module)
:message ,ok
:error ,ko))
post-install-fun)))
......
......@@ -22,16 +22,17 @@
(defun el-get-darcs-get (package url post-install-fun)
"Get a given PACKAGE following the URL using darcs."
(let* ((darcs-executable (el-get-executable-find "darcs"))
(name (format "*darcs get %s*" package))
(ok (format "Package %s installed" package))
(ko (format "Could not install package %s." package)))
(pname (el-get-as-string package))
(name (format "*darcs get %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 ,darcs-executable
:args ("get" "--lazy" ,url ,package)
:args ("get" "--lazy" ,url ,pname)
:message ,ok
:error ,ko))
post-install-fun)))
......
......@@ -106,7 +106,7 @@ the recipe, then return nil."
emacs-lisp-mode-hook fundamental-mode-hook prog-mode-hook)
(unless p
(package-refresh-contents)))
(package-install (intern package)))
(package-install (el-get-as-symbol 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
......@@ -117,7 +117,7 @@ the recipe, then return nil."
"Ask elpa to update given PACKAGE."
(el-get-elpa-remove package url nil)
(package-refresh-contents)
(package-install (intern package))
(package-install (el-get-as-symbol package))
(funcall post-update-fun package))
(defun el-get-elpa-remove (package url post-remove-fun)
......
......@@ -29,7 +29,7 @@
;;
(defun el-get-emacsmirror-clone (package url post-install-fun)
(let* ((source (el-get-package-def package))
(pkgname (or (plist-get source :pkgname) package))
(pkgname (or (plist-get source :pkgname) (el-get-as-string package)))
(url (or url (format el-get-emacsmirror-base-url pkgname))))
(el-get-git-clone package url post-install-fun)))
......
......@@ -38,7 +38,7 @@
"sudo -S fink install PACKAGE"
(let* ((name (format "*fink install %s*" package))
(source (el-get-package-def package))
(pkgname (or (plist-get source :pkgname) package))
(pkgname (or (plist-get source :pkgname) (el-get-as-string package)))
(ok (format "Package %s installed." package))
(ko (format "Could not install package %s." package)))
......@@ -59,7 +59,7 @@
"apt-get remove PACKAGE. URL is there for API compliance."
(let* ((name (format "*fink remove %s*" package))
(source (el-get-package-def package))
(pkgname (or (plist-get source :pkgname) package))
(pkgname (or (plist-get source :pkgname) (el-get-as-string package)))
(ok (format "Package %s removed." package))
(ko (format "Could not remove package %s." package)))
......@@ -76,7 +76,7 @@
(add-hook 'el-get-fink-remove-hook 'el-get-dpkg-remove-symlink)
(el-get-register
(el-get-register-method
:fink
#'el-get-fink-install #'el-get-fink-install #'el-get-fink-remove
#'el-get-fink-install-hook #'el-get-fink-remove-hook)
......
......@@ -22,9 +22,10 @@
(defun el-get-git-svn-clone (package url post-install-fun)
"Clone the given svn PACKAGE following the URL using git."
(let ((git-executable (el-get-executable-find "git"))
(name (format "*git svn clone %s*" package))
(ok (format "Package %s installed." package))
(ko (format "Could not install package %s." package)))
(pname (el-get-as-string package))
(name (format "*git svn clone %s*" package))
(ok (format "Package %s installed." package))
(ko (format "Could not install package %s." package)))
(el-get-start-process-list
package
......@@ -32,7 +33,7 @@
:buffer-name ,name
:default-directory ,el-get-dir
:program ,git-executable
:args ( "--no-pager" "svn" "clone" ,url ,package)
:args ( "--no-pager" "svn" "clone" ,url ,pname)
:message ,ok
:error ,ko))
post-install-fun)))
......
......@@ -36,12 +36,13 @@ found."
"Clone the given package following the URL."
(let* ((git-executable (el-get-executable-find "git"))
(pdir (el-get-package-directory package))
(pname (el-get-as-string package))
(name (format "*git clone %s*" package))
(source (el-get-package-def package))
(branch (plist-get source :branch))
(args (if branch
(list "--no-pager" "clone" "-b" branch url package)
(list "--no-pager" "clone" url package)))
(list "--no-pager" "clone" "-b" branch url pname)
(list "--no-pager" "clone" url pname)))
(ok (format "Package %s installed." package))
(ko (format "Could not install package %s." package)))
(el-get-start-process-list
......
......@@ -22,10 +22,11 @@
(defun el-get-hg-clone (package url post-install-fun)
"Clone the given package following the URL."
(let* ((hg-executable (el-get-executable-find "hg"))
(pdir (el-get-package-directory package))
(name (format "*hg clone %s*" package))
(ok (format "Package %s installed." package))
(ko (format "Could not install package %s." package)))
(pdir (el-get-package-directory package))
(pname (el-get-as-string package))
(name (format "*hg clone %s*" package))
(ok (format "Package %s installed." package))
(ko (format "Could not install package %s." package)))
(el-get-start-process-list
package
......@@ -33,7 +34,7 @@
:buffer-name ,name
:default-directory ,el-get-dir
:program ,hg-executable
:args ("clone" ,url ,package)
:args ("clone" ,url ,pname)
:message ,ok
:error ,ko))
post-install-fun)))
......
......@@ -29,7 +29,7 @@ Test url: http://repo.or.cz/w/ShellArchive.git?a=blob_plain;hb=HEAD;f=ack.el"
(defun el-get-http-retrieve-callback (status package post-install-fun &optional dest sources)
"Callback function for `url-retrieve', store the emacs lisp file for the package."
(let* ((pdir (el-get-package-directory package))
(dest (or dest (concat (file-name-as-directory pdir) package ".el")))
(dest (or dest (format "%s%s.el" (file-name-as-directory pdir) package)))
(part (concat dest ".part"))
(el-get-sources (if sources sources el-get-sources))
(buffer-file-coding-system 'no-conversion)
......
......@@ -24,7 +24,7 @@
(defun el-get-pacman-install (package url post-install-fun)
"echo $pass | sudo -S pacman install PACKAGE"
(let* ((source (el-get-package-def package))
(pkgname (or (plist-get source :pkgname) package))
(pkgname (or (plist-get source :pkgname) (el-get-as-string package)))
(name (format "*pacman install %s*" package))
(ok (format "Package %s installed." package))
(ko (format "Could not install package %s." package)))
......@@ -44,7 +44,7 @@
(defun el-get-pacman-remove (package url post-remove-fun)
"pacman remove PACKAGE, URL is there for API compliance"
(let* ((source (el-get-package-def package))
(pkgname (or (plist-get source :pkgname) package))
(pkgname (or (plist-get source :pkgname) (el-get-as-string package)))
(name (format "*pacman remove %s*" package))
(ok (format "Package %s removed." package))
(ko (format "Could not remove package %s." package)))
......
......@@ -31,6 +31,7 @@
"svn checkout the package."
(let* ((svn-executable (el-get-executable-find "svn"))
(source (el-get-package-def package))
(pname (el-get-as-string package))
(name (format "*svn checkout %s*" package))
(ok (format "Checked out package %s." package))
(ko (format "Could not checkout package %s." package)))
......@@ -41,7 +42,7 @@
:buffer-name ,name
:default-directory ,el-get-dir
:program ,svn-executable
:args ("checkout" ,url ,package)
:args ("checkout" ,url ,pname)
:message ,ok
:error ,ko))
post-install-fun)))
......
= Tests
Like, yes, we have some! :)
== el-get manual tests
Tries to cover some known issues, example that will allow building a
regression test suite some day.
Typical run:
mkdir -p /tmp/test/.emacs.d
rm -rf /tmp/test/.emacs.d/el-get/
HOME=/tmp/test /Applications/Emacs.app/Contents/MacOS/Emacs -Q -batch -l test/el-get-issue-303.el
At the moment you need to run the el-get-issue scripts with some known
working el-get version to know what to expect, and you probably need to have
el-get installed at +~/dev/emacs/el-get/+ for this to work as-is.
Yet it might be useful.
== el-get automated tests
See +test.el+ in this directory, and see the el-get-devel mailing list for a
promising patch to port the effort to +ert+. This has yet to happen,
though.
;; https://github.com/dimitri/el-get/issues/200
;;
;; yasnippet recipe fails to install
(let ((debug-on-error t)
;; (el-get-byte-compile nil)
(el-get-verbose t))
(add-to-list 'load-path "/Users/dim/dev/emacs/el-get")
(require 'el-get)
(el-get 'sync 'yasnippet))
;;
;; https://github.com/dimitri/el-get/issues/284
;;
;; set HOME to an empty directory, launch emacs and evaluate the
;; following. It fails because initsplit has not been added to the load
;; path.
(let ((debug-on-error t))
(add-to-list 'load-path "/Users/dim/dev/emacs/el-get")
(setq el-get-byte-compile nil
el-get-verbose t)
(require 'el-get)
(el-get 'sync '(initsplit))
(find-library "initsplit"))
;; https://github.com/dimitri/el-get/issues/289
;;
;; flymake-fringe-icons recipe won't initialize
;;
;; Because it eagerly loads flymake-fringe-icons by using :features, and
;; that recipe require's fringe-helper, which isn't yet init'ed. The
;; solution is either to remove :features from the flymake-fringe-icons
;; recipe or to make el-get-init respect the :depends clause.
(let ((debug-on-error t))
(add-to-list 'load-path "/Users/dim/dev/emacs/el-get")
(setq el-get-byte-compile nil
el-get-verbose t)
(require 'el-get)
(el-get 'sync '(flymake-fringe-icons)))
;; https://github.com/dimitri/el-get/issues/303
;;
;; error in process sentinel
(let (
(debug-on-error t)
(debug-ignored-errors '())
;; (el-get-byte-compile nil)
(el-get-verbose t)
(el-get-default-process-sync t)
(el-get-sources
'((:name xmlunicode :depends
(unichars)
:type http :url "http://nwalsh.com/emacs/xmlchars/xmlunicode.el")
(:name unichars :type http :url "http://nwalsh.com/emacs/xmlchars/unichars.el"))))
(add-to-list 'load-path "/Users/dim/dev/emacs/el-get")
(require 'el-get)
(el-get-install "xmlunicode"))
;; https://github.com/dimitri/el-get/issues/310
;;
;; el-get refuses to compile
(let ((debug-on-error t)
(debug-ignored-errors '()))
(add-to-list 'load-path "/Users/dim/dev/emacs/el-get")
(require 'el-get)
(setq el-get-default-process-sync t
el-get-verbose t)
(el-get-install "mailq"))
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment