diff options
| author | Stefan Monnier | 2013-06-20 23:08:47 -0400 |
|---|---|---|
| committer | Stefan Monnier | 2013-06-20 23:08:47 -0400 |
| commit | fd846ab406e00ac85b6ed01a6715e795a549c02f (patch) | |
| tree | 4134d89eb45a3a63fce8902d7d07f1f5ffd49e34 | |
| parent | d1f7f5a0d927a5a51c989fcf97688e57916bf9d9 (diff) | |
| download | emacs-fd846ab406e00ac85b6ed01a6715e795a549c02f.tar.gz emacs-fd846ab406e00ac85b6ed01a6715e795a549c02f.zip | |
* lisp/emacs-lisp/package.el: Use tar-mode rather than tar executable.
Consolidate the single-file vs tarball code.
(package-desc-suffix): New function.
(package-desc-full-name): Don't bother inlining it.
(package-load-descriptor): Return the new package-desc.
(package-mark-obsolete): Remove unused arg `package'.
(package-unpack): Make it work for single files as well.
Make it update package-alist.
(package--make-autoloads-and-stuff): Rename from
package--make-autoloads-and-compile. Don't compile any more.
(package--compile): New function.
(package-generate-description-file): New function, extracted from
package-unpack-single.
(package-unpack-single): Remove.
(package--with-work-buffer): Add indentation and debugging info.
(package-download-single): Remove.
(package-install-from-archive): Rename from package-download-tar, make
it take a pkg-desc, and make it work for single files as well.
(package-download-transaction): Simplify.
(package-tar-file-info): Remove `file' arg. Rewrite not to use an
external tar program.
(package-install-from-buffer): Remove `pkg-desc' argument.
Use package-tar-file-info for tar-mode buffers.
(package-install-file): Simplify accordingly.
(package-archive-base): Change to take a pkg-desc.
* lisp/tar-mode.el (tar--check-descriptor): New function, extracted from
tar-get-descriptor.
(tar-get-descriptor): Use it.
(tar-get-file-descriptor): New function.
(tar--extract): New function, extracted from tar-extract.
(tar--extract): Use it.
* lisp/emacs-lisp/package-x.el (package-upload-file): Decode the file, in
case the summary uses non-ascii. Adjust to new calling convention of
package-tar-file-info.
| -rw-r--r-- | lisp/ChangeLog | 46 | ||||
| -rw-r--r-- | lisp/emacs-lisp/package-x.el | 5 | ||||
| -rw-r--r-- | lisp/emacs-lisp/package.el | 302 | ||||
| -rw-r--r-- | lisp/tar-mode.el | 193 |
4 files changed, 284 insertions, 262 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog index e4c67dde1d9..39013982477 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog | |||
| @@ -1,7 +1,45 @@ | |||
| 1 | 2013-06-21 Stefan Monnier <monnier@iro.umontreal.ca> | ||
| 2 | Daniel Hackney <dan@haxney.org> | ||
| 3 | |||
| 4 | * emacs-lisp/package.el: Use tar-mode rather than tar executable. | ||
| 5 | Consolidate the single-file vs tarball code. | ||
| 6 | (package-desc-suffix): New function. | ||
| 7 | (package-desc-full-name): Don't bother inlining it. | ||
| 8 | (package-load-descriptor): Return the new package-desc. | ||
| 9 | (package-mark-obsolete): Remove unused arg `package'. | ||
| 10 | (package-unpack): Make it work for single files as well. | ||
| 11 | Make it update package-alist. | ||
| 12 | (package--make-autoloads-and-stuff): Rename from | ||
| 13 | package--make-autoloads-and-compile. Don't compile any more. | ||
| 14 | (package--compile): New function. | ||
| 15 | (package-generate-description-file): New function, extracted from | ||
| 16 | package-unpack-single. | ||
| 17 | (package-unpack-single): Remove. | ||
| 18 | (package--with-work-buffer): Add indentation and debugging info. | ||
| 19 | (package-download-single): Remove. | ||
| 20 | (package-install-from-archive): Rename from package-download-tar, make | ||
| 21 | it take a pkg-desc, and make it work for single files as well. | ||
| 22 | (package-download-transaction): Simplify. | ||
| 23 | (package-tar-file-info): Remove `file' arg. Rewrite not to use an | ||
| 24 | external tar program. | ||
| 25 | (package-install-from-buffer): Remove `pkg-desc' argument. | ||
| 26 | Use package-tar-file-info for tar-mode buffers. | ||
| 27 | (package-install-file): Simplify accordingly. | ||
| 28 | (package-archive-base): Change to take a pkg-desc. | ||
| 29 | * tar-mode.el (tar--check-descriptor): New function, extracted from | ||
| 30 | tar-get-descriptor. | ||
| 31 | (tar-get-descriptor): Use it. | ||
| 32 | (tar-get-file-descriptor): New function. | ||
| 33 | (tar--extract): New function, extracted from tar-extract. | ||
| 34 | (tar--extract): Use it. | ||
| 35 | * emacs-lisp/package-x.el (package-upload-file): Decode the file, in | ||
| 36 | case the summary uses non-ascii. Adjust to new calling convention of | ||
| 37 | package-tar-file-info. | ||
| 38 | |||
| 1 | 2013-06-21 Leo Liu <sdl.web@gmail.com> | 39 | 2013-06-21 Leo Liu <sdl.web@gmail.com> |
| 2 | 40 | ||
| 3 | * comint.el (comint-redirect-results-list-from-process): Fix | 41 | * comint.el (comint-redirect-results-list-from-process): |
| 4 | random delay. (Bug#14681) | 42 | Fix random delay. (Bug#14681) |
| 5 | 43 | ||
| 6 | 2013-06-21 Juanma Barranquero <lekktu@gmail.com> | 44 | 2013-06-21 Juanma Barranquero <lekktu@gmail.com> |
| 7 | 45 | ||
| @@ -135,8 +173,8 @@ | |||
| 135 | 2013-06-19 Michael Albinus <michael.albinus@gmx.de> | 173 | 2013-06-19 Michael Albinus <michael.albinus@gmx.de> |
| 136 | 174 | ||
| 137 | * net/secrets.el (secrets-struct-secret-content-type): Replace | 175 | * net/secrets.el (secrets-struct-secret-content-type): Replace |
| 138 | check of introspection data by a test call of "CreateItem". Some | 176 | check of introspection data by a test call of "CreateItem". |
| 139 | servers do not offer introspection. | 177 | Some servers do not offer introspection. |
| 140 | 178 | ||
| 141 | 2013-06-19 Stefan Monnier <monnier@iro.umontreal.ca> | 179 | 2013-06-19 Stefan Monnier <monnier@iro.umontreal.ca> |
| 142 | 180 | ||
diff --git a/lisp/emacs-lisp/package-x.el b/lisp/emacs-lisp/package-x.el index 3300e89ec1e..7d0d75f7cee 100644 --- a/lisp/emacs-lisp/package-x.el +++ b/lisp/emacs-lisp/package-x.el | |||
| @@ -291,10 +291,11 @@ If `package-archive-upload-base' does not specify a valid upload | |||
| 291 | destination, prompt for one." | 291 | destination, prompt for one." |
| 292 | (interactive "fPackage file name: ") | 292 | (interactive "fPackage file name: ") |
| 293 | (with-temp-buffer | 293 | (with-temp-buffer |
| 294 | (insert-file-contents-literally file) | 294 | (insert-file-contents file) |
| 295 | (let ((pkg-desc | 295 | (let ((pkg-desc |
| 296 | (cond | 296 | (cond |
| 297 | ((string-match "\\.tar\\'" file) (package-tar-file-info file)) | 297 | ((string-match "\\.tar\\'" file) |
| 298 | (tar-mode) (package-tar-file-info)) | ||
| 298 | ((string-match "\\.el\\'" file) (package-buffer-info)) | 299 | ((string-match "\\.el\\'" file) (package-buffer-info)) |
| 299 | (t (error "Unrecognized extension `%s'" | 300 | (t (error "Unrecognized extension `%s'" |
| 300 | (file-name-extension file)))))) | 301 | (file-name-extension file)))))) |
diff --git a/lisp/emacs-lisp/package.el b/lisp/emacs-lisp/package.el index ae4ebb87ee2..1bf1e6027e2 100644 --- a/lisp/emacs-lisp/package.el +++ b/lisp/emacs-lisp/package.el | |||
| @@ -340,11 +340,17 @@ package came. | |||
| 340 | dir) | 340 | dir) |
| 341 | 341 | ||
| 342 | ;; Pseudo fields. | 342 | ;; Pseudo fields. |
| 343 | (defsubst package-desc-full-name (pkg-desc) | 343 | (defun package-desc-full-name (pkg-desc) |
| 344 | (format "%s-%s" | 344 | (format "%s-%s" |
| 345 | (package-desc-name pkg-desc) | 345 | (package-desc-name pkg-desc) |
| 346 | (package-version-join (package-desc-version pkg-desc)))) | 346 | (package-version-join (package-desc-version pkg-desc)))) |
| 347 | 347 | ||
| 348 | (defun package-desc-suffix (pkg-desc) | ||
| 349 | (pcase (package-desc-kind pkg-desc) | ||
| 350 | (`single ".el") | ||
| 351 | (`tar ".tar") | ||
| 352 | (kind (error "Unknown package kind: %s" kind)))) | ||
| 353 | |||
| 348 | ;; Package descriptor format used in finder-inf.el and package--builtins. | 354 | ;; Package descriptor format used in finder-inf.el and package--builtins. |
| 349 | (cl-defstruct (package--bi-desc | 355 | (cl-defstruct (package--bi-desc |
| 350 | (:constructor package-make-builtin (version summary)) | 356 | (:constructor package-make-builtin (version summary)) |
| @@ -422,7 +428,8 @@ This is, approximately, the inverse of `version-to-list'. | |||
| 422 | (goto-char (point-min)) | 428 | (goto-char (point-min)) |
| 423 | (let ((pkg-desc (package-process-define-package | 429 | (let ((pkg-desc (package-process-define-package |
| 424 | (read (current-buffer)) pkg-file))) | 430 | (read (current-buffer)) pkg-file))) |
| 425 | (setf (package-desc-dir pkg-desc) pkg-dir)))))) | 431 | (setf (package-desc-dir pkg-desc) pkg-dir) |
| 432 | pkg-desc))))) | ||
| 426 | 433 | ||
| 427 | (defun package-load-all-descriptors () | 434 | (defun package-load-all-descriptors () |
| 428 | "Load descriptors for installed Emacs Lisp packages. | 435 | "Load descriptors for installed Emacs Lisp packages. |
| @@ -529,13 +536,13 @@ Required package `%s-%s' is unavailable" | |||
| 529 | ;; If all goes well, activate the package itself. | 536 | ;; If all goes well, activate the package itself. |
| 530 | (package-activate-1 pkg-vec))))))) | 537 | (package-activate-1 pkg-vec))))))) |
| 531 | 538 | ||
| 532 | (defun package-mark-obsolete (package pkg-vec) | 539 | (defun package-mark-obsolete (pkg-desc) |
| 533 | "Put package on the obsolete list, if not already there." | 540 | "Put PKG-DESC on the obsolete list, if not already there." |
| 534 | (push pkg-vec package-obsolete-list)) | 541 | (push pkg-desc package-obsolete-list)) |
| 535 | 542 | ||
| 536 | (defun define-package (name-string version-string | 543 | (defun define-package (_name-string _version-string |
| 537 | &optional docstring requirements | 544 | &optional _docstring _requirements |
| 538 | &rest _extra-properties) | 545 | &rest _extra-properties) |
| 539 | "Define a new package. | 546 | "Define a new package. |
| 540 | NAME-STRING is the name of the package, as a string. | 547 | NAME-STRING is the name of the package, as a string. |
| 541 | VERSION-STRING is the version of the package, as a string. | 548 | VERSION-STRING is the version of the package, as a string. |
| @@ -559,13 +566,13 @@ EXTRA-PROPERTIES is currently unused." | |||
| 559 | ;; If it's not newer than a builtin version, mark it obsolete. | 566 | ;; If it's not newer than a builtin version, mark it obsolete. |
| 560 | ((let ((bi (assq name package--builtin-versions))) | 567 | ((let ((bi (assq name package--builtin-versions))) |
| 561 | (and bi (version-list-<= version (cdr bi)))) | 568 | (and bi (version-list-<= version (cdr bi)))) |
| 562 | (package-mark-obsolete name new-pkg-desc)) | 569 | (package-mark-obsolete new-pkg-desc)) |
| 563 | ;; If there's no old package, just add this to `package-alist'. | 570 | ;; If there's no old package, just add this to `package-alist'. |
| 564 | ((null old-pkg) | 571 | ((null old-pkg) |
| 565 | (push (cons name new-pkg-desc) package-alist)) | 572 | (push (cons name new-pkg-desc) package-alist)) |
| 566 | ((version-list-< (package-desc-version (cdr old-pkg)) version) | 573 | ((version-list-< (package-desc-version (cdr old-pkg)) version) |
| 567 | ;; Remove the old package and declare it obsolete. | 574 | ;; Remove the old package and declare it obsolete. |
| 568 | (package-mark-obsolete name (cdr old-pkg)) | 575 | (package-mark-obsolete (cdr old-pkg)) |
| 569 | (setq package-alist (cons (cons name new-pkg-desc) | 576 | (setq package-alist (cons (cons name new-pkg-desc) |
| 570 | (delq old-pkg package-alist)))) | 577 | (delq old-pkg package-alist)))) |
| 571 | ;; You can have two packages with the same version, e.g. one in | 578 | ;; You can have two packages with the same version, e.g. one in |
| @@ -573,10 +580,10 @@ EXTRA-PROPERTIES is currently unused." | |||
| 573 | ;; directory. We just let the first one win. | 580 | ;; directory. We just let the first one win. |
| 574 | ((not (version-list-= (package-desc-version (cdr old-pkg)) version)) | 581 | ((not (version-list-= (package-desc-version (cdr old-pkg)) version)) |
| 575 | ;; The package is born obsolete. | 582 | ;; The package is born obsolete. |
| 576 | (package-mark-obsolete name new-pkg-desc))) | 583 | (package-mark-obsolete new-pkg-desc))) |
| 577 | new-pkg-desc)) | 584 | new-pkg-desc)) |
| 578 | 585 | ||
| 579 | ;; From Emacs 22. | 586 | ;; From Emacs 22, but changed so it adds to load-path. |
| 580 | (defun package-autoload-ensure-default-file (file) | 587 | (defun package-autoload-ensure-default-file (file) |
| 581 | "Make sure that the autoload file FILE exists and if not create it." | 588 | "Make sure that the autoload file FILE exists and if not create it." |
| 582 | (unless (file-exists-p file) | 589 | (unless (file-exists-p file) |
| @@ -632,74 +639,79 @@ untar into a directory named DIR; otherwise, signal an error." | |||
| 632 | (error "Package does not untar cleanly into directory %s/" dir))))) | 639 | (error "Package does not untar cleanly into directory %s/" dir))))) |
| 633 | (tar-untar-buffer)) | 640 | (tar-untar-buffer)) |
| 634 | 641 | ||
| 635 | (defun package-unpack (package version) | 642 | (defun package-generate-description-file (pkg-desc pkg-dir) |
| 636 | (let* ((name (symbol-name package)) | 643 | "Create the foo-pkg.el file for single-file packages." |
| 637 | (dirname (concat name "-" version)) | 644 | (let* ((name (package-desc-name pkg-desc)) |
| 645 | (pkg-file (expand-file-name (package--description-file pkg-dir) | ||
| 646 | pkg-dir))) | ||
| 647 | (let ((print-level nil) | ||
| 648 | (print-quoted t) | ||
| 649 | (print-length nil)) | ||
| 650 | (write-region | ||
| 651 | (concat | ||
| 652 | (prin1-to-string | ||
| 653 | (list 'define-package | ||
| 654 | (symbol-name name) | ||
| 655 | (package-version-join (package-desc-version pkg-desc)) | ||
| 656 | (package-desc-summary pkg-desc) | ||
| 657 | (let ((requires (package-desc-reqs pkg-desc))) | ||
| 658 | (list 'quote | ||
| 659 | ;; Turn version lists into string form. | ||
| 660 | (mapcar | ||
| 661 | (lambda (elt) | ||
| 662 | (list (car elt) | ||
| 663 | (package-version-join (cadr elt)))) | ||
| 664 | requires))))) | ||
| 665 | "\n") | ||
| 666 | nil | ||
| 667 | pkg-file)))) | ||
| 668 | |||
| 669 | (defun package-unpack (pkg-desc) | ||
| 670 | "Install the contents of the current buffer as a package." | ||
| 671 | (let* ((name (package-desc-name pkg-desc)) | ||
| 672 | (dirname (package-desc-full-name pkg-desc)) | ||
| 638 | (pkg-dir (expand-file-name dirname package-user-dir))) | 673 | (pkg-dir (expand-file-name dirname package-user-dir))) |
| 639 | (make-directory package-user-dir t) | 674 | (pcase (package-desc-kind pkg-desc) |
| 640 | ;; FIXME: should we delete PKG-DIR if it exists? | 675 | (`tar |
| 641 | (let* ((default-directory (file-name-as-directory package-user-dir))) | 676 | (make-directory package-user-dir t) |
| 642 | (package-untar-buffer dirname) | 677 | ;; FIXME: should we delete PKG-DIR if it exists? |
| 643 | (package--make-autoloads-and-compile package pkg-dir) | 678 | (let* ((default-directory (file-name-as-directory package-user-dir))) |
| 644 | pkg-dir))) | 679 | (package-untar-buffer dirname))) |
| 645 | 680 | (`single | |
| 646 | (defun package--make-autoloads-and-compile (name pkg-dir) | 681 | (let ((el-file (expand-file-name (format "%s.el" name) pkg-dir))) |
| 647 | "Generate autoloads and do byte-compilation for package named NAME. | 682 | (make-directory pkg-dir t) |
| 648 | PKG-DIR is the name of the package directory." | 683 | (package--write-file-no-coding el-file))) |
| 649 | (let ((auto-name (package-generate-autoloads name pkg-dir)) | 684 | (kind (error "Unknown package kind: %S" kind))) |
| 650 | (load-path (cons pkg-dir load-path))) | 685 | (package--make-autoloads-and-stuff pkg-desc pkg-dir) |
| 651 | ;; We must load the autoloads file before byte compiling, in | 686 | ;; Update package-alist. |
| 652 | ;; case there are magic cookies to set up non-trivial paths. | 687 | (let ((new-desc (package-load-descriptor pkg-dir))) |
| 653 | (load auto-name nil t) | 688 | ;; FIXME: Check that `new-desc' matches `desc'! |
| 654 | ;; FIXME: Compilation should be done as a separate, optional, step. | 689 | ;; FIXME: Compilation should be done as a separate, optional, step. |
| 655 | ;; E.g. for multi-package installs, we should first install all packages | 690 | ;; E.g. for multi-package installs, we should first install all packages |
| 656 | ;; and then compile them. | 691 | ;; and then compile them. |
| 657 | (byte-recompile-directory pkg-dir 0 t))) | 692 | (package--compile new-desc)) |
| 693 | ;; Try to activate it. | ||
| 694 | (package-activate name (package-desc-version pkg-desc)) | ||
| 695 | pkg-dir)) | ||
| 696 | |||
| 697 | (defun package--make-autoloads-and-stuff (pkg-desc pkg-dir) | ||
| 698 | "Generate autoloads, description file, etc.. for PKG-DESC installed at PKG-DIR." | ||
| 699 | (package-generate-autoloads (package-desc-name pkg-desc) pkg-dir) | ||
| 700 | (let ((desc-file (package--description-file pkg-dir))) | ||
| 701 | (unless (file-exists-p desc-file) | ||
| 702 | (package-generate-description-file pkg-desc pkg-dir))) | ||
| 703 | ;; FIXME: Create foo.info and dir file from foo.texi? | ||
| 704 | ) | ||
| 705 | |||
| 706 | (defun package--compile (pkg-desc) | ||
| 707 | "Byte-compile installed package PKG-DESC." | ||
| 708 | (package-activate-1 pkg-desc) | ||
| 709 | (byte-recompile-directory (package-desc-dir pkg-desc) 0 t)) | ||
| 658 | 710 | ||
| 659 | (defun package--write-file-no-coding (file-name) | 711 | (defun package--write-file-no-coding (file-name) |
| 660 | (let ((buffer-file-coding-system 'no-conversion)) | 712 | (let ((buffer-file-coding-system 'no-conversion)) |
| 661 | (write-region (point-min) (point-max) file-name))) | 713 | (write-region (point-min) (point-max) file-name))) |
| 662 | 714 | ||
| 663 | (defun package-unpack-single (name version desc requires) | ||
| 664 | "Install the contents of the current buffer as a package." | ||
| 665 | ;; Special case "package". FIXME: Should this still be supported? | ||
| 666 | (if (eq name 'package) | ||
| 667 | (package--write-file-no-coding | ||
| 668 | (expand-file-name (format "%s.el" name) package-user-dir)) | ||
| 669 | (let* ((pkg-dir (expand-file-name (format "%s-%s" name | ||
| 670 | (package-version-join | ||
| 671 | (version-to-list version))) | ||
| 672 | package-user-dir)) | ||
| 673 | (el-file (expand-file-name (format "%s.el" name) pkg-dir)) | ||
| 674 | (pkg-file (expand-file-name (package--description-file pkg-dir) | ||
| 675 | pkg-dir))) | ||
| 676 | (make-directory pkg-dir t) | ||
| 677 | (package--write-file-no-coding el-file) | ||
| 678 | (let ((print-level nil) | ||
| 679 | (print-quoted t) | ||
| 680 | (print-length nil)) | ||
| 681 | (write-region | ||
| 682 | (concat | ||
| 683 | (prin1-to-string | ||
| 684 | (list 'define-package | ||
| 685 | (symbol-name name) | ||
| 686 | version | ||
| 687 | desc | ||
| 688 | (when requires ;Don't bother quoting nil. | ||
| 689 | (list 'quote | ||
| 690 | ;; Turn version lists into string form. | ||
| 691 | (mapcar | ||
| 692 | (lambda (elt) | ||
| 693 | (list (car elt) | ||
| 694 | (package-version-join (cadr elt)))) | ||
| 695 | requires))))) | ||
| 696 | "\n") | ||
| 697 | nil | ||
| 698 | pkg-file | ||
| 699 | nil nil nil 'excl)) | ||
| 700 | (package--make-autoloads-and-compile name pkg-dir) | ||
| 701 | pkg-dir))) | ||
| 702 | |||
| 703 | (defmacro package--with-work-buffer (location file &rest body) | 715 | (defmacro package--with-work-buffer (location file &rest body) |
| 704 | "Run BODY in a buffer containing the contents of FILE at LOCATION. | 716 | "Run BODY in a buffer containing the contents of FILE at LOCATION. |
| 705 | LOCATION is the base location of a package archive, and should be | 717 | LOCATION is the base location of a package archive, and should be |
| @@ -709,6 +721,7 @@ FILE is the name of a file relative to that base location. | |||
| 709 | This macro retrieves FILE from LOCATION into a temporary buffer, | 721 | This macro retrieves FILE from LOCATION into a temporary buffer, |
| 710 | and evaluates BODY while that buffer is current. This work | 722 | and evaluates BODY while that buffer is current. This work |
| 711 | buffer is killed afterwards. Return the last value in BODY." | 723 | buffer is killed afterwards. Return the last value in BODY." |
| 724 | (declare (indent 2) (debug t)) | ||
| 712 | `(let* ((http (string-match "\\`https?:" ,location)) | 725 | `(let* ((http (string-match "\\`https?:" ,location)) |
| 713 | (buffer | 726 | (buffer |
| 714 | (if http | 727 | (if http |
| @@ -741,19 +754,13 @@ It will move point to somewhere in the headers." | |||
| 741 | (error "Error during download request:%s" | 754 | (error "Error during download request:%s" |
| 742 | (buffer-substring-no-properties (point) (line-end-position)))))) | 755 | (buffer-substring-no-properties (point) (line-end-position)))))) |
| 743 | 756 | ||
| 744 | (defun package-download-single (name version desc requires) | 757 | (defun package-install-from-archive (pkg-desc) |
| 745 | "Download and install a single-file package." | ||
| 746 | (let ((location (package-archive-base name)) | ||
| 747 | (file (concat (symbol-name name) "-" version ".el"))) | ||
| 748 | (package--with-work-buffer location file | ||
| 749 | (package-unpack-single name version desc requires)))) | ||
| 750 | |||
| 751 | (defun package-download-tar (name version) | ||
| 752 | "Download and install a tar package." | 758 | "Download and install a tar package." |
| 753 | (let ((location (package-archive-base name)) | 759 | (let ((location (package-archive-base pkg-desc)) |
| 754 | (file (concat (symbol-name name) "-" version ".tar"))) | 760 | (file (concat (package-desc-full-name pkg-desc) |
| 761 | (package-desc-suffix pkg-desc)))) | ||
| 755 | (package--with-work-buffer location file | 762 | (package--with-work-buffer location file |
| 756 | (package-unpack name version)))) | 763 | (package-unpack pkg-desc)))) |
| 757 | 764 | ||
| 758 | (defvar package--initialized nil) | 765 | (defvar package--initialized nil) |
| 759 | 766 | ||
| @@ -918,30 +925,8 @@ PACKAGE-LIST are satisfied, i.e. that PACKAGE-LIST is computed | |||
| 918 | using `package-compute-transaction'." | 925 | using `package-compute-transaction'." |
| 919 | ;; FIXME: make package-list a list of pkg-desc. | 926 | ;; FIXME: make package-list a list of pkg-desc. |
| 920 | (dolist (elt package-list) | 927 | (dolist (elt package-list) |
| 921 | (let* ((desc (cdr (assq elt package-archive-contents))) | 928 | (let ((desc (cdr (assq elt package-archive-contents)))) |
| 922 | ;; As an exception, if package is "held" in | 929 | (package-install-from-archive desc)))) |
| 923 | ;; `package-load-list', download the held version. | ||
| 924 | (hold (cadr (assq elt package-load-list))) | ||
| 925 | (v-string (or (and (stringp hold) hold) | ||
| 926 | (package-version-join (package-desc-version desc)))) | ||
| 927 | (kind (package-desc-kind desc)) | ||
| 928 | (pkg-dir | ||
| 929 | (cond | ||
| 930 | ((eq kind 'tar) | ||
| 931 | (package-download-tar elt v-string)) | ||
| 932 | ((eq kind 'single) | ||
| 933 | (package-download-single elt v-string | ||
| 934 | (package-desc-summary desc) | ||
| 935 | (package-desc-reqs desc))) | ||
| 936 | (t | ||
| 937 | (error "Unknown package kind: %s" (symbol-name kind)))))) | ||
| 938 | ;; Update package-alist. | ||
| 939 | ;; FIXME: Check that the installed package's descriptor matches `desc'! | ||
| 940 | (package-load-descriptor pkg-dir) | ||
| 941 | ;; If package A depends on package B, then A may `require' B | ||
| 942 | ;; during byte compilation. So we need to activate B before | ||
| 943 | ;; unpacking A. | ||
| 944 | (package-activate elt (version-to-list v-string))))) | ||
| 945 | 930 | ||
| 946 | ;;;###autoload | 931 | ;;;###autoload |
| 947 | (defun package-install (pkg-desc) | 932 | (defun package-install (pkg-desc) |
| @@ -1018,60 +1003,48 @@ boundaries." | |||
| 1018 | (if requires-str (package-read-from-string requires-str)) | 1003 | (if requires-str (package-read-from-string requires-str)) |
| 1019 | :kind 'single)))) | 1004 | :kind 'single)))) |
| 1020 | 1005 | ||
| 1021 | (defun package-tar-file-info (file) | 1006 | (defun package-tar-file-info () |
| 1022 | "Find package information for a tar file. | 1007 | "Find package information for a tar file. |
| 1023 | FILE is the name of the tar file to examine. | 1008 | The return result is a `package-desc'." |
| 1024 | The return result is a vector like `package-buffer-info'." | 1009 | (cl-assert (derived-mode-p 'tar-mode)) |
| 1025 | (let* ((default-directory (file-name-directory file)) | 1010 | (let* ((dir-name (file-name-directory |
| 1026 | (file (file-name-nondirectory file)) | 1011 | (tar-header-name (car tar-parse-info)))) |
| 1027 | (dir-name | ||
| 1028 | (if (string-match "\\.tar\\'" file) | ||
| 1029 | (substring file 0 (match-beginning 0)) | ||
| 1030 | (error "Invalid package name `%s'" file))) | ||
| 1031 | (desc-file (package--description-file dir-name)) | 1012 | (desc-file (package--description-file dir-name)) |
| 1032 | ;; Extract the package descriptor. | 1013 | (tar-desc (tar-get-file-descriptor (concat dir-name desc-file)))) |
| 1033 | (pkg-def-contents (shell-command-to-string | 1014 | (unless tar-desc |
| 1034 | ;; Requires GNU tar. | 1015 | (error "No package descriptor file found")) |
| 1035 | (concat "tar -xOf " file " " | 1016 | (with-current-buffer (tar--extract tar-desc) |
| 1036 | dir-name "/" desc-file))) | 1017 | (goto-char (point-min)) |
| 1037 | (pkg-def-parsed (package-read-from-string pkg-def-contents))) | 1018 | (unwind-protect |
| 1038 | (unless (eq (car pkg-def-parsed) 'define-package) | 1019 | (let* ((pkg-def-parsed (read (current-buffer))) |
| 1039 | (error "Can't find define-package in %s" desc-file)) | 1020 | (pkg-desc |
| 1040 | (let ((pkg-desc | 1021 | (if (not (eq (car pkg-def-parsed) 'define-package)) |
| 1041 | (apply #'package-desc-from-define (append (cdr pkg-def-parsed) | 1022 | (error "Can't find define-package in %s" |
| 1042 | '(:kind tar))))) | 1023 | (tar-header-name tar-desc)) |
| 1043 | (unless (equal dir-name (package-desc-full-name pkg-desc)) | 1024 | (apply #'package-desc-from-define |
| 1044 | ;; FIXME: Shouldn't this just be a message/warning? | 1025 | (append (cdr pkg-def-parsed)))))) |
| 1045 | (error "Package has inconsistent name")) | 1026 | (setf (package-desc-kind pkg-desc) 'tar) |
| 1046 | pkg-desc))) | 1027 | pkg-desc) |
| 1028 | (kill-buffer (current-buffer)))))) | ||
| 1047 | 1029 | ||
| 1048 | 1030 | ||
| 1049 | ;;;###autoload | 1031 | ;;;###autoload |
| 1050 | (defun package-install-from-buffer (pkg-desc) | 1032 | (defun package-install-from-buffer () |
| 1051 | "Install a package from the current buffer. | 1033 | "Install a package from the current buffer. |
| 1052 | When called interactively, the current buffer is assumed to be a | 1034 | The current buffer is assumed to be a single .el or .tar file that follows the |
| 1053 | single .el file that follows the packaging guidelines; see info | 1035 | packaging guidelines; see info node `(elisp)Packaging'. |
| 1054 | node `(elisp)Packaging'. | 1036 | Downloads and installs required packages as needed." |
| 1055 | 1037 | (interactive) | |
| 1056 | When called from Lisp, PKG-DESC is a `package-desc' describing the | 1038 | (let ((pkg-desc (if (derived-mode-p 'tar-mode) |
| 1057 | information)." | 1039 | (package-tar-file-info) |
| 1058 | (interactive (list (package-buffer-info))) | 1040 | (package-buffer-info)))) |
| 1059 | (save-excursion | 1041 | ;; Download and install the dependencies. |
| 1060 | (save-restriction | 1042 | (let* ((requires (package-desc-reqs pkg-desc)) |
| 1061 | (let* ((name (package-desc-name pkg-desc)) | 1043 | (transaction (package-compute-transaction nil requires))) |
| 1062 | (requires (package-desc-reqs pkg-desc)) | 1044 | (package-download-transaction transaction)) |
| 1063 | (desc (package-desc-summary pkg-desc)) | 1045 | ;; Install the package itself. |
| 1064 | (pkg-version (package-desc-version pkg-desc))) | 1046 | (package-unpack pkg-desc) |
| 1065 | ;; Download and install the dependencies. | 1047 | pkg-desc)) |
| 1066 | (let ((transaction (package-compute-transaction nil requires))) | ||
| 1067 | (package-download-transaction transaction)) | ||
| 1068 | ;; Install the package itself. | ||
| 1069 | (pcase (package-desc-kind pkg-desc) | ||
| 1070 | (`single (package-unpack-single name pkg-version desc requires)) | ||
| 1071 | (`tar (package-unpack name pkg-version)) | ||
| 1072 | (type (error "Unknown type: %S" type))) | ||
| 1073 | ;; Try to activate it. | ||
| 1074 | (package-initialize))))) | ||
| 1075 | 1048 | ||
| 1076 | ;;;###autoload | 1049 | ;;;###autoload |
| 1077 | (defun package-install-file (file) | 1050 | (defun package-install-file (file) |
| @@ -1080,12 +1053,8 @@ The file can either be a tar file or an Emacs Lisp file." | |||
| 1080 | (interactive "fPackage file name: ") | 1053 | (interactive "fPackage file name: ") |
| 1081 | (with-temp-buffer | 1054 | (with-temp-buffer |
| 1082 | (insert-file-contents-literally file) | 1055 | (insert-file-contents-literally file) |
| 1083 | (cond | 1056 | (when (string-match "\\.tar\\'" file) (tar-mode)) |
| 1084 | ((string-match "\\.el\\'" file) | 1057 | (package-install-from-buffer))) |
| 1085 | (package-install-from-buffer (package-buffer-info))) | ||
| 1086 | ((string-match "\\.tar\\'" file) | ||
| 1087 | (package-install-from-buffer (package-tar-file-info file))) | ||
| 1088 | (t (error "Unrecognized extension `%s'" (file-name-extension file)))))) | ||
| 1089 | 1058 | ||
| 1090 | (defun package-delete (pkg-desc) | 1059 | (defun package-delete (pkg-desc) |
| 1091 | (let ((dir (package-desc-dir pkg-desc))) | 1060 | (let ((dir (package-desc-dir pkg-desc))) |
| @@ -1099,10 +1068,9 @@ The file can either be a tar file or an Emacs Lisp file." | |||
| 1099 | (error "Package `%s' is a system package, not deleting" | 1068 | (error "Package `%s' is a system package, not deleting" |
| 1100 | (package-desc-full-name pkg-desc))))) | 1069 | (package-desc-full-name pkg-desc))))) |
| 1101 | 1070 | ||
| 1102 | (defun package-archive-base (name) | 1071 | (defun package-archive-base (desc) |
| 1103 | "Return the archive containing the package NAME." | 1072 | "Return the archive containing the package NAME." |
| 1104 | (let ((desc (cdr (assq (intern-soft name) package-archive-contents)))) | 1073 | (cdr (assoc (package-desc-archive desc) package-archives))) |
| 1105 | (cdr (assoc (package-desc-archive desc) package-archives)))) | ||
| 1106 | 1074 | ||
| 1107 | (defun package--download-one-archive (archive file) | 1075 | (defun package--download-one-archive (archive file) |
| 1108 | "Retrieve an archive file FILE from ARCHIVE, and cache it. | 1076 | "Retrieve an archive file FILE from ARCHIVE, and cache it. |
| @@ -1292,7 +1260,7 @@ If optional arg NO-ACTIVATE is non-nil, don't activate packages." | |||
| 1292 | ;; For elpa packages, try downloading the commentary. If that | 1260 | ;; For elpa packages, try downloading the commentary. If that |
| 1293 | ;; fails, try an existing readme file in `package-user-dir'. | 1261 | ;; fails, try an existing readme file in `package-user-dir'. |
| 1294 | (cond ((condition-case nil | 1262 | (cond ((condition-case nil |
| 1295 | (package--with-work-buffer (package-archive-base package) | 1263 | (package--with-work-buffer (package-archive-base desc) |
| 1296 | (concat package-name "-readme.txt") | 1264 | (concat package-name "-readme.txt") |
| 1297 | (setq buffer-file-name | 1265 | (setq buffer-file-name |
| 1298 | (expand-file-name readme package-user-dir)) | 1266 | (expand-file-name readme package-user-dir)) |
diff --git a/lisp/tar-mode.el b/lisp/tar-mode.el index 109107e857f..be7bdb25d26 100644 --- a/lisp/tar-mode.el +++ b/lisp/tar-mode.el | |||
| @@ -740,10 +740,8 @@ tar-file's buffer." | |||
| 740 | nil | 740 | nil |
| 741 | (error "This line does not describe a tar-file entry")))) | 741 | (error "This line does not describe a tar-file entry")))) |
| 742 | 742 | ||
| 743 | (defun tar-get-descriptor () | 743 | (defun tar--check-descriptor (descriptor) |
| 744 | (let* ((descriptor (tar-current-descriptor)) | 744 | (let ((link-p (tar-header-link-type descriptor))) |
| 745 | (size (tar-header-size descriptor)) | ||
| 746 | (link-p (tar-header-link-type descriptor))) | ||
| 747 | (if link-p | 745 | (if link-p |
| 748 | (error "This is %s, not a real file" | 746 | (error "This is %s, not a real file" |
| 749 | (cond ((eq link-p 5) "a directory") | 747 | (cond ((eq link-p 5) "a directory") |
| @@ -754,10 +752,24 @@ tar-file's buffer." | |||
| 754 | ((eq link-p 38) "a volume header") | 752 | ((eq link-p 38) "a volume header") |
| 755 | ((eq link-p 55) "a pax global extended header") | 753 | ((eq link-p 55) "a pax global extended header") |
| 756 | ((eq link-p 72) "a pax extended header") | 754 | ((eq link-p 72) "a pax extended header") |
| 757 | (t "a link")))) | 755 | (t "a link")))))) |
| 756 | |||
| 757 | (defun tar-get-descriptor () | ||
| 758 | (let* ((descriptor (tar-current-descriptor)) | ||
| 759 | (size (tar-header-size descriptor))) | ||
| 760 | (tar--check-descriptor descriptor) | ||
| 758 | (if (zerop size) (message "This is a zero-length file")) | 761 | (if (zerop size) (message "This is a zero-length file")) |
| 759 | descriptor)) | 762 | descriptor)) |
| 760 | 763 | ||
| 764 | (defun tar-get-file-descriptor (file) | ||
| 765 | ;; Used by package.el. | ||
| 766 | (let ((desc ())) | ||
| 767 | (dolist (hdr tar-parse-info) | ||
| 768 | (when (equal file (tar-header-name hdr)) | ||
| 769 | (setq desc hdr))) | ||
| 770 | (tar--check-descriptor desc) | ||
| 771 | desc)) | ||
| 772 | |||
| 761 | (defun tar-mouse-extract (event) | 773 | (defun tar-mouse-extract (event) |
| 762 | "Extract a file whose tar directory line you click on." | 774 | "Extract a file whose tar directory line you click on." |
| 763 | (interactive "e") | 775 | (interactive "e") |
| @@ -776,96 +788,99 @@ tar-file's buffer." | |||
| 776 | (let ((file-name-handler-alist nil)) | 788 | (let ((file-name-handler-alist nil)) |
| 777 | (apply op args)))) | 789 | (apply op args)))) |
| 778 | 790 | ||
| 791 | (defun tar--extract (descriptor) | ||
| 792 | "Extract this entry of the tar file into its own buffer." | ||
| 793 | (let* ((name (tar-header-name descriptor)) | ||
| 794 | (size (tar-header-size descriptor)) | ||
| 795 | (start (tar-header-data-start descriptor)) | ||
| 796 | (end (+ start size)) | ||
| 797 | (tarname (buffer-name)) | ||
| 798 | (bufname (concat (file-name-nondirectory name) | ||
| 799 | " (" | ||
| 800 | tarname | ||
| 801 | ")")) | ||
| 802 | (buffer (generate-new-buffer bufname))) | ||
| 803 | (with-current-buffer buffer | ||
| 804 | (setq buffer-undo-list t)) | ||
| 805 | (with-current-buffer tar-data-buffer | ||
| 806 | (let (coding) | ||
| 807 | (narrow-to-region start end) | ||
| 808 | (goto-char start) | ||
| 809 | (setq coding (or coding-system-for-read | ||
| 810 | (and set-auto-coding-function | ||
| 811 | (funcall set-auto-coding-function | ||
| 812 | name (- end start))) | ||
| 813 | ;; The following binding causes | ||
| 814 | ;; find-buffer-file-type-coding-system | ||
| 815 | ;; (defined on dos-w32.el) to act as if | ||
| 816 | ;; the file being extracted existed, so | ||
| 817 | ;; that the file's contents' encoding and | ||
| 818 | ;; EOL format are auto-detected. | ||
| 819 | (let ((file-name-handler-alist | ||
| 820 | '(("" . tar-file-name-handler)))) | ||
| 821 | (car (find-operation-coding-system | ||
| 822 | 'insert-file-contents | ||
| 823 | (cons name (current-buffer)) t))))) | ||
| 824 | (if (or (not coding) | ||
| 825 | (eq (coding-system-type coding) 'undecided)) | ||
| 826 | (setq coding (detect-coding-region start end t))) | ||
| 827 | (if (and (default-value 'enable-multibyte-characters) | ||
| 828 | (coding-system-get coding :for-unibyte)) | ||
| 829 | (with-current-buffer buffer | ||
| 830 | (set-buffer-multibyte nil))) | ||
| 831 | (widen) | ||
| 832 | (decode-coding-region start end coding buffer))) | ||
| 833 | buffer)) | ||
| 834 | |||
| 779 | (defun tar-extract (&optional other-window-p) | 835 | (defun tar-extract (&optional other-window-p) |
| 780 | "In Tar mode, extract this entry of the tar file into its own buffer." | 836 | "In Tar mode, extract this entry of the tar file into its own buffer." |
| 781 | (interactive) | 837 | (interactive) |
| 782 | (let* ((view-p (eq other-window-p 'view)) | 838 | (let* ((view-p (eq other-window-p 'view)) |
| 783 | (descriptor (tar-get-descriptor)) | 839 | (descriptor (tar-get-descriptor)) |
| 784 | (name (tar-header-name descriptor)) | 840 | (name (tar-header-name descriptor)) |
| 785 | (size (tar-header-size descriptor)) | 841 | (tar-buffer (current-buffer)) |
| 786 | (start (tar-header-data-start descriptor)) | 842 | (tarname (buffer-name)) |
| 787 | (end (+ start size))) | 843 | (read-only-p (or buffer-read-only view-p)) |
| 788 | (let* ((tar-buffer (current-buffer)) | 844 | (new-buffer-file-name (expand-file-name |
| 789 | (tarname (buffer-name)) | 845 | ;; `:' is not allowed on Windows |
| 790 | (bufname (concat (file-name-nondirectory name) | 846 | (concat tarname "!" |
| 791 | " (" | 847 | (if (string-match "/" name) |
| 792 | tarname | 848 | name |
| 793 | ")")) | 849 | ;; Make sure `name' contains a / |
| 794 | (read-only-p (or buffer-read-only view-p)) | 850 | ;; so set-auto-mode doesn't try |
| 795 | (new-buffer-file-name (expand-file-name | 851 | ;; to look at `tarname' for hints. |
| 796 | ;; `:' is not allowed on Windows | 852 | (concat "./" name))))) |
| 797 | (concat tarname "!" | 853 | (buffer (get-file-buffer new-buffer-file-name)) |
| 798 | (if (string-match "/" name) | 854 | (just-created nil)) |
| 799 | name | 855 | (unless buffer |
| 800 | ;; Make sure `name' contains a / | 856 | (setq buffer (tar--extract descriptor)) |
| 801 | ;; so set-auto-mode doesn't try | 857 | (setq just-created t) |
| 802 | ;; to look at `tarname' for hints. | 858 | (with-current-buffer buffer |
| 803 | (concat "./" name))))) | 859 | (goto-char (point-min)) |
| 804 | (buffer (get-file-buffer new-buffer-file-name)) | 860 | (setq buffer-file-name new-buffer-file-name) |
| 805 | (just-created nil) | 861 | (setq buffer-file-truename |
| 806 | undo-list) | 862 | (abbreviate-file-name buffer-file-name)) |
| 807 | (unless buffer | 863 | ;; Force buffer-file-coding-system to what |
| 808 | (setq buffer (generate-new-buffer bufname)) | 864 | ;; decode-coding-region actually used. |
| 809 | (with-current-buffer buffer | 865 | (set-buffer-file-coding-system last-coding-system-used t) |
| 810 | (setq undo-list buffer-undo-list | 866 | ;; Set the default-directory to the dir of the |
| 811 | buffer-undo-list t)) | 867 | ;; superior buffer. |
| 812 | (setq bufname (buffer-name buffer)) | 868 | (setq default-directory |
| 813 | (setq just-created t) | 869 | (with-current-buffer tar-buffer |
| 814 | (with-current-buffer tar-data-buffer | 870 | default-directory)) |
| 815 | (let (coding) | 871 | (set-buffer-modified-p nil) |
| 816 | (narrow-to-region start end) | 872 | (setq buffer-undo-list t) |
| 817 | (goto-char start) | 873 | (normal-mode) ; pick a mode. |
| 818 | (setq coding (or coding-system-for-read | 874 | (set (make-local-variable 'tar-superior-buffer) tar-buffer) |
| 819 | (and set-auto-coding-function | 875 | (set (make-local-variable 'tar-superior-descriptor) descriptor) |
| 820 | (funcall set-auto-coding-function | 876 | (setq buffer-read-only read-only-p) |
| 821 | name (- end start))) | 877 | (tar-subfile-mode 1))) |
| 822 | ;; The following binding causes | 878 | (cond |
| 823 | ;; find-buffer-file-type-coding-system | 879 | (view-p |
| 824 | ;; (defined on dos-w32.el) to act as if | 880 | (view-buffer buffer (and just-created 'kill-buffer-if-not-modified))) |
| 825 | ;; the file being extracted existed, so | 881 | ((eq other-window-p 'display) (display-buffer buffer)) |
| 826 | ;; that the file's contents' encoding and | 882 | (other-window-p (switch-to-buffer-other-window buffer)) |
| 827 | ;; EOL format are auto-detected. | 883 | (t (switch-to-buffer buffer))))) |
| 828 | (let ((file-name-handler-alist | ||
| 829 | '(("" . tar-file-name-handler)))) | ||
| 830 | (car (find-operation-coding-system | ||
| 831 | 'insert-file-contents | ||
| 832 | (cons name (current-buffer)) t))))) | ||
| 833 | (if (or (not coding) | ||
| 834 | (eq (coding-system-type coding) 'undecided)) | ||
| 835 | (setq coding (detect-coding-region start end t))) | ||
| 836 | (if (and (default-value 'enable-multibyte-characters) | ||
| 837 | (coding-system-get coding :for-unibyte)) | ||
| 838 | (with-current-buffer buffer | ||
| 839 | (set-buffer-multibyte nil))) | ||
| 840 | (widen) | ||
| 841 | (decode-coding-region start end coding buffer))) | ||
| 842 | (with-current-buffer buffer | ||
| 843 | (goto-char (point-min)) | ||
| 844 | (setq buffer-file-name new-buffer-file-name) | ||
| 845 | (setq buffer-file-truename | ||
| 846 | (abbreviate-file-name buffer-file-name)) | ||
| 847 | ;; Force buffer-file-coding-system to what | ||
| 848 | ;; decode-coding-region actually used. | ||
| 849 | (set-buffer-file-coding-system last-coding-system-used t) | ||
| 850 | ;; Set the default-directory to the dir of the | ||
| 851 | ;; superior buffer. | ||
| 852 | (setq default-directory | ||
| 853 | (with-current-buffer tar-buffer | ||
| 854 | default-directory)) | ||
| 855 | (rename-buffer bufname) | ||
| 856 | (set-buffer-modified-p nil) | ||
| 857 | (setq buffer-undo-list undo-list) | ||
| 858 | (normal-mode) ; pick a mode. | ||
| 859 | (set (make-local-variable 'tar-superior-buffer) tar-buffer) | ||
| 860 | (set (make-local-variable 'tar-superior-descriptor) descriptor) | ||
| 861 | (setq buffer-read-only read-only-p) | ||
| 862 | (tar-subfile-mode 1))) | ||
| 863 | (cond | ||
| 864 | (view-p | ||
| 865 | (view-buffer buffer (and just-created 'kill-buffer-if-not-modified))) | ||
| 866 | ((eq other-window-p 'display) (display-buffer buffer)) | ||
| 867 | (other-window-p (switch-to-buffer-other-window buffer)) | ||
| 868 | (t (switch-to-buffer buffer)))))) | ||
| 869 | 884 | ||
| 870 | 885 | ||
| 871 | (defun tar-extract-other-window () | 886 | (defun tar-extract-other-window () |