comparison lisp/emacs-lisp/package.el @ 111394:72d2a83a2641

* emacs-lisp/package.el (package-unpack): Remove no-op. (package--builtins, package--dir): Doc fix. (package-activate-1, package-activate, package-install) (package-compute-transaction): Fix error message. (package-delete): Use delete-directory. Omit system packages. (package-initialize): Set package-alist to nil first. (package-menu-mark-delete, package-menu-mark-install): Don't add symbols that are inconsistent with the package state. (package-menu-execute): Perform deletions and installations as single batch operations.
author Chong Yidong <cyd@stupidchicken.com>
date Wed, 03 Nov 2010 19:21:51 -0400
parents 27839df805b0
children 59101ed2e4c6
comparison
equal deleted inserted replaced
111393:230a50b33a46 111394:72d2a83a2641
75 ;; available to the user. 75 ;; available to the user.
76 ;; * Load. Actually load the package and run some code from it. 76 ;; * Load. Actually load the package and run some code from it.
77 77
78 ;; Other external functions you may want to use: 78 ;; Other external functions you may want to use:
79 ;; 79 ;;
80 ;; M-x package-list-packages 80 ;; M-x list-packages
81 ;; Enters a mode similar to buffer-menu which lets you manage 81 ;; Enters a mode similar to buffer-menu which lets you manage
82 ;; packages. You can choose packages for install (mark with "i", 82 ;; packages. You can choose packages for install (mark with "i",
83 ;; then "x" to execute) or deletion (not implemented yet), and you 83 ;; then "x" to execute) or deletion (not implemented yet), and you
84 ;; can see what packages are available. This will automatically 84 ;; can see what packages are available. This will automatically
85 ;; fetch the latest list of packages from ELPA. 85 ;; fetch the latest list of packages from ELPA.
213 (defvar Info-directory-list) 213 (defvar Info-directory-list)
214 (declare-function info-initialize "info" ()) 214 (declare-function info-initialize "info" ())
215 (declare-function url-http-parse-response "url-http" ()) 215 (declare-function url-http-parse-response "url-http" ())
216 (declare-function lm-header "lisp-mnt" (header)) 216 (declare-function lm-header "lisp-mnt" (header))
217 (declare-function lm-commentary "lisp-mnt" (&optional file)) 217 (declare-function lm-commentary "lisp-mnt" (&optional file))
218 (declare-function dired-delete-file "dired" (file &optional recursive trash))
219 (defvar url-http-end-of-headers) 218 (defvar url-http-end-of-headers)
220 219
221 (defcustom package-archives '(("gnu" . "http://elpa.gnu.org/packages/")) 220 (defcustom package-archives '(("gnu" . "http://elpa.gnu.org/packages/"))
222 "An alist of archives from which to fetch. 221 "An alist of archives from which to fetch.
223 The default value points to the GNU Emacs package repository. 222 The default value points to the GNU Emacs package repository.
276 275
277 ;; The value is precomputed in finder-inf.el, but don't load that 276 ;; The value is precomputed in finder-inf.el, but don't load that
278 ;; until it's needed (i.e. when `package-intialize' is called). 277 ;; until it's needed (i.e. when `package-intialize' is called).
279 (defvar package--builtins nil 278 (defvar package--builtins nil
280 "Alist of built-in packages. 279 "Alist of built-in packages.
280 The actual value is initialized by loading the library
281 `finder-inf'; this is not done until it is needed, e.g. by the
282 function `package-built-in-p'.
283
281 Each element has the form (PKG . DESC), where PKG is a package 284 Each element has the form (PKG . DESC), where PKG is a package
282 name (a symbol) and DESC is a vector that describes the package. 285 name (a symbol) and DESC is a vector that describes the package.
283
284 The vector DESC has the form [VERSION REQS DOCSTRING]. 286 The vector DESC has the form [VERSION REQS DOCSTRING].
285 VERSION is a version list. 287 VERSION is a version list.
286 REQS is a list of packages (symbols) required by the package. 288 REQS is a list of packages (symbols) required by the package.
287 DOCSTRING is a brief description of the package.") 289 DOCSTRING is a brief description of the package.")
288 (put 'package--builtins 'risky-local-variable t) 290 (put 'package--builtins 'risky-local-variable t)
387 389
388 (defsubst package-desc-kind (desc) 390 (defsubst package-desc-kind (desc)
389 "Extract the kind of download from an archive package description vector." 391 "Extract the kind of download from an archive package description vector."
390 (aref desc 3)) 392 (aref desc 3))
391 393
392 (defun package--dir (name version-string) 394 (defun package--dir (name version)
393 (let* ((subdir (concat name "-" version-string)) 395 "Return the directory where a package is installed, or nil if none.
396 NAME and VERSION are both strings."
397 (let* ((subdir (concat name "-" version))
394 (dir-list (cons package-user-dir package-directory-list)) 398 (dir-list (cons package-user-dir package-directory-list))
395 pkg-dir) 399 pkg-dir)
396 (while dir-list 400 (while dir-list
397 (let ((subdir-full (expand-file-name subdir (car dir-list)))) 401 (let ((subdir-full (expand-file-name subdir (car dir-list))))
398 (if (file-directory-p subdir-full) 402 (if (file-directory-p subdir-full)
404 (defun package-activate-1 (package pkg-vec) 408 (defun package-activate-1 (package pkg-vec)
405 (let* ((name (symbol-name package)) 409 (let* ((name (symbol-name package))
406 (version-str (package-version-join (package-desc-vers pkg-vec))) 410 (version-str (package-version-join (package-desc-vers pkg-vec)))
407 (pkg-dir (package--dir name version-str))) 411 (pkg-dir (package--dir name version-str)))
408 (unless pkg-dir 412 (unless pkg-dir
409 (error "Internal error: could not find directory for %s-%s" 413 (error "Internal error: unable to find directory for `%s-%s'"
410 name version-str)) 414 name version-str))
411 ;; Add info node. 415 ;; Add info node.
412 (when (file-exists-p (expand-file-name "dir" pkg-dir)) 416 (when (file-exists-p (expand-file-name "dir" pkg-dir))
413 ;; FIXME: not the friendliest, but simple. 417 ;; FIXME: not the friendliest, but simple.
414 (require 'info) 418 (require 'info)
455 (dolist (req (package-desc-reqs pkg-vec)) 459 (dolist (req (package-desc-reqs pkg-vec))
456 (unless (package-activate (car req) (cadr req)) 460 (unless (package-activate (car req) (cadr req))
457 (throw 'dep-failure req)))))) 461 (throw 'dep-failure req))))))
458 (if fail 462 (if fail
459 (warn "Unable to activate package `%s'. 463 (warn "Unable to activate package `%s'.
460 Required package `%s', version %s, is unavailable" 464 Required package `%s-%s' is unavailable"
461 package (car fail) (package-version-join (cadr fail))) 465 package (car fail) (package-version-join (cadr fail)))
462 ;; If all goes well, activate the package itself. 466 ;; If all goes well, activate the package itself.
463 (package-activate-1 package pkg-vec))))))) 467 (package-activate-1 package pkg-vec)))))))
464 468
465 (defun package-mark-obsolete (package pkg-vec) 469 (defun package-mark-obsolete (package pkg-vec)
563 "xf" "-"))) 567 "xf" "-")))
564 568
565 (defun package-unpack (name version) 569 (defun package-unpack (name version)
566 (let ((pkg-dir (expand-file-name (concat (symbol-name name) "-" version) 570 (let ((pkg-dir (expand-file-name (concat (symbol-name name) "-" version)
567 package-user-dir))) 571 package-user-dir)))
568 ;; Be careful!!
569 (make-directory package-user-dir t) 572 (make-directory package-user-dir t)
570 (if (file-directory-p pkg-dir) 573 ;; FIXME: should we delete PKG-DIR if it exists?
571 (mapc (lambda (file) nil) ; 'delete-file -- FIXME: when we're
572 ; more confident
573 (directory-files pkg-dir t "^[^.]")))
574 (let* ((default-directory (file-name-as-directory package-user-dir))) 574 (let* ((default-directory (file-name-as-directory package-user-dir)))
575 (package-untar-buffer) 575 (package-untar-buffer)
576 (package-generate-autoloads (symbol-name name) pkg-dir) 576 (package-generate-autoloads (symbol-name name) pkg-dir)
577 (let ((load-path (cons pkg-dir load-path))) 577 (let ((load-path (cons pkg-dir load-path)))
578 (byte-recompile-directory pkg-dir 0 t))))) 578 (byte-recompile-directory pkg-dir 0 t)))))
606 (list 'quote 606 (list 'quote
607 ;; Turn version lists into string form. 607 ;; Turn version lists into string form.
608 (mapcar 608 (mapcar
609 (lambda (elt) 609 (lambda (elt)
610 (list (car elt) 610 (list (car elt)
611 (package-version-join (car (cdr elt))))) 611 (package-version-join (cadr elt))))
612 requires)))) 612 requires))))
613 "\n") 613 "\n")
614 nil 614 nil
615 pkg-file 615 pkg-file
616 nil nil nil 'excl)) 616 nil nil nil 'excl))
696 (error "Required package '%s' is disabled" 696 (error "Required package '%s' is disabled"
697 (symbol-name next-pkg))) 697 (symbol-name next-pkg)))
698 ((null (stringp hold)) 698 ((null (stringp hold))
699 (error "Invalid element in `package-load-list'")) 699 (error "Invalid element in `package-load-list'"))
700 ((version-list-< (version-to-list hold) next-version) 700 ((version-list-< (version-to-list hold) next-version)
701 (error "Package '%s' held at version %s, \ 701 (error "Package `%s' held at version %s, \
702 but version %s required" 702 but version %s required"
703 (symbol-name next-pkg) hold 703 (symbol-name next-pkg) hold
704 (package-version-join next-version))))) 704 (package-version-join next-version)))))
705 (unless pkg-desc 705 (unless pkg-desc
706 (error "Package '%s', version %s, unavailable for installation" 706 (error "Package `%s-%s' is unavailable"
707 (symbol-name next-pkg) 707 (symbol-name next-pkg)
708 (package-version-join next-version))) 708 (package-version-join next-version)))
709 (unless (version-list-<= next-version 709 (unless (version-list-<= next-version
710 (package-desc-vers (cdr pkg-desc))) 710 (package-desc-vers (cdr pkg-desc)))
711 (error 711 (error
712 "Need package '%s' with version %s, but only %s is available" 712 "Need package `%s-%s', but only %s is available"
713 (symbol-name next-pkg) (package-version-join next-version) 713 (symbol-name next-pkg) (package-version-join next-version)
714 (package-version-join (package-desc-vers (cdr pkg-desc))))) 714 (package-version-join (package-desc-vers (cdr pkg-desc)))))
715 ;; Only add to the transaction if we don't already have it. 715 ;; Only add to the transaction if we don't already have it.
716 (unless (memq next-pkg package-list) 716 (unless (memq next-pkg package-list)
717 (push next-pkg package-list)) 717 (push next-pkg package-list))
817 nil)) 817 nil))
818 package-archive-contents) 818 package-archive-contents)
819 nil t)))) 819 nil t))))
820 (let ((pkg-desc (assq name package-archive-contents))) 820 (let ((pkg-desc (assq name package-archive-contents)))
821 (unless pkg-desc 821 (unless pkg-desc
822 (error "Package '%s' is not available for installation" 822 (error "Package `%s' is not available for installation"
823 (symbol-name name))) 823 (symbol-name name)))
824 (package-download-transaction 824 (package-download-transaction
825 (package-compute-transaction (list name) 825 (package-compute-transaction (list name)
826 (package-desc-reqs (cdr pkg-desc))))) 826 (package-desc-reqs (cdr pkg-desc)))))
827 ;; Try to activate it. 827 ;; Try to activate it.
974 ((string-match "\\.tar$" file) 974 ((string-match "\\.tar$" file)
975 (package-install-from-buffer (package-tar-file-info file) 'tar)) 975 (package-install-from-buffer (package-tar-file-info file) 'tar))
976 (t (error "Unrecognized extension `%s'" (file-name-extension file)))))) 976 (t (error "Unrecognized extension `%s'" (file-name-extension file))))))
977 977
978 (defun package-delete (name version) 978 (defun package-delete (name version)
979 (require 'dired) ; for dired-delete-file 979 (let ((dir (package--dir name version)))
980 (dired-delete-file (expand-file-name (concat name "-" version) 980 (if (string-equal (file-name-directory dir)
981 package-user-dir) 981 (file-name-as-directory
982 ;; FIXME: query user? 982 (expand-file-name package-user-dir)))
983 'always)) 983 (progn
984 (delete-directory dir t t)
985 (message "Package `%s-%s' deleted." name version))
986 ;; Don't delete "system" packages
987 (error "Package `%s-%s' is a system package, not deleting"
988 name version))))
984 989
985 (defun package-archive-url (name) 990 (defun package-archive-url (name)
986 "Return the archive containing the package NAME." 991 "Return the archive containing the package NAME."
987 (let ((desc (cdr (assq (intern-soft name) package-archive-contents)))) 992 (let ((desc (cdr (assq (intern-soft name) package-archive-contents))))
988 (cdr (assoc (aref desc (- (length desc) 1)) package-archives)))) 993 (cdr (assoc (aref desc (- (length desc) 1)) package-archives))))
1028 (defun package-initialize (&optional no-activate) 1033 (defun package-initialize (&optional no-activate)
1029 "Load Emacs Lisp packages, and activate them. 1034 "Load Emacs Lisp packages, and activate them.
1030 The variable `package-load-list' controls which packages to load. 1035 The variable `package-load-list' controls which packages to load.
1031 If optional arg NO-ACTIVATE is non-nil, don't activate packages." 1036 If optional arg NO-ACTIVATE is non-nil, don't activate packages."
1032 (interactive) 1037 (interactive)
1033 (setq package-obsolete-alist nil) 1038 (setq package-alist nil
1039 package-obsolete-alist nil)
1034 (package-load-all-descriptors) 1040 (package-load-all-descriptors)
1035 (package-read-all-archive-contents) 1041 (package-read-all-archive-contents)
1036 (unless no-activate 1042 (unless no-activate
1037 (dolist (elt package-alist) 1043 (dolist (elt package-alist)
1038 (package-activate (car elt) (package-desc-vers (cdr elt))))) 1044 (package-activate (car elt) (package-desc-vers (cdr elt)))))
1359 1365
1360 ;; fixme numeric argument 1366 ;; fixme numeric argument
1361 (defun package-menu-mark-delete (num) 1367 (defun package-menu-mark-delete (num)
1362 "Mark a package for deletion and move to the next line." 1368 "Mark a package for deletion and move to the next line."
1363 (interactive "p") 1369 (interactive "p")
1364 (package-menu-mark-internal "D")) 1370 (if (string-equal (package-menu-get-status) "installed")
1371 (package-menu-mark-internal "D")
1372 (forward-line)))
1365 1373
1366 (defun package-menu-mark-install (num) 1374 (defun package-menu-mark-install (num)
1367 "Mark a package for installation and move to the next line." 1375 "Mark a package for installation and move to the next line."
1368 (interactive "p") 1376 (interactive "p")
1369 (package-menu-mark-internal "I")) 1377 (if (string-equal (package-menu-get-status) "available")
1378 (package-menu-mark-internal "I")
1379 (forward-line)))
1370 1380
1371 (defun package-menu-mark-unmark (num) 1381 (defun package-menu-mark-unmark (num)
1372 "Clear any marks on a package and move to the next line." 1382 "Clear any marks on a package and move to the next line."
1373 (interactive "p") 1383 (interactive "p")
1374 (package-menu-mark-internal " ")) 1384 (package-menu-mark-internal " "))
1418 (if (looking-at ". [^ \t]*[ \t]*[^ \t]*[ \t]*\\([^ \t]*\\)") 1428 (if (looking-at ". [^ \t]*[ \t]*[^ \t]*[ \t]*\\([^ \t]*\\)")
1419 (match-string 1) 1429 (match-string 1)
1420 ""))) 1430 "")))
1421 1431
1422 (defun package-menu-execute () 1432 (defun package-menu-execute ()
1423 "Perform all the marked actions. 1433 "Perform marked Package Menu actions.
1424 Packages marked for installation will be downloaded and 1434 Packages marked for installation are downloaded and installed;
1425 installed. Packages marked for deletion will be removed. 1435 packages marked for deletion are removed."
1426 Note that after installing packages you will want to restart
1427 Emacs."
1428 (interactive) 1436 (interactive)
1429 (goto-char (point-min)) 1437 (let (install-list delete-list cmd)
1430 (while (not (eobp)) 1438 (save-excursion
1431 (let ((cmd (char-after)) 1439 (goto-char (point-min))
1432 (pkg-name (package-menu-get-package)) 1440 (while (not (eobp))
1433 (pkg-vers (package-menu-get-version)) 1441 (setq cmd (char-after))
1434 (pkg-status (package-menu-get-status))) 1442 (cond
1435 (cond 1443 ((eq cmd ?\s) t)
1436 ((eq cmd ?D) 1444 ((eq cmd ?D)
1437 (when (and (string= pkg-status "installed") 1445 (push (cons (package-menu-get-package)
1438 (string= pkg-name "package")) 1446 (package-menu-get-version))
1439 ;; FIXME: actually, we could be tricky and remove all info. 1447 delete-list))
1440 ;; But that is drastic and the user can do that instead. 1448 ((eq cmd ?I)
1441 (error "Can't delete most recent version of `package'")) 1449 (push (package-menu-get-package) install-list)))
1442 ;; Ask for confirmation here? Maybe if package status is ""? 1450 (forward-line)))
1443 ;; Or if any lisp from package is actually loaded? 1451 ;; Delete packages, prompting if necessary.
1444 (message "Deleting %s-%s..." pkg-name pkg-vers) 1452 (when delete-list
1445 (package-delete pkg-name pkg-vers) 1453 (if (yes-or-no-p
1446 (message "Deleting %s-%s... done" pkg-name pkg-vers)) 1454 (if (= (length delete-list) 1)
1447 ((eq cmd ?I) 1455 (format "Delete package `%s-%s'? "
1448 (package-install (intern pkg-name))))) 1456 (caar delete-list)
1449 (forward-line)) 1457 (cdr (car delete-list)))
1450 (package-menu-revert)) 1458 (format "Delete these %d packages (%s)? "
1459 (length delete-list)
1460 (mapconcat (lambda (elt)
1461 (concat (car elt) "-" (cdr elt)))
1462 delete-list
1463 ", "))))
1464 (dolist (elt delete-list)
1465 (condition-case err
1466 (package-delete (car elt) (cdr elt))
1467 (error (message (cadr err)))))
1468 (error "Aborted")))
1469 (when install-list
1470 (if (yes-or-no-p
1471 (if (= (length install-list) 1)
1472 (format "Install package `%s'? " (car install-list))
1473 (format "Install these %d packages (%s)? "
1474 (length install-list)
1475 (mapconcat 'identity install-list ", "))))
1476 (dolist (elt install-list)
1477 (package-install (intern elt)))))
1478 ;; If we deleted anything, regenerate `package-alist'. This is done
1479 ;; automatically if we installed a package.
1480 (and delete-list (null install-list)
1481 (package-initialize))
1482 (if (or delete-list install-list)
1483 (package-menu-revert)
1484 (message "No operations specified."))))
1451 1485
1452 (defun package-print-package (package version key desc) 1486 (defun package-print-package (package version key desc)
1453 (let ((face 1487 (let ((face
1454 (cond ((string= key "built-in") 'font-lock-builtin-face) 1488 (cond ((string= key "built-in") 'font-lock-builtin-face)
1455 ((string= key "available") 'default) 1489 ((string= key "available") 'default)