Skip to content

Commit b23841d

Browse files
All lint subcommands should exit with status 1 on error (#367)
* Add lint exit-code tests and test case files * elint should exit with code 1 when --strict * Skip unnecessary file load and package install in indent linter * Better examples for lint keywords tests * lint package should respect --strict flag * Update relint format matcher for relint 2.1 * lint regexps should respect --strict * lint elsa should exit with code 1 on errors or given --strict * fix: Indentation and clean up logic * fix: output log should be clean string * fix: Revert load deps and files for indent-lint command * fix: Handle indent list infos can be missing * feat: Introduce global error/warn flag * fix: Copyright info --------- Co-authored-by: Jen-Chieh Shen <jcs090218@gmail.com>
1 parent a7ce6aa commit b23841d

File tree

19 files changed

+656
-50
lines changed

19 files changed

+656
-50
lines changed

lisp/_prepare.el

Lines changed: 44 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -479,10 +479,15 @@ You can pass BUFFER-OR-NAME to replace current buffer."
479479
(with-current-buffer (or buffer-or-name (current-buffer))
480480
(goto-char (point-min))
481481
(while (not (eobp))
482-
(let ((line (buffer-substring-no-properties (line-beginning-position) (line-end-position))))
483-
(cond ((string-match-p "[: ][Ee]rror: " line) (eask-error line))
484-
((string-match-p "[: ][Ww]arning: " line) (eask-warn line))
485-
(t (eask-log line))))
482+
(let ((line (buffer-substring-no-properties (line-beginning-position)
483+
(line-end-position))))
484+
;; The variable `line' can contains format specifier, avoid it with `%s'!
485+
(cond ((string-match-p "[: ][Ee]rror: " line)
486+
(eask-error "%s" line))
487+
((string-match-p "[: ][Ww]arning: " line)
488+
(eask-warn "%s" line))
489+
(t
490+
(eask-log "%s" line))))
486491
(forward-line 1))))
487492

