Skip to content

Commit

Permalink
Fix running checkers on remote hosts via TRAMP.
Browse files Browse the repository at this point in the history
This patch does three things:

* Update `flycheck-default-executable-find` to search remote hosts when
  `default-directory` is a remote directory. See also the documentation for
  [executable-find](https://www.gnu.org/software/emacs/manual/html_node/elisp/Locating-Files.html).

* Change uses of `call-process` and `start-process` to `start-file-process`
  which is the same as these two functions, but starts the process on a remote
  host when `default-directory` is a remote directory. See also the
  documentation for
  [start-file-process](https://www.gnu.org/software/emacs/manual/html_node/elisp/Asynchronous-Processes.html).

* Passes the local part of `buffer-file-name` to the compile command,
  e.g. strips `/ssh:10.0.0.42`, since the checker is run on the remote machine
  where the file name must be local. See also the documentation for
  [file-local-name](https://www.gnu.org/software/emacs/manual/html_node/elisp/Magic-File-Names.html).
  • Loading branch information
carrete committed Aug 29, 2021
1 parent 784f184 commit 802b666
Showing 1 changed file with 31 additions and 17 deletions.
48 changes: 31 additions & 17 deletions flycheck.el
Original file line number Diff line number Diff line change
Expand Up @@ -507,6 +507,15 @@ sandboxes."
:package-version '(flycheck . "32")
:risky t)

;; This can be removed when Emacs 27.1 is the oldest supported version.
;; See https://github.com/flycheck/flycheck/pull/1842
(defun executable-find-add-remote (args)
"Add optional remote argument t to ARGS when supported."
(if (and (not (version< emacs-version "27.1")) (= (length args) 1))
(append args '(t))
args))
(advice-add 'executable-find :filter-args 'executable-find-add-remote)

(defun flycheck-default-executable-find (executable)
"Resolve EXECUTABLE to a full path.

Expand Down Expand Up @@ -5881,13 +5890,18 @@ Return nil (or raise an error if ERROR is non-nil) when CHECKER's
executable cannot be found, and return a numeric exit status or a
signal description string otherwise. CHECKER's input is taken
from INFILE, and its output is sent to DESTINATION, as in
`call-process'."
`start-file-process'."
(-if-let (executable (flycheck-find-checker-executable checker))
(condition-case err
(apply #'call-process executable infile destination nil args)
;; `start-file-process' runs synchronously, like `call-process',
;; when let bound.`start-file-process' is required to support remote
;; processes. See https://github.com/flycheck/flycheck/pull/1842
(let ((rc (apply #'start-file-process
executable infile destination nil args)))
rc)
(error (when error (signal (car err) (cdr err)))))
(when error
(user-error "Cannot find `%s' using `flycheck-executable-find'"
(user-error "Cannot find `%s' using `flycheck-find-checker-executable'"
(flycheck-checker-executable checker)))))

(defun flycheck-call-checker-process-for-output
Expand Down Expand Up @@ -6195,16 +6209,21 @@ and rely on Emacs' own buffering and chunking."
;; can easily use pipes.
(process-connection-type nil))
;; We pass do not associate the process with any buffer, by
;; passing nil for the BUFFER argument of `start-process'.
;; passing nil for the BUFFER argument of `start-file-process'.
;; Instead, we just remember the buffer being checked in a
;; process property (see below). This neatly avoids all
;; side-effects implied by attached a process to a buffer, which
;; may cause conflicts with other packages.
;;
;; See https://github.com/flycheck/flycheck/issues/298 for an
;; example for such a conflict.
(setq process (apply 'start-process (format "flycheck-%s" checker)
nil command))
;;
;; `start-file-process' runs synchronously, like `call-process',
;; when let bound.`start-file-process' is required to support remote
;; processes. See https://github.com/flycheck/flycheck/pull/1842
(let ((rc (apply 'start-file-process
(format "flycheck-%s" checker) nil command)))
(setq process rc))
;; Process sentinels can be called while sending input to the process.
;; We want to record errors raised by process-send before calling
;; `flycheck-handle-signal', so initially just accumulate events.
Expand Down Expand Up @@ -6705,22 +6724,17 @@ shell execution."
(let* ((args (flycheck--checker-substituted-shell-command-arguments checker))
(program
(or (flycheck-find-checker-executable checker)
(user-error "Cannot find `%s' using `flycheck-executable-find'"
(flycheck-checker-executable checker))))
(user-error
"Cannot find `%s' using `flycheck-find-checker-executable'"
(flycheck-checker-executable checker))))
(wrapped (flycheck--wrap-command program args))
(abs-prog
;; The executable path returned by `flycheck-command-wrapper-function'
;; may not be absolute, so expand it here. See URL
;; `https://github.com/flycheck/flycheck/issues/1461'.
(or (executable-find (car wrapped))
(user-error "Cannot find `%s' using `executable-find'"
(car wrapped))))
(command (mapconcat #'shell-quote-argument
(cons abs-prog (cdr wrapped)) " ")))
(cons program (cdr wrapped)) " ")))
(if (flycheck-checker-get checker 'standard-input)
;; If the syntax checker expects the source from standard input add an
;; appropriate shell redirection
(concat command " < " (shell-quote-argument (buffer-file-name)))
(concat command " < " (shell-quote-argument
(file-local-name (buffer-file-name))))
command)))

(defun flycheck-compile-name (_name)
Expand Down

0 comments on commit 802b666

Please sign in to comment.