diff --git a/lisp/_prepare.el b/lisp/_prepare.el index a929a421..ffd99226 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 @@ -2000,7 +2022,7 @@ Argument ARGS are direct arguments for functions `eask-error' or `eask-warn'." "On error. Arguments FNC and ARGS are used for advice `:around'." - (setq eask--has-error-p t) + (setq eask--has-error-p t) ; Just a record. (let ((msg (eask--ansi 'error (apply #'format-message args)))) (unless eask-inhibit-error-message (eask--unsilent (eask-msg "%s" msg))) @@ -2012,7 +2034,7 @@ Arguments FNC and ARGS are used for advice `:around'." "On warn. Arguments FNC and ARGS are used for advice `:around'." - (setq eask--has-warn-p t) + (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))) diff --git a/lisp/lint/elint.el b/lisp/lint/elint.el index 278f4815..ede7f7a9 100644 --- a/lisp/lint/elint.el +++ b/lisp/lint/elint.el @@ -44,11 +44,6 @@ (eask-print-log-buffer log-buffer) (kill-buffer log-buffer)))) -(defun eask-lint-elint--has-error-p () - "Return non-nil if we should report error for exit status." - (and eask--has-warn-p - (eask-strict-p))) - (eask-start (require 'elint) (let* ((patterns (eask-args)) @@ -62,10 +57,7 @@ (eask-msg "") (eask-info "(Total of %s file%s %s checked)" (length files) (eask--sinr files "" "s") - (eask--sinr files "has" "have")) - ;; Report error. - (when (eask-lint-elint--has-error-p) - (eask--exit 'failure))) + (eask--sinr files "has" "have"))) ;; Pattern defined, but no file found! (patterns (eask-info "(No files match wildcard: %s)" diff --git a/lisp/lint/elsa.el b/lisp/lint/elsa.el index 21392432..69b0e107 100644 --- a/lisp/lint/elsa.el +++ b/lisp/lint/elsa.el @@ -60,12 +60,6 @@ (t (eask-log line))))) (eask-msg "No issues found")))) -(defun eask-lint-elsa--has-error-p () - "Return non-nil if we should report error for exit status." - (or eask--has-error-p - (and eask--has-warn-p - (eask-strict-p)))) - (eask-start ;; Preparation (eask-archive-install-packages '("gnu" "melpa") @@ -85,10 +79,7 @@ (mapcar #'eask-lint-elsa--analyse-file files) (eask-msg "") (eask-info "(Total of %s file%s linted)" (length files) - (eask--sinr files "" "s")) - ;; Report error. - (when (eask-lint-elsa--has-error-p) - (eask--exit 'failure))) + (eask--sinr files "" "s"))) ;; Pattern defined, but no file found! (patterns (eask-msg "") diff --git a/lisp/lint/package.el b/lisp/lint/package.el index 9ba6d09b..676ddcdc 100644 --- a/lisp/lint/package.el +++ b/lisp/lint/package.el @@ -57,11 +57,6 @@ (kill-current-buffer))) (eask-print-log-buffer "*Package-Lint*")) -(defun eask-lint-package--has-error-p () - "Return non-nil if we should report error for exit status." - (and eask--has-warn-p - (eask-strict-p))) - (eask-start ;; Preparation (eask-archive-install-packages '("gnu" "melpa") @@ -82,10 +77,7 @@ (mapcar #'eask-lint-package--file files) (eask-msg "") (eask-info "(Total of %s file%s linted)" (length files) - (eask--sinr files "" "s")) - ;; Report error. - (when (eask-lint-package--has-error-p) - (eask--exit 'failure))) + (eask--sinr files "" "s"))) ;; Pattern defined, but no file found! (patterns (eask-msg "") diff --git a/lisp/lint/regexps.el b/lisp/lint/regexps.el index 5818ef3d..dfddef4f 100644 --- a/lisp/lint/regexps.el +++ b/lisp/lint/regexps.el @@ -61,11 +61,6 @@ (eask-msg "No issues found")) (kill-current-buffer)))) -(defun eask-lint-regexps--has-error-p () - "Return non-nil if we should report error for exit status." - (and eask--has-warn-p - (eask-strict-p))) - (eask-start ;; Preparation (eask-archive-install-packages '("gnu") @@ -85,10 +80,7 @@ (mapcar #'eask-lint-regexps--relint-file files) (eask-msg "") (eask-info "(Total of %s file%s linted)" (length files) - (eask--sinr files "" "s")) - ;; Report error. - (when (eask-lint-regexps--has-error-p) - (eask--exit 'failure))) + (eask--sinr files "" "s"))) ;; Pattern defined, but no file found! (patterns (eask-msg "") diff --git a/package-lock.json b/package-lock.json index 820d4748..d1091a22 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17,7 +17,8 @@ }, "devDependencies": { "@yao-pkg/pkg": "^6.0.0", - "jest": "^29.7.0" + "jest": "^29.7.0", + "semver-compare": "^1.0.0" } }, "node_modules/@ampproject/remapping": { @@ -4200,6 +4201,13 @@ "node": ">=10" } }, + "node_modules/semver-compare": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", + "integrity": "sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==", + "dev": true, + "license": "MIT" + }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", diff --git a/package.json b/package.json index b60de1c2..feb29fab 100644 --- a/package.json +++ b/package.json @@ -37,7 +37,8 @@ }, "devDependencies": { "@yao-pkg/pkg": "^6.0.0", - "jest": "^29.7.0" + "jest": "^29.7.0", + "semver-compare": "^1.0.0" }, "jest": { "rootDir": "./test/jest", diff --git a/test/jest/exec.test.js b/test/jest/exec.test.js index 2ff26bf3..4b1536d2 100644 --- a/test/jest/exec.test.js +++ b/test/jest/exec.test.js @@ -1,9 +1,15 @@ -const { TestContext } = require("./helpers"); +const cmp = require('semver-compare'); +const { emacsVersion, TestContext } = require("./helpers"); describe("exec", () => { const ctx = new TestContext("./test/jest/exec"); - beforeAll(async () => await ctx.runEask("install-deps")); + beforeAll(async () => { + await ctx.runEask( + "install-deps", { timeout: 40000 }, + // See https://github.com/emacs-eask/cli/issues/11. + cmp(await emacsVersion(), "28.1") == -1); + }); afterAll(() => ctx.cleanUp()); diff --git a/test/jest/helpers.js b/test/jest/helpers.js index d23488af..60a36f42 100644 --- a/test/jest/helpers.js +++ b/test/jest/helpers.js @@ -157,8 +157,8 @@ class TestContext { * @param {any} config * @returns {Promise.} */ - runEask(command, config) { - return this.run(this.easkCommand + " " + command, config); + runEask(command, config, safe = false) { + return this.run(this.easkCommand + " " + command, config, safe); } /** @@ -170,7 +170,7 @@ class TestContext { * @param {any} config * @returns {Promise.} */ - run(command, config) { + run(command, config, safe = false) { return exec(command, { cwd: this.cwd, signal: this.controller.signal, @@ -188,7 +188,12 @@ class TestContext { return new CommandOutput(obj, this.cwd); }) .catch((err) => { - if (!err.code) err.message += "\nexec: TIMEOUT"; + if (safe) + return this.errorToCommandOutput(err); + + if (!err.code) + err.message += "\nexec: TIMEOUT"; + throw err; }); } diff --git a/test/jest/install.test.js b/test/jest/install.test.js index d7bd81d2..9abd3816 100644 --- a/test/jest/install.test.js +++ b/test/jest/install.test.js @@ -1,3 +1,4 @@ +const cmp = require('semver-compare'); const { emacsVersion, TestContext } = require("./helpers"); describe("install and uninstall", () => { @@ -12,8 +13,12 @@ describe("install and uninstall", () => { afterAll(() => ctx.cleanUp()); it("installs project package", async () => { - await ctx.runEask("package"); // creates dist/.tar - await ctx.runEask("install"); // installs dependencies and generated package + // creates dist/.tar + await ctx.runEask("package", { timeout: 40000 }, + // See https://github.com/emacs-eask/cli/issues/11. + cmp(await emacsVersion(), "28.1") == -1); + // installs dependencies and generated package + await ctx.runEask("install"); const { stderr } = await ctx.runEask("list"); expect(stderr).toMatch(packageName); }); @@ -36,13 +41,18 @@ describe("install and uninstall", () => { }); it("uninstalls project package", async () => { - await ctx.runEask("uninstall"); + await ctx.runEask("uninstall", { timeout: 40000 }, + // See https://github.com/emacs-eask/cli/issues/11. + cmp(await emacsVersion(), "28.1") == -1); const { stderr } = await ctx.runEask("list"); expect(stderr).not.toMatch(packageName); }); it("installs dependencies", async () => { - const { stderr } = await ctx.runEask("install-deps"); + const { stderr } = await ctx.runEask( + "install-deps", { timeout: 40000 }, + // See https://github.com/emacs-eask/cli/issues/11. + cmp(await emacsVersion(), "28.1") == -1); expect(stderr).not.toMatch(packageName); }); @@ -97,7 +107,7 @@ describe("install and uninstall", () => { /* VC install */ test.skip("installs vc directly", async () => { - if ((await emacsVersion()) >= "29.1") { + if (cmp(await emacsVersion(), "29.1") == 1) { const { stderr } = await ctx.runEask( "install-vc https://github.com/jcs-elpa/msgu" ); diff --git a/test/jest/lint/checkdoc-fail.el b/test/jest/lint/checkdoc-fail.el index f521198d..07c05e53 100644 --- a/test/jest/lint/checkdoc-fail.el +++ b/test/jest/lint/checkdoc-fail.el @@ -1,4 +1,4 @@ -;;; ert-test.el --- Test the command ert -*- lexical-binding: t; -*- +;;; checkdoc-fail.el --- Test checkdoc fail -*- lexical-binding: t; -*- ;; Copyright (C) 2025 the Eask authors. @@ -26,4 +26,4 @@ in this " ignore) -;;; declare-ok.el ends here +;;; checkdoc-fail.el ends here diff --git a/test/jest/lint/declare-fail.el b/test/jest/lint/declare-fail.el index 2a3207e5..08c132e6 100644 --- a/test/jest/lint/declare-fail.el +++ b/test/jest/lint/declare-fail.el @@ -1,4 +1,4 @@ -;;; declare-fail.el --- Test lint declare -*- lexical-binding: t; -*- +;;; declare-fail.el --- Test declare-fail -*- lexical-binding: t; -*- ;; Copyright (C) 2025 the Eask authors. diff --git a/test/jest/lint/declare-ok.el b/test/jest/lint/declare-ok.el index 70ab1bfe..fe82549a 100644 --- a/test/jest/lint/declare-ok.el +++ b/test/jest/lint/declare-ok.el @@ -1,4 +1,4 @@ -;;; ert-test.el --- Test the command ert -*- lexical-binding: t; -*- +;;; declare-ok.el --- Test declare-ok -*- lexical-binding: t; -*- ;; Copyright (C) 2025 the Eask authors. diff --git a/test/jest/lint/elisp-lint-ok.el b/test/jest/lint/elisp-lint-ok.el index 29915e81..409f5558 100644 --- a/test/jest/lint/elisp-lint-ok.el +++ b/test/jest/lint/elisp-lint-ok.el @@ -1,4 +1,4 @@ -;;; elisp-lint-ok.el --- Test the linting -*- lexical-binding: t; -*- +;;; elisp-lint-ok.el --- Test elisp-lint-ok -*- lexical-binding: t; -*- ;; Copyright (C) 2025 the Eask authors. diff --git a/test/jest/lint/elsa-warn.el b/test/jest/lint/elsa-warn.el index d7e9ace4..563f7b31 100644 --- a/test/jest/lint/elsa-warn.el +++ b/test/jest/lint/elsa-warn.el @@ -1,4 +1,4 @@ -;;; elsa-warn.el --- Test elsa linting -*- lexical-binding: t; -*- +;;; elsa-warn.el --- Test elsa-warn -*- lexical-binding: t; -*- ;; Copyright (C) 2025 the Eask authors. diff --git a/test/jest/lint/indent-warn.el b/test/jest/lint/indent-warn.el index d2d6156e..42b65490 100644 --- a/test/jest/lint/indent-warn.el +++ b/test/jest/lint/indent-warn.el @@ -1,4 +1,4 @@ -;;; indent-warn.el --- Test indent linting -*- lexical-binding: t; -*- +;;; indent-warn.el --- Test indent-warn -*- lexical-binding: t; -*- ;; Copyright (C) 2025 the Eask authors. diff --git a/test/jest/lint/regexp-warn.el b/test/jest/lint/regexp-warn.el index ecfdc2b2..83f9d8a9 100644 --- a/test/jest/lint/regexp-warn.el +++ b/test/jest/lint/regexp-warn.el @@ -1,4 +1,4 @@ -;;; regexp-warn.el --- Test regexp linting -*- lexical-binding: t; -*- +;;; regexp-warn.el --- Test regexp-warn -*- lexical-binding: t; -*- ;; Copyright (C) 2025 the Eask authors. diff --git a/test/jest/local.test.js b/test/jest/local.test.js index 1b2b3278..a1054922 100644 --- a/test/jest/local.test.js +++ b/test/jest/local.test.js @@ -4,16 +4,22 @@ // 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", () => { const cwd = "./test/jest/local"; const ctx = new TestContext(cwd); - // NOTE: install-deps takes a long time in this package + // NOTE: `install-deps` takes a long time in this package // this is because of recipe dependencies triggering // "temporary archives" build. - beforeAll(async () => await ctx.runEask("install-deps", { timeout: 40000 })); + beforeAll(async () => { + await ctx.runEask( + "install-deps", { timeout: 40000 }, + // See https://github.com/emacs-eask/cli/issues/11. + cmp(await emacsVersion(), "28.1") == -1); + }); afterAll(() => ctx.cleanUp()); @@ -49,7 +55,7 @@ describe("local", () => { // NOTE: eask loc is a long running command it("loc", async () => { // installs markdown mode -- depends on emacs 28.1 - if ((await emacsVersion()) >= "28.1") { + if (cmp(await emacsVersion(), "28.1") == 1) { await ctx.runEask("loc"); await ctx.runEask("loc Eask"); } @@ -77,7 +83,13 @@ describe("local", () => { }); describe("Development", () => { - beforeAll(async () => await ctx.runEask("install-deps")); + beforeAll(async () => { + await ctx.runEask( + "install-deps", { timeout: 40000 }, + // See https://github.com/emacs-eask/cli/issues/11. + cmp(await emacsVersion(), "28.1") == -1) + }); + // this requires install-deps it("compile", async () => { await ctx.runEask("compile"); @@ -110,7 +122,11 @@ describe("local", () => { }); describe("Execution", () => { - beforeAll(async () => await ctx.runEask("install-deps")); + beforeAll(async () => { + await ctx.runEask("install-deps", { timeout: 40000 }, + // See https://github.com/emacs-eask/cli/issues/11. + cmp(await emacsVersion(), "28.1") == -1) + }); test("eval", async () => { await ctx.runEask('eval "(progn (require \'mini.pkg.1))"'); @@ -195,13 +211,16 @@ describe("local", () => { describe("Linting", () => { // some lint commands may fail if packages are missing - beforeAll(async () => await ctx.runEask("install-deps")); + beforeAll(async () => { + await ctx.runEask("install-deps", { timeout: 40000 }, + // See https://github.com/emacs-eask/cli/issues/11. + cmp(await emacsVersion(), "28.1") == -1) + }); it.each([ "lint checkdoc", "lint declare", "lint elint", - "lint elisp-lint", "lint indent", "lint keywords", "lint license", @@ -210,17 +229,23 @@ describe("local", () => { await ctx.runEask(cmd); }); - it("lint regexps", async () => { - if ((await emacsVersion()) >= "27.1") { - await ctx.runEask("lint regexps"); - } - }); - // XXX: Elsa is not stable, ignore it for now test.skip("lint elsa", async () => { 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"); + } + }); + it("lint org *.org", async () => { await ctx.runEask("lint org *.org"); }); @@ -235,7 +260,7 @@ describe("local", () => { describe("Formatting", () => { // installs elisp-autofmt it("format elisp-autofmt", async () => { - if ((await emacsVersion()) >= "29.1") { + if (cmp(await emacsVersion(), "29.1") == 1) { await ctx.runEask("format elisp-autofmt"); } }); diff --git a/test/jest/local/Eask b/test/jest/local/Eask index 91d8bb6d..10dde27f 100644 --- a/test/jest/local/Eask +++ b/test/jest/local/Eask @@ -1,7 +1,7 @@ ;; -*- mode: eask; lexical-binding: t -*- (package "mini.pkg.1" - "9.9.10" + "12.12.13" "Minimal test package") (website-url "https://github.com/emacs-eask/cli/tree/master/test/fixtures/mini.pkg.1") diff --git a/test/jest/local/mini.pkg.1.el b/test/jest/local/mini.pkg.1.el index fd474bcc..3ee45d9d 100644 --- a/test/jest/local/mini.pkg.1.el +++ b/test/jest/local/mini.pkg.1.el @@ -5,7 +5,7 @@ ;; Author: Shen, Jen-Chieh ;; URL: https://github.com/emacs-eask/cli/tree/master/test/fixtures/mini.pkg.1 -;; Version: 9.9.10 +;; Version: 12.12.13 ;; Package-Requires: ((emacs "24.3") (s "1.12.0") (fringe-helper "1.0.1")) ;; Keywords: test local diff --git a/test/jest/options/options.el b/test/jest/options/options.el new file mode 100644 index 00000000..c46c536b --- /dev/null +++ b/test/jest/options/options.el @@ -0,0 +1,37 @@ +;;; options.el --- Test all options flag -*- lexical-binding: t; -*- + +;; Copyright (C) 2025 the Eask authors. + +;; Author: Shen, Jen-Chieh +;; Maintainer: Shen, Jen-Chieh +;; URL: https://github.com/emacs-eask/options +;; Version: 0.0.0 +;; Package-Requires: ((emacs "26.1")) +;; Keywords: test + +;; This file is not part of GNU Emacs. + +;; This program is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see . + +;;; Commentary: +;; +;; Test options. +;; + +;;; Code: + +;; Empty.. + +(provide 'options) +;;; options.el ends here diff --git a/test/jest/outdated-upgrade.test.js b/test/jest/outdated-upgrade.test.js index 660545ed..985990ae 100644 --- a/test/jest/outdated-upgrade.test.js +++ b/test/jest/outdated-upgrade.test.js @@ -1,10 +1,14 @@ -const { TestContext } = require("./helpers"); +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"); + 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("load make-outdate.el"); });