From 695ab5e78520b352a9e7b03c9d41905849a1a60d Mon Sep 17 00:00:00 2001 From: Thomas Fini Hansen Date: Sun, 3 Aug 2025 13:36:47 +0200 Subject: [PATCH 1/5] Fix flycheck to use 'source instead of 'source-inplace --- flycheck-eldev.el | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/flycheck-eldev.el b/flycheck-eldev.el index d307835..6f92081 100644 --- a/flycheck-eldev.el +++ b/flycheck-eldev.el @@ -199,6 +199,20 @@ If FROM is nil, search from `default-directory'." (defun flycheck-eldev--working-directory (&rest _) (flycheck-eldev-find-root)) +(defun flycheck-eldev--checker-substituted-arguments (checker) + "Get the substituted arguments of a CHECKER. + +Wrapper for `flycheck-checker-substituted-arguments' which replaces +\='source-inplace with \='source. + +CHECKER is passed to `flycheck-checker-substituted-arguments'." + (apply #'append + (seq-map (lambda (arg) + (when (eq arg 'source-inplace) + (setq arg 'source)) + (flycheck-substitute-argument arg checker)) + (flycheck-checker-arguments checker)))) + (defun flycheck-eldev--build-command-line () `("--quiet" "--no-time" "--color=never" "--no-debug" "--no-backtrace-on-abort" ,@(if (flycheck-eldev-project-trusted-p default-directory) @@ -208,7 +222,7 @@ If FROM is nil, search from `default-directory'." ;; future improvements for free. (let* ((super (let ((flycheck-emacs-lisp-load-path nil) (flycheck-emacs-lisp-initialize-packages nil)) - (flycheck-checker-substituted-arguments 'emacs-lisp))) + (flycheck-eldev--checker-substituted-arguments 'emacs-lisp))) (head (-drop-last 2 super)) (tail (-take-last 2 super)) (filename (cadr tail)) @@ -242,7 +256,10 @@ If FROM is nil, search from `default-directory'." (eldev-advised (#'insert-file-contents :around (lambda (original filename &rest arguments) - (unless (file-equal-p filename ,real-filename) + (if (file-equal-p filename ,real-filename) + ;; Load the temp file + ;; instead. + (apply original ,filename arguments) (apply original filename arguments)))) (funcall original))))) ;; When checking project's main file, use the temporary as the main file From 3389a50cb7ebf4253ac23b42936566bb508c0410 Mon Sep 17 00:00:00 2001 From: Thomas Fini Hansen Date: Thu, 7 Aug 2025 20:56:40 +0200 Subject: [PATCH 2/5] Update copyright year --- flycheck-eldev.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flycheck-eldev.el b/flycheck-eldev.el index 6f92081..3a3678b 100644 --- a/flycheck-eldev.el +++ b/flycheck-eldev.el @@ -1,6 +1,6 @@ ;;; flycheck-eldev.el --- Eldev support in Flycheck -*- lexical-binding: t -*- -;;; Copyright (C) 2020-2023 Paul Pogonyshev +;;; Copyright (C) 2020-2025 Paul Pogonyshev ;; Author: Paul Pogonyshev ;; Maintainer: Paul Pogonyshev From 1d4f40be8235e82b0938c4933bd19b16d31d2eda Mon Sep 17 00:00:00 2001 From: Paul Pogonyshev Date: Sun, 7 Sep 2025 21:27:28 +0200 Subject: [PATCH 3/5] Reimplement changes in commit 695ab5e differently, but with the same effect. --- flycheck-eldev.el | 44 +++++++++++++++++++++---------------- test/flycheck-eldev-test.el | 33 ++++++++++++++++------------ 2 files changed, 44 insertions(+), 33 deletions(-) diff --git a/flycheck-eldev.el b/flycheck-eldev.el index 3a3678b..1672325 100644 --- a/flycheck-eldev.el +++ b/flycheck-eldev.el @@ -120,6 +120,19 @@ concerns when checking Eldev (or any Elisp) projects." (const :tag "Don't trust" dont-trust) (const :tag "Trust if ever initialized" trust-if-ever-initialized))) +(defcustom flycheck-eldev-outside-temp-files t + "Normally, Flycheck creates visible files in project directory. +This sometimes leads to various annoying side effects, for example +interference with Git or file watchers on project directory. For this +reason, `flycheck-eldev' puts such files in `temporary-file-directory' +by default (utilizing built-in Flycheck capability, that is simply not +used for Elisp). + +However, if this causes any issues, you can revert to the standard +Flycheck behavior by setting this to nil." + :group 'flycheck-eldev + :type 'boolean) + (defvar flycheck-eldev-active t "Whether Eldev extension to Flycheck is active.") @@ -199,20 +212,6 @@ If FROM is nil, search from `default-directory'." (defun flycheck-eldev--working-directory (&rest _) (flycheck-eldev-find-root)) -(defun flycheck-eldev--checker-substituted-arguments (checker) - "Get the substituted arguments of a CHECKER. - -Wrapper for `flycheck-checker-substituted-arguments' which replaces -\='source-inplace with \='source. - -CHECKER is passed to `flycheck-checker-substituted-arguments'." - (apply #'append - (seq-map (lambda (arg) - (when (eq arg 'source-inplace) - (setq arg 'source)) - (flycheck-substitute-argument arg checker)) - (flycheck-checker-arguments checker)))) - (defun flycheck-eldev--build-command-line () `("--quiet" "--no-time" "--color=never" "--no-debug" "--no-backtrace-on-abort" ,@(if (flycheck-eldev-project-trusted-p default-directory) @@ -221,8 +220,15 @@ CHECKER is passed to `flycheck-checker-substituted-arguments'." ;; rewrite the command line provided by the standard checker, so we get any ;; future improvements for free. (let* ((super (let ((flycheck-emacs-lisp-load-path nil) - (flycheck-emacs-lisp-initialize-packages nil)) - (flycheck-eldev--checker-substituted-arguments 'emacs-lisp))) + (flycheck-emacs-lisp-initialize-packages nil) + (original-command-template (flycheck-checker-get 'emacs-lisp 'command))) + (unwind-protect + (progn + (when flycheck-eldev-outside-temp-files + (setf (flycheck-checker-get 'emacs-lisp 'command) + (mapcar (lambda (x) (if (eq x 'source-inplace) 'source x)) original-command-template))) + (flycheck-checker-substituted-arguments 'emacs-lisp)) + (setf (flycheck-checker-get 'emacs-lisp 'command) original-command-template)))) (head (-drop-last 2 super)) (tail (-take-last 2 super)) (filename (cadr tail)) @@ -257,9 +263,9 @@ CHECKER is passed to `flycheck-checker-substituted-arguments'." (#'insert-file-contents :around (lambda (original filename &rest arguments) (if (file-equal-p filename ,real-filename) - ;; Load the temp file - ;; instead. - (apply original ,filename arguments) + (when ,flycheck-eldev-outside-temp-files + ;; Load the temp file instead. + (apply original ,filename arguments)) (apply original filename arguments)))) (funcall original))))) ;; When checking project's main file, use the temporary as the main file diff --git a/test/flycheck-eldev-test.el b/test/flycheck-eldev-test.el index 6c31b6e..880ed2d 100644 --- a/test/flycheck-eldev-test.el +++ b/test/flycheck-eldev-test.el @@ -38,21 +38,26 @@ (:unknown-projects (setf flycheck-eldev-unknown-projects (pop body))) (:enable-checkdoc (if (pop body) (push 'emacs-lisp-checkdoc enabled-checkers) + ;; We don't use `emacs-lisp-checkdoc' unless explicitly enabled. (setf enabled-checkers (delq 'emacs-lisp-checkdoc enabled-checkers)))))) - ;; Don't use `emacs-lisp-checkdoc'. - `(let ((flycheck-checkers (--filter (memq it ',enabled-checkers) flycheck-checkers)) - (flycheck-disabled-checkers nil) - (flycheck-check-syntax-automatically nil) - (flycheck-eldev-whitelist ',flycheck-eldev-whitelist) - (flycheck-eldev-blacklist ',flycheck-eldev-blacklist) - (flycheck-eldev-unknown-projects ',flycheck-eldev-unknown-projects) - (file (expand-file-name ,file flycheck-eldev--test-dir))) - (with-temp-buffer - (insert-file-contents file t) - (setf default-directory (file-name-directory file)) - (emacs-lisp-mode) - (flycheck-mode 1) - ,@body)))) + ;; Currently not testing if `flycheck-eldev-outside-temp-files' actually achieves what it promises, but at + ;; least make sure that everything works regardless if that is set to t or nil. + `(dolist (outside-temp-files '(nil t)) + (ert-info ((format "flycheck-eldev-outside-temp-files = %s" outside-temp-files)) + (let ((flycheck-checkers (--filter (memq it ',enabled-checkers) flycheck-checkers)) + (flycheck-disabled-checkers nil) + (flycheck-check-syntax-automatically nil) + (flycheck-eldev-whitelist ',flycheck-eldev-whitelist) + (flycheck-eldev-blacklist ',flycheck-eldev-blacklist) + (flycheck-eldev-unknown-projects ',flycheck-eldev-unknown-projects) + (flycheck-eldev-outside-temp-files outside-temp-files) + (file (expand-file-name ,file flycheck-eldev--test-dir))) + (with-temp-buffer + (insert-file-contents file t) + (setf default-directory (file-name-directory file)) + (emacs-lisp-mode) + (flycheck-mode 1) + ,@body)))))) (defmacro flycheck-eldev--test-with-temp-file (file content-creation &rest body) (declare (indent 2) (debug (sexp form body))) From a3698c377750b9b456df736705535377a1c36df9 Mon Sep 17 00:00:00 2001 From: Paul Pogonyshev Date: Tue, 9 Sep 2025 17:36:47 +0200 Subject: [PATCH 4/5] Add tests that demonstrate that certain piece of code concerning `eldev-project-main-file` is still needed. --- test/flycheck-eldev-test.el | 19 ++++++++++++------- test/project-c/Eldev | 7 +++++++ test/project-c/project-c-util.el | 9 +++++++++ test/project-c/project-c.el | 24 ++++++++++++++++++++++++ test/project-c/test/project-c-util.el | 6 ++++++ test/project-c/test/project-c.el | 6 ++++++ 6 files changed, 64 insertions(+), 7 deletions(-) create mode 100644 test/project-c/Eldev create mode 100644 test/project-c/project-c-util.el create mode 100644 test/project-c/project-c.el create mode 100644 test/project-c/test/project-c-util.el create mode 100644 test/project-c/test/project-c.el diff --git a/test/flycheck-eldev-test.el b/test/flycheck-eldev-test.el index 880ed2d..3110e89 100644 --- a/test/flycheck-eldev-test.el +++ b/test/flycheck-eldev-test.el @@ -101,13 +101,13 @@ (flycheck-eldev-ert-defargtest flycheck-eldev-basics-1 (file) - ("project-a/project-a.el" "project-b/project-b.el" "project-b/project-b-util.el") + ("project-a/project-a.el" "project-b/project-b.el" "project-b/project-b-util.el" "project-c/project-c.el" "project-c/project-c-util.el") (flycheck-eldev--test file (flycheck-eldev--test-recheck) (flycheck-eldev--test-expect-no-errors))) (flycheck-eldev-ert-defargtest flycheck-eldev-basics-2 (file) - ("project-a/Eldev" "project-b/Eldev") + ("project-a/Eldev" "project-b/Eldev" "project-c/Eldev") (flycheck-eldev--test file ;; Enable `checkdoc'. Must be disabled at runtime (currently through our own hack) ;; for the test to pass. @@ -137,7 +137,9 @@ (flycheck-eldev--test-expect-no-errors))) (flycheck-eldev-ert-defargtest flycheck-eldev-test-file-1 (file) - ("project-a/test/project-a.el" "project-b/test/project-b.el" "project-b/test/project-b-util.el") + ("project-a/test/project-a.el" + "project-b/test/project-b.el" "project-b/test/project-b-util.el" + "project-c/test/project-c.el" "project-c/test/project-c-util.el") (flycheck-eldev--test file (flycheck-eldev--test-recheck) (flycheck-eldev--test-expect-no-errors))) @@ -149,12 +151,15 @@ (flycheck-eldev--test-expect-errors '(:matches "dependency-a"))))) ;; Test that removing dependencies gives errors immediately. -(ert-deftest flycheck-eldev-remove-dependency-1 () - (flycheck-eldev--test "project-a/project-a.el" - (search-forward "(dependency-a \"1.0\")") +(flycheck-eldev-ert-defargtest flycheck-eldev-remove-dependency-1 (file dependency) + (("project-a/project-a.el" 'dependency-a) + ("project-b/project-b.el" 'dependency-b) + ("project-c/project-c.el" 'dependency-b)) + (flycheck-eldev--test file + (re-search-forward (format "(%s \"[^\"]+\")" dependency)) (replace-match "") (flycheck-eldev--test-recheck) - (flycheck-eldev--test-expect-errors '(:matches "dependency-a")))) + (flycheck-eldev--test-expect-errors `(:matches ,(symbol-name dependency))))) ;; Test that adding unaccessible dependencies gives errors immediately. (ert-deftest flycheck-eldev-add-dependency-1 () diff --git a/test/project-c/Eldev b/test/project-c/Eldev new file mode 100644 index 0000000..1608135 --- /dev/null +++ b/test/project-c/Eldev @@ -0,0 +1,7 @@ +; -*- mode: emacs-lisp; lexical-binding: t -*- + +(eldev-use-package-archive `("archive-a" . ,(expand-file-name "../package-archive-a"))) + +;; The point of this test project is to verify that explicitly set `eldev-project-main-file' still works as +;; expected. +(setf eldev-project-main-file "project-c.el") diff --git a/test/project-c/project-c-util.el b/test/project-c/project-c-util.el new file mode 100644 index 0000000..1d456e2 --- /dev/null +++ b/test/project-c/project-c-util.el @@ -0,0 +1,9 @@ +;;; -*- lexical-binding: t; -*- + +(require 'dependency-a) +(require 'dependency-b) + +(defun project-c-do-hello () + (dependency-a-hello)) + +(provide 'project-c-util) diff --git a/test/project-c/project-c.el b/test/project-c/project-c.el new file mode 100644 index 0000000..588682a --- /dev/null +++ b/test/project-c/project-c.el @@ -0,0 +1,24 @@ +;;; project-c.el --- Exactly like `project-b', but with explicitly set `eldev-project-main-file' -*- lexical-binding: t; -*- + +;; Version: 1.0 +;; Homepage: https://example.com/ +;; Package-Requires: ((dependency-a "1.0") (dependency-b "1.0")) + +;;; Commentary: + +;; Comments to make linters happy. + +;;; Code: + +(require 'project-c-util) +(require 'dependency-a) +(require 'dependency-b) + +(defun project-c-hello () + "Invoke `project-c-do-hello' from `project-c-util'. +This docstring exists to make linters happy." + (project-c-do-hello)) + +(provide 'project-c) + +;;; project-c.el ends here diff --git a/test/project-c/test/project-c-util.el b/test/project-c/test/project-c-util.el new file mode 100644 index 0000000..515b06b --- /dev/null +++ b/test/project-c/test/project-c-util.el @@ -0,0 +1,6 @@ +;; -*- lexical-binding: t; -*- + +(require 'project-c) +(require 'ert) + +(provide 'test/project-c-util) diff --git a/test/project-c/test/project-c.el b/test/project-c/test/project-c.el new file mode 100644 index 0000000..a7284e9 --- /dev/null +++ b/test/project-c/test/project-c.el @@ -0,0 +1,6 @@ +;; -*- lexical-binding: t; -*- + +(require 'test/project-c-util) + +(ert-deftest project-c-test-hello () + (should (string= (project-c-hello) "Hello"))) From abfbf127b3f926325aa5df2ed14ee122046c2970 Mon Sep 17 00:00:00 2001 From: Thomas Fini Hansen Date: Wed, 10 Sep 2025 20:49:11 +0200 Subject: [PATCH 5/5] Always fake that the temp file is the main file --- flycheck-eldev.el | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/flycheck-eldev.el b/flycheck-eldev.el index 1672325..221f12e 100644 --- a/flycheck-eldev.el +++ b/flycheck-eldev.el @@ -257,23 +257,16 @@ If FROM is nil, search from `default-directory'." ;; `eldev-project-main-file' is specified, this does nothing. "--setup-first" ,(flycheck-sexp-to-string - `(advice-add #'eldev--package-dir-info :around + `(advice-add #'eldev-package-descriptor :around (lambda (original) (eldev-advised (#'insert-file-contents :around (lambda (original filename &rest arguments) (if (file-equal-p filename ,real-filename) - (when ,flycheck-eldev-outside-temp-files - ;; Load the temp file instead. - (apply original ,filename arguments)) + ;; Load the temp file instead. + (apply original ,filename arguments) (apply original filename arguments)))) (funcall original))))) - ;; When checking project's main file, use the temporary as the main file - ;; instead. - "--setup" - ,(flycheck-sexp-to-string - `(when (and eldev-project-main-file (file-equal-p eldev-project-main-file ,real-filename)) - (setf eldev-project-main-file ,filename))) ;; Special handling for test files: load extra dependencies as if testing ;; now. Likewise for loading roots. "--setup"