diff --git a/.github/workflows/test_exit-status.yml b/.github/workflows/test_exit-status.yml
new file mode 100644
index 00000000..f5f5370d
--- /dev/null
+++ b/.github/workflows/test_exit-status.yml
@@ -0,0 +1,54 @@
+name: Test Exit Status of Commands
+
+on:
+ push:
+ branches:
+ - master
+ paths:
+ - 'eask'
+ - '**.yml'
+ - lisp/**
+ - cmds/**
+ - src/**
+ - test/**
+ pull_request:
+ branches:
+ - master
+ paths-ignore:
+ - '**.md'
+ workflow_dispatch:
+
+concurrency:
+ group: ${{ github.workflow }}-${{ github.ref }}
+ cancel-in-progress: true
+
+jobs:
+ test:
+ runs-on: ${{ matrix.os }}
+ strategy:
+ fail-fast: false
+ matrix:
+ os: [ubuntu-latest, macos-latest, windows-latest]
+ emacs-version:
+ - 29.4
+
+ steps:
+ - uses: jcs090218/setup-emacs@master
+ with:
+ version: ${{ matrix.emacs-version }}
+
+ - uses: actions/checkout@v4
+
+ - name: Prepare Eask (Unix)
+ if: matrix.os == 'ubuntu-latest' || matrix.os == 'macos-latest'
+ run: |
+ chmod -R 777 ./
+ .github/scripts/setup-eask
+
+ - name: Prepare Eask (Windows)
+ if: matrix.os == 'windows-latest'
+ run: .github/scripts/setup-eask.ps1
+
+ - name: Testing...
+ run: |
+ make test-exit-status
diff --git a/Makefile b/Makefile
index d5fa01b9..fbc86126 100644
--- a/Makefile
+++ b/Makefile
@@ -34,7 +34,7 @@ command-local:
command-analyze:
./test/commands/analyze/dsl/run.sh
- ./test/commands/analyze/metadata/run.sh
+ ./test/commands/analyze/metadata/run.sh;
command-docker:
./test/commands/docker/run.sh
@@ -68,3 +68,24 @@ test-buttercup:
test-ecukes:
./test/commands/test/ecukes/run.sh
+
+test-exit-status:
+ ./test/exit-status/analyze/run.sh
+ ./test/exit-status/clean/run.sh
+ ./test/exit-status/compile/run.sh
+ ./test/exit-status/create/run.sh
+ ./test/exit-status/eval/run.sh
+ ./test/exit-status/fixtures/run.sh
+ ./test/exit-status/format/run.sh
+ ./test/exit-status/generate/run.sh
+ ./test/exit-status/install/run.sh
+ ./test/exit-status/install-deps/run.sh
+ ./test/exit-status/link/run.sh
+ ./test/exit-status/lint/run.sh
+ ./test/exit-status/load/run.sh
+ ./test/exit-status/package/run.sh
+ ./test/exit-status/refresh/run.sh
+ ./test/exit-status/reinstall/run.sh
+ ./test/exit-status/run/run.sh
+ ./test/exit-status/test/run.sh
+ ./test/exit-status/uninstall/run.sh
diff --git a/lisp/help/test/ert b/lisp/help/test/ert
index 44a7e18e..97ae201f 100644
--- a/lisp/help/test/ert
+++ b/lisp/help/test/ert
@@ -1,4 +1,4 @@
-💡 You need to specify the file(s) you want the ert to run:
+💡 You need to specify the file(s) you want ert to run:
$ eask test ert FILE-1 FILE-2
diff --git a/test/exit-status/analyze/Eask-error b/test/exit-status/analyze/Eask-error
new file mode 100644
index 00000000..3d2cb3f3
--- /dev/null
+++ b/test/exit-status/analyze/Eask-error
@@ -0,0 +1,2 @@
+(package "" "" "")
+(scrog "unrecognized")
diff --git a/test/exit-status/analyze/Eask-normal b/test/exit-status/analyze/Eask-normal
new file mode 100644
index 00000000..1b2c2e27
--- /dev/null
+++ b/test/exit-status/analyze/Eask-normal
@@ -0,0 +1,2 @@
+(package "check-dsl" "0.0.1" "Test for DSL")
+(keywords "dsl")
diff --git a/test/exit-status/analyze/Eask-warn b/test/exit-status/analyze/Eask-warn
new file mode 100644
index 00000000..9fdb2623
--- /dev/null
+++ b/test/exit-status/analyze/Eask-warn
@@ -0,0 +1,5 @@
+(package "check-dsl" "0.0.1" "Test for DSL")
+
+(keywords "dsl")
+
+(package-file "none.el")
diff --git a/test/exit-status/analyze/run.sh b/test/exit-status/analyze/run.sh
new file mode 100755
index 00000000..9a3f9b00
--- /dev/null
+++ b/test/exit-status/analyze/run.sh
@@ -0,0 +1,50 @@
+#!/usr/bin/env bash
+
+# Copyright (C) 2022-2024 the Eask authors.
+
+# 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, 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:
+#
+# Tests "analyze" command's option handling and error behaviour.
+# See the tests in the test/checker directory too.
+
+set -e
+
+source ./test/fixtures/home/scripts/testing.sh
+
+cd $(dirname "$0")
+
+# Eask-normal - no errors or warnings
+# Eask-warn - only warnings
+# Eask-error - errors and warnings
+
+should_run eask analyze Eask-normal
+
+should_run eask analyze Eask-warn
+
+should_error eask analyze Eask-error
+
+should_error eask analyze Eask-warn --strict
+
+# sanity check: flag should not change behavior in this case
+should_error eask analyze Eask-error --allow-error
+
+# Should report that Eask-normal was tested
+OUTPUT=$(should_error eask analyze --allow-error Eask-normal Eask-error)
+echo "$OUTPUT"
+should_match "(Checked 2 files)" "$OUTPUT"
+
+# Can also use a more concise form, but it doesn't print the output
+# should_match "(Checked 2 files)" "$(should_error eask analyze --allow-error Eask-normal Eask-error)"
diff --git a/test/exit-status/clean/Eask b/test/exit-status/clean/Eask
new file mode 100644
index 00000000..f5a12ebb
--- /dev/null
+++ b/test/exit-status/clean/Eask
@@ -0,0 +1 @@
+(package "check-clean" "0.0.1" "mock package")
diff --git a/test/exit-status/clean/mock.el b/test/exit-status/clean/mock.el
new file mode 100644
index 00000000..fa64e929
--- /dev/null
+++ b/test/exit-status/clean/mock.el
@@ -0,0 +1,5 @@
+;;;###autoload
+(defun my-ignore-fn ()
+ "Mock for testing"
+ (interactive)
+ (message "foo"))
diff --git a/test/exit-status/clean/run.sh b/test/exit-status/clean/run.sh
new file mode 100755
index 00000000..6632fa07
--- /dev/null
+++ b/test/exit-status/clean/run.sh
@@ -0,0 +1,57 @@
+#!/usr/bin/env bash
+
+# Copyright (C) 2022-2024 the Eask authors.
+
+# 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, 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:
+#
+# Tests "clean" command's option handling and error behaviour.
+
+set -e
+
+source ./test/fixtures/home/scripts/testing.sh
+cd $(dirname "$0")
+
+echo "Preparing test"
+# clean elc should work
+eask compile mock.el
+if [ ! -f ./mock.elc ]; then
+ echo "failed to create .elc files"
+ exit 1
+fi
+
+echo "Test clean command"
+
+# partial input
+should_error eask clean
+
+should_run eask clean elc
+
+# dist is write protected
+# FIXME either or both of these should error
+# should_error eask clean dist
+# should_error eask clean dist --strict
+
+# recompile to use for --allow-error
+eask compile mock.el
+
+# FIXME
+# expect that clean dist fails and clean elc succeeds
+# should_error eask clean all --allow-error
+
+# if [ -f ./mock.elc ]; then
+# echo "expected .elc files to be removed by eask clean all"
+# exit 1
+# fi
diff --git a/test/exit-status/compile/Eask b/test/exit-status/compile/Eask
new file mode 100644
index 00000000..3767928c
--- /dev/null
+++ b/test/exit-status/compile/Eask
@@ -0,0 +1 @@
+(package "check" "0.0.1" "mock package")
diff --git a/test/exit-status/compile/empty/.gitkeep b/test/exit-status/compile/empty/.gitkeep
new file mode 100644
index 00000000..e69de29b
diff --git a/test/exit-status/compile/fail.el b/test/exit-status/compile/fail.el
new file mode 100644
index 00000000..10bdc5b5
--- /dev/null
+++ b/test/exit-status/compile/fail.el
@@ -0,0 +1,3 @@
+;; -*- lexical-binding: t -*-
+;; this must fail to compile
+(fail "" (
diff --git a/test/exit-status/compile/mock.el b/test/exit-status/compile/mock.el
new file mode 100644
index 00000000..fa64e929
--- /dev/null
+++ b/test/exit-status/compile/mock.el
@@ -0,0 +1,5 @@
+;;;###autoload
+(defun my-ignore-fn ()
+ "Mock for testing"
+ (interactive)
+ (message "foo"))
diff --git a/test/exit-status/compile/run.sh b/test/exit-status/compile/run.sh
new file mode 100755
index 00000000..50b835e3
--- /dev/null
+++ b/test/exit-status/compile/run.sh
@@ -0,0 +1,48 @@
+#!/usr/bin/env bash
+
+# Copyright (C) 2022-2024 the Eask authors.
+
+# 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, 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:
+#
+# Tests "compile" command's option handling and error behaviour.
+
+set -e
+
+source ./test/fixtures/home/scripts/testing.sh
+cd $(dirname "$0")
+
+# FIXME this should match other commands which exit with status 1
+# partial input errors when there are no files
+# cd empty
+# should_error eask compile
+# cd ../
+
+# compiles with a warning
+should_run eask compile mock.el
+
+should_error eask compile --strict mock.el
+
+# --allow-error
+# rest state
+eask clean elc -v 0
+should_error eask compile fail.el
+should_error eask compile --allow-error fail.el mock.el
+
+# ensure mock.el is still compiled
+if [ ! -f mock.elc ]; then
+ echo "fail: expected to see mock.elc"
+ exit 1
+fi
diff --git a/test/exit-status/create/foo/.gitkeep b/test/exit-status/create/foo/.gitkeep
new file mode 100644
index 00000000..e69de29b
diff --git a/test/exit-status/create/run.sh b/test/exit-status/create/run.sh
new file mode 100755
index 00000000..6408b04c
--- /dev/null
+++ b/test/exit-status/create/run.sh
@@ -0,0 +1,35 @@
+#!/usr/bin/env bash
+
+# Copyright (C) 2022-2024 the Eask authors.
+
+# 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, 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:
+#
+# Tests "complete" command's error behaviour.
+
+set -e
+
+source ./test/fixtures/home/scripts/testing.sh
+cd $(dirname "$0")
+
+# partial input errors
+should_error eask create
+should_error eask create elpa
+should_error eask create package
+
+# FIXME
+# existing file errors
+# should_error eask create elpa foo
+# should_error eask create package foo
diff --git a/test/exit-status/eval/Eask b/test/exit-status/eval/Eask
new file mode 100644
index 00000000..3767928c
--- /dev/null
+++ b/test/exit-status/eval/Eask
@@ -0,0 +1 @@
+(package "check" "0.0.1" "mock package")
diff --git a/test/exit-status/eval/run.sh b/test/exit-status/eval/run.sh
new file mode 100755
index 00000000..04a173b9
--- /dev/null
+++ b/test/exit-status/eval/run.sh
@@ -0,0 +1,40 @@
+#!/usr/bin/env bash
+
+# Copyright (C) 2022-2024 the Eask authors.
+
+# 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, 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:
+#
+# Tests "eval" command's option handling and error behaviour.
+
+set -e
+
+source ./test/fixtures/home/scripts/testing.sh
+cd $(dirname "$0")
+
+# partial input
+should_error eask eval
+
+should_run eask eval '(message "hello")'
+
+should_run eask eval '(warn "hello")'
+
+# FIXME
+# should_error eask eval '(warn "hello")' --strict
+
+should_error eask eval '(error "hello")'
+should_error eask eval "(signal 'error \"hello\")"
+# --allow-error doesn't really change anything here
+should_error eask eval '(error "hello")' --allow-error
diff --git a/test/exit-status/fixtures/valid/Eask b/test/exit-status/fixtures/valid/Eask
new file mode 100644
index 00000000..74d06a82
--- /dev/null
+++ b/test/exit-status/fixtures/valid/Eask
@@ -0,0 +1,6 @@
+(package "valid-package" "0.0.1" "mock package that installs cleanly")
+
+(source 'gnu)
+(source 'melpa)
+
+(depends-on "emacs" "28.3")
diff --git a/test/exit-status/fixtures/valid/foo.el b/test/exit-status/fixtures/valid/foo.el
new file mode 100644
index 00000000..1467b85e
--- /dev/null
+++ b/test/exit-status/fixtures/valid/foo.el
@@ -0,0 +1,6 @@
+(defun foo-nothing (args)
+ "docstring"
+ (interactive "P")
+ )
+
+(provide 'foo)
diff --git a/test/exit-status/fixtures/valid/valid-package-pkg.el b/test/exit-status/fixtures/valid/valid-package-pkg.el
new file mode 100644
index 00000000..16f1199c
--- /dev/null
+++ b/test/exit-status/fixtures/valid/valid-package-pkg.el
@@ -0,0 +1,2 @@
+(define-package "valid-package" "0.0.1"
+ "mock package that installs cleanly" '((emacs "28.3")))
diff --git a/test/exit-status/format/Eask b/test/exit-status/format/Eask
new file mode 100644
index 00000000..3767928c
--- /dev/null
+++ b/test/exit-status/format/Eask
@@ -0,0 +1 @@
+(package "check" "0.0.1" "mock package")
diff --git a/test/exit-status/format/empty/.gitkeep b/test/exit-status/format/empty/.gitkeep
new file mode 100644
index 00000000..e69de29b
diff --git a/test/exit-status/format/fail.el b/test/exit-status/format/fail.el
new file mode 100644
index 00000000..10bdc5b5
--- /dev/null
+++ b/test/exit-status/format/fail.el
@@ -0,0 +1,3 @@
+;; -*- lexical-binding: t -*-
+;; this must fail to compile
+(fail "" (
diff --git a/test/exit-status/format/mock.el b/test/exit-status/format/mock.el
new file mode 100644
index 00000000..fa64e929
--- /dev/null
+++ b/test/exit-status/format/mock.el
@@ -0,0 +1,5 @@
+;;;###autoload
+(defun my-ignore-fn ()
+ "Mock for testing"
+ (interactive)
+ (message "foo"))
diff --git a/test/exit-status/format/run.sh b/test/exit-status/format/run.sh
new file mode 100755
index 00000000..ccf5fccb
--- /dev/null
+++ b/test/exit-status/format/run.sh
@@ -0,0 +1,48 @@
+#!/usr/bin/env bash
+
+# Copyright (C) 2022-2024 the Eask authors.
+
+# 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, 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:
+#
+# Tests "format" command's option handling and error behaviour.
+
+set -e
+
+source ./test/fixtures/home/scripts/testing.sh
+cd $(dirname "$0")
+
+# partial input
+should_error eask format
+
+# other commands default to apply to everything
+should_run eask format elfmt mock.el
+should_run eask format elisp-autofmt mock.el
+
+# does anything create elfmt warnings?
+
+should_error eask format elfmt fail.el
+# FIXME
+# should_error eask format elisp-autofmt fail.el
+
+# FIXME throws
+# OUTPUT=$(should_error eask format elfmt --allow-error fail.el mock.el)
+# echo "$OUTPUT"
+# should_match "Total of 1 .*" "$OUTPUT"
+
+# FIXME
+# OUTPUT=$(should_error eask format elisp-autofmt --allow-error fail.el mock.el)
+# echo "$OUTPUT"
+# should_match "Total of 1 .* formatted" "$OUTPUT"
diff --git a/test/exit-status/generate/Eask b/test/exit-status/generate/Eask
new file mode 100644
index 00000000..f5a12ebb
--- /dev/null
+++ b/test/exit-status/generate/Eask
@@ -0,0 +1 @@
+(package "check-clean" "0.0.1" "mock package")
diff --git a/test/exit-status/generate/fail.el b/test/exit-status/generate/fail.el
new file mode 100644
index 00000000..10bdc5b5
--- /dev/null
+++ b/test/exit-status/generate/fail.el
@@ -0,0 +1,3 @@
+;; -*- lexical-binding: t -*-
+;; this must fail to compile
+(fail "" (
diff --git a/test/exit-status/generate/mock.el b/test/exit-status/generate/mock.el
new file mode 100644
index 00000000..5f1b5594
--- /dev/null
+++ b/test/exit-status/generate/mock.el
@@ -0,0 +1,7 @@
+;;;###autoload
+(defun my-ignore-fn ()
+ "Mock for testing"
+ (interactive)
+ (message "foo"))
+
+(provide 'foo)
diff --git a/test/exit-status/generate/run.sh b/test/exit-status/generate/run.sh
new file mode 100755
index 00000000..93188a16
--- /dev/null
+++ b/test/exit-status/generate/run.sh
@@ -0,0 +1,51 @@
+#!/usr/bin/env bash
+
+# Copyright (C) 2022-2024 the Eask authors.
+
+# 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, 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:
+#
+# Tests "generate" command's option handling and error behaviour.
+
+set -e
+
+source ./test/fixtures/home/scripts/testing.sh
+cd $(dirname "$0")
+
+# partial input
+should_error eask generate
+should_error eask generate ignore
+should_error eask generate license
+should_error eask generate test
+should_error eask generate workflow
+
+# FIXME partial input
+# should_error eask generate recipe
+
+# FIXME
+# should_error eask generate ignore foobar123
+# should_error eask generate license foobar123
+
+should_run eask generate license mit
+# FIXME when LICENSE already exists
+# should_error eask generate licence mpl-2.0
+
+# FIXME prints a stack trace
+# folder exists
+should_error eask generate test ert
+
+# TODO can't test until autoload error is handled
+# --strict
+# --allow-error
diff --git a/test/exit-status/install-deps/Eask b/test/exit-status/install-deps/Eask
new file mode 100644
index 00000000..e90aabf6
--- /dev/null
+++ b/test/exit-status/install-deps/Eask
@@ -0,0 +1,8 @@
+(package "check-clean" "0.0.1" "mock package")
+
+(source 'gnu)
+
+(development
+ (depends-on "ert")
+ (depends-on "dash"))
+(depends-on "not-a-package")
diff --git a/test/exit-status/install-deps/run.sh b/test/exit-status/install-deps/run.sh
new file mode 100755
index 00000000..500feffd
--- /dev/null
+++ b/test/exit-status/install-deps/run.sh
@@ -0,0 +1,36 @@
+#!/usr/bin/env bash
+
+# Copyright (C) 2022-2024 the Eask authors.
+
+# 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, 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:
+#
+# Tests "install-deps" command's option handling and error behaviour.
+
+set -e
+
+source ./test/fixtures/home/scripts/testing.sh
+cd $(dirname "$0")
+
+should_error eask install-deps
+# dev dep is not installed
+should_error eask install-deps --dev
+
+# dev dep is installed
+should_error eask install-deps --dev --allow-error
+
+echo "Check: eask list should show dash"
+OUTPUT="$(eask list 2>&1)"
+should_match "dash" "$OUTPUT"
diff --git a/test/exit-status/install/Eask b/test/exit-status/install/Eask
new file mode 100644
index 00000000..446e6f9e
--- /dev/null
+++ b/test/exit-status/install/Eask
@@ -0,0 +1,6 @@
+(package "check-clean" "0.0.1" "mock package")
+
+(source 'gnu)
+(source 'melpa)
+
+(depends-on "not-a-package")
diff --git a/test/exit-status/install/run.sh b/test/exit-status/install/run.sh
new file mode 100755
index 00000000..9e2b4532
--- /dev/null
+++ b/test/exit-status/install/run.sh
@@ -0,0 +1,43 @@
+#!/usr/bin/env bash
+
+# Copyright (C) 2022-2024 the Eask authors.
+
+# 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, 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:
+#
+# Tests "install" command's option handling and error behaviour.
+
+set -e
+
+source ./test/fixtures/home/scripts/testing.sh
+cd $(dirname "$0")
+
+# due to bad package dependency in Eask
+should_error eask install
+
+# requires melpa source
+should_run eask install s
+
+# not a package
+should_error eask install 1234
+
+# uninstall s before
+eask uninstall s 1>/dev/null 2>&1
+should_error eask install --allow-error 1234 s
+
+# ensure s installed
+echo "Check: eask list should show s"
+OUTPUT="$(eask list 2>&1)"
+should_match "s" "$OUTPUT"
diff --git a/test/exit-status/link/Eask b/test/exit-status/link/Eask
new file mode 100644
index 00000000..8b92913b
--- /dev/null
+++ b/test/exit-status/link/Eask
@@ -0,0 +1,4 @@
+(package "check-clean" "0.0.1" "mock package")
+
+(source 'gnu)
+(source 'melpa)
diff --git a/test/exit-status/link/run.sh b/test/exit-status/link/run.sh
new file mode 100755
index 00000000..7c418a6f
--- /dev/null
+++ b/test/exit-status/link/run.sh
@@ -0,0 +1,56 @@
+#!/usr/bin/env bash
+
+# Copyright (C) 2022-2024 the Eask authors.
+
+# 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, 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:
+#
+# Tests "link" command's option handling and error behaviour.
+
+set -e
+
+source ./test/fixtures/home/scripts/testing.sh
+cd $(dirname "$0")
+
+# partial input
+should_error eask link
+should_error eask link add
+# FIXME should error
+# should_error eask link delete
+
+# FIXME stack trace when package name doesn't match link name
+# prefer a better warning if this is important
+# should_run eask link add foo ../fixtures/valid/
+
+should_run eask link add valid-package ../fixtures/valid/
+
+# FIXME stack trace when package doesn't have -pkg.el
+# FIXME stack trace when link name does not match package name
+# should_run eask link add valid-package ../install/
+
+OUTPUT="$(should_run eask link list)"
+echo "$OUTPUT"
+should_match "valid-package" "$OUTPUT"
+
+# when package/link doesn't exist
+# FIXME: doesn't error
+# should_error eask link delete foo
+
+# no package after delete
+# FIXME: can't delete using original link name, must use full name with version
+# e.g. valid-package-0.0.1 works, but expect valid-package to work also
+# OUTPUT=$(should_run eask link delete valid-package)
+# echo "$OUTPUT"
+# should_match "1 package unlinked" "$OUTPUT"
diff --git a/test/exit-status/lint/Eask b/test/exit-status/lint/Eask
new file mode 100644
index 00000000..4fed337f
--- /dev/null
+++ b/test/exit-status/lint/Eask
@@ -0,0 +1,7 @@
+(package "lint"
+ "0.0.1"
+ "Test project for lint")
+(package-file "lint-pkg.el")
+
+(source 'gnu)
+(source 'melpa)
diff --git a/test/exit-status/lint/checkdoc-fail.el b/test/exit-status/lint/checkdoc-fail.el
new file mode 100644
index 00000000..ecbc4aad
--- /dev/null
+++ b/test/exit-status/lint/checkdoc-fail.el
@@ -0,0 +1,29 @@
+;;; ert-test.el --- Test the command ert -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2022-2024 the Eask authors.
+
+;; 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:
+
+;; Tests for the command ert
+
+;;; Code:
+
+(defun my-foo (arg)
+ ".make a lot of checkdoc errors
+
+in this " ignore)
+
+;;; declare-ok.el ends here
diff --git a/test/exit-status/lint/declare-fail.el b/test/exit-status/lint/declare-fail.el
new file mode 100644
index 00000000..fa2739e3
--- /dev/null
+++ b/test/exit-status/lint/declare-fail.el
@@ -0,0 +1,24 @@
+;;; declare-fail.el --- Test lint declare -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2022-2024 the Eask authors.
+
+;; 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:
+
+;;; Code:
+
+(declare-function not-a-function "subr.el" (x y z))
+
+;;; declare-fail.el ends here
diff --git a/test/exit-status/lint/declare-ok.el b/test/exit-status/lint/declare-ok.el
new file mode 100644
index 00000000..0ff0ff03
--- /dev/null
+++ b/test/exit-status/lint/declare-ok.el
@@ -0,0 +1,26 @@
+;;; ert-test.el --- Test the command ert -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2022-2024 the Eask authors.
+
+;; 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:
+
+;; Tests for the command ert
+
+;;; Code:
+
+(declare-function ignore "subr.el" (&rest args))
+
+;;; declare-ok.el ends here
diff --git a/test/exit-status/lint/elisp-lint-ok.el b/test/exit-status/lint/elisp-lint-ok.el
new file mode 100644
index 00000000..4b25a403
--- /dev/null
+++ b/test/exit-status/lint/elisp-lint-ok.el
@@ -0,0 +1,21 @@
+;;; elisp-lint-ok.el --- Test the linting -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2022-2024 the Eask authors.
+
+;;; Version: 0.0.1
+;;; URL: https://foo.com
+;;; Package-Requires: ((emacs "28.1"))
+
+;;; Commentary:
+
+;; Tests linting with elisp-lint
+;; Also clean for packge lint
+
+;;; Code:
+
+(defun elisp-lint-ok-foo ()
+ "Nothing here."
+ (message "ok"))
+
+(provide 'elisp-lint-ok)
+;;; elisp-lint-ok.el ends here
diff --git a/test/exit-status/lint/elsa-warn.el b/test/exit-status/lint/elsa-warn.el
new file mode 100644
index 00000000..a91f18c9
--- /dev/null
+++ b/test/exit-status/lint/elsa-warn.el
@@ -0,0 +1,29 @@
+;;; elsa-warn.el --- Test elsa linting -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2022-2024 the Eask authors.
+
+;; 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 elsa.
+;; Should only cause warnings
+
+;;; Code:
+
+(defun elsa-warn-foo ()
+ (some-foo) ;; not declared warning
+ (message "Ok"))
+
+;;; elsa-warn.el ends here
diff --git a/test/exit-status/lint/indent-warn.el b/test/exit-status/lint/indent-warn.el
new file mode 100644
index 00000000..7e009664
--- /dev/null
+++ b/test/exit-status/lint/indent-warn.el
@@ -0,0 +1,31 @@
+;;; indent-warn.el --- Test indent linting -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2022-2024 the Eask authors.
+
+;; 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 indent.
+;; Should only cause warnings
+
+;;; Code:
+
+(defun indent-warn-foo ()
+ (if 't
+ (message "Ok")
+ (message
+ "no")))
+
+;;; indent-warn.el ends here
diff --git a/test/exit-status/lint/lint-pkg.el b/test/exit-status/lint/lint-pkg.el
new file mode 100644
index 00000000..b9f0f037
--- /dev/null
+++ b/test/exit-status/lint/lint-pkg.el
@@ -0,0 +1 @@
+(define-package "lint" "0.0.1" "Test project for lint" 'nil)
diff --git a/test/exit-status/lint/regexp-warn.el b/test/exit-status/lint/regexp-warn.el
new file mode 100644
index 00000000..5025297b
--- /dev/null
+++ b/test/exit-status/lint/regexp-warn.el
@@ -0,0 +1,28 @@
+;;; regexp-warn.el --- Test regexp linting -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2022-2024 the Eask authors.
+
+;; 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 regexp.
+;; Should only cause warnings
+
+;;; Code:
+
+(defun regexp-warn-foo ()
+ (re-search-backward "^[.:wrod:]$"))
+
+;;; regexp-warn.el ends here
diff --git a/test/exit-status/lint/run.sh b/test/exit-status/lint/run.sh
new file mode 100755
index 00000000..c93c7e45
--- /dev/null
+++ b/test/exit-status/lint/run.sh
@@ -0,0 +1,119 @@
+#!/usr/bin/env bash
+
+# Copyright (C) 2022-2024 the Eask authors.
+
+# 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, 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 command `lint`
+#
+
+set -e
+
+source ./test/fixtures/home/scripts/testing.sh
+cd $(dirname "$0")
+
+# partial input
+should_error eask lint
+
+echo "checkdoc"
+echo "----------"
+should_run eask lint checkdoc declare-ok.el
+# FIXME
+# should_error eask lint checkdoc --strict checkdoc-fail.el
+# should_error eask lint checkdoc --strict --allow-error checkdoc-fail.el declare-ok.el
+
+echo "declare"
+echo "----------"
+should_run eask lint declare declare-ok.el
+
+# warnings are default ignored
+should_run eask lint declare declare-fail.el
+
+# --strict
+# FIXME should exit with error
+# should_error eask lint declare --strict declare-fail.el
+
+# FIXME should exit with error
+# should_error eask lint declare --strict --allow-error ./*.el
+
+echo "elint"
+echo "----------"
+
+should_run eask lint elint declare-ok.el
+# FIXME
+# should_error eask lint elint --strict checkdoc-fail.el
+
+echo "elisp-lint"
+echo "----------"
+
+# no warnings
+should_run eask lint elisp-lint --strict elisp-lint-ok.el
+# warnings
+should_run eask lint elisp-lint declare-ok.el
+
+should_error eask lint elisp-lint --strict declare-ok.el
+OUTPUT="$(should_error eask lint elisp-lint --strict --allow-error checkdoc-fail.el elisp-lint-ok.el )"
+echo "$OUTPUT"
+should_match "2 files linted" "$OUTPUT"
+
+echo "elsa"
+echo "----------"
+
+# no warnings
+should_run eask lint elsa elisp-lint-ok.el
+# warnings
+should_run eask lint elsa elsa-warn.el
+# elsa reports some issues as errors here
+should_error eask lint elsa declare-ok.el
+
+# FIXME
+# should_error eask lint elsa --strict elsa-warn.el
+
+echo "indent"
+echo "----------"
+
+should_run eask lint indent indent-warn.el
+should_error eask lint indent --strict indent-warn.el
+OUTPUT="$(should_error eask lint indent --strict --allow-error indent-warn.el declare-ok.el)"
+echo "$OUTPUT"
+should_match "2 files linted" "$OUTPUT"
+
+echo "keywords"
+echo "----------"
+
+# TODO seems like keywords in actual file are ignored
+# only those in Eask file are checked
+# but those interfere with --strict handling in other commands
+# should_run eask lint keywords
+# should_error eask lint keywords --strict
+
+echo "package"
+echo "----------"
+
+should_run eask lint package declare-ok.el
+# FIXME
+# should_error eask lint package --strict declare-ok.el
+
+# note that all files are checked anyway so --allow-error has no effect
+
+echo "regexps"
+echo "----------"
+
+should_error eask lint regexps regexp-warn.el
+# FIXME regexp throws and is not caught so second file not linted
+# OUTPUT="$(should_error eask lint regexps --allow-error regexp-warn.el declare-ok.el)"
+# echo "$OUTPUT"
+# should_match "2 files linted" "$OUTPUT"
diff --git a/test/exit-status/load/Eask b/test/exit-status/load/Eask
new file mode 100644
index 00000000..4fed337f
--- /dev/null
+++ b/test/exit-status/load/Eask
@@ -0,0 +1,7 @@
+(package "lint"
+ "0.0.1"
+ "Test project for lint")
+(package-file "lint-pkg.el")
+
+(source 'gnu)
+(source 'melpa)
diff --git a/test/exit-status/load/declare-ok.el b/test/exit-status/load/declare-ok.el
new file mode 100644
index 00000000..0ff0ff03
--- /dev/null
+++ b/test/exit-status/load/declare-ok.el
@@ -0,0 +1,26 @@
+;;; ert-test.el --- Test the command ert -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2022-2024 the Eask authors.
+
+;; 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:
+
+;; Tests for the command ert
+
+;;; Code:
+
+(declare-function ignore "subr.el" (&rest args))
+
+;;; declare-ok.el ends here
diff --git a/test/exit-status/load/lint-pkg.el b/test/exit-status/load/lint-pkg.el
new file mode 100644
index 00000000..b9f0f037
--- /dev/null
+++ b/test/exit-status/load/lint-pkg.el
@@ -0,0 +1 @@
+(define-package "lint" "0.0.1" "Test project for lint" 'nil)
diff --git a/test/exit-status/load/run.sh b/test/exit-status/load/run.sh
new file mode 100755
index 00000000..6000d217
--- /dev/null
+++ b/test/exit-status/load/run.sh
@@ -0,0 +1,35 @@
+#!/usr/bin/env bash
+
+# Copyright (C) 2022-2024 the Eask authors.
+
+# 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, 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 command `load`
+#
+
+set -e
+
+source ./test/fixtures/home/scripts/testing.sh
+cd $(dirname "$0")
+
+should_run eask load declare-ok.el
+# for some reason this errors
+# unsure if it is expected behavior, use it for now
+should_error eask load lint-pkg.el
+
+# FIXME
+# OUTPUT="$(should_error eask load --allow-error lint-pkg.el declare-ok.el)"
+# should_match "Loading .*declare-ok.el" "$OUTPUT"
diff --git a/test/exit-status/package/Eask b/test/exit-status/package/Eask
new file mode 100644
index 00000000..4fed337f
--- /dev/null
+++ b/test/exit-status/package/Eask
@@ -0,0 +1,7 @@
+(package "lint"
+ "0.0.1"
+ "Test project for lint")
+(package-file "lint-pkg.el")
+
+(source 'gnu)
+(source 'melpa)
diff --git a/test/exit-status/package/lint-pkg.el b/test/exit-status/package/lint-pkg.el
new file mode 100644
index 00000000..b9f0f037
--- /dev/null
+++ b/test/exit-status/package/lint-pkg.el
@@ -0,0 +1 @@
+(define-package "lint" "0.0.1" "Test project for lint" 'nil)
diff --git a/test/exit-status/package/lint.el b/test/exit-status/package/lint.el
new file mode 100644
index 00000000..e1d7e259
--- /dev/null
+++ b/test/exit-status/package/lint.el
@@ -0,0 +1,26 @@
+;;; lint.el --- Test the command package -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2022-2024 the Eask authors.
+
+;; 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:
+
+;;; Code:
+
+(declare-function ignore "subr.el" (&rest args))
+
+(provide 'lint)
+
+;;; lint.el ends here
diff --git a/test/exit-status/package/run.sh b/test/exit-status/package/run.sh
new file mode 100755
index 00000000..490498d6
--- /dev/null
+++ b/test/exit-status/package/run.sh
@@ -0,0 +1,34 @@
+#!/usr/bin/env bash
+
+# Copyright (C) 2022-2024 the Eask authors.
+
+# 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, 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 command `package`
+#
+
+set -e
+
+source ./test/fixtures/home/scripts/testing.sh
+cd $(dirname "$0")
+
+should_run eask package
+
+# FIXME I think this should error
+# warning :files spec is equivalent to default
+# should_error eask package --strict
+
+# --allow-error doesn't make sense for this command
diff --git a/test/exit-status/refresh/bad/Eask b/test/exit-status/refresh/bad/Eask
new file mode 100644
index 00000000..2018e015
--- /dev/null
+++ b/test/exit-status/refresh/bad/Eask
@@ -0,0 +1,8 @@
+(package "lint"
+ "0.0.1"
+ "Test project for lint")
+(package-file "lint-pkg.el")
+
+(source 'gnu)
+(source 'melpa)
+(source 'foobar)
diff --git a/test/exit-status/refresh/good/Eask b/test/exit-status/refresh/good/Eask
new file mode 100644
index 00000000..4fed337f
--- /dev/null
+++ b/test/exit-status/refresh/good/Eask
@@ -0,0 +1,7 @@
+(package "lint"
+ "0.0.1"
+ "Test project for lint")
+(package-file "lint-pkg.el")
+
+(source 'gnu)
+(source 'melpa)
diff --git a/test/exit-status/refresh/run.sh b/test/exit-status/refresh/run.sh
new file mode 100755
index 00000000..134ebf53
--- /dev/null
+++ b/test/exit-status/refresh/run.sh
@@ -0,0 +1,36 @@
+#!/usr/bin/env bash
+
+# Copyright (C) 2022-2024 the Eask authors.
+
+# 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, 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 command `refresh`
+#
+
+set -e
+
+source ./test/fixtures/home/scripts/testing.sh
+cd $(dirname "$0")
+
+cd ./good/
+should_run eask refresh
+cd ../
+
+cd ./bad/
+should_error eask refresh
+OUTPUT="$(should_error eask refresh --allow-error)"
+echo "$OUTPUT"
+should_match "Downloading gnu" "$OUTPUT"
diff --git a/test/exit-status/reinstall/Eask b/test/exit-status/reinstall/Eask
new file mode 100644
index 00000000..d3341117
--- /dev/null
+++ b/test/exit-status/reinstall/Eask
@@ -0,0 +1,10 @@
+(package "check-clean" "0.0.1" "mock package")
+
+(package-file "lint.el")
+
+(source 'gnu)
+
+(development
+ (depends-on "ert")
+ (depends-on "dash"))
+;; (depends-on "not-a-package")
diff --git a/test/exit-status/reinstall/lint.el b/test/exit-status/reinstall/lint.el
new file mode 100644
index 00000000..564720ef
--- /dev/null
+++ b/test/exit-status/reinstall/lint.el
@@ -0,0 +1,28 @@
+;;; lint.el --- Test the command package -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2022-2024 the Eask authors.
+
+;; 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 .
+
+;;; Version: 0.0.1
+
+;;; Commentary:
+
+;;; Code:
+
+(declare-function ignore "subr.el" (&rest args))
+
+(provide 'lint)
+
+;;; lint.el ends here
diff --git a/test/exit-status/reinstall/run.sh b/test/exit-status/reinstall/run.sh
new file mode 100755
index 00000000..1dcaf105
--- /dev/null
+++ b/test/exit-status/reinstall/run.sh
@@ -0,0 +1,49 @@
+#!/usr/bin/env bash
+
+# Copyright (C) 2022-2024 the Eask authors.
+
+# 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, 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:
+#
+# Tests "reinstall" command
+
+set -e
+
+source ./test/fixtures/home/scripts/testing.sh
+cd $(dirname "$0")
+
+# FIXME
+# unclear what should happen here
+# message seems to suggest that the package-file will be uninstalled
+# but this does not work, e.g. eask install -> eask uninstall does not undo
+# should_error eask reinstall
+
+# TODO this is some weird bug with install
+eask install || true # this fails, seems to want to print a message but throws
+eask install lint # already installed, but without the previous step it would fail
+
+# now it thinks this is unavailable
+should_run eask reinstall lint
+# FIXME no effect
+# should_error eask reinstall --strict lint
+
+# reinstall a package that isn't installed
+should_run eask reinstall s
+
+# reinstall a built-in package
+# FIXME huge stack trace
+should_error eask reinstall ert
+
+# seems like neither --strict or --allow-error has any effect
diff --git a/test/exit-status/run/Eask b/test/exit-status/run/Eask
new file mode 100644
index 00000000..5e85bb1f
--- /dev/null
+++ b/test/exit-status/run/Eask
@@ -0,0 +1,19 @@
+(package "check-clean" "0.0.1" "mock package")
+
+(package-file "lint.el")
+
+(source 'gnu)
+
+(eask-defcommand my-command
+ "This is a command"
+ (message "hello world"))
+
+(eask-defcommand my-warn
+ (warn "A warning"))
+
+(eask-defcommand my-error
+ (error "An error"))
+
+(script "hello" "echo 'hello'")
+(script "warn" "eask" "run" "command" "my-warn")
+(script "exit" "exit" "1")
diff --git a/test/exit-status/run/lint.el b/test/exit-status/run/lint.el
new file mode 100644
index 00000000..564720ef
--- /dev/null
+++ b/test/exit-status/run/lint.el
@@ -0,0 +1,28 @@
+;;; lint.el --- Test the command package -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2022-2024 the Eask authors.
+
+;; 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 .
+
+;;; Version: 0.0.1
+
+;;; Commentary:
+
+;;; Code:
+
+(declare-function ignore "subr.el" (&rest args))
+
+(provide 'lint)
+
+;;; lint.el ends here
diff --git a/test/exit-status/run/no-scripts/Eask b/test/exit-status/run/no-scripts/Eask
new file mode 100644
index 00000000..77f5a3b9
--- /dev/null
+++ b/test/exit-status/run/no-scripts/Eask
@@ -0,0 +1,15 @@
+(package "check-clean" "0.0.1" "mock package")
+
+(package-file "lint.el")
+
+(source 'gnu)
+
+(eask-defcommand my-command
+ "This is a command"
+ (message "hello world"))
+
+(eask-defcommand my-warn
+ (warn "A warning"))
+
+(eask-defcommand my-error
+ (error "An error"))
diff --git a/test/exit-status/run/run.sh b/test/exit-status/run/run.sh
new file mode 100755
index 00000000..85a7e153
--- /dev/null
+++ b/test/exit-status/run/run.sh
@@ -0,0 +1,52 @@
+#!/usr/bin/env bash
+
+# Copyright (C) 2022-2024 the Eask authors.
+
+# 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, 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:
+#
+# Tests "run" command
+
+set -e
+
+source ./test/fixtures/home/scripts/testing.sh
+cd $(dirname "$0")
+
+should_error eask run
+# FIXME
+# should_error eask run command
+# FIXME
+# cd ./no-scripts/
+# should_error eask run script
+# cd ../
+
+should_run eask run command my-command my-warn
+# FIXME
+# should_error eask run command --strict my-command my-warn
+
+# FIXME stack trace
+should_error eask run command my-error
+
+OUTPUT="$(should_error eask run command --allow-error my-error my-command)"
+# FIXME
+# should_match "hello world" "$OUTPUT"
+
+should_run eask run script hello
+should_run eask run script hello foo
+# FIXME
+# should_error eask run script --strict hello foo
+
+# FIXME this doesn't actually run the script
+should_run eask run script warn
diff --git a/test/exit-status/test/Eask b/test/exit-status/test/Eask
new file mode 100644
index 00000000..4fed337f
--- /dev/null
+++ b/test/exit-status/test/Eask
@@ -0,0 +1,7 @@
+(package "lint"
+ "0.0.1"
+ "Test project for lint")
+(package-file "lint-pkg.el")
+
+(source 'gnu)
+(source 'melpa)
diff --git a/test/exit-status/test/activate/Eask b/test/exit-status/test/activate/Eask
new file mode 100644
index 00000000..5040df85
--- /dev/null
+++ b/test/exit-status/test/activate/Eask
@@ -0,0 +1,7 @@
+(package "test-activate"
+ "0.0.1"
+ "Test project for test-activate")
+(package-file "test-activate-pkg.el")
+
+(source 'gnu)
+(source 'melpa)
diff --git a/test/exit-status/test/activate/test-activate.el b/test/exit-status/test/activate/test-activate.el
new file mode 100644
index 00000000..edb8cdee
--- /dev/null
+++ b/test/exit-status/test/activate/test-activate.el
@@ -0,0 +1,32 @@
+;;; test-activate.el --- Test "activate" -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2022-2024 the Eask authors.
+
+;; 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 .
+
+;;; Version: 0.0.1
+
+;;; Commentary:
+
+;;; Code:
+
+(declare-function ignore "subr.el" (&rest args))
+
+(eval-after-load
+ 'test-activate
+ (warn "called on activate"))
+
+(provide 'test-activate)
+
+;;; test-activate.el ends here
diff --git a/test/exit-status/test/buttercup/Eask b/test/exit-status/test/buttercup/Eask
new file mode 100644
index 00000000..7790a4af
--- /dev/null
+++ b/test/exit-status/test/buttercup/Eask
@@ -0,0 +1,7 @@
+(package "test-buttercup"
+ "0.0.1"
+ "Test project for test-buttercup")
+(package-file "test-buttercup-pkg.el")
+
+(source 'gnu)
+(source 'melpa)
diff --git a/test/exit-status/test/buttercup/test-fail.el b/test/exit-status/test/buttercup/test-fail.el
new file mode 100644
index 00000000..caeeb151
--- /dev/null
+++ b/test/exit-status/test/buttercup/test-fail.el
@@ -0,0 +1,4 @@
+;;; -*- lexical-binding: t; -*-
+(describe "A suite"
+ (it "contains a spec with an expectation"
+ (expect t :to-be t)))
diff --git a/test/exit-status/test/buttercup/test-feature.el b/test/exit-status/test/buttercup/test-feature.el
new file mode 100644
index 00000000..caeeb151
--- /dev/null
+++ b/test/exit-status/test/buttercup/test-feature.el
@@ -0,0 +1,4 @@
+;;; -*- lexical-binding: t; -*-
+(describe "A suite"
+ (it "contains a spec with an expectation"
+ (expect t :to-be t)))
diff --git a/test/exit-status/test/buttercup/test-warn.el b/test/exit-status/test/buttercup/test-warn.el
new file mode 100644
index 00000000..28d47619
--- /dev/null
+++ b/test/exit-status/test/buttercup/test-warn.el
@@ -0,0 +1,4 @@
+;;; -*- lexical-binding: t; -*-
+(describe "A failing suite"
+ (it "contains a spec with a failed expectation"
+ (expect t :to-be nil)))
diff --git a/test/exit-status/test/ecukes/Eask b/test/exit-status/test/ecukes/Eask
new file mode 100644
index 00000000..cc5ec20f
--- /dev/null
+++ b/test/exit-status/test/ecukes/Eask
@@ -0,0 +1,13 @@
+(package "ecukes"
+ "0.0.1"
+ "Test project for command `ecukes'")
+
+(package-file "ecukes.el")
+
+(source 'gnu)
+(source 'melpa)
+
+(development
+ (depends-on "ecukes"))
+
+(setq network-security-level 'low) ; see https://github.com/jcs090218/setup-emacs-windows/issues/156#issuecomment-932956432
diff --git a/test/exit-status/test/ecukes/features/bad.feature b/test/exit-status/test/ecukes/features/bad.feature
new file mode 100644
index 00000000..d3acdc97
--- /dev/null
+++ b/test/exit-status/test/ecukes/features/bad.feature
@@ -0,0 +1,4 @@
+Feature: Bad test
+
+ Scenario: This fails
+ Then identical things are different
diff --git a/test/exit-status/test/ecukes/features/foo.feature b/test/exit-status/test/ecukes/features/foo.feature
new file mode 100644
index 00000000..e69de29b
diff --git a/test/exit-status/test/ecukes/features/step-definitions/ecukes-steps.el b/test/exit-status/test/ecukes/features/step-definitions/ecukes-steps.el
new file mode 100644
index 00000000..39de4026
--- /dev/null
+++ b/test/exit-status/test/ecukes/features/step-definitions/ecukes-steps.el
@@ -0,0 +1,3 @@
+(require 'ert)
+(Then "identical things are different"
+ (lambda () (should (equal 1 2))))
diff --git a/test/exit-status/test/ecukes/features/support/env.el b/test/exit-status/test/ecukes/features/support/env.el
new file mode 100644
index 00000000..e69de29b
diff --git a/test/exit-status/test/empty/Eask b/test/exit-status/test/empty/Eask
new file mode 100644
index 00000000..e40036cb
--- /dev/null
+++ b/test/exit-status/test/empty/Eask
@@ -0,0 +1,7 @@
+(package "empty"
+ "0.0.1"
+ "Test project for empty")
+(package-file "empty-pkg.el")
+
+(source 'gnu)
+(source 'melpa)
diff --git a/test/exit-status/test/melpazoid-fail/bad-package-version.el b/test/exit-status/test/melpazoid-fail/bad-package-version.el
new file mode 100644
index 00000000..e86d13d0
--- /dev/null
+++ b/test/exit-status/test/melpazoid-fail/bad-package-version.el
@@ -0,0 +1,36 @@
+;;; lint-autoloads.el --- automatically extracted autoloads (do not edit) -*- lexical-binding: t -*-
+;; Generated by the `loaddefs-generate' function.
+;; This is about the only thing that causes melpazoid to error
+;; Package-Version: (("foo", 12345
+
+;; This file is part of GNU Emacs.
+
+;;; Code:
+
+(add-to-list 'load-path (or (and load-file-name (directory-file-name (file-name-directory load-file-name))) (car load-path)))
+
+
+
+;;; Generated autoloads from checkdoc-fail.el
+
+(register-definition-prefixes "checkdoc-fail" '("my-foo"))
+
+
+;;; Generated autoloads from elisp-lint-ok.el
+
+(register-definition-prefixes "elisp-lint-ok" '("elisp-lint-ok-foo"))
+
+
+;;; End of scraped data
+
+(provide 'lint-autoloads)
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; no-native-compile: t
+;; coding: utf-8-emacs-unix
+;; End:
+
+;;; lint-autoloads.el ends here
diff --git a/test/exit-status/test/melpazoid-warn/checkdoc-fail.el b/test/exit-status/test/melpazoid-warn/checkdoc-fail.el
new file mode 100644
index 00000000..ecbc4aad
--- /dev/null
+++ b/test/exit-status/test/melpazoid-warn/checkdoc-fail.el
@@ -0,0 +1,29 @@
+;;; ert-test.el --- Test the command ert -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2022-2024 the Eask authors.
+
+;; 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:
+
+;; Tests for the command ert
+
+;;; Code:
+
+(defun my-foo (arg)
+ ".make a lot of checkdoc errors
+
+in this " ignore)
+
+;;; declare-ok.el ends here
diff --git a/test/exit-status/test/run.sh b/test/exit-status/test/run.sh
new file mode 100755
index 00000000..470f0e0f
--- /dev/null
+++ b/test/exit-status/test/run.sh
@@ -0,0 +1,94 @@
+#!/usr/bin/env bash
+
+# Copyright (C) 2022-2024 the Eask authors.
+
+# 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, 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 command `test`
+#
+
+set -e
+
+source ./test/fixtures/home/scripts/testing.sh
+cd $(dirname "$0")
+
+# partial input
+should_error eask test
+
+# FIXME
+# should_error eask test ert
+
+echo "activate"
+echo "----------"
+cd ./activate/
+should_run eask test activate
+# FIXME stack trace when missing file
+
+# can create an error by having (eval-after-load 'something (warn "")) in a file that provides 'something
+should_run eask test activate test-activate.el
+# FIXME
+# should_error eask test activate --strict test-activate.el
+cd ..
+
+echo "buttercup"
+echo "----------"
+should_error eask test buttercup empty # no tests
+
+# seems like buttercup either errors or runs, no warn?
+should_error eask test buttercup ./buttercup/
+
+echo "ecukes"
+echo "----------"
+# FIXME this throws file-missing, emits stack trace
+should_error eask test ecukes
+
+cd ./ecukes/
+should_run eask test ecukes features/foo.feature
+# FIXME expect failing tests to exit with non-zero
+# should_error eask test ecukes
+cd ..
+
+echo "ert-runner"
+echo "----------"
+cd empty/
+should_error eask test ert-runner
+cd ..
+
+# FIXME ert-runner ignores arguments
+# should_run eask test ert-runner test/ert-test.el
+# should_error eask test ert-runner test/ert-fail-test.el
+should_error eask test ert-runner # all tests
+
+echo "ert"
+echo "----------"
+# FIXME partial input should error
+# should_error eask test ert
+
+should_run eask test ert test/ert-test.el
+should_error eask test ert test/ert-fail-test.el
+should_error eask test ert test/*.el
+
+# --allow-error has no effect
+
+echo "melpazoid"
+echo "----------"
+# FIXME doesn't error, in fact it hardly seems to error
+# should_error eask test --strict melpazoid melpazoid-warn/
+
+# The only time it errors is with a malformed package-version header
+should_error eask test melpazoid melpazoid-fail/
+
+should_run eask test melpazoid empty/
diff --git a/test/exit-status/test/test/ert-fail-test.el b/test/exit-status/test/test/ert-fail-test.el
new file mode 100644
index 00000000..53af5450
--- /dev/null
+++ b/test/exit-status/test/test/ert-fail-test.el
@@ -0,0 +1,5 @@
+(require 'ert)
+
+(ert-deftest my-fail/test ()
+ "Tests something."
+ (should (equal 't nil)))
diff --git a/test/exit-status/test/test/ert-test.el b/test/exit-status/test/test/ert-test.el
new file mode 100644
index 00000000..d42da8ec
--- /dev/null
+++ b/test/exit-status/test/test/ert-test.el
@@ -0,0 +1,9 @@
+(require 'ert)
+
+(ert-deftest my-something/test ()
+ "Tests something."
+ (should (equal 't 't)))
+
+(ert-deftest my-something-2/test ()
+ "Tests something."
+ (should-not nil))
diff --git a/test/exit-status/uninstall/Eask b/test/exit-status/uninstall/Eask
new file mode 100644
index 00000000..d3341117
--- /dev/null
+++ b/test/exit-status/uninstall/Eask
@@ -0,0 +1,10 @@
+(package "check-clean" "0.0.1" "mock package")
+
+(package-file "lint.el")
+
+(source 'gnu)
+
+(development
+ (depends-on "ert")
+ (depends-on "dash"))
+;; (depends-on "not-a-package")
diff --git a/test/exit-status/uninstall/lint.el b/test/exit-status/uninstall/lint.el
new file mode 100644
index 00000000..564720ef
--- /dev/null
+++ b/test/exit-status/uninstall/lint.el
@@ -0,0 +1,28 @@
+;;; lint.el --- Test the command package -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2022-2024 the Eask authors.
+
+;; 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 .
+
+;;; Version: 0.0.1
+
+;;; Commentary:
+
+;;; Code:
+
+(declare-function ignore "subr.el" (&rest args))
+
+(provide 'lint)
+
+;;; lint.el ends here
diff --git a/test/exit-status/uninstall/run.sh b/test/exit-status/uninstall/run.sh
new file mode 100755
index 00000000..be5a40a0
--- /dev/null
+++ b/test/exit-status/uninstall/run.sh
@@ -0,0 +1,44 @@
+#!/usr/bin/env bash
+
+# Copyright (C) 2022-2024 the Eask authors.
+
+# 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, 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:
+#
+# Tests "uninstall" command
+
+set -e
+
+source ./test/fixtures/home/scripts/testing.sh
+cd $(dirname "$0")
+
+# FIXME
+# unclear what should happen here
+# message seems to suggest that the package-file will be uninstalled
+# but this does not work, e.g. eask install -> eask uninstall does not undo
+# should_error eask uninstall
+
+# TODO what if package file is specified
+
+# Uninstall a package that isn't installed
+should_run eask uninstall s
+
+# Uninstall a built-in package
+# FIXME huge stack trace
+should_error eask uninstall ert
+
+# seems like neither --strict or --allow-error has any effect
+# there are eask warnings but strict does not effect them
+should_run eask uninstall --strict s
diff --git a/test/fixtures/home/scripts/testing.sh b/test/fixtures/home/scripts/testing.sh
new file mode 100755
index 00000000..bccd8a95
--- /dev/null
+++ b/test/fixtures/home/scripts/testing.sh
@@ -0,0 +1,57 @@
+#!/usr/bin/env bash
+
+# Test reporting functions
+# This file will be sourced by other shell test scripts.
+# Expects to run with set -e
+
+# TODO note that eask output is always to stderr
+
+# Run command and exit with the same status
+# All args interpreted as program to run
+# e.g. should_run cmd arg1 arg2 ...
+should_run() {
+ echo "Run: $*"
+ echo "---------------"
+ "$@" 2>&1 | cat
+ local TEST_STATUS=${PIPESTATUS[0]}
+
+ echo ""
+
+ if [ $TEST_STATUS -gt 0 ]; then
+ printf "Fail: \'%s\' exited with status %s\n" "$*" "$TEST_STATUS" >&2
+ exit 1
+ fi
+}
+
+# Run command and exit with non-zero if command exits with zero.
+# All args interpreted as program to run
+# e.g. should_error cmd arg1 arg2 ...
+should_error() {
+ echo "Run: $*"
+ echo "---------------"
+ # a shorter alternative is
+ # ! "$@" || (echo "failed" && exit 1)
+
+ # this version allow for more formatting
+ "$@" 2>&1 | cat # Exit status of individual commands in a pipeline are ignored
+ local TEST_STATUS=${PIPESTATUS[0]} # Get the true status, $? will always be 0
+
+ echo ""
+
+ if [ $TEST_STATUS -eq 0 ]; then
+ printf "Fail: \'%s\' should exit with non-zero status\n" "$*" >&2
+ exit 1
+ fi
+}
+
+# Check if (grep) pattern ARG1 is found in string ARG2
+# E.g. should_match "foo*" "foobar"
+should_match() {
+ echo "$2" | grep "$1" - | cat > /dev/null
+ local SEARCH_RES=${PIPESTATUS[1]}
+
+ if [ $SEARCH_RES -gt 0 ]; then
+ printf "Fail: Output did not match \'%s\'\n" "$1"
+ exit 1
+ fi
+}