Fix checking for SNAPSHOT deps with managed deps - fixes #2205

This commit fixes #2205: when using managed dependencies in
a project, if the project itself was a non-SNAPSHOT version,
then when `lein install` and similar tasks were executed,
lein would check to make sure that none of the dependencies
were a SNAPSHOT version.  lein was checking that directly against
the `:dependencies` vector, which would cause an NPE if a dependency
didn't specify a version number (because it was inheriting it from
the `:managed-dependencies` section).

This commit fixes the bug by calling the code that merges the
`:dependencies` and `:managed-dependencies` vectors together prior
to performing the SNAPSHOT check.
This commit is contained in:
Chris Price 2016-09-15 21:06:03 -07:00
parent 705b1a70bd
commit 3feae04e76
6 changed files with 78 additions and 42 deletions

View file

@ -7,7 +7,8 @@
[clojure.set :as set] [clojure.set :as set]
[clojure.string :as s] [clojure.string :as s]
[clojure.java.shell :as sh] [clojure.java.shell :as sh]
[clojure.data.xml :as xml])) [clojure.data.xml :as xml]
[leiningen.core.classpath :as classpath]))
(defn- relativize [project] (defn- relativize [project]
(let [root (str (:root project) (System/getProperty "file.separator"))] (let [root (str (:root project) (System/getProperty "file.separator"))]
@ -366,11 +367,14 @@
(defn check-for-snapshot-deps [project] (defn check-for-snapshot-deps [project]
(when (and (not (snapshot? project)) (when (and (not (snapshot? project))
(not (System/getenv "LEIN_SNAPSHOTS_IN_RELEASE")) (not (System/getenv "LEIN_SNAPSHOTS_IN_RELEASE")))
(some #(re-find #"SNAPSHOT" (second %)) (:dependencies project))) (let [merged-deps (classpath/merge-versions-from-managed-coords
(main/abort "Release versions may not depend upon snapshots." (:dependencies project)
"\nFreeze snapshots to dated versions or set the" (:managed-dependencies project))]
"LEIN_SNAPSHOTS_IN_RELEASE environment variable to override."))) (when (some #(re-find #"SNAPSHOT" (second %)) merged-deps)
(main/abort "Release versions may not depend upon snapshots."
"\nFreeze snapshots to dated versions or set the"
"LEIN_SNAPSHOTS_IN_RELEASE environment variable to override.")))))
(defn make-pom (defn make-pom
([project] (make-pom project false)) ([project] (make-pom project false))

View file

@ -74,6 +74,8 @@
(def managed-deps-project (read-test-project "managed-deps")) (def managed-deps-project (read-test-project "managed-deps"))
(def managed-deps-snapshot-project (read-test-project "managed-deps-snapshot"))
(defn abort-msg (defn abort-msg
"Catches main/abort thrown by calling f on its args and returns its error "Catches main/abort thrown by calling f on its args and returns its error
message." message."

View file

@ -5,7 +5,7 @@
[leiningen.core.user :as user] [leiningen.core.user :as user]
[leiningen.test.helper [leiningen.test.helper
:only [sample-project sample-profile-meta-project :only [sample-project sample-profile-meta-project
managed-deps-project] managed-deps-project managed-deps-snapshot-project]
:as lthelper]) :as lthelper])
(:require [clojure.data.xml :as xml] (:require [clojure.data.xml :as xml]
[leiningen.core.project :as project] [leiningen.core.project :as project]
@ -355,31 +355,33 @@
(is (not (snapshot? nil))))) (is (not (snapshot? nil)))))
(deftest test-managed-dependencies (deftest test-managed-dependencies
(let [xml (xml/parse-str (doseq [proj [managed-deps-snapshot-project
(make-pom managed-deps-project))] managed-deps-project]]
(testing "normal dependencies are written to pom properly" (let [xml (xml/parse-str
(is (= ["org.clojure" "rome" "ring" "ring" "commons-codec" "commons-math" (make-pom proj))]
"org.clojure" "org.clojure"] (testing "normal dependencies are written to pom properly"
(map #(first-in % [:dependency :groupId]) (is (= ["org.clojure" "rome" "ring" "ring" "commons-codec" "commons-math"
(deep-content xml [:project :dependencies])))) "org.clojure" "org.clojure"]
(is (= ["clojure" "rome" "ring" "ring-codec" "commons-codec" "commons-math" (map #(first-in % [:dependency :groupId])
"tools.emitter.jvm" "tools.namespace"] (deep-content xml [:project :dependencies]))))
(map #(first-in % [:dependency :artifactId]) (is (= ["clojure" "rome" "ring" "ring-codec" "commons-codec" "commons-math"
(deep-content xml [:project :dependencies])))) "tools.emitter.jvm" "tools.namespace"]
(is (= [nil nil nil nil "1.6" nil "0.1.0-beta5" "0.3.0-alpha3"] (map #(first-in % [:dependency :artifactId])
(map #(first-in % [:dependency :version]) (deep-content xml [:project :dependencies]))))
(deep-content xml [:project :dependencies]))))) (is (= [nil nil nil nil "1.6" nil "0.1.0-beta5" "0.3.0-alpha3"]
(testing "managed dependencies are written to pom properly" (map #(first-in % [:dependency :version])
(is (= ["org.clojure" "rome" "ring" "ring" "commons-math" "ring" "org.clojure"] (deep-content xml [:project :dependencies])))))
(map #(first-in % [:dependency :groupId]) (testing "managed dependencies are written to pom properly"
(deep-content xml [:project :dependencyManagement :dependencies])))) (is (= ["org.clojure" "rome" "ring" "ring" "commons-math" "ring" "org.clojure"]
(is (= ["clojure" "rome" "ring" "ring-codec" "commons-math" "ring-defaults" (map #(first-in % [:dependency :groupId])
"tools.reader"] (deep-content xml [:project :dependencyManagement :dependencies]))))
(map #(first-in % [:dependency :artifactId]) (is (= ["clojure" "rome" "ring" "ring-codec" "commons-math" "ring-defaults"
(deep-content xml [:project :dependencyManagement :dependencies])))) "tools.reader"]
(is (= ["1.3.0" "0.9" "1.0.0" "1.0.1" "1.2" "0.2.1" "1.0.0-beta3"] (map #(first-in % [:dependency :artifactId])
(map #(first-in % [:dependency :version]) (deep-content xml [:project :dependencyManagement :dependencies]))))
(deep-content xml [:project :dependencyManagement :dependencies])))) (is (= ["1.3.0" "0.9" "1.0.0" "1.0.1" "1.2" "0.2.1" "1.0.0-beta3"]
(is (= [nil nil nil nil "sources" nil nil] (map #(first-in % [:dependency :version])
(map #(first-in % [:dependency :classifier]) (deep-content xml [:project :dependencyManagement :dependencies]))))
(deep-content xml [:project :dependencyManagement :dependencies]))))))) (is (= [nil nil nil nil "sources" nil nil]
(map #(first-in % [:dependency :classifier])
(deep-content xml [:project :dependencyManagement :dependencies]))))))))

View file

@ -7,7 +7,8 @@
[leiningen.test.helper :refer [sample-no-aot-project [leiningen.test.helper :refer [sample-no-aot-project
uberjar-merging-project uberjar-merging-project
provided-project provided-project
managed-deps-project]]) managed-deps-project
managed-deps-snapshot-project]])
(:import (java.io File FileOutputStream) (:import (java.io File FileOutputStream)
(java.util.zip ZipFile))) (java.util.zip ZipFile)))
@ -67,8 +68,13 @@
(is (= 0 (:exit (sh "java" bootclasspath "-jar" filename)))))) (is (= 0 (:exit (sh "java" bootclasspath "-jar" filename))))))
(deftest test-uberjar-managed-dependencies (deftest test-uberjar-managed-dependencies
(uberjar managed-deps-project) (doseq [[proj jarfile] [[managed-deps-snapshot-project
(let [filename (str "test_projects/managed-deps/target/" (str "test_projects/managed-deps-snapshot/target/"
"mgmt-0.99.0-SNAPSHOT-standalone.jar") "mgmt-0.99.0-SNAPSHOT-standalone.jar")]
uberjar-file (File. filename)] [managed-deps-project
(is (= true (.exists uberjar-file))))) (str "test_projects/managed-deps/target/"
"mgmt-0.99.0-standalone.jar")]]]
(uberjar proj)
(let [uberjar-file (File. jarfile)]
(is (= true (.exists uberjar-file))
(format "File '%s' does not exist!" uberjar-file)))))

