Warn when hooks or implicit middleware is found.

Fixes #2387.
This commit is contained in:
Phil Hagelberg 2018-01-22 14:50:28 -08:00
parent f82107e4e5
commit 3e1459a2b2
4 changed files with 51 additions and 29 deletions

View file

@ -1,5 +1,9 @@
# Leiningen News -- history of user-visible changes # Leiningen News -- history of user-visible changes
## ??? / ???
* Add project coordinate data to jar metadata. (Conor McDermottroe)
## 2.8.1 / 2017-10-27 ## 2.8.1 / 2017-10-27
* Fix a bug where `lein help` couldn't list built-in tasks on Java 9. (Phil Hagelberg) * Fix a bug where `lein help` couldn't list built-in tasks on Java 9. (Phil Hagelberg)

View file

@ -252,10 +252,10 @@ bug with the dependency which does this.
**A:** You probably downloaded `lein`/`lein.bat` from the [master branch](https://github.com/technomancy/leiningen/tree/master/bin). Unless you plan to build leiningen yourself or help develop it, we suggest you use the latest stable version: [lein](https://raw.githubusercontent.com/technomancy/leiningen/stable/bin/lein)/[lein.bat](https://raw.githubusercontent.com/technomancy/leiningen/stable/bin/lein.bat) **A:** You probably downloaded `lein`/`lein.bat` from the [master branch](https://github.com/technomancy/leiningen/tree/master/bin). Unless you plan to build leiningen yourself or help develop it, we suggest you use the latest stable version: [lein](https://raw.githubusercontent.com/technomancy/leiningen/stable/bin/lein)/[lein.bat](https://raw.githubusercontent.com/technomancy/leiningen/stable/bin/lein.bat)
**Q:** I have a dependency whose group ID and/or artifact ID starts with a **Q:** I have a dependency whose group ID and/or artifact ID starts with a
number (which is invalid for symbols in Clojure). How can I add it to my number (which is invalid for symbols in Clojure). How can I add it to my
project's dependencies? project's dependencies?
**A:** As of version 2.8.0, Leiningen supports string dependency names like **A:** As of version 2.8.0, Leiningen supports string dependency names like
this: this:
```clj ```clj
:dependencies [["net.3scale/3scale-api" "3.0.2"]] :dependencies [["net.3scale/3scale-api" "3.0.2"]]
@ -266,3 +266,15 @@ Prior to version 2.8.0, this is the workaround:
```clj ```clj
:dependencies [[~(symbol "net.3scale" "3scale-api") "3.0.2"]] :dependencies [[~(symbol "net.3scale" "3scale-api") "3.0.2"]]
``` ```
**Q:** I'm getting warnings for implicit hooks or implicit middleware.
**A:** Hooks are a deprecated feature where plugins can modify the
behavior of built-in Leiningen functionality; they result in
situations which can be very difficult to debug and usually point
to situations in which the original API is not flexible enough.
Leiningen also has a deprecated feature for implicitly loading
middleware. Middleware is not deprecated but should now be declared using
`:middleware` instead of being auto-detected from plugins.
Adding `:implicits false` to `project.clj` will disable all implicit features.

View file

@ -377,11 +377,6 @@ before manually specified hooks.
### Project Middleware ### Project Middleware
**Note**: Leiningen supports project middleware in plugins;
however this mechanism is extremely error-prone and difficult to
debug. It should be considered deprecated as of 2.8.0 onward and will
continue to work until version 3.0 but is strongly advised against.
Project middleware is just a function that is called on a project map Project middleware is just a function that is called on a project map
returning a new project map. Middleware gives a plugin the power to do returning a new project map. Middleware gives a plugin the power to do
any kind of transformation on the project map. However, problems with any kind of transformation on the project map. However, problems with
@ -394,7 +389,7 @@ The following middleware injects additional javac options into the project map,
but only if there are any java source paths in the project: but only if there are any java source paths in the project:
```clj ```clj
(ns lein-inject.plugin (ns leiningen.inject
(:require [leiningen.core.project :as p])) (:require [leiningen.core.project :as p]))
(def javac-params-profile (def javac-params-profile
@ -406,12 +401,12 @@ but only if there are any java source paths in the project:
project)) project))
``` ```
Projects use middleware by adding `:middleware` as a vector of var
names into their `project.clj`:
Like hooks, middleware will be applied automatically for plugins if you put it ```clj
in `plugin-name.plugin/middleware`. You can also load middleware manually by :middleware [leiningen.inject/middleware]
setting the `:middleware` key in project.clj to a seq of vars to call to ```
transform your project map. Note that automatic middleware is applied before
manually specified middleware.
Also note that the currently active middleware depends on which Also note that the currently active middleware depends on which
profiles are active. This means we need to reapply the middleware profiles are active. This means we need to reapply the middleware
@ -429,6 +424,12 @@ middleware to inject values into the project map is if the profiles has to be
programmatically computed, or if you have to modify the project map in a way programmatically computed, or if you have to modify the project map in a way
that is not possible with `merge-profiles`. that is not possible with `merge-profiles`.
**Note**: Leiningen supports loading middleware implicitly when the
middleware is named `plugin-name.plugin/middleware`; however this
mechanism is even more difficult to debug than regular middleware. It
should be considered deprecated as of 2.8.0 onward and will continue
to work until version 3.0 but is strongly advised against.
### Maven Wagons ### Maven Wagons
[Pomegranate](https://github.com/cemerick/pomegranate) (the library [Pomegranate](https://github.com/cemerick/pomegranate) (the library

View file

@ -29,7 +29,9 @@
(defn- warn [& args] (defn- warn [& args]
;; TODO: remove with 3.0.0 ;; TODO: remove with 3.0.0
(require 'leiningen.core.main) (require 'leiningen.core.main)
((resolve 'leiningen.core.main/warn) args)) (apply (resolve 'leiningen.core.main/warn) args))
(def ^:private warn-once (memoize warn))
(defn- update-each-contained [m keys f & args] (defn- update-each-contained [m keys f & args]
(reduce (fn [m k] (reduce (fn [m k]
@ -389,7 +391,7 @@
(meta project)))) (meta project))))
([project] ([project]
(let [repos (if (:omit-default-repositories project) (let [repos (if (:omit-default-repositories project)
(do (warn "WARNING:" (do (warn-once "WARNING:"
":omit-default-repositories is deprecated;" ":omit-default-repositories is deprecated;"
"use :repositories ^:replace [...] instead.") "use :repositories ^:replace [...] instead.")
empty-repositories) empty-repositories)
@ -675,18 +677,14 @@
profiles)] profiles)]
(when (and (seq repo-profiles) (when (and (seq repo-profiles)
(not (System/getenv "LEIN_SUPPRESS_USER_LEVEL_REPO_WARNINGS"))) (not (System/getenv "LEIN_SUPPRESS_USER_LEVEL_REPO_WARNINGS")))
(warn ":repositories detected in user-level profiles!" (warn-once ":repositories detected in user-level profiles!"
(vec (map first repo-profiles)) "\nSee" (vec (map first repo-profiles)) "\nSee"
"https://github.com/technomancy/leiningen/wiki/Repeatability")))) "https://github.com/technomancy/leiningen/wiki/Repeatability"))))
(alter-var-root #'warn-user-repos memoize)
(defn- warn-user-profile [root profiles] (defn- warn-user-profile [root profiles]
(when (and root (contains? profiles :user)) (when (and root (contains? profiles :user))
(warn "WARNING: user-level profile defined in project files."))) (warn "WARNING: user-level profile defined in project files.")))
(alter-var-root #'warn-user-profile memoize)
(defn- system-profiles [] (defn- system-profiles []
(let [sys-profile-dir (if (= :windows (utils/get-os)) (let [sys-profile-dir (if (= :windows (utils/get-os))
(io/file (System/getenv "AllUsersProfile") "Leiningen") (io/file (System/getenv "AllUsersProfile") "Leiningen")
@ -772,11 +770,14 @@
(defn- load-hook [hook-name] (defn- load-hook [hook-name]
(if-let [hook (try (utils/require-resolve hook-name) (if-let [hook (try (utils/require-resolve hook-name)
(catch Throwable e (catch Exception e
(utils/error "problem requiring" hook-name "hook") (utils/error "problem requiring" hook-name "hook")
(throw e)))] (throw e)))]
(try (hook) (try (warn-once "Warning: implicit hook found:" hook-name
(catch Throwable e "\nHooks are deprecated and will be removed"
"in a future version.")
(hook)
(catch Exception e
(utils/error "problem activating" hook-name "hook") (utils/error "problem activating" hook-name "hook")
(throw e))) (throw e)))
(when-not (:optional (meta hook-name)) (when-not (:optional (meta hook-name))
@ -799,7 +800,11 @@
([project middleware-name] ([project middleware-name]
(if (and (:implicits project true) (:implicit-middleware project true)) (if (and (:implicits project true) (:implicit-middleware project true))
(if-let [middleware (utils/require-resolve middleware-name)] (if-let [middleware (utils/require-resolve middleware-name)]
(middleware project) (do (when-not (some #{middleware-name} (:middleware project))
(warn-once "Warning: implicit middleware found:" middleware-name
"\nPlease declare all middleware in :middleware"
"as implicit loading is deprecated."))
(middleware project))
(do (when-not (:optional (meta middleware-name)) (do (when-not (:optional (meta middleware-name))
(utils/error "cannot resolve" middleware-name "middleware")) (utils/error "cannot resolve" middleware-name "middleware"))
project)) project))