diff options
| -rw-r--r-- | CHANGELOG.md | 1 | ||||
| -rw-r--r-- | projectile.el | 27 | ||||
| -rw-r--r-- | test/projectile-test.el | 26 |
3 files changed, 47 insertions, 7 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 9b1c821..40a5c62 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ ### New features * Warn once per session when `projectile-indexing-method' is `alien' but the project has a non-empty `.projectile' file, so users notice their dirconfig rules are being bypassed. Controlled by the new `projectile-warn-when-dirconfig-is-ignored' option. +* Warn when a `+' keep entry in `.projectile' contains glob metacharacters. The `+' prefix is for subdirectory paths only and globs are silently coerced into a non-matching directory name; the warning surfaces the misuse rather than letting it fail silently. * [#1964](https://github.com/bbatsov/projectile/issues/1964): Implement `project-name` and `project-buffers` methods for the `project.el` integration, so that code using `project.el` APIs returns correct results for Projectile-managed projects. * [#1837](https://github.com/bbatsov/projectile/issues/1837): Add `eat` project terminal commands with keybindings `x x` and `x 4 x`. * Add keybinding `A` (in the projectile command map) and a menu entry for `projectile-add-known-project`. diff --git a/projectile.el b/projectile.el index 7d7d745..7f2b754 100644 --- a/projectile.el +++ b/projectile.el @@ -2176,6 +2176,18 @@ Unignored files/directories are not included." "Return the absolute path to the project's dirconfig file." (expand-file-name projectile-dirconfig-file (projectile-project-root))) +(defun projectile--warn-glob-in-keep-entry (entry dirconfig) + "Warn that ENTRY in DIRCONFIG looks like a glob pattern after a `+'. +The `+' prefix is for subdirectories only; the parser silently coerces +each entry to a directory, so a glob pattern would never match." + (display-warning + 'projectile + (format "%s contains `+%s', but `+' entries are treated as \ +subdirectory paths and globs are not expanded. Use a plain directory \ +or move the pattern to a `-'/`!' rule." + dirconfig entry) + :warning)) + (defun projectile--parse-dirconfig-file-uncached () "Parse the dirconfig file without caching. Returns a list of (KEEP IGNORE ENSURE) or nil if the file doesn't exist." @@ -2200,12 +2212,15 @@ Returns a list of (KEEP IGNORE ENSURE) or nil if the file doesn't exist." (?! (push (buffer-substring (1+ (point)) (line-end-position)) ensure)) (_ (push (buffer-substring (point) (line-end-position)) ignore))) (forward-line))) - (list (mapcar (lambda (f) (file-name-as-directory (string-trim f))) - (delete "" (reverse keep))) - (mapcar #'string-trim - (delete "" (reverse ignore))) - (mapcar #'string-trim - (delete "" (reverse ensure))))))) + (let ((trimmed-keep (mapcar #'string-trim (delete "" (reverse keep))))) + (dolist (entry trimmed-keep) + (when (string-match-p "[*?[]" entry) + (projectile--warn-glob-in-keep-entry entry dirconfig))) + (list (mapcar #'file-name-as-directory trimmed-keep) + (mapcar #'string-trim + (delete "" (reverse ignore))) + (mapcar #'string-trim + (delete "" (reverse ensure)))))))) (defun projectile-parse-dirconfig-file () "Parse project ignore file and return directories to ignore and keep. diff --git a/test/projectile-test.el b/test/projectile-test.el index 21e04f9..7e1e2a1 100644 --- a/test/projectile-test.el +++ b/test/projectile-test.el @@ -572,7 +572,31 @@ Just delegates OPERATION and ARGS for all operations except for`shell-command`'. "-keep-this\n")))) (let ((projectile-dirconfig-comment-prefix ?#)) (expect (projectile-parse-dirconfig-file) - :to-equal '(nil ("keep-this") nil))))) + :to-equal '(nil ("keep-this") nil)))) + (it "warns when a + keep entry contains glob metacharacters" + (spy-on 'file-exists-p :and-return-value t) + (spy-on 'insert-file-contents :and-call-fake + (lambda (_filename) + (save-excursion (insert "+/*.json\n+/src\n")))) + (spy-on 'display-warning) + (projectile-parse-dirconfig-file) + (expect 'display-warning :to-have-been-called-times 1)) + (it "does not warn for plain + subdirectory entries" + (spy-on 'file-exists-p :and-return-value t) + (spy-on 'insert-file-contents :and-call-fake + (lambda (_filename) + (save-excursion (insert "+/src\n+/tests/foo\n")))) + (spy-on 'display-warning) + (projectile-parse-dirconfig-file) + (expect 'display-warning :not :to-have-been-called)) + (it "does not warn for - ignore entries that contain globs" + (spy-on 'file-exists-p :and-return-value t) + (spy-on 'insert-file-contents :and-call-fake + (lambda (_filename) + (save-excursion (insert "-*.json\n-build/*.tmp\n")))) + (spy-on 'display-warning) + (projectile-parse-dirconfig-file) + (expect 'display-warning :not :to-have-been-called))) (describe "projectile-parse-dirconfig-file with a real file" (before-each |
