Clarify docs, add tests for transitive deps

This commit clarifies some things in the docs based on PR review.
It also adds additional test coverage for managed dependencies;
specifically, a case where two normal dependencies both have
a transitive dependency on the same library, but with different
versions.  The test validates that this conflict is properly
resolved via `:managed-dependencies`.
This commit is contained in:
Chris Price 2016-06-30 09:41:27 -07:00
parent 2fb603b2bf
commit 7ea847d16f
4 changed files with 44 additions and 19 deletions

View file

@ -23,13 +23,14 @@ regular `:dependencies` section, with two exceptions:
1. It does not actually introduce any dependencies to your project. It only says,
"hey leiningen, if you encounter one of these dependencies later, here are the
versions that you should use."
versions that you should fall back to if the version numbers aren't explicitly
specified."
2. It allows the version number to be omitted from the `:dependencies` section,
for any artifact that you've listed in your `:managed-dependencies` section.
Here's an example:
```clojure
```clj
(defproject superfun/happyslide "1.0.0-SNAPSHOT"
:description "A Clojure project with managed dependencies"
:min-lein-version "2.7.0"
@ -59,7 +60,7 @@ the [`lein-parent` plugin](https://github.com/achin/lein-parent). This plugin
will allow you to define a single "parent" project that is inherited by multiple
"child" projects; e.g.:
```
```clj
(defproject superfun/myparent "1.0.0"
:managed-dependencies [[clj-time "0.12.0"]
[me.raynes/fs "1.4.6"]

View file

@ -158,33 +158,48 @@
(:dependencies managed-deps-project)
(:managed-dependencies managed-deps-project)))
;; the list of deps from the managed deps section that aren't used
unused-managed-deps (remove
(fn [dep]
(some (partial coordinates-match? dep) merged-deps))
managed-deps)
unused-managed-deps (-> (remove
(fn [dep]
(or (some (partial coordinates-match? dep) merged-deps)
;; special-casing to remove tools.reader, which is a common transitive dep
;; of two of our normal dependencies
(= 'org.clojure/tools.reader (first dep))))
managed-deps))
;; deps that have classifiers
classified-deps (filter
#(some #{:classifier} %)
merged-deps)]
;; make sure the sample data has some unmanaged deps, some unused managed deps,
;; and some classified deps, for completeness
(is (not (empty? versioned-unmanaged-deps)))
(is (not (empty? unused-managed-deps)))
(is (not (empty? classified-deps)))
(is (seq versioned-unmanaged-deps))
(is (seq unused-managed-deps))
(is (seq classified-deps))
;; delete all of the existing artifacts for merged deps
(doseq [[n v] merged-deps]
(delete-file-recursively (m2-dir n v) :silently))
;; delete all of the artifacts for the managed deps too
(doseq [[n v] managed-deps]
(delete-file-recursively (m2-dir n v) :silently))
;; delete all copies of tools.reader so we know that the managed dependency
;; for it is taking precedence
(delete-file-recursively (m2-dir 'org.clojure/tools.reader) :silently)
(deps managed-deps-project)
;; artifacts should be available for all merged deps
(doseq [[n v] merged-deps]
(is (.exists (m2-dir n v)) (str n " was not downloaded.")))
(is (.exists (m2-dir n v)) (str n " was not downloaded (missing dir '" (m2-dir n v) "').")))
;; artifacts should *not* have been downloaded for unused managed deps
(doseq [[n v] unused-managed-deps]
(is (not (.exists (m2-dir n v))) (str n " was unexpectedly downloaded.")))
(is (not (.exists (m2-dir n v))) (str n " was unexpectedly downloaded (found unexpected dir '" (m2-dir n v) "').")))
;; artifacts with classifiers should be available
(doseq [[n v _ classifier] classified-deps]
(let [f (m2-file n v classifier)]
(is (.exists f) (str f " was not downloaded."))))))
(is (.exists f) (str f " was not downloaded."))))
;; check tools.reader explicitly, since it is our special transitive dependency
(let [tools-reader-versions (into [] (.listFiles (m2-dir 'org.clojure/tools.reader)))]
(is (= 1 (count tools-reader-versions)))
(is (= (first tools-reader-versions) (m2-dir 'org.clojure/tools.reader
(->> managed-deps
(filter
(fn [dep] (= 'org.clojure/tools.reader (first dep))))
first
second)))))))

View file

@ -2,7 +2,8 @@
(:require [leiningen.core.project :as project]
[leiningen.core.user :as user]
[leiningen.core.test.helper :as helper]
[clojure.java.io :as io])
[clojure.java.io :as io]
[clojure.string :as str])
(:import (java.io ByteArrayOutputStream PrintStream FileDescriptor
FileOutputStream)))
@ -11,9 +12,13 @@
(def tmp-dir (System/getProperty "java.io.tmpdir"))
(defn m2-dir [n v]
(io/file local-repo
(if (string? n) n (or (namespace n) (name n))) (name n) v))
(defn m2-dir
([n]
(let [group (-> (if (string? n) n (or (namespace n) (name n)))
(str/replace "." "/"))]
(io/file local-repo group (name n))))
([n v]
(io/file (m2-dir n) v)))
(defn m2-file [n v classifier]
(io/file (m2-dir n v) (str (name n) "-" v "-" classifier ".jar")))

View file

@ -8,11 +8,15 @@
[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"]]
[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"]])
[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
])