From 7468cf1038f17a2b85fe3de36d6d6b7e9d6919a8 Mon Sep 17 00:00:00 2001 From: Jen-Chieh Shen Date: Sun, 16 Nov 2025 04:58:07 +0800 Subject: [PATCH 1/4] fix: Handle Can't find library error --- lisp/_prepare.el | 41 +++++++++++++++++++++++++----- test/jest/exec.test.js | 5 +--- test/jest/install.test.js | 13 +++------- test/jest/local.test.js | 26 ++++--------------- test/jest/outdated-upgrade.test.js | 6 +---- 5 files changed, 45 insertions(+), 46 deletions(-) diff --git a/lisp/_prepare.el b/lisp/_prepare.el index 4e8670fb..29578430 100644 --- a/lisp/_prepare.el +++ b/lisp/_prepare.el @@ -1432,7 +1432,29 @@ This uses function `locate-dominating-file' to look up directory tree." (ignore-errors (make-directory package-user-dir t)) (eask--silent (eask-setup-paths)) (eask-with-verbosity 'debug (eask--load-config)) - (eask--with-hooks ,@body)))))))))) + (eask--with-hooks ,@body)))))) + ;; Report exit stats if any. + (eask--handle-exit-status))))) + +(defun eask--error-status () + "Return error status." + (let ((result)) + ;; Error. + (when eask--has-error-p + (push 'error result)) + ;; Warning. + (when eask--has-warn-p + (push (if (eask-strict-p) + 'error + 'warn) + result)) + ;; No repeat. + (delete-dups result))) + +(defun eask--handle-exit-status () + "Return non-nil if we should report error for exit status." + (when (memq 'error (eask--error-status)) + (eask--exit 'failure))) ;; ;;; Eask file @@ -1991,16 +2013,23 @@ Argument ARGS are direct arguments for functions `eask-error' or `eask-warn'." (defun eask--trigger-error () "Trigger error event." (when (and (not eask--ignore-error-p) - (not (eask-checker-p))) ; Ignore when checking Eask-file. - (if (eask-allow-error-p) ; Trigger error at the right time. - (add-hook 'eask-after-command-hook #'eask--exit) - (eask--exit)))) + (not (eask-allow-error-p)) + ;; Ignore when checking Eask-file. + (not (eask-checker-p))) + ;; Stop immediately. + (eask--exit 'failure))) (defun eask--error (fnc &rest args) "On error. Arguments FNC and ARGS are used for advice `:around'." - (setq eask--has-error-p t) ; Just a record. + ;; Handle https://github.com/emacs-eask/cli/issues/11. + (cond ((< emacs-major-version 28) + (unless (string-prefix-p "Can't find library " (car args)) + (setq eask--has-error-p t))) + (t + ;; Just a record. + (setq eask--has-error-p t))) (let ((msg (eask--ansi 'error (apply #'format-message args)))) (unless eask-inhibit-error-message (eask--unsilent (eask-msg "%s" msg))) diff --git a/test/jest/exec.test.js b/test/jest/exec.test.js index 4b1536d2..6df6915f 100644 --- a/test/jest/exec.test.js +++ b/test/jest/exec.test.js @@ -1,4 +1,3 @@ -const cmp = require('semver-compare'); const { emacsVersion, TestContext } = require("./helpers"); describe("exec", () => { @@ -6,9 +5,7 @@ describe("exec", () => { beforeAll(async () => { await ctx.runEask( - "install-deps", { timeout: 40000 }, - // See https://github.com/emacs-eask/cli/issues/11. - cmp(await emacsVersion(), "28.1") == -1); + "install-deps", { timeout: 40000 }); }); afterAll(() => ctx.cleanUp()); diff --git a/test/jest/install.test.js b/test/jest/install.test.js index 9abd3816..43c0832a 100644 --- a/test/jest/install.test.js +++ b/test/jest/install.test.js @@ -14,9 +14,7 @@ describe("install and uninstall", () => { it("installs project package", async () => { // creates dist/.tar - await ctx.runEask("package", { timeout: 40000 }, - // See https://github.com/emacs-eask/cli/issues/11. - cmp(await emacsVersion(), "28.1") == -1); + await ctx.runEask("package"); // installs dependencies and generated package await ctx.runEask("install"); const { stderr } = await ctx.runEask("list"); @@ -41,18 +39,13 @@ describe("install and uninstall", () => { }); it("uninstalls project package", async () => { - await ctx.runEask("uninstall", { timeout: 40000 }, - // See https://github.com/emacs-eask/cli/issues/11. - cmp(await emacsVersion(), "28.1") == -1); + await ctx.runEask("uninstall"); const { stderr } = await ctx.runEask("list"); expect(stderr).not.toMatch(packageName); }); it("installs dependencies", async () => { - const { stderr } = await ctx.runEask( - "install-deps", { timeout: 40000 }, - // See https://github.com/emacs-eask/cli/issues/11. - cmp(await emacsVersion(), "28.1") == -1); + const { stderr } = await ctx.runEask("install-deps"); expect(stderr).not.toMatch(packageName); }); diff --git a/test/jest/local.test.js b/test/jest/local.test.js index a1054922..fd8eb73d 100644 --- a/test/jest/local.test.js +++ b/test/jest/local.test.js @@ -4,7 +4,6 @@ // Notice, below we clone a random package (repo) that uses Eask as the // dependencies management tool. -const cmp = require('semver-compare'); const { emacsVersion, TestContext } = require("./helpers"); describe("local", () => { @@ -15,10 +14,7 @@ describe("local", () => { // this is because of recipe dependencies triggering // "temporary archives" build. beforeAll(async () => { - await ctx.runEask( - "install-deps", { timeout: 40000 }, - // See https://github.com/emacs-eask/cli/issues/11. - cmp(await emacsVersion(), "28.1") == -1); + await ctx.runEask("install-deps", { timeout: 40000 }); }); afterAll(() => ctx.cleanUp()); @@ -84,10 +80,7 @@ describe("local", () => { describe("Development", () => { beforeAll(async () => { - await ctx.runEask( - "install-deps", { timeout: 40000 }, - // See https://github.com/emacs-eask/cli/issues/11. - cmp(await emacsVersion(), "28.1") == -1) + await ctx.runEask("install-deps", { timeout: 40000 }); }); // this requires install-deps @@ -123,9 +116,7 @@ describe("local", () => { describe("Execution", () => { beforeAll(async () => { - await ctx.runEask("install-deps", { timeout: 40000 }, - // See https://github.com/emacs-eask/cli/issues/11. - cmp(await emacsVersion(), "28.1") == -1) + await ctx.runEask("install-deps", { timeout: 40000 }); }); test("eval", async () => { @@ -212,15 +203,14 @@ describe("local", () => { describe("Linting", () => { // some lint commands may fail if packages are missing beforeAll(async () => { - await ctx.runEask("install-deps", { timeout: 40000 }, - // See https://github.com/emacs-eask/cli/issues/11. - cmp(await emacsVersion(), "28.1") == -1) + await ctx.runEask("install-deps", { timeout: 40000 }); }); it.each([ "lint checkdoc", "lint declare", "lint elint", + "lint elisp-lint", "lint indent", "lint keywords", "lint license", @@ -234,12 +224,6 @@ describe("local", () => { await ctx.runEask("lint elsa"); }); - it("lint elint", async () => { - await ctx.runEask("lint elisp-lint", { }, - // See https://github.com/emacs-eask/cli/issues/11. - cmp(await emacsVersion(), "28.1") == -1); - }); - it("lint regexps", async () => { if (cmp(await emacsVersion(), "27.1") == 1) { await ctx.runEask("lint regexps"); diff --git a/test/jest/outdated-upgrade.test.js b/test/jest/outdated-upgrade.test.js index 985990ae..6ca117c4 100644 --- a/test/jest/outdated-upgrade.test.js +++ b/test/jest/outdated-upgrade.test.js @@ -1,14 +1,10 @@ -const cmp = require('semver-compare'); const { emacsVersion, TestContext } = require("./helpers"); describe("outdated and upgrade", () => { const ctx = new TestContext("./test/jest/outdated-upgrade"); beforeAll(async () => { - await ctx.runEask( - "install-deps", { timeout: 40000 }, - // See https://github.com/emacs-eask/cli/issues/11. - cmp(await emacsVersion(), "28.1") == -1); + await ctx.runEask("install-deps", { timeout: 40000 }); await ctx.runEask("load make-outdate.el"); }); From 2dc84523d400cd0e77ac93aa3e7abdc5d1691b2a Mon Sep 17 00:00:00 2001 From: Jen-Chieh Shen Date: Sun, 16 Nov 2025 05:01:12 +0800 Subject: [PATCH 2/4] revert safe options --- test/jest/helpers.js | 9 +++------ test/jest/local.test.js | 1 + 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/test/jest/helpers.js b/test/jest/helpers.js index 0fe395b5..df0b3d7d 100644 --- a/test/jest/helpers.js +++ b/test/jest/helpers.js @@ -160,8 +160,8 @@ class TestContext { * @param {any} config * @returns {Promise.} */ - runEask(command, config, safe = false) { - return this.run(this.easkCommand + " " + command, config, safe); + runEask(command, config) { + return this.run(this.easkCommand + " " + command, config); } /** @@ -173,7 +173,7 @@ class TestContext { * @param {any} config * @returns {Promise.} */ - run(command, config, safe = false) { + run(command, config) { return exec(command, { cwd: this.cwd, signal: this.controller.signal, @@ -191,9 +191,6 @@ class TestContext { return new CommandOutput(obj, this.cwd); }) .catch((err) => { - if (safe) - return this.errorToCommandOutput(err); - if (!err.code) err.message += "\nexec: TIMEOUT"; diff --git a/test/jest/local.test.js b/test/jest/local.test.js index fd8eb73d..08f6152d 100644 --- a/test/jest/local.test.js +++ b/test/jest/local.test.js @@ -4,6 +4,7 @@ // Notice, below we clone a random package (repo) that uses Eask as the // dependencies management tool. +const cmp = require('semver-compare'); const { emacsVersion, TestContext } = require("./helpers"); describe("local", () => { From 1cfac4f4f2fbc4cbf807e195b49e0d5f8f905d09 Mon Sep 17 00:00:00 2001 From: Jen-Chieh Shen Date: Sun, 16 Nov 2025 05:08:41 +0800 Subject: [PATCH 3/4] refactor: ordering --- lisp/_prepare.el | 58 ++++++++++++++++++++++++++---------------------- 1 file changed, 31 insertions(+), 27 deletions(-) diff --git a/lisp/_prepare.el b/lisp/_prepare.el index 29578430..2fbdc309 100644 --- a/lisp/_prepare.el +++ b/lisp/_prepare.el @@ -1434,25 +1434,10 @@ This uses function `locate-dominating-file' to look up directory tree." (eask-with-verbosity 'debug (eask--load-config)) (eask--with-hooks ,@body)))))) ;; Report exit stats if any. - (eask--handle-exit-status))))) + (eask--resolve-exit-status))))) -(defun eask--error-status () - "Return error status." - (let ((result)) - ;; Error. - (when eask--has-error-p - (push 'error result)) - ;; Warning. - (when eask--has-warn-p - (push (if (eask-strict-p) - 'error - 'warn) - result)) - ;; No repeat. - (delete-dups result))) - -(defun eask--handle-exit-status () - "Return non-nil if we should report error for exit status." +(defun eask--resolve-exit-status () + "Resolve current exit status." (when (memq 'error (eask--error-status)) (eask--exit 'failure))) @@ -2010,8 +1995,30 @@ Argument ARGS are direct arguments for functions `eask-error' or `eask-warn'." (declare (indent 0) (debug t)) `(eask-ignore-errors (eask--silent-error ,@body))) +(defun eask--error-status () + "Return error status." + (let ((result)) + ;; Error. + (when eask--has-error-p + (push 'error result)) + ;; Warning. + (when eask--has-warn-p + (push (if (eask-strict-p) + 'error + 'warn) + result)) + ;; No repeat. + (delete-dups result))) + (defun eask--trigger-error () "Trigger error event." + (cond ((< emacs-major-version 28) + ;; Handle https://github.com/emacs-eask/cli/issues/11. + (unless (string-prefix-p "Can't find library " (car args)) + (setq eask--has-error-p t))) + (t + (setq eask--has-error-p t))) ; Just a record. + (when (and (not eask--ignore-error-p) (not (eask-allow-error-p)) ;; Ignore when checking Eask-file. @@ -2023,13 +2030,6 @@ Argument ARGS are direct arguments for functions `eask-error' or `eask-warn'." "On error. Arguments FNC and ARGS are used for advice `:around'." - ;; Handle https://github.com/emacs-eask/cli/issues/11. - (cond ((< emacs-major-version 28) - (unless (string-prefix-p "Can't find library " (car args)) - (setq eask--has-error-p t))) - (t - ;; Just a record. - (setq eask--has-error-p t))) (let ((msg (eask--ansi 'error (apply #'format-message args)))) (unless eask-inhibit-error-message (eask--unsilent (eask-msg "%s" msg))) @@ -2037,15 +2037,19 @@ Arguments FNC and ARGS are used for advice `:around'." (eask--trigger-error)) (when debug-on-error (apply fnc args))) +(defun eask--trigger-warn () + "Trigger warning event." + (setq eask--has-warn-p t)) ; Just a record. + (defun eask--warn (fnc &rest args) "On warn. Arguments FNC and ARGS are used for advice `:around'." - (setq eask--has-warn-p t) ; Just a record. (let ((msg (eask--ansi 'warn (apply #'format-message args)))) (unless eask-inhibit-error-message (eask--unsilent (eask-msg "%s" msg))) - (run-hook-with-args 'eask-on-warning-hook 'warn msg)) + (run-hook-with-args 'eask-on-warning-hook 'warn msg) + (eask--trigger-warn)) (eask--silent (apply fnc args))) ;; Don't pollute outer exection. From b5c38c0f54a30ae9a840280753c5f47b1bbc683e Mon Sep 17 00:00:00 2001 From: Jen-Chieh Shen Date: Sun, 16 Nov 2025 05:21:54 +0800 Subject: [PATCH 4/4] fix: args --- lisp/_prepare.el | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/lisp/_prepare.el b/lisp/_prepare.el index 2fbdc309..5dd83b98 100644 --- a/lisp/_prepare.el +++ b/lisp/_prepare.el @@ -2010,8 +2010,10 @@ Argument ARGS are direct arguments for functions `eask-error' or `eask-warn'." ;; No repeat. (delete-dups result))) -(defun eask--trigger-error () - "Trigger error event." +(defun eask--trigger-error (args) + "Trigger error event. + +The argument ARGS is passed from the function `eask--error'." (cond ((< emacs-major-version 28) ;; Handle https://github.com/emacs-eask/cli/issues/11. (unless (string-prefix-p "Can't find library " (car args)) @@ -2034,7 +2036,7 @@ Arguments FNC and ARGS are used for advice `:around'." (unless eask-inhibit-error-message (eask--unsilent (eask-msg "%s" msg))) (run-hook-with-args 'eask-on-error-hook 'error msg) - (eask--trigger-error)) + (eask--trigger-error args)) (when debug-on-error (apply fnc args))) (defun eask--trigger-warn ()