From 606b783acb3388249c38264f8e37e08af832e1ea Mon Sep 17 00:00:00 2001 From: Ioannis Kappas Date: Tue, 20 Jul 2021 15:53:34 +0200 Subject: [PATCH] Allow installing packages with DOS line endings * lisp/emacs-lisp/package.el (package-install-from-buffer): Allow installing files with different line ending conventions (Unix, DOS and Macos) (bug#48137). --- lisp/emacs-lisp/package.el | 21 ++++++++- test/lisp/emacs-lisp/package-tests.el | 68 +++++++++++++++++++++++++++ 2 files changed, 87 insertions(+), 2 deletions(-) diff --git a/lisp/emacs-lisp/package.el b/lisp/emacs-lisp/package.el index 6bbd4c99763..f1daa8d124a 100644 --- a/lisp/emacs-lisp/package.el +++ b/lisp/emacs-lisp/package.el @@ -2195,8 +2195,24 @@ Downloads and installs required packages as needed." ((derived-mode-p 'tar-mode) (package-tar-file-info)) (t - (save-excursion - (package-buffer-info))))) + ;; Package headers should be parsed from decoded text + ;; (see Bug#48137) where possible. + (if (and (eq buffer-file-coding-system 'no-conversion) + buffer-file-name) + (let* ((package-buffer (current-buffer)) + (decoding-system + (car (find-operation-coding-system + 'insert-file-contents + (cons buffer-file-name + package-buffer))))) + (with-temp-buffer + (insert-buffer-substring package-buffer) + (decode-coding-region (point-min) (point-max) + decoding-system) + (package-buffer-info))) + + (save-excursion + (package-buffer-info)))))) (name (package-desc-name pkg-desc))) ;; Download and install the dependencies. (let* ((requires (package-desc-reqs pkg-desc)) @@ -2222,6 +2238,7 @@ directory." (setq default-directory file) (dired-mode)) (insert-file-contents-literally file) + (set-visited-file-name file) (when (string-match "\\.tar\\'" file) (tar-mode))) (package-install-from-buffer))) diff --git a/test/lisp/emacs-lisp/package-tests.el b/test/lisp/emacs-lisp/package-tests.el index 67d647d3b9e..29435799555 100644 --- a/test/lisp/emacs-lisp/package-tests.el +++ b/test/lisp/emacs-lisp/package-tests.el @@ -263,6 +263,74 @@ Must called from within a `tar-mode' buffer." (should (file-exists-p autoloads-file)) (should-not (get-file-buffer autoloads-file))))) +(ert-deftest package-test-install-file () + "Install files with `package-install-file'." + (with-package-test (:basedir (ert-resource-directory)) + (package-initialize) + (let* ((pkg-el "simple-single-1.3.el") + (source-file (expand-file-name pkg-el (ert-resource-directory)))) + (should-not (package-installed-p 'simple-single)) + (package-install-file source-file) + (should (package-installed-p 'simple-single)) + (package-delete (cadr (assq 'simple-single package-alist))) + (should-not (package-installed-p 'simple-single))) + + (let* ((pkg-el "multi-file-0.2.3.tar") + (source-file (expand-file-name pkg-el (ert-resource-directory)))) + (package-initialize) + (should-not (package-installed-p 'multie-file)) + (package-install-file source-file) + (should (package-installed-p 'multi-file)) + (package-delete (cadr (assq 'multi-file package-alist)))) + )) + +(ert-deftest package-test-install-file-EOLs () + "Install same file multiple time with `package-install-file' +but with a different end of line convention (bug#48137)." + (with-package-test (:basedir (ert-resource-directory)) + (package-initialize) + (let* ((pkg-el "simple-single-1.3.el") + (source-file (expand-file-name pkg-el (ert-resource-directory)))) + + (with-temp-buffer + (insert-file-contents source-file) + + (let (hashes) + (dolist (coding '(unix dos mac) hashes) + (let* ((eol-file (expand-file-name pkg-el package-test-user-dir))) + ;; save package with this EOL convention. + (set-buffer-file-coding-system coding) + (write-region (point-min) (point-max) eol-file) + + (should-not (package-installed-p 'simple-single)) + (package-install-file eol-file) + (should (package-installed-p 'simple-single)) + + ;; check the package file has been installed unmodified. + (let ((eol-hash (with-temp-buffer + (insert-file-contents-literally eol-file) + (buffer-hash)))) + ;; also perform an additional check that the package + ;; file created with this EOL convention is different + ;; than all the others created so far. + (should-not (member eol-hash hashes)) + (setq hashes (cons eol-hash hashes)) + + (let* ((descr (cadr (assq 'simple-single package-alist))) + (pkg-dir (package-desc-dir descr)) + (dest-file (expand-file-name "simple-single.el" pkg-dir )) + (dest-hash (with-temp-buffer + (insert-file-contents-literally dest-file) + (buffer-hash)))) + + (should (string= dest-hash eol-hash)))) + + (package-delete (cadr (assq 'simple-single package-alist))) + (should-not (package-installed-p 'simple-single)) + (delete-file eol-file) + (should-not (file-exists-p eol-file)) + ))))))) + (ert-deftest package-test-install-dependency () "Install a package which includes a dependency." (with-package-test () -- 2.39.2