Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow flymake-ruff to use Ruff config files from remote TRAMP hosts #24

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 53 additions & 8 deletions flymake-ruff.el
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,53 @@

(defvar flymake-ruff--output-regex "\\(.*\\):\\([0-9]+\\):\\([0-9]+\\): \\([A-Za-z0-9]+\\):? \\(.*\\)")

(defvar flymake-ruff--no-config-tramp-dirs
nil
"List of TRAMP directories that ruff checked for config in but found none. This prevents repeatedly looking for config files that do not exist.")

(defconst flymake-ruff--default-configs
'(".ruff.toml" "ruff.toml" "pyproject.toml")
"Default configuration files supported by Ruff.")

(defun flymake-ruff--get-config ()
"Look for configuration files supported by Ruff in project root.
When project is on remote host, cache config using `default-directory' as key."
(if (and (tramp-handle-file-remote-p default-directory))
(when (not (seq-contains-p flymake-ruff--no-config-tramp-dirs default-directory #'string-equal))
(let ((cache-dir (expand-file-name
(concat "ruff-config-" (sha1 default-directory))
"/tmp")))
(if (file-directory-p cache-dir)
;; Return cached config if exists
(seq-find #'file-readable-p
(mapcar (lambda (f)
(expand-file-name f cache-dir))
flymake-ruff--default-configs))
;; Create cache and return config path
(if-let* ((project-current (project-current))
(config (seq-find
#'tramp-handle-file-readable-p
(mapcar (lambda (f)
(tramp-handle-expand-file-name f (project-root project-current)))
flymake-ruff--default-configs)))
(temp-file (tramp-handle-expand-file-name (tramp-handle-file-name-nondirectory config) cache-dir))
(temp-copy (tramp-handle-file-local-copy config)))
(progn
(make-directory cache-dir)
(copy-file temp-copy temp-file t)
(delete-file temp-copy)
temp-file)
(progn
(push default-directory flymake-ruff--no-config-tramp-dirs)
nil)))))

;; Local project path
(when-let ((project-current (project-current)))
(seq-find #'file-readable-p
(mapcar (lambda (f)
(expand-file-name f (project-root project-current)))
flymake-ruff--default-configs)))))

(defun flymake-ruff--check-buffer ()
"Generate a list of diagnostics for the current buffer."
(let ((code-buffer (current-buffer))
Expand All @@ -52,14 +95,8 @@
;; check if the current buffer belongs to a project before
;; trying to build a path using `project-current' otherwise it
;; will fail silently
(let* ((config (and (project-current)
(seq-find
#'file-readable-p
(mapcar
(lambda (f)
(expand-file-name f (project-root (project-current))))
flymake-ruff--default-configs))))
(args (if config
(let* ((config (flymake-ruff--get-config))
(args (if config
;; for version > 0.5 the work "check" is
;; included so we need to extract it and put it
;; before --config argument
Expand Down Expand Up @@ -94,6 +131,14 @@
"Load hook for the current buffer to tell flymake to run checker."
(interactive)
(when (derived-mode-p 'python-mode 'python-ts-mode)
;; If cached TRAMP config file exists for current buffer, remove it so that cache can be refreshed on reverting buffer.
(when-let* ((_remote (file-remote-p default-directory))
(cache-dir (expand-file-name
(concat "ruff-config-" (sha1 default-directory))
"/tmp"))
(_cache_exist (file-directory-p cache-dir)))
(delete-directory cache-dir t))

(add-hook 'flymake-diagnostic-functions #'flymake-ruff--run-checker nil t)))

(defun flymake-ruff--run-checker (report-fn &rest _args)
Expand Down