From 8343007ad251990836327a22b1c779f24c2f06d9 Mon Sep 17 00:00:00 2001 From: Charles Loomis Date: Sun, 30 Oct 2016 20:48:57 +0100 Subject: [PATCH 1/2] first working version with tests --- .../clojure/cemerick/pomegranate/aether.clj | 81 +++++++++++++------ .../cemerick/pomegranate/aether_test.clj | 64 +++++++++++++++ 2 files changed, 119 insertions(+), 26 deletions(-) diff --git a/src/main/clojure/cemerick/pomegranate/aether.clj b/src/main/clojure/cemerick/pomegranate/aether.clj index f0dd8a1..5aeda14 100644 --- a/src/main/clojure/cemerick/pomegranate/aether.clj +++ b/src/main/clojure/cemerick/pomegranate/aether.clj @@ -612,17 +612,6 @@ kwarg to the repository kwarg. (merge {:result result} m)))) coordinates)))) - -(defn- add-version-from-managed-coord - "Given an entry from a coordinates vector, and the corresponding entry from the - managed coordinates vector, update the version number in the coordinate with the - value from the managed coordinate." - [coord managed-coord] - (if-let [managed-version (second managed-coord)] - (vec (concat [(first coord) managed-version] - (nthrest coord 2))) - (throw (IllegalArgumentException. (str "Provided artifact is missing a version: " coord))))) - (defn- coordinates-match? [[dep version & opts] [sdep sversion & sopts]] (let [om (apply hash-map opts) @@ -637,20 +626,60 @@ kwarg to the repository kwarg. (= (:classifier om) (:classifier som))))) -(defn- find-managed-coord - "Given an entry from a coordinates vector, and a managed coordinates vector, find - the entry in the managed coordinates vector (if any) that matches the coordinate." - [coord managed-coords] - (first (filter #(coordinates-match? coord %) managed-coords))) - -(defn- add-version-from-managed-coords-if-missing - "Given a managed coordinates vector and an entry from a coordinates vector, check - to see if the coordinate specifies a version string, and if not, update it with - the version string from the managed coordinates (if it is defined)." - [managed-coords coord] - (if (nil? (second coord)) - (add-version-from-managed-coord coord (find-managed-coord coord managed-coords)) - coord)) +(defn- coord-map-key + "Creates the unique key for the given coordinate map. This is + essentially a representation of the full maven coordinate except + the version." + [{:keys [project extension classifier]}] + [project extension classifier]) + +(defn- canonical-id [id] + (apply symbol (distinct ((juxt group name) id)))) + +(defn- conform-coord + "Returns a map describing the coordinate. The full project ID is + under the :project key and the version, if specified and not nil, + under the :version key. All other specified options appear with + the keys and values specified (including nil values)." + [[project & opts]] + (if project + (let [has-version? (odd? (count opts)) + version (if has-version? (first opts)) + opts (if has-version? (rest opts) opts) + opts-map (apply hash-map opts)] + (-> (if (and has-version? version) {:version version} {}) + (assoc :project (canonical-id project)) + (merge opts-map))))) + +(defn- strip-defaults [dep-map] + (remove #(or (some #{:project :version} %) + (= [:scope "compile"] %) + (= [:extension "jar"] %) + (= [:optional false] %)) dep-map)) + +(defn- unform-coord + "Returns the canonical, vector form of a dependency that was + specified as a map." + [{:keys [project version] :as dep-map}] + (-> (if version [project version] [project]) + (cons (strip-defaults dep-map)) + ((partial mapcat identity)) + (vec))) + +(defn- managed-coords-map [managed-coords] + (->> managed-coords + (map conform-coord) + (map (juxt coord-map-key identity)) + (into {}))) + +(defn- merge-managed-coord [managed-coords-m coord] + (let [coord-map (conform-coord coord) + coord-key (coord-map-key coord-map) + managed-coord (get managed-coords-m coord-key) + merged-map (merge managed-coord coord-map)] + (if (:version merged-map) + (unform-coord (into {} (remove (comp nil? second) merged-map))) + (throw (IllegalArgumentException. (str "Provided artifact is missing a version: " coord)))))) (defn- merge-versions-from-managed-coords "Given a vector of coordinates (e.g. [[group/name <\"version\"> & settings] ..]) @@ -658,7 +687,7 @@ kwarg to the repository kwarg. returns an updated vector of coordinates with version numbers merged in from the managed-coordinates vector as necessary." [coordinates managed-coordinates] - (vec (map (partial add-version-from-managed-coords-if-missing managed-coordinates) + (vec (map (partial merge-managed-coord (managed-coords-map managed-coordinates)) coordinates))) (defn- coords->Dependencies diff --git a/src/test/clojure/cemerick/pomegranate/aether_test.clj b/src/test/clojure/cemerick/pomegranate/aether_test.clj index 345b338..b7653a4 100644 --- a/src/test/clojure/cemerick/pomegranate/aether_test.clj +++ b/src/test/clojure/cemerick/pomegranate/aether_test.clj @@ -548,6 +548,70 @@ ['tester "0.1.0-20120403.012847-1"] nil} (aether/dependency-hierarchy coords deps))))) +(deftest check-canonical-id + (let [f @#'aether/canonical-id] + (are [expect input] (= expect (f input))) + 'foo 'foo + 'foo 'foo/foo + 'foo/bar 'foo/bar)) + +(deftest check-conform-coord + (let [f @#'aether/conform-coord] + (are [expect input] (= expect (f input)) + nil nil + {:project 'foo} '[foo] + {:project 'foo/bar} '[foo/bar] + {:project 'foo} '[foo nil] + {:project 'foo, :version "1.2.3"} '[foo "1.2.3"] + {:project 'foo, :version "1.2.3", :scope "test"} '[foo "1.2.3" :scope "test"] + {:project 'foo, :scope "test"} '[foo :scope "test"] + {:project 'foo, :scope "test"} '[foo nil :scope "test"] + {:project 'foo, :scope nil} '[foo nil :scope nil] + {:project 'foo, :scope "test", :optional true} '[foo :scope "test" :optional true] + {:project 'foo, :version "1.2.3" :exclusions '[[bar]]} '[foo "1.2.3" :exclusions [[bar]]]))) + +(deftest check-unform-coord + (let [f @#'aether/unform-coord] + (are [expect input] (= expect (f input)) + '[foo] {:project 'foo} + '[foo/bar] {:project 'foo/bar} + '[foo "1.2.3"] {:project 'foo, :version "1.2.3"} + '[foo "1.2.3" :scope "test"] {:project 'foo, :version "1.2.3", :scope "test"} + '[foo :scope "test"] {:project 'foo, :scope "test"} + '[foo :scope nil] {:project 'foo, :scope nil} + + '[foo :scope "test"] {:project 'foo, :scope "test"} + '[foo] {:project 'foo, :scope "compile"} + '[foo :optional true] {:project 'foo, :optional true} + '[foo] {:project 'foo, :optional false} + '[foo :extension "zip"] {:project 'foo, :extension "zip"} + '[foo] {:project 'foo, :extension "jar"} + + '[foo "1.2.3" :exclusions [[bar]]] {:project 'foo, :version "1.2.3" :exclusions '[[bar]]}))) + +(deftest check-merge-managed-coord + (let [f @#'aether/merge-managed-coord + managed-coords-map @#'aether/managed-coords-map + managed-coords-m (managed-coords-map + '[[demo "1.0.0"] + [demo-test "2.0.0" :scope "test"] + [demo-compile "3.0.0" :scope "compile"] + [demo-excl "4.0.0" :exclusions [[demo] [demo-test]]]])] + (is (thrown-with-msg? IllegalArgumentException #"Provided artifact is missing a version: " + (f nil nil))) + (is (thrown-with-msg? IllegalArgumentException #"Provided artifact is missing a version: \[demo-unk\]" + (f nil '[demo-unk]))) + (is (= '[demo "1.0.0"] (f nil '[demo/demo "1.0.0"]))) + (is (= '[demo "1.0.0"] (f managed-coords-m '[demo]))) + (is (= '[demo "1.0.0"] (f managed-coords-m '[demo nil]))) + (is (= '[demo-test "2.0.0" :scope "test"] (f managed-coords-m '[demo-test]))) + (is (= '[demo-test "2.0.0" :scope "provided"] (f managed-coords-m '[demo-test :scope "provided"]))) + (is (= '[demo-test "2.0.0"] (f managed-coords-m '[demo-test :scope "compile"]))) + (is (= '[demo-test "2.0.0"] (f managed-coords-m '[demo-test :scope nil]))) + (is (= '[demo-compile "3.0.0"] (f managed-coords-m '[demo-compile]))) + (is (= '[demo-excl "4.0.0" :exclusions [[demo] [demo-test]]] (f managed-coords-m '[demo-excl]))) + (is (= '[demo-excl "4.0.0"] (f managed-coords-m '[demo-excl :exclusions nil]))))) + (comment "tests needed for: repository authentication From a14b1e874487af81647ba511167c18e6eb4a40f0 Mon Sep 17 00:00:00 2001 From: Charles Loomis Date: Sun, 22 Jan 2017 09:59:49 +0100 Subject: [PATCH 2/2] make merge-versions-from-managed-coords, conform-coord and unform-coord public --- .../clojure/cemerick/pomegranate/aether.clj | 6 ++--- .../cemerick/pomegranate/aether_test.clj | 25 +++++++++++++++++-- 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/src/main/clojure/cemerick/pomegranate/aether.clj b/src/main/clojure/cemerick/pomegranate/aether.clj index 5aeda14..9d8b4b3 100644 --- a/src/main/clojure/cemerick/pomegranate/aether.clj +++ b/src/main/clojure/cemerick/pomegranate/aether.clj @@ -636,7 +636,7 @@ kwarg to the repository kwarg. (defn- canonical-id [id] (apply symbol (distinct ((juxt group name) id)))) -(defn- conform-coord +(defn conform-coord "Returns a map describing the coordinate. The full project ID is under the :project key and the version, if specified and not nil, under the :version key. All other specified options appear with @@ -657,7 +657,7 @@ kwarg to the repository kwarg. (= [:extension "jar"] %) (= [:optional false] %)) dep-map)) -(defn- unform-coord +(defn unform-coord "Returns the canonical, vector form of a dependency that was specified as a map." [{:keys [project version] :as dep-map}] @@ -681,7 +681,7 @@ kwarg to the repository kwarg. (unform-coord (into {} (remove (comp nil? second) merged-map))) (throw (IllegalArgumentException. (str "Provided artifact is missing a version: " coord)))))) -(defn- merge-versions-from-managed-coords +(defn merge-versions-from-managed-coords "Given a vector of coordinates (e.g. [[group/name <\"version\"> & settings] ..]) where the version field is optional or can be nil, and a vector of managed coordinates, returns an updated vector of coordinates with version numbers merged in from the diff --git a/src/test/clojure/cemerick/pomegranate/aether_test.clj b/src/test/clojure/cemerick/pomegranate/aether_test.clj index b7653a4..74ec4f6 100644 --- a/src/test/clojure/cemerick/pomegranate/aether_test.clj +++ b/src/test/clojure/cemerick/pomegranate/aether_test.clj @@ -556,7 +556,7 @@ 'foo/bar 'foo/bar)) (deftest check-conform-coord - (let [f @#'aether/conform-coord] + (let [f aether/conform-coord] (are [expect input] (= expect (f input)) nil nil {:project 'foo} '[foo] @@ -571,7 +571,7 @@ {:project 'foo, :version "1.2.3" :exclusions '[[bar]]} '[foo "1.2.3" :exclusions [[bar]]]))) (deftest check-unform-coord - (let [f @#'aether/unform-coord] + (let [f aether/unform-coord] (are [expect input] (= expect (f input)) '[foo] {:project 'foo} '[foo/bar] {:project 'foo/bar} @@ -612,6 +612,27 @@ (is (= '[demo-excl "4.0.0" :exclusions [[demo] [demo-test]]] (f managed-coords-m '[demo-excl]))) (is (= '[demo-excl "4.0.0"] (f managed-coords-m '[demo-excl :exclusions nil]))))) +;; simple functionality test; edge cases checked in underlying functions +(deftest check-merge-versions-from-managed-coords + (let [canonical-form #(-> % aether/conform-coord aether/unform-coord) + + managed-coords '[[demo "1.0.0"] + [demo-test "2.0.0" :scope "test"] + [demo-provided "3.0.0" :scope "provided"] + [demo-compile "3.0.1" :scope "compile"] + [demo-excl "4.0.0" :exclusions [[demo] [demo-test]]]] + local-coords '[[foo "1.0.0" :scope "test"] + [foo/bar "2.0.0" :exclusions [[demo]] :scope "compile"]] + + coords (concat local-coords '[[demo] + [demo-test "2.0.0"] + [demo-provided] + [demo-compile] + [demo-excl]]) + merged-coords (aether/merge-versions-from-managed-coords coords managed-coords) + expected-coords (map canonical-form (concat managed-coords local-coords))] + (is (= (set merged-coords) (set expected-coords))))) + (comment "tests needed for: repository authentication