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.string :as s]
[clojure.java.shell :as sh]
[clojure.data.xml :as xml]))
[clojure.data.xml :as xml]
[leiningen.core.classpath :as classpath]))
(defn- relativize [project]
(let [root (str (:root project) (System/getProperty "file.separator"))]
@ -366,11 +367,14 @@
(defn check-for-snapshot-deps [project]
(when (and (not (snapshot? project))
(not (System/getenv "LEIN_SNAPSHOTS_IN_RELEASE"))
(some #(re-find #"SNAPSHOT" (second %)) (:dependencies project)))
(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.")))
(not (System/getenv "LEIN_SNAPSHOTS_IN_RELEASE")))
(let [merged-deps (classpath/merge-versions-from-managed-coords
(:dependencies project)
(:managed-dependencies project))]
(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
([project] (make-pom project false))

View file

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

View file

@ -5,7 +5,7 @@
[leiningen.core.user :as user]
[leiningen.test.helper
:only [sample-project sample-profile-meta-project
managed-deps-project]
managed-deps-project managed-deps-snapshot-project]
:as lthelper])
(:require [clojure.data.xml :as xml]
[leiningen.core.project :as project]
@ -355,31 +355,33 @@
(is (not (snapshot? nil)))))
(deftest test-managed-dependencies
(let [xml (xml/parse-str
(make-pom managed-deps-project))]
(testing "normal dependencies are written to pom properly"
(is (= ["org.clojure" "rome" "ring" "ring" "commons-codec" "commons-math"
"org.clojure" "org.clojure"]
(map #(first-in % [:dependency :groupId])
(deep-content xml [:project :dependencies]))))
(is (= ["clojure" "rome" "ring" "ring-codec" "commons-codec" "commons-math"
"tools.emitter.jvm" "tools.namespace"]
(map #(first-in % [:dependency :artifactId])
(deep-content xml [:project :dependencies]))))
(is (= [nil nil nil nil "1.6" nil "0.1.0-beta5" "0.3.0-alpha3"]
(map #(first-in % [:dependency :version])
(deep-content xml [:project :dependencies])))))
(testing "managed dependencies are written to pom properly"
(is (= ["org.clojure" "rome" "ring" "ring" "commons-math" "ring" "org.clojure"]
(map #(first-in % [:dependency :groupId])
(deep-content xml [:project :dependencyManagement :dependencies]))))
(is (= ["clojure" "rome" "ring" "ring-codec" "commons-math" "ring-defaults"
"tools.reader"]
(map #(first-in % [:dependency :artifactId])
(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"]
(map #(first-in % [:dependency :version])
(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])))))))
(doseq [proj [managed-deps-snapshot-project
managed-deps-project]]
(let [xml (xml/parse-str
(make-pom proj))]
(testing "normal dependencies are written to pom properly"
(is (= ["org.clojure" "rome" "ring" "ring" "commons-codec" "commons-math"
"org.clojure" "org.clojure"]
(map #(first-in % [:dependency :groupId])
(deep-content xml [:project :dependencies]))))
(is (= ["clojure" "rome" "ring" "ring-codec" "commons-codec" "commons-math"
"tools.emitter.jvm" "tools.namespace"]
(map #(first-in % [:dependency :artifactId])
(deep-content xml [:project :dependencies]))))
(is (= [nil nil nil nil "1.6" nil "0.1.0-beta5" "0.3.0-alpha3"]
(map #(first-in % [:dependency :version])
(deep-content xml [:project :dependencies])))))
(testing "managed dependencies are written to pom properly"
(is (= ["org.clojure" "rome" "ring" "ring" "commons-math" "ring" "org.clojure"]
(map #(first-in % [:dependency :groupId])
(deep-content xml [:project :dependencyManagement :dependencies]))))
(is (= ["clojure" "rome" "ring" "ring-codec" "commons-math" "ring-defaults"
"tools.reader"]
(map #(first-in % [:dependency :artifactId])
(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"]
(map #(first-in % [:dependency :version])
(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
uberjar-merging-project
provided-project
managed-deps-project]])
managed-deps-project
managed-deps-snapshot-project]])
(:import (java.io File FileOutputStream)
(java.util.zip ZipFile)))
@ -67,8 +68,13 @@
(is (= 0 (:exit (sh "java" bootclasspath "-jar" filename))))))
(deftest test-uberjar-managed-dependencies
(uberjar managed-deps-project)
(let [filename (str "test_projects/managed-deps/target/"
"mgmt-0.99.0-SNAPSHOT-standalone.jar")
uberjar-file (File. filename)]
(is (= true (.exists uberjar-file)))))
(doseq [[proj jarfile] [[managed-deps-snapshot-project
(str "test_projects/managed-deps-snapshot/target/"
"mgmt-0.99.0-SNAPSHOT-standalone.jar")]
[managed-deps-project
(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")
(defproject mgmt "0.99.0-SNAPSHOT"
(defproject mgmt "0.99.0"
:description "A test project"
:managed-dependencies [[~(symbol "org.clojure" "clojure") ~clj-version]