diff options
Diffstat (limited to 'tw/home/files/emacs-packages/actionlint.el')
-rw-r--r-- | tw/home/files/emacs-packages/actionlint.el | 147 |
1 files changed, 0 insertions, 147 deletions
diff --git a/tw/home/files/emacs-packages/actionlint.el b/tw/home/files/emacs-packages/actionlint.el deleted file mode 100644 index 68a25c57..00000000 --- a/tw/home/files/emacs-packages/actionlint.el +++ /dev/null @@ -1,147 +0,0 @@ -;;; actionlint.el --- Flycheck checker for GitHub Actions. -*- lexical-binding: t -*- -;;; Commentary: -;; GitHub Actions are defined using mostly plain YAML files. -;; Actionlint is a linter catching GitHub Action-specific mistakes, and also -;; checks Shell and Python code embedded in Actions (using shellcheck and -;; pyflakes, respectively). -;;; Code: - -(require 'custom) -(require 'flymake) - -(defgroup actionlint nil - "Actionlint-related options." - :group 'languages - :prefix "actionlint-") - -(defcustom actionlint-executable "actionlint" - "The alidistlint executable to use. This will be looked up in $PATH." - :type '(string) - :risky t - :group 'actionlint) - -(defvar actionlint--message-regexp - (rx bol "<stdin>:" ; filename - (group-n 2 (+ digit)) ":" ; line - (group-n 3 (+ digit)) ": " ; column - (? (or (seq "pyflakes reported issue in this script: " - (group-n 4 (+ digit)) ":" ; inner line - (group-n 5 (+ digit)) " ") ; inner column - (seq "shellcheck reported issue in this script: " - (group-n 8 "SC" (+ digit)) ":" ; shellcheck code - (group-n 6 (or "info" "warning" "error")) ":" ; type - (group-n 4 (+ digit)) ":" ; inner line - (group-n 5 (+ digit)) ": "))) ; inner column - (group-n 1 (+? not-newline)) " " ; message - "[" (group-n 7 (+ (not ?\]))) "]" eol) ; backend/error name - "Regular expression matching messages reported by actionlint. - -The following convention for match groups is used: - - 1. free-form message - 2. outer line number - 3. outer column number - 4. (optional) inner line number - 5. (optional) inner column number - 6. (optional) error level/type - 7. backend/error name (e.g. syntax-check or pyflakes) - 8. (optional) backend-specific error code - -The outer line/column numbers are always present and refer to the location of -the key where the error is, normally. If the message was passed through from -another linter (e.g. shellcheck), it may have an inner line/column, which will -be relative to the contents of the key instead.") - -(defun actionlint--next-message (source) - "Return the next message according to REGEXP for buffer SOURCE, if any." - (when-let* ((match (search-forward-regexp actionlint--message-regexp nil t)) - (inner-line (if-let ((match (match-string 4))) - ;; 1-based; don't subtract 1 since we assume - ;; that the script actually starts on the next - ;; line. - (string-to-number match) - 0)) - (inner-column (if-let ((match (match-string 5))) - ;; 1-based; add 1 (assuming 2-space indents) - ;; to pick the right place inside the string. - (1+ (string-to-number match)) - 0)) - (region (flymake-diag-region - source - (+ (string-to-number (match-string 2)) inner-line) - (+ (string-to-number (match-string 3)) inner-column))) - (type (pcase (match-string 6) - ("info" :note) - ("warning" :warning) - ("error" :error) - ('nil :error))) - (message (if-let ((code (match-string 8))) - (concat (match-string 1) " (" (match-string 7) " " code ")") - (concat (match-string 1) " (" (match-string 7) ")")))) - (flymake-make-diagnostic source (car region) (cdr region) type message))) - -(defvar-local actionlint--flymake-proc nil - "The latest invocation of actionlint.") - -;; See info node: (flymake)An annotated example backend. -(defun actionlint-flymake (report-fn &rest _args) - "Run actionlint and report diagnostics from it using REPORT-FN. -Any running invocations are killed before running another one." - (unless (executable-find actionlint-executable) - (funcall report-fn :panic - :explanation "Cannot find `actionlint-executable' program") - (error "Cannot find actionlint executable")) - - ;; Kill previous check, if it's still running. - (when (process-live-p actionlint--flymake-proc) - (kill-process actionlint--flymake-proc)) - - ;; This needs `lexical-binding'. - (let ((source (current-buffer))) - (save-restriction - (widen) - (setq actionlint--flymake-proc - (make-process - :name "actionlint-flymake" :noquery t :connection-type 'pipe - ;; Direct output to a temporary buffer. - :buffer (generate-new-buffer " *actionlint-flymake*") - :command (list actionlint-executable "-oneline" "-no-color" "-") - :sentinel - (lambda (proc _event) - "Parse diagnostic messages once the process PROC has exited." - ;; Check the process has actually exited, not just been suspended. - (when (memq (process-status proc) '(exit signal)) - (unwind-protect - ;; Only proceed if we've got the "latest" process. - (if (with-current-buffer source (eq proc actionlint--flymake-proc)) - (with-current-buffer (process-buffer proc) - (goto-char (point-min)) - (cl-do (diags - (msg (actionlint--next-message source) - (actionlint--next-message source))) - ((null msg) - (funcall report-fn diags)) - (push msg diags))) - (flymake-log :warning "Canceling obsolete check %s" proc)) - ;; Clean up temporary buffer. - (kill-buffer (process-buffer proc))))))) - ;; Send the buffer to actionlint on stdin. - (process-send-region actionlint--flymake-proc (point-min) (point-max)) - (process-send-eof actionlint--flymake-proc)))) - -(defun actionlint-github-workflow-p () - "Does the current buffer contain a GitHub Action?" - (let ((name (buffer-file-name))) - (and name (string-match-p - (rx ".github/workflows/" (+ (not ?\/)) ".yml" eos) name)))) - -(defun actionlint-setup () - "Set up actionlint in this buffer, if it is recognised as a workflow file." - (when (actionlint-github-workflow-p) - (add-hook 'flymake-diagnostic-functions #'actionlint-flymake nil t))) - -(add-hook 'yaml-mode-hook #'actionlint-setup) -(add-hook 'yaml-ts-mode-hook #'actionlint-setup) - -(provide 'actionlint) -;;; actionlint.el ends here |