[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[nongnu] elpa/projectile 1654956cfe 1/2: Allow multiple project-files pe
From: |
ELPA Syncer |
Subject: |
[nongnu] elpa/projectile 1654956cfe 1/2: Allow multiple project-files per type and wildcards in project-files |
Date: |
Fri, 18 Nov 2022 05:59:31 -0500 (EST) |
branch: elpa/projectile
commit 1654956cfed4691f3e9553d91e573efe0be8646a
Author: toshokan <toshokan@shojigate.net>
Commit: Bozhidar Batsov <bozhidar@batsov.dev>
Allow multiple project-files per type and wildcards in project-files
---
CHANGELOG.md | 1 +
doc/modules/ROOT/pages/projects.adoc | 17 +++++++++++++++--
projectile.el | 30 ++++++++++++++++++++++--------
test/projectile-test.el | 19 +++++++++++++++++++
4 files changed, 57 insertions(+), 10 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 3538ab626e..154d6a907e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -8,6 +8,7 @@
* Add new command `projectile-find-references` (bound to `C-c C-p ?` and `C-c
C-p s x`).
* [#1737](https://github.com/bbatsov/projectile/pull/1737): Add helpers for
`dir-local-variables` for 3rd party use. Functions
`projectile-add-dir-local-variable` and `projectile-delete-dir-local-variable`
wrap their built-in counterparts. They always use `.dir-locals.el` from the
root of the current Projectile project.
* Add a new defcustom (`projectile-dirconfig-file`) controlling the name of
the file used as Projectile’s root marker and configuration file.
+* [#1813](https://github.com/bbatsov/projectile/pull/1813): Allow
project-files to contain wildcards and allow multiple project-files per project
type registration. Add a new project-type for .NET solutions.
### Changes
diff --git a/doc/modules/ROOT/pages/projects.adoc
b/doc/modules/ROOT/pages/projects.adoc
index c39beaca67..f3db50d8f1 100644
--- a/doc/modules/ROOT/pages/projects.adoc
+++ b/doc/modules/ROOT/pages/projects.adoc
@@ -162,8 +162,8 @@ initialization code
What this does is:
. add your own type of project, in this case `npm` package.
-. add a list of files and/or folders in a root of the project that helps to
identify the type, in this case it is only `package.json`.
-. add _project-file_, which is typically the primary project configuration
file. In this case that's `package.json`.
+. add a list of files and/or folders in a root of the project that helps to
identify the type, in this case it is only `package.json`. This can also be a
function which takes a project root as argument and verifies whether that
directory has the correct project structure for the type.
+. add _project-file_, which is typically the primary project configuration
file. In this case that's `package.json`. The value can contain wildcards
and/or be a list containing multiple project files to look for.
. add _compile-command_, in this case it is `npm install`.
. add _test-command_, in this case it is `npm test`.
. add _run-command_, in this case it is `npm start`.
@@ -171,6 +171,19 @@ What this does is:
Let's see a couple of more complex examples.
+[source,elisp]
+----
+;; .NET C# or F# projects
+(projectile-register-project-type 'dotnet #'projectile-dotnet-project-p
+ :project-file '("?*.csproj" "?*.fsproj")
+ :compile "dotnet build"
+ :run "dotnet run"
+ :test "dotnet test")
+----
+
+This example uses _projectile-dotnet-project-p_ to validate the project's
structure.
+Since C# and F# project files have names containing the name of the project,
it uses a list of wildcards to specify the different valid _project-file_ name
patterns.
+
[source,elisp]
----
;; Ruby + RSpec
diff --git a/projectile.el b/projectile.el
index db275a1f40..62e1d40e62 100644
--- a/projectile.el
+++ b/projectile.el
@@ -1181,7 +1181,7 @@ which we're looking."
(null file)
(string-match locate-dominating-stop-dir-regexp file)))
(setq try (if (stringp name)
- (projectile-file-exists-p (expand-file-name name file))
+ (projectile-file-exists-p
(projectile-expand-file-name-wildcard name file))
(funcall name file)))
(cond (try (setq root file))
((equal file (setq file (file-name-directory
@@ -1204,7 +1204,7 @@ Return the first (topmost) matched directory or nil if
not found."
(projectile-locate-dominating-file
dir
(lambda (dir)
- (cl-find-if (lambda (f) (projectile-file-exists-p (expand-file-name f
dir)))
+ (cl-find-if (lambda (f) (projectile-file-exists-p
(projectile-expand-file-name-wildcard f dir)))
(or list projectile-project-root-files)))))
(defun projectile-root-marked (dir)
@@ -1232,9 +1232,9 @@ topmost sequence of matched directories. Nil otherwise."
(projectile-locate-dominating-file
dir
(lambda (dir)
- (and (projectile-file-exists-p (expand-file-name f dir))
+ (and (projectile-file-exists-p (projectile-expand-file-name-wildcard f
dir))
(or (string-match locate-dominating-stop-dir-regexp
(projectile-parent dir))
- (not (projectile-file-exists-p (expand-file-name f
(projectile-parent dir)))))))))
+ (not (projectile-file-exists-p
(projectile-expand-file-name-wildcard f (projectile-parent dir)))))))))
(or list projectile-project-root-files-top-down-recurring)))
(defun projectile-project-root (&optional dir)
@@ -2612,7 +2612,7 @@ PROJECT-ROOT is the project root."
(when (or paths (null predicates))
(list :paths (cl-remove-if-not
(lambda (f)
- (projectile-file-exists-p (expand-file-name f
project-root)))
+ (projectile-file-exists-p
(projectile-expand-file-name-wildcard f project-root)))
paths)))
(when predicates
(list :predicate (if (= 1 (length predicates))
@@ -2806,9 +2806,13 @@ files such as test/impl/other files as below:
'test-command test
'install-command install
'package-command package
- 'run-command run)))
- (when (and project-file (not (member project-file
projectile-project-root-files)))
- (add-to-list 'projectile-project-root-files project-file))
+ 'run-command run))
+ (project-files (if (listp project-file)
+ project-file
+ (list project-file))))
+ (dolist (project-file project-files)
+ (when (and project-file (not (member project-file
projectile-project-root-files)))
+ (add-to-list 'projectile-project-root-files project-file)))
(when test-suffix
(plist-put project-plist 'test-suffix test-suffix))
(when test-prefix
@@ -2963,6 +2967,16 @@ it acts on the current project."
(or (projectile-verify-file "Eldev" dir)
(projectile-verify-file "Eldev-local" dir)))
+(defun projectile-expand-file-name-wildcard (name-pattern dir)
+ "Expand the maybe-wildcard-containing NAME-PATTERN in DIR.
+If there are results expanding a wildcard, get the first result,
+otherwise expand NAME-PATTERN in DIR ignoring wildcards."
+ (let ((expanded (expand-file-name name-pattern dir)))
+ (or (if (string-match-p "[[*?]" name-pattern)
+ (car
+ (file-expand-wildcards expanded)))
+ expanded)))
+
(defun projectile-cabal-project-p (&optional dir)
"Check if a project contains *.cabal files but no stack.yaml file.
When DIR is specified it checks DIR's project, otherwise
diff --git a/test/projectile-test.el b/test/projectile-test.el
index de89580a04..a6e4e91a00 100644
--- a/test/projectile-test.el
+++ b/test/projectile-test.el
@@ -165,6 +165,25 @@ Just delegates OPERATION and ARGS for all operations
except for`shell-command`'.
(expect (projectile-expand-root "foo/bar") :to-equal
"/path/to/project/foo/bar")
(expect (projectile-expand-root "./foo/bar") :to-equal
"/path/to/project/foo/bar")))
+(describe "projectile-expand-file-name-wildcard"
+ (it "expands a filename not containing wildcards"
+ (expect (projectile-expand-file-name-wildcard "test" "/path/to/project/")
+ :to-equal "/path/to/project/test"))
+ (it "does not try to resolve wildcards if there are none in the pattern"
+ (spy-on 'file-expand-wildcards)
+ (expect (projectile-expand-file-name-wildcard "foo" "/path/to/project/")
+ :to-equal "/path/to/project/foo")
+ (expect (spy-calls-any 'file-expand-wildcards) :to-equal nil))
+ (it "returns the first wildcard result if any exist"
+ (spy-on 'file-expand-wildcards
+ :and-return-value '("/path/to/project/one"
+ "/path/to/project/two"))
+ (expect (projectile-expand-file-name-wildcard "*" "/path/to/project")
+ :to-equal "/path/to/project/one"))
+ (it "returns the expanded result if the are no wildcard results"
+ (expect (projectile-expand-file-name-wildcard "*" "/path/to/project-b")
+ :to-equal "/path/to/project-b/*")))
+
(describe "projectile--combine-plists"
(it "Items in second plist override elements in first"
(expect (projectile--combine-plists