View file

@ -0,0 +1,22 @@
(def clj-version "1.3.0")
(defproject mgmt "0.99.0-SNAPSHOT"
:description "A test project"
:managed-dependencies [[~(symbol "org.clojure" "clojure") ~clj-version]
[rome ~(str "0." "9")]
[ring/ring "1.0.0"]
[ring/ring-codec "1.0.1"]
[commons-math/commons-math "1.2" :classifier "sources"]
[ring/ring-defaults "0.2.1"]
[org.clojure/tools.reader "1.0.0-beta3"]]
:dependencies [[org.clojure/clojure]
[rome/rome nil]
[ring]
[ring/ring-codec nil :exclusions [commons-codec]]
[commons-codec "1.6"]
[commons-math nil :classifier "sources"]
[org.clojure/tools.emitter.jvm "0.1.0-beta5"] ; depends on tools.reader 0.8.5
[org.clojure/tools.namespace "0.3.0-alpha3"] ; depends on tools.reader 0.10.0
])

View file

@ -1,6 +1,6 @@
(def clj-version "1.3.0") (def clj-version "1.3.0")
(defproject mgmt "0.99.0-SNAPSHOT" (defproject mgmt "0.99.0"
:description "A test project" :description "A test project"
:managed-dependencies [[~(symbol "org.clojure" "clojure") ~clj-version] :managed-dependencies [[~(symbol "org.clojure" "clojure") ~clj-version]