488493
(defun eask-delete-file (filename)
@@ -1821,49 +1826,48 @@ Execute forms BODY limit by the verbosity level (SYMBOL)."
18211826
(defun eask--ansi (symbol string)
18221827
"Paint STRING with color defined by log level (SYMBOL)."
18231828
(if-let* ((ansi-function (cdr (assq symbol eask-level-color))))
1824-
(funcall ansi-function string)
1829+
;; The `%s` is use to avoid `not enough arguments for string` error.
1830+
(funcall ansi-function "%s" string)
18251831
string))
18261832

18271833
(defun eask--format (prefix fmt &rest args)
18281834
"Format Eask messages.
18291835
18301836
Argument PREFIX is a string identify the type of this messages. Arguments FMT
18311837
and ARGS are used to pass through function `format'."
1832-
(apply #'format
1833-
(concat (when eask-timestamps (format-time-string "%Y-%m-%d %H:%M:%S "))
1834-
(when eask-log-level (concat prefix " "))
1835-
fmt)
1836-
args))
1838+
(concat (when eask-timestamps (format-time-string "%Y-%m-%d %H:%M:%S "))
1839+
(when eask-log-level (concat prefix " "))
1840+
(apply #'format fmt args)))
18371841

1838-
(defun eask--msg (symbol prefix msg &rest args)
1842+
(defun eask--msg (symbol prefix fmt &rest args)
18391843
"If level (SYMBOL) is at or below `eask-verbosity'; then, log the message.
18401844
1841-
For arguments PREFIX, MSG and ARGS, please see funtion `eask--format' for the
1845+
For arguments PREFIX, FMT and ARGS, please see funtion `eask--format' for the
18421846
detials."
18431847
(eask-with-verbosity symbol
1844-
(let* ((string (apply #'eask--format prefix msg args))
1845-
(output (eask--ansi symbol string))
1848+
(let* ((output (apply #'eask--format prefix fmt args))
1849+
(output (eask--ansi symbol output))
18461850
(output (eask--msg-displayable-kwds output)) ; Don't color, but replace it!
18471851
(func (cl-case symbol
18481852
((or error warn) symbol)
1849-
(t #'message))))
1853+
(t #'message))))
18501854
(funcall func "%s" output))))
18511855

1852-
(defun eask-debug (msg &rest args)
1853-
"Send debug message; see function `eask--msg' for arguments MSG and ARGS."
1854-
(apply #'eask--msg 'debug "[DEBUG]" msg args))
1855-
(defun eask-log (msg &rest args)
1856-
"Send log message; see function `eask--msg' for arguments MSG and ARGS."
1857-
(apply #'eask--msg 'log "[LOG]" msg args))
1858-
(defun eask-info (msg &rest args)
1859-
"Send info message; see function `eask--msg' for arguments MSG and ARGS."
1860-
(apply #'eask--msg 'info "[INFO]" msg args))
1861-
(defun eask-warn (msg &rest args)
1862-
"Send warn message; see function `eask--msg' for arguments MSG and ARGS."
1863-
(apply #'eask--msg 'warn "[WARNING]" msg args))
1864-
(defun eask-error (msg &rest args)
1865-
"Send error message; see function `eask--msg' for arguments MSG and ARGS."
1866-
(apply #'eask--msg 'error "[ERROR]" msg args))
1856+
(defun eask-debug (fmt &rest args)
1857+
"Send debug message; see function `eask--msg' for arguments FMT and ARGS."
1858+
(apply #'eask--msg 'debug "[DEBUG]" fmt args))
1859+
(defun eask-log (fmt &rest args)
1860+
"Send log message; see function `eask--msg' for arguments FMT and ARGS."
1861+
(apply #'eask--msg 'log "[LOG]" fmt args))
1862+
(defun eask-info (fmt &rest args)
1863+
"Send info message; see function `eask--msg' for arguments FMT and ARGS."
1864+
(apply #'eask--msg 'info "[INFO]" fmt args))
1865+
(defun eask-warn (fmt &rest args)
1866+
"Send warn message; see function `eask--msg' for arguments FMT and ARGS."
1867+
(apply #'eask--msg 'warn "[WARNING]" fmt args))
1868+
(defun eask-error (fmt &rest args)
1869+
"Send error message; see function `eask--msg' for arguments FMT and ARGS."
1870+
(apply #'eask--msg 'error "[ERROR]" fmt args))
18671871

18681872
(defun eask--msg-char-displayable (char replacement s)
18691873
"Ensure CHAR is displayable in S; if not, we fallback to REPLACEMENT
@@ -1963,6 +1967,12 @@ Argument ARGS are direct arguments for functions `eask-error' or `eask-warn'."
19631967
(defvar eask-inhibit-error-message nil
19641968
"Non-nil to stop error/warning message.")
19651969

1970+
(defvar eask--has-error-p nil
1971+
"Non-nil if an error has occurred.")
1972+
1973+
(defvar eask--has-warn-p nil
1974+
"Non-nil if a warning has occurred.")
1975+
19661976
(defmacro eask-ignore-errors (&rest body)
19671977
"Execute BODY without killing the process."
19681978
(declare (indent 0) (debug t))
@@ -1981,15 +1991,16 @@ Argument ARGS are direct arguments for functions `eask-error' or `eask-warn'."
19811991
(defun eask--trigger-error ()
19821992
"Trigger error event."
19831993
(when (and (not eask--ignore-error-p)
1984-
(not (eask-checker-p))) ; ignore when checking Eask-file
1985-
(if (eask-allow-error-p) ; Trigger error at the right time
1994+
(not (eask-checker-p))) ; Ignore when checking Eask-file.
1995+
(if (eask-allow-error-p) ; Trigger error at the right time.
19861996
(add-hook 'eask-after-command-hook #'eask--exit)
19871997
(eask--exit))))
19881998

19891999
(defun eask--error (fnc &rest args)
19902000
"On error.
19912001
19922002
Arguments FNC and ARGS are used for advice `:around'."
2003+
(setq eask--has-error-p t)
19932004
(let ((msg (eask--ansi 'error (apply #'format-message args))))
19942005
(unless eask-inhibit-error-message
19952006
(eask--unsilent (eask-msg "%s" msg)))
@@ -2001,6 +2012,7 @@ Arguments FNC and ARGS are used for advice `:around'."
20012012
"On warn.
20022013
20032014
Arguments FNC and ARGS are used for advice `:around'."
2015+
(setq eask--has-warn-p t)
20042016
(let ((msg (eask--ansi 'warn (apply #'format-message args))))
20052017
(unless eask-inhibit-error-message
20062018
(eask--unsilent (eask-msg "%s" msg)))

lisp/lint/elint.el

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,14 @@
4040
(eask-lint-first-newline)
4141
(eask-msg "`%s` with elint" (ansi-green file))
4242
(eask-with-verbosity 'debug (elint-file filename))
43-
(eask-print-log-buffer (elint-get-log-buffer))
44-
(kill-buffer (elint-get-log-buffer))))
43+
(let ((log-buffer (elint-get-log-buffer)))
44+
(eask-print-log-buffer log-buffer)
45+
(kill-buffer log-buffer))))
46+
47+
(defun eask-lint-elint--has-error-p ()
48+
"Return non-nil if we should report error for exit status."
49+
(and eask--has-warn-p
50+
(eask-strict-p)))
4551

4652
(eask-start
4753
(require 'elint)
@@ -56,7 +62,10 @@
5662
(eask-msg "")
5763
(eask-info "(Total of %s file%s %s checked)" (length files)
5864
(eask--sinr files "" "s")
59-
(eask--sinr files "has" "have")))
65+
(eask--sinr files "has" "have"))
66+
;; Report error.
67+
(when (eask-lint-elint--has-error-p)
68+
(eask--exit 'failure)))
6069
;; Pattern defined, but no file found!
6170
(patterns
6271
(eask-info "(No files match wildcard: %s)"

lisp/lint/elsa.el

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,11 +53,19 @@
5353
(if errors
5454
(--each (reverse errors)
5555
(let ((line (string-trim (concat file ":" (elsa-message-format it)))))
56-
(cond ((string-match-p "[: ][Ee]rror:" line) (eask-error line))
57-
((string-match-p "[: ][Ww]arning:" line) (eask-warn line))
56+
(cond ((string-match-p "[: ][Ee]rror:" line)
57+
(eask-error line))
58+
((string-match-p "[: ][Ww]arning:" line)
59+
(eask-warn line))
5860
(t (eask-log line)))))
5961
(eask-msg "No issues found"))))
6062

63+
(defun eask-lint-elsa--has-error-p ()
64+
"Return non-nil if we should report error for exit status."
65+
(or eask--has-error-p
66+
(and eask--has-warn-p
67+
(eask-strict-p))))
68+
6169
(eask-start
6270
;; Preparation
6371
(eask-archive-install-packages '("gnu" "melpa")
@@ -77,7 +85,10 @@
7785
(mapcar #'eask-lint-elsa--analyse-file files)
7886
(eask-msg "")
7987
(eask-info "(Total of %s file%s linted)" (length files)
80-
(eask--sinr files "" "s")))
88+
(eask--sinr files "" "s"))
89+
;; Report error.
90+
(when (eask-lint-elsa--has-error-p)
91+
(eask--exit 'failure)))
8192
;; Pattern defined, but no file found!
8293
(patterns
8394
(eask-msg "")

lisp/lint/indent.el

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,10 @@
5353
(bs (buffer-string)))
5454
(eask-with-temp-buffer (insert bs))
5555
(eask--silent (indent-region (point-min) (point-max)))
56-
(if (/= tick (buffer-modified-tick))
56+
(if-let* (((/= tick (buffer-modified-tick)))
57+
(infos (eask-lint-indent--undo-infos buffer-undo-list)))
5758
;; Indentation changed: warn for each line.
58-
(dolist (info (eask-lint-indent--undo-infos buffer-undo-list))
59+
(dolist (info infos)
5960
(let* ((line (nth 0 info))
6061
(column (nth 1 info))
6162
(current (eask-with-buffer
@@ -68,9 +69,12 @@
6869
(let* ((patterns (eask-args))
6970
(files (if patterns (eask-expand-file-specs (eask-args))
7071
(eask-package-el-files))))
71-
(eask-install-dependencies)
72-
(eask-with-verbosity 'debug
73-
(ignore-errors (mapc #'load (eask-package-el-files))))
72+
;; XXX: Load all dependencies and elisp files to ensure
73+
;; all macros' indentation is applied.
74+
(progn
75+
(eask-install-dependencies)
76+
(eask-with-verbosity 'debug
77+
(ignore-errors (mapc #'load (eask-package-el-files)))))
7478
(cond
7579
;; Files found, do the action!
7680
(files

lisp/lint/package.el

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,11 @@
5757
(kill-current-buffer)))
5858
(eask-print-log-buffer "*Package-Lint*"))
5959

60+
(defun eask-lint-package--has-error-p ()
61+
"Return non-nil if we should report error for exit status."
62+
(and eask--has-warn-p
63+
(eask-strict-p)))
64+
6065
(eask-start
6166
;; Preparation
6267
(eask-archive-install-packages '("gnu" "melpa")
@@ -77,7 +82,10 @@
7782
(mapcar #'eask-lint-package--file files)
7883
(eask-msg "")
7984
(eask-info "(Total of %s file%s linted)" (length files)
80-
(eask--sinr files "" "s")))
85+
(eask--sinr files "" "s"))
86+
;; Report error.
87+
(when (eask-lint-package--has-error-p)
88+
(eask--exit 'failure)))
8189
;; Pattern defined, but no file found!
8290
(patterns
8391
(eask-msg "")

lisp/lint/regexps.el

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -47,19 +47,25 @@
4747
(with-current-buffer (find-file filename)
4848
(setq errors (relint-buffer (current-buffer)))
4949
(dolist (err errors)
50-
(let* ((msg (nth 0 err))
51-
(error-pos (nth 2 err))
52-
(severity (nth 5 err))
50+
(let* ((msg (seq-elt err 0))
51+
(error-pos (seq-elt err 2))
52+
(severity (seq-elt err 7))
5353
(report-func (pcase severity
54-
(`error #'eask-error)
55-
(`warning #'eask-warn))))
54+
(`error #'eask-error)
55+
(`warning #'eask-warn)
56+
(_ #'eask-info))))
5657
(funcall report-func "%s:%s %s: %s"
5758
file (line-number-at-pos error-pos)
5859
(capitalize (eask-2str severity)) msg)))
5960
(unless errors
6061
(eask-msg "No issues found"))
6162
(kill-current-buffer))))
6263

64+
(defun eask-lint-regexps--has-error-p ()
65+
"Return non-nil if we should report error for exit status."
66+
(and eask--has-warn-p
67+
(eask-strict-p)))
68+
6369
(eask-start
6470
;; Preparation
6571
(eask-archive-install-packages '("gnu")
@@ -79,7 +85,10 @@
7985
(mapcar #'eask-lint-regexps--relint-file files)
8086
(eask-msg "")
8187
(eask-info "(Total of %s file%s linted)" (length files)
82-
(eask--sinr files "" "s")))
88+
(eask--sinr files "" "s"))
89+
;; Report error.
90+
(when (eask-lint-regexps--has-error-p)
91+
(eask--exit 'failure)))
8392
;; Pattern defined, but no file found!
8493
(patterns
8594
(eask-msg "")

0 commit comments

Comments
 (0)