Skip to content

Commit 275dab4

Browse files
authored
Get correct install package name (#318)
* fix typos * Get actual package name * Need to ignore unhelpful package.el errors * Add more tests for install-file * Should error if install-file FILE is not a package * Correctly handle tar files * Add missing test files * Match only package name in test to avoid control chars
1 parent a479d53 commit 275dab4

File tree

11 files changed

+189
-14
lines changed

11 files changed

+189
-14
lines changed

lisp/_prepare.el

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -733,7 +733,7 @@ Argument BODY are forms for execution."
733733
;; Handle `--force` flag.
734734
(when should-reinstall-p (package-delete (eask-package-desc pkg t) t))
735735
;; Install it.
736-
(package-install-file (expand-file-name file)))
736+
(eask-ignore-errors (package-install-file (expand-file-name file))))
737737
"done ✓")))))
738738

739739
(defun eask-package-install (pkg)

lisp/core/install-file.el

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,39 @@
2222

2323
(eask-load "core/install")
2424

25-
(defun eask-install-file--guess-name (file)
26-
"Guess the package name of the install FILE."
27-
(file-name-sans-extension (file-name-nondirectory (directory-file-name file))))
25+
(defun eask-install-file--get-package-name (path)
26+
"Get the package name from PATH, which is a file, directory or archive."
27+
(cond
28+
((not (file-exists-p path))
29+
(eask-error "File does not exist %s" path))
30+
((or (string-suffix-p ".tar" path)
31+
(string-suffix-p ".tar.gz" path))
32+
;; tar file
33+
;; Note this can throw strange errors if
34+
;; - there is no -pkg.el in the tar file
35+
;; - the tar file was built in a folder with a different name
36+
;; tar files created with eask package are fine
37+
(require 'tar-mode)
38+
(let ((pkg-desc (with-current-buffer (find-file (expand-file-name path))
39+
(eask-ignore-errors-silent (package-tar-file-info)))))
40+
(unless pkg-desc
41+
;; package-dir-info will return nil if there is no -pkg.el and no .el files at path
42+
(eask-error "No package in %s" path))
43+
(package-desc-name pkg-desc))
44+
)
45+
(t ;; .el file or directory
46+
;; Note package-dir-info doesn't work outside of dired mode!
47+
(let ((pkg-desc (with-current-buffer (dired (expand-file-name path))
48+
(eask-ignore-errors-silent (package-dir-info)))))
49+
(unless pkg-desc
50+
;; package-dir-info will return nil if there is no -pkg.el and no .el files at path
51+
(eask-error "No package in %s" path))
52+
(package-desc-name pkg-desc)))))
2853

2954
(defun eask-install-file--packages (files)
3055
"The file install packages with FILES."
3156
(let* ((deps (mapcar (lambda (file)
32-
(list (eask-install-file--guess-name file) file))
57+
(list (eask-install-file--get-package-name file) file))
3358
files))
3459
(names (mapcar #'car deps))
3560
(len (length deps))
@@ -52,7 +77,7 @@
5277
;; If package [files..] are specified, we try to install it
5378
(eask-install-file--packages files)
5479
;; Otherwise, report error.
55-
(eask-info "(No file packages have been intalled)")
80+
(eask-info "(No file packages have been installed)")
5681
(eask-help "core/install-file")))
5782

5883
;;; core/install-file.el ends here

lisp/core/install-vc.el

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,10 @@
2121
nil t))
2222

2323
(eask-load "core/install")
24-
(eask-load "core/install-file")
24+
25+
(defun eask-install-vc--guess-name (file)
26+
"Guess the package name of the install FILE."
27+
(file-name-sans-extension (file-name-nondirectory (directory-file-name file))))
2528

2629
(defun eask-install-vc--split-sepcs (specs)
2730
"Split the SPECS and return a list of specification."
@@ -32,7 +35,7 @@
3235
(cond ((ffap-url-p spec)
3336
(push (reverse current-spec) new-specs)
3437
;; We're using the push, so the order is reversed.
35-
(setq current-spec (list spec (eask-install-file--guess-name spec))))
38+
(setq current-spec (list spec (eask-install-vc--guess-name spec))))
3639
(t
3740
(push spec current-spec))))
3841
;; Push thes rest of the specification.
@@ -67,7 +70,7 @@
6770
;; If package [specs..] are specified, we try to install it
6871
(eask-install-vc--packages specs)
6972
;; Otherwise, report error.
70-
(eask-info "(No vc packages have been intalled)")
73+
(eask-info "(No vc packages have been installed)")
7174
(eask-help "core/install-vc")))
7275

7376
;;; core/install-vc.el ends here

test/jest/install.test.js

Lines changed: 46 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -53,11 +53,6 @@ describe("install and uninstall", () => {
5353
expect(stderr).not.toMatch(packageName);
5454
});
5555

