Skip to content

Commit

Permalink
[CI] Add flycheck as linting
Browse files Browse the repository at this point in the history
  • Loading branch information
pkryger committed Nov 20, 2024
1 parent a44393c commit 46cfa31
Show file tree
Hide file tree
Showing 5 changed files with 145 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -79,3 +79,9 @@ Available [[https://download.tuxfamily.org/user42/checkdoc-batch.el][here]]
(checkdoc-batch)
#+end_src
Did initial check, but the file seems a bit stale and the usrer42 ELPA lacks a signature. Could download the file, but it already has errors.

* Run Flycheck as part of CI
** Use =flycheck-compile=
In essence ~flycheck-compile~ is calling ~compilation-start~ with ~flycheck-checker-shell-command~ as a command line. The latter is flexible enough, such that it can be used in a similar mechanism to what [[*Use compile command from =flymake=][Use compile command from =flymake=]] did.

The output is processed to find relevant warnings and errors, while filtering some things which we may not need to fix in Exordium, see [[file:batch-flycheck.el][batch-flycheck.el]].
5 changes: 3 additions & 2 deletions .ci/batch-checkdoc.el
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@
;;; Commentary:
;; This is a transformation of
;; (flycheck-checker-shell-command 'emacs-lisp-checkdoc)
;; See batch-checkdoc.org file for a tips how to get a template to fiddle with
;; to produce function `batch-checkdoc'.
;;
;; See batch-checkdoc-and-flycheck.org file for a tips how to get a template to
;; fiddle with to produce function `batch-checkdoc'.

;;; Code:

Expand Down
102 changes: 102 additions & 0 deletions .ci/batch-flycheck.el
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
;;; batch-flycheck.el --- Run flycheck on command line arguments -*- lexical-binding: t -*-

;;; Commentary:
;; This is a transformation of batch-checkdoc.el to handle support `emacs-lisp'
;; checker, with `flycheck-checker-shell-command'.

;;; Code:

(require 'flycheck)
(require 'rx)
(require 'cl-lib)

(defun exordium--relevant-flycheck-warnings-and-errors (buffer source)
"Find relevant flycheck warning and errors in BUFFER, in reverse order.
SOURCE is the source file used to compile with
`flycheck-checker-shell-command'."
(with-current-buffer buffer
(goto-char (point-min))
(let (matches
(not-errors
(list
(rx "the function ‘exordium--require-load’ might not be defined at runtime."))))
(when-let* (((re-search-forward (rx-to-string `(seq " -- " ,source line-end))
nil t))
(pattern (rx-to-string
`(group line-start ,(file-name-nondirectory source)
(optional ":" (one-or-more digit)
":" (optional (one-or-more digit)))
": " (or "Warning" "Error") ": "
(one-or-more not-newline) line-end))))
(while (re-search-forward pattern nil t)
(push (buffer-substring-no-properties (match-beginning 1) (match-end 1))
matches)))
(cl-remove-if
(lambda (match)
(cl-some (lambda (pat)
(string-match pat match))
not-errors))
matches))))

(defun batch-flycheck ()
"Run `flycheck-checker-shell-command' on the files remaining on the command line."
(let (errors
(number-of-errors 0))
(unwind-protect
(let
((jka-compr-inhibit t))
(when
(equal
(car command-line-args-left)
"--")
(setq command-line-args-left
(cdr command-line-args-left)))
(unless
(require 'elisp-mode nil 'no-error)
(require 'lisp-mode))
(require 'cl-lib)
(while command-line-args-left
(let
((source
(car command-line-args-left))
(buffer-name "*exordium flycheck compile*")
(process-default-directory default-directory))
(with-temp-buffer
(insert-file-contents source 'visit)
(setq buffer-file-name source)
(setq default-directory process-default-directory)
(with-demoted-errors "Error in flycheck: %S"
(delay-mode-hooks
(emacs-lisp-mode))
(setq delayed-mode-hooks nil)
(let ((comp-buf
(compilation-start
(flycheck-checker-shell-command 'emacs-lisp)
nil (lambda (&rest _) buffer-name))))
(when-let* ((comp-proc (get-buffer-process comp-buf)))
(while (process-live-p comp-proc)
(sleep-for 0 1))) ;; 1ms
(with-current-buffer comp-buf
(princ
(buffer-substring-no-properties
(point-min)
(point-max)))
(princ "\n")
(dolist (err (exordium--relevant-flycheck-warnings-and-errors
comp-buf source))
(push err errors)
(cl-incf number-of-errors))
(kill-buffer))))))
(setq command-line-args-left (cdr command-line-args-left))))
(setq command-line-args-left nil)
(when (< 0 number-of-errors)
(message "\n===Errors and Warnings===\n%s\n"
(mapconcat #'identity errors "\n"))
(let ((msg (format "There are %s flycheck errors!" number-of-errors)))
(if (version< "30" emacs-version)
(message msg)
(error msg)))))))

(provide 'batch-flycheck)

;;; batch-flycheck.el ends here
29 changes: 29 additions & 0 deletions .ci/batch-flycheck.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#!/usr/bin/env bash

set -x
set -e

EMACS_DIR="$(cd "${GITHUB_WORKSPACE:-${HOME}}/${1:-.emacs.d}" && pwd -P)"
EMACS=${EMACS:=emacs}

for pattern in "modules/*.el" "init.el" "themes/*.el" ".ci/*.el"; do
echo "===Flycheck: ${pattern}==="

# Use find to find file names such that globs are expanded while prevent
# splitting paths on spaces
mapfile -t files <<< \
"$(find "${EMACS_DIR}" -type f -path "${EMACS_DIR}/${pattern}")"
${EMACS} -Q --batch \
--eval '
(progn
(setq debug-on-error t
eval-expression-print-length 100
edebug-print-length 500
user-emacs-directory "'"${EMACS_DIR}"'/")
(load-file "'"${EMACS_DIR}"'/init.el")
(load-file "'"${EMACS_DIR}"'/.ci/batch-flycheck.el")
(message "===Flycheck start===")
(batch-flycheck))' \
"${files[@]}"
done
6 changes: 5 additions & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -65,11 +65,15 @@ jobs:
if: contains(fromJSON('["29.4", "snapshot"]'), matrix.emacs_version)
run: .emacs.d/.ci/batch-checkdoc.sh

- name: 'Lint: compilation' # At the end, to let other builds escape errors
- name: 'Lint: compilation' # Close to the end, to let other builds escape errors
# caused by compilation shenanigans
if: contains(fromJSON('["29.4", "snapshot"]'), matrix.emacs_version)
run: .emacs.d/.ci/batch-byte-compile.sh

- name: 'Lint: flycheck' # After compilation that should install all packages
if: contains(fromJSON('["29.4", "snapshot"]'), matrix.emacs_version)
run: .emacs.d/.ci/batch-flycheck.sh

pkryger-taps:
runs-on: ${{ matrix.os }}
env:
Expand Down

0 comments on commit 46cfa31

Please sign in to comment.