diff options
| -rw-r--r-- | CHANGELOG.md | 1 | ||||
| -rw-r--r-- | doc/modules/ROOT/pages/projects.adoc | 45 | ||||
| -rw-r--r-- | projectile.el | 78 |
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" |
