aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.md1
-rw-r--r--doc/modules/ROOT/pages/projects.adoc45
-rw-r--r--projectile.el78
3 files changed, 91 insertions, 33 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 7232073..6c8acac 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -11,6 +11,7 @@
### Changes
* [#1540](https://github.com/bbatsov/projectile/pull/1540): Add default `test-suffix` to Angular projects.
+* Add a `:project-file` param to `projectile-register-project-type`.
## 2.2.0 (2020-06-10)
diff --git a/doc/modules/ROOT/pages/projects.adoc b/doc/modules/ROOT/pages/projects.adoc
index d635a69..0390dd3 100644
--- a/doc/modules/ROOT/pages/projects.adoc
+++ b/doc/modules/ROOT/pages/projects.adoc
@@ -121,6 +121,7 @@ initialization code
[source,elisp]
----
(projectile-register-project-type 'npm '("package.json")
+ :project-file "package.json"
:compile "npm install"
:test "npm test"
:run "npm start"
@@ -130,17 +131,59 @@ initialization code
What this does is:
. add your own type of project, in this case `npm` package.
-. add a file in a root of the project that helps to identify the type, in this case it is `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`.
+* add _root-marker_, which is typically the primary project configuration file. In this case that's `package.json`.
. 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`.
. add test files suffix for toggling between implementation/test files, in this case it is `.spec`, so the implementation/test file pair could be `service.js`/`service.spec.js` for example.
+Let's see a couple of more complex examples.
+
+[source,elisp]
+----
+;; Ruby
+(projectile-register-project-type 'ruby-rspec '("Gemfile" "lib" "spec")
+ :project-file "Gemfile"
+ :compile "bundle exec rake"
+ :src-dir "lib/"
+ :test "bundle exec rspec"
+ :test-dir "spec/"
+ :test-suffix "_spec")
+
+(projectile-register-project-type 'ruby-test '("Gemfile" "lib" "test")
+ :project-file "Gemfile"
+ :compile"bundle exec rake"
+ :src-dir "lib/"
+ :test "bundle exec rake test"
+ :test-suffix "_test")
+
+(projectile-register-project-type 'rails-test '("Gemfile" "app" "lib" "db" "config" "test")
+ :project-file "Gemfile"
+ :compile "bundle exec rails server"
+ :src-dir "lib/"
+ :test "bundle exec rake test"
+ :test-suffix "_test")
+
+(projectile-register-project-type 'rails-rspec '("Gemfile" "app" "lib" "db" "config" "spec")
+ :project-file "Gemfile"
+ :compile "bundle exec rails server"
+ :src-dir "lib/"
+ :test "bundle exec rspec"
+ :test-dir "spec/"
+ :test-suffix "_spec")
+----
+
+All those projects are using `Gemfile` (`bundler`'s project file), but they have different directory structures.
+
The available options are:
|===
| Option | Documentation
+| :project-file
+| A file, relative to the project root, typically the main project file (e.g. `pom.xml` for Maven projects).
+
| :compilation-dir
| A path, relative to the project root, from where to run the tests and compilation commands.
diff --git a/projectile.el b/projectile.el
index 9274715..aec9ff7 100644
--- a/projectile.el
+++ b/projectile.el
@@ -298,33 +298,6 @@ If variable `projectile-project-name' is non-nil, this function will not be used
(defcustom projectile-project-root-files
'(
- ".ensime" ; Ensime configuration file
- "Cargo.toml" ; Cargo project file
- "DESCRIPTION" ; R package description file
- "Gemfile" ; Bundler file
- "SConstruct" ; Scons project file
- "WORKSPACE" ; Bazel project file
- "build.boot" ; Boot-clj project file
- "build.gradle" ; Gradle project file
- "build.sbt" ; SBT project file
- "composer.json" ; Composer project file
- "default.nix" ; Nix
- "deps.edn" ; Clojure CLI project file
- "go.mod" ; golang default package root as of 1.13
- "gradlew" ; Gradle wrapper script
- "info.rkt" ; Racket package description file
- "meson.build" ; Meson
- "mix.exs" ; Elixir mix project file
- "pom.xml" ; Maven project file
- "project.clj" ; Leiningen project file
- "pyproject.toml" ; Python project file
- "rebar.config" ; Rebar project file
- "requirements.txt" ; Pip file
- "setup.py" ; Setuptools file
- "stack.yaml" ; Haskell's stack tool based project
- "tox.ini" ; Tox file
- ;; More generic markers are at the end of the list as
- ;; they might exist alongside other project markers
"GTAGS" ; GNU Global tags
"TAGS" ; etags/ctags are usually in the root of project
"configure.ac" ; autoconf new style
@@ -332,7 +305,8 @@ If variable `projectile-project-name' is non-nil, this function will not be used
"cscope.out" ; cscope
)
"A list of files considered to mark the root of a project.
-The topmost match has precedence."
+The topmost match has precedence.
+See `projectile-register-project-type'."
:group 'projectile
:type '(repeat string))
@@ -2522,11 +2496,12 @@ The project types are symbols and they are linked to plists holding
the properties of the various project types.")
(cl-defun projectile-register-project-type
- (project-type marker-files &key compilation-dir configure compile test run test-suffix test-prefix src-dir test-dir related-files-fn)
+ (project-type marker-files &key project-file compilation-dir configure compile test run test-suffix test-prefix src-dir test-dir related-files-fn)
"Register a project type with projectile.
A project type is defined by PROJECT-TYPE, a set of MARKER-FILES,
and optional keyword arguments:
+PROJECT-FILE the main project file in the root project directory.
COMPILATION-DIR the directory to run the tests- and compilations in,
CONFIGURE which specifies a command that configures the project
`%s' in the command will be substituted with (projectile-project-root)
@@ -2544,6 +2519,7 @@ test/impl/other files as below:
a plist containing :test, :impl or :other as key and the relative path/paths or
predicate as value. PREDICATE accepts a relative path as the input."
(let ((project-plist (list 'marker-files marker-files
+ 'project-file project-file
'compilation-dir compilation-dir
'configure-command configure
'compile-command compile
@@ -2553,6 +2529,8 @@ test/impl/other files as below:
;; explicit argument of nil and an omitted argument. However, the
;; body of the function is free to consider nil an abbreviation
;; for some other meaningful value
+ (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
@@ -2599,9 +2577,6 @@ test/impl/other files as below:
;; it should be listed first).
;;
;; Ideally common project types should be checked earlier than exotic ones.
-;;
-;; NOTE: If a project type has some project root file marker (e.g. pom.xml) it
-;; should be added to `projectile-project-root-files' as well.
;; Function-based detection project type
(projectile-register-project-type 'haskell-cabal #'projectile-cabal-project-p
@@ -2621,129 +2596,157 @@ test/impl/other files as below:
;; Universal
(projectile-register-project-type 'scons '("SConstruct")
+ :project-file "SConstruct"
:compile "scons"
:test "scons test"
:test-suffix "test")
(projectile-register-project-type 'meson '("meson.build")
+ :project-file "meson.build"
:compilation-dir "build"
:configure "meson %s"
:compile "ninja"
:test "ninja test")
(projectile-register-project-type 'nix '("default.nix")
+ :project-file "default.nix"
:compile "nix-build"
:test "nix-build")
(projectile-register-project-type 'bazel '("WORKSPACE")
+ :project-file "WORKSPACE"
:compile "bazel build"
:test "bazel test"
:run "bazel run")
;; Make & CMake
(projectile-register-project-type 'make '("Makefile")
+ :project-file "Makefile"
:compile "make"
:test "make test")
(projectile-register-project-type 'cmake '("CMakeLists.txt")
+ :project-file "CMakeLists.txt"
:compilation-dir "build"
:configure "cmake %s -B %s"
:compile "cmake --build ."
:test "ctest")
;; PHP
(projectile-register-project-type 'php-symfony '("composer.json" "app" "src" "vendor")
+ :project-file "composer.json"
:compile "app/console server:run"
:test "phpunit -c app "
:test-suffix "Test")
;; Erlang & Elixir
(projectile-register-project-type 'rebar '("rebar.config")
+ :project-file "rebar.config"
:compile "rebar"
:test "rebar eunit"
:test-suffix "_SUITE")
(projectile-register-project-type 'elixir '("mix.exs")
+ :project-file "mix.exs"
:compile "mix compile"
:src-dir "lib/"
:test "mix test"
:test-suffix "_test")
;; JavaScript
(projectile-register-project-type 'grunt '("Gruntfile.js")
+ :project-file "Gruntfile.js"
:compile "grunt"
:test "grunt test")
(projectile-register-project-type 'gulp '("gulpfile.js")
+ :project-file "gulpfile.js"
:compile "gulp"
:test "gulp test")
(projectile-register-project-type 'npm '("package.json")
+ :project-file "package.json"
:compile "npm install"
:test "npm test"
:test-suffix ".test")
;; Angular
(projectile-register-project-type 'angular '("angular.json" ".angular-cli.json")
+ :project-file "angular.json"
:compile "ng build"
:run "ng serve"
:test "ng test"
:test-suffix ".spec")
;; Python
(projectile-register-project-type 'django '("manage.py")
+ :project-file "manage.py"
:compile "python manage.py runserver"
:test "python manage.py test"
:test-prefix "test_"
:test-suffix"_test")
(projectile-register-project-type 'python-pip '("requirements.txt")
+ :project-file "requirements.txt"
:compile "python setup.py build"
:test "python -m unittest discover"
:test-prefix "test_"
:test-suffix"_test")
(projectile-register-project-type 'python-pkg '("setup.py")
+ :project-file "setup.py"
:compile "python setup.py build"
:test "python -m unittest discover"
:test-prefix "test_"
:test-suffix"_test")
(projectile-register-project-type 'python-tox '("tox.ini")
+ :project-file "tox.ini"
:compile "tox -r --notest"
:test "tox"
:test-prefix "test_"
:test-suffix"_test")
(projectile-register-project-type 'python-pipenv '("Pipfile")
+ :project-file "Pipfile"
:compile "pipenv run build"
:test "pipenv run test"
:test-prefix "test_"
:test-suffix "_test")
;; Java & friends
(projectile-register-project-type 'maven '("pom.xml")
+ :project-file "pom.xml"
:compile "mvn clean install"
:test "mvn test"
:test-suffix "Test"
:src-dir "main/src/"
:test-dir "main/test/")
(projectile-register-project-type 'gradle '("build.gradle")
+ :project-file "build.gradle"
:compile "gradle build"
:test "gradle test"
:test-suffix "Spec")
(projectile-register-project-type 'gradlew '("gradlew")
+ :project-file "gradlew"
:compile "./gradlew build"
:test "./gradlew test"
:test-suffix "Spec")
(projectile-register-project-type 'grails '("application.properties" "grails-app")
+ :project-file "application.properties"
:compile "grails package"
:test "grails test-app"
:test-suffix "Spec")
;; Scala
(projectile-register-project-type 'sbt '("build.sbt")
+ :project-file "build.sbt"
:compile "sbt compile"
:test "sbt test"
:test-suffix "Spec")
;; Clojure
(projectile-register-project-type 'lein-test '("project.clj")
+ :project-file "project.clj"
:compile "lein compile"
:test "lein test"
:test-suffix "_test")
(projectile-register-project-type 'lein-midje '("project.clj" ".midje.clj")
+ :project-file "project.clj"
:compile "lein compile"
:test "lein midje"
:test-prefix "t_")
(projectile-register-project-type 'boot-clj '("build.boot")
+ :project-file "build.boot"
:compile "boot aot"
:test "boot test"
:test-suffix "_test")
(projectile-register-project-type 'clojure-cli '("deps.edn")
+ :project-file "deps.edn"
:test-suffix "_test")
(projectile-register-project-type 'bloop '(".bloop")
+ :project-file ".bloop"
:compile "bloop compile root"
:test "bloop test --propagate --reporter scalac root"
:src-dir "src/main/"
@@ -2751,12 +2754,14 @@ test/impl/other files as below:
:test-suffix "Spec")
;; Ruby
(projectile-register-project-type 'ruby-rspec '("Gemfile" "lib" "spec")
+ :project-file "Gemfile"
:compile "bundle exec rake"
:src-dir "lib/"
:test "bundle exec rspec"
:test-dir "spec/"
:test-suffix "_spec")
(projectile-register-project-type 'ruby-test '("Gemfile" "lib" "test")
+ :project-file "Gemfile"
:compile"bundle exec rake"
:src-dir "lib/"
:test "bundle exec rake test"
@@ -2764,11 +2769,13 @@ test/impl/other files as below:
;; Rails needs to be registered after npm, otherwise `package.json` makes it `npm`.
;; https://github.com/bbatsov/projectile/pull/1191
(projectile-register-project-type 'rails-test '("Gemfile" "app" "lib" "db" "config" "test")
+ :project-file "Gemfile"
:compile "bundle exec rails server"
:src-dir "lib/"
:test "bundle exec rake test"
:test-suffix "_test")
(projectile-register-project-type 'rails-rspec '("Gemfile" "app" "lib" "db" "config" "spec")
+ :project-file "Gemfile"
:compile "bundle exec rails server"
:src-dir "lib/"
:test "bundle exec rspec"
@@ -2776,6 +2783,7 @@ test/impl/other files as below:
:test-suffix "_spec")
;; Crystal
(projectile-register-project-type 'crystal-spec '("shard.yml")
+ :project-file "shard.yml"
:src-dir "src/"
:test "crystal spec"
:test-dir "spec/"
@@ -2783,6 +2791,7 @@ test/impl/other files as below:
;; Emacs
(projectile-register-project-type 'emacs-cask '("Cask")
+ :project-file "Cask"
:compile "cask install"
:test-prefix "test-"
:test-suffix "-test")
@@ -2794,27 +2803,32 @@ test/impl/other files as below:
;; R
(projectile-register-project-type 'r '("DESCRIPTION")
+ :project-file "DESCRIPTION"
:compile "R CMD INSTALL --with-keep.source ."
:test (concat "R CMD check -o " temporary-file-directory " ."))
;; Haskell
(projectile-register-project-type 'haskell-stack '("stack.yaml")
+ :project-file "stack.yaml"
:compile "stack build"
:test "stack build --test"
:test-suffix "Spec")
;; Rust
(projectile-register-project-type 'rust-cargo '("Cargo.toml")
+ :project-file "Cargo.toml"
:compile "cargo build"
:test "cargo test"
:run "cargo run")
;; Racket
(projectile-register-project-type 'racket '("info.rkt")
+ :project-file "info.rkt"
:test "raco test .")
;; Dart
(projectile-register-project-type 'dart '("pubspec.yaml")
+ :project-file "pubspec.yaml"
:compile "pub get"
:test "pub run test"
:run "dart"