56-
it("installs file directly", async () => {
57-
const { stderr } = await ctx.runEask("install-file ./mini.pkg.2");
58-
expect(stderr).toMatch("mini.pkg.2");
59-
});
60-
6156
test.skip("installs vc directly", async () => {
6257
if ((await emacsVersion()) >= "29.1") {
6358
const { stderr } = await ctx.runEask(
@@ -66,6 +61,52 @@ describe("install and uninstall", () => {
6661
expect(stderr).toMatch("msgu");
6762
}
6863
});
64+
65+
describe("eask install-file", () => {
66+
beforeAll(async () => {
67+
await ctx.runEask("clean workspace");
68+
});
69+
70+
it("installs file directly", async () => {
71+
const { stderr } = await ctx.runEask("install-file ./mini.pkg.2");
72+
expect(stderr).toMatch("mini.pkg.2");
73+
});
74+
75+
it("uses the correct package name", async () => {
76+
const { stderr } = await ctx.runEask("install-file ./foo-mode");
77+
expect(stderr).toMatch("foo");
78+
});
79+
80+
it("can repeat installs", async () => {
81+
await ctx.runEask("install-file ./foo-mode");
82+
});
83+
84+
it("reinstalls a package using --force", async () => {
85+
const { stderr } = await ctx.runEask("install-file --force ./foo-mode");
86+
expect(stderr).toMatch("foo");
87+
});
88+
89+
it("installs a package with only an Eask file", async () => {
90+
await ctx.runEask("install-file ./foo-no-pkg");
91+
});
92+
93+
it("errors when path is non-existing", async () => {
94+
await expect(ctx.runEask("install-file ./foo")).rejects.toThrow();
95+
});
96+
97+
it("errors when path is an empty directory", async () => {
98+
await expect(ctx.runEask("install-file ../empty")).rejects.toThrow();
99+
});
100+
101+
it("gets the package name from a tar file", async () => {
102+
await ctx.runEask("install-file ./foo.tar.gz");
103+
});
104+
105+
it("can install tar files created with eask package", async () => {
106+
// foo-0.0.1.tar is created by running eask package in ./foo-no-pkg
107+
await ctx.runEask("install-file ./foo-0.0.1.tar");
108+
});
109+
});
69110
});
70111

71112
describe("in an empty project", () => {

test/jest/install/foo-0.0.1.tar

10 KB
Binary file not shown.

test/jest/install/foo-mode/Eask

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
(package "foo"
2+
"0.0.1"
3+
"")
4+
5+
(website-url "")
6+
(keywords )
7+
8+
(package-file "foo.el")
9+
10+
(script "test" "echo \"Error: no test specified\" && exit 1")
11+
12+
(source "gnu")
13+
14+
(depends-on "emacs" "26.1")
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
;;; Generated package description from foo.el -*- no-byte-compile: t -*-
2+
(define-package "foo" "0.0.1" "foo" '((emacs "0")) :keywords '("test"))

test/jest/install/foo-mode/foo.el

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
;;; foo.el --- foo -*- lexical-binding: t -*-
2+
3+
;; Author: none
4+
;; Maintainer: none
5+
;; Version: 0.0.1
6+
;; Package-Requires: (emacs)
7+
;; Keywords: test
8+
9+
10+
;; This file is not part of GNU Emacs
11+
12+
;; This program is free software: you can redistribute it and/or modify
13+
;; it under the terms of the GNU General Public License as published by
14+
;; the Free Software Foundation, either version 3 of the License, or
15+
;; (at your option) any later version.
16+
17+
;; This program is distributed in the hope that it will be useful,
18+
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
19+
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20+
;; GNU General Public License for more details.
21+
22+
;; You should have received a copy of the GNU General Public License
23+
;; along with this program. If not, see <https://www.gnu.org/licenses/>.
24+
25+
26+
;;; Commentary:
27+
28+
;; commentary
29+
30+
;;; Code:
31+
32+
(defun foo-message ()
33+
"docstring"
34+
(interactive "P")
35+
(message "Hello World!"))
36+
37+
(provide 'foo)
38+
;;; foo.el ends here

test/jest/install/foo-no-pkg/Eask

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
(package "foo"
2+
"0.0.1"
3+
"")
4+
5+
(website-url "")
6+
(keywords )
7+
8+
(package-file "foo.el")
9+
10+
(script "test" "echo \"Error: no test specified\" && exit 1")
11+
12+
(source "gnu")
13+
14+
(depends-on "emacs" "26.1")
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
;;; foo.el --- foo -*- lexical-binding: t -*-
2+
3+
;; Author: none
4+
;; Maintainer: none
5+
;; Version: 0.0.1
6+
;; Package-Requires: (emacs)
7+
;; Keywords: test
8+
9+
10+
;; This file is not part of GNU Emacs
11+
12+
;; This program is free software: you can redistribute it and/or modify
13+
;; it under the terms of the GNU General Public License as published by
14+
;; the Free Software Foundation, either version 3 of the License, or
15+
;; (at your option) any later version.
16+
17+
;; This program is distributed in the hope that it will be useful,
18+
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
19+
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20+
;; GNU General Public License for more details.
21+
22+
;; You should have received a copy of the GNU General Public License
23+
;; along with this program. If not, see <https://www.gnu.org/licenses/>.
24+
25+
26+
;;; Commentary:
27+
28+
;; commentary
29+
30+
;;; Code:
31+
32+
(defun foo-message ()
33+
"docstring"
34+
(interactive "P")
35+
(message "Hello World!"))
36+
37+
(provide 'foo)
38+
;;; foo.el ends here

0 commit comments

Comments
 (0)