lib.aether

Maven dependency resolution, installation, and repository operations

Resolve dependency graphs with Eclipse Aether, prepare artifact requests, and connect resolved coordinates to JVM classloaders.

1    Overview

lib.aether builds repository-system requests from jvm.artifact coordinates. It can collect dependency graphs, resolve files and versions, install local artifacts, and prepare repository operations.

2    Walkthrough

2.1    Resolve dependencies

(require '[lib.aether :as aether])

(aether/collect-dependencies
 '[org.clojure/data.json "2.5.0"]
 {:type :coord})

(aether/resolve-dependencies
 '[[org.clojure/data.json "2.5.0"]]
 {:type :coord})

2.2    Attach a dependency to a loader

pull resolves coordinates and adds their local files to a loader. Options control dependency traversal, replacement of another loaded version, and whether loaded entries are retained.

(aether/pull
 '[[org.clojure/data.json "2.5.0"]]
 {:keep true})

(aether/resolve-versions
 '[[org.clojure/data.json "LATEST"]])

2.3    Install project artifacts

(aether/install-artifact
 '[example/library "1.0.0"]
 {:artifacts [{:file "target/library.jar"
               :extension "jar"}
              {:file "target/library.pom"
               :extension "pom"}]})

3    Supporting namespaces

Request, result, repository, session, authentication, listener, wagon, and dependency namespaces expose the lower-level Aether integration used by the public functions.

4    API



aether ^

[] [config]
Added 3.0

creates an `Aether` object

v 3.0
(defn aether
  ([] (aether {}))
  ([config]
   (let [system  (system/repository-system)
         session (->> (select-keys config [:local-repo])
                      (session/session system))]
     (-> +defaults+
         (merge {:system system
                 :session session}
                (select-keys config [:repositories]))
         (map->Aether)))))
link
(aether) => (contains-in {:repositories (contains [{:id "clojars", :type "default", :url "https://clojars.org/repo"} {:id "central", :type "default", :url "https://repo1.maven.org/maven2/"}] :in-any-order :gaps-ok), :system org.eclipse.aether.RepositorySystem :session org.eclipse.aether.RepositorySystemSession})

artifact->dependency ^

[artifact]
Added 3.0

converts an artifact to a dependency

v 3.0
(defn artifact->dependency
  ([artifact]
   (let [coord (cond (artifact/coord? artifact)
                     artifact

                     (map? artifact)
                     (apply vector (:name artifact) (:version artifact)
                            (mapcat identity (dissoc artifact :name :version)))

                     :else
                     (artifact/artifact :coord artifact))
         [name version & {:keys [scope exclusions]}] coord]
     (object/from-data {:artifact [name version]
                        :scope scope
                        :exclusions exclusions}
                       Dependency))))
link
(artifact->dependency '[org.clojure/clojure "1.8.0" :scope "compile" :exclusions [org.asm/compile]]) ;; #dep{:artifact "org.clojure:clojure:jar:1.8.0", ;; :exclusions ["org.asm:compile:jar:"], ;; :optional false, :scope "compile", :optional? false} => org.eclipse.aether.graph.Dependency

collect-dependencies ^

[coords] [coords opts] [{:keys [system session repositories]} coords opts]
Added 3.0

getting the dependencies of a repo using pom files

v 3.0
(defn collect-dependencies
  ([coords]
   (collect-dependencies coords {}))
  ([coords opts]
   (collect-dependencies (base/aether) coords opts))
  ([{:keys [^RepositorySystem system session repositories]} coords opts]
   (binding [listener/*progress* (atom [])
             listener/*pairs* (atom {})]
     (let [opts   (collection/merge-nested {:type :defalut
                                   :return :hierarchy
                                   :print {:hierarchy true
                                           :title true
                                           :timing true}}
                                  opts)
           reqm   (cond (and (sequential? coords)
                             (not (artifact/coord? coords)))
                        {:dependencies (mapv artifact->dependency coords)}

                        :else
                        {:root (artifact->dependency coords)})
           request (request/collect-request
                    (assoc reqm :repositories repositories))]
       (if (-> opts :print :title)
         (print/print-title "COLLECTING DEPENDENCIES")
         (print/print "n"))
       (-> (.collectDependencies system session request)
           (result/return-deps @listener/*progress* opts))))))
link
(collect-dependencies '[prismatic/schema "1.1.3"] {:type :coord}) => '[[prismatic/schema "1.1.3"]]

deploy-artifact ^

[coord {:keys [artifacts repository], :as opts}] [{:keys [system session]} coord {:keys [artifacts repository], :as opts}]
Added 3.0

deploys artifacts to the given coordinate

v 3.0
(defn deploy-artifact
  ([coord {:keys [artifacts repository] :as opts}]
   (deploy-artifact (base/aether) coord opts))
  ([{:keys [^RepositorySystem system session]}
    coord
    {:keys [artifacts repository] :as opts}]
   (binding [listener/*progress* (atom [])
             listener/*pairs* (atom {})]
     (let [opts   (collection/merge-nested {:type :default
                                   :print {:title true
                                           :timing true}}
                                  opts)
           opts    (populate-artifact coord opts)
           request (request/deploy-request opts)]
       (if (-> opts :print :title)
         (print/print-title "DEPLOYING ARTIFACTS")
         (print/print "n"))
       (-> (.deploy system session request)
           (result/return @listener/*progress* opts))))))
link
deploy-artifact => fn?

install-artifact ^

[coord {:keys [artifacts], :as opts}] [{:keys [system session]} coord {:keys [artifacts], :as opts}]
Added 3.0

installs artifacts to the given coordinate

v 3.0
(defn install-artifact
  ([coord {:keys [artifacts] :as opts}]
   (install-artifact (base/aether) coord opts))
  ([{:keys [^RepositorySystem system session]} coord {:keys [artifacts] :as opts}]
   (binding [listener/*progress* (atom [])
             listener/*pairs* (atom {})]
     (let [opts   (collection/merge-nested {:type :default
                                   :print {:title true
                                           :timing true}}
                                  opts)
           opts (populate-artifact coord opts)
           request (request/install-request opts)]
       (if (-> opts :print :title)
         (print/print-title "INSTALLING ARTIFACTS")
         (print/print "n"))
       (-> (.install system session request)
           (result/return @listener/*progress* opts))))))
link
install-artifact => fn?

outdated? ^

[coords] [coords opts] [aether coords opts]
Added 3.0

checks if a set of artifacts are outdated

v 3.0
(defn outdated?
  ([coords]
   (outdated? coords {}))
  ([coords opts]
   (outdated? (base/aether) coords opts))
  ([aether coords opts]
   (let [opts    (collection/merge-nested opts {:print {:results true}})
         reps    (mapv artifact/artifact coords)
         inputs  (map #(assoc % :version "LATEST") reps)
         latest  (resolve-versions aether inputs opts)
         results (->> (mapv (fn [in new]
                              (if (not= (:version in)
                                        (:version new))
                                [(first (artifact/artifact :coord in)) (:version in)  '=> (:version new)]))
                            reps latest)
                      (filterv identity))]
     (cond-> results
       (and (seq results) (-> opts :print :results)) (doto prn)))))
link
(outdated? '[[binaryage/devtools "0.9.7"]]) => (contains-in [['binaryage/devtools "0.9.7" '=> string?]])

populate-artifact ^

[coord opts]
Added 3.0

allows coordinate to fill rest of values

v 3.0
(defn populate-artifact
  ([coord opts]
   (let [root (-> (artifact/artifact coord)
                  (select-keys [:artifact :group :version]))]
     opts (update-in opts [:artifacts]
                     (fn [arr] (mapv #(merge % root) arr))))))
link
(populate-artifact '[midje "1.6.3"] {:artifacts [{:extension "pom" :file "midje.pom"} {:extension "jar" :file "midje.jar"}]}) => {:artifacts [{:extension "pom", :file "midje.pom", :artifact "midje", :group "midje", :version "1.6.3"} {:extension "jar", :file "midje.jar", :artifact "midje", :group "midje", :version "1.6.3"}]}

pull ^

[coords] [coords opts] [{:keys [loader], :as aether} coords {:keys [keep renew nodeps], :as opts}]
Added 3.0

resolves the coordinate from maven and loads dependency into classpath

v 3.0
(defn pull
  ([coords]
   (pull coords {}))
  ([coords opts]
   (pull (base/aether opts) coords opts))
  ([{:keys [loader] :as aether} coords {:keys [keep renew nodeps] :as opts}]
   (let [loader    (or loader (classloader/dynamic-classloader))
         coords    (if (or (not (vector? coords))
                           (artifact/coord? coords))
                     [coords]
                     coords)
         coords    (if-not renew (remove #(deps/loaded-artifact? % loader) coords))
         coords    (if nodeps
                     coords
                     (resolve-dependencies aether coords {:print {:hierarchy false}}))
         unloaded  (if-not keep (deps/unload coords loader :different))
         loaded    (deps/load coords loader)]
     {:artifacts coords
      :unloaded unloaded
      :loaded loaded})))
link
(pull '[[joda-time "2.9"]]) => (contains {:artifacts sequential? :unloaded sequential? :loaded sequential?})

push ^

[coords] [coords opts] [{:keys [loader], :as aether} coords {:keys [clean simulate nodeps], :as opts}]
Added 3.0

gets rid of a dependency that is not needed

v 3.0
(defn push
  ([coords]
   (push coords {}))
  ([coords opts]
   (push (base/aether) coords opts))
  ([{:keys [loader] :as aether} coords {:keys [clean simulate nodeps] :as opts}]
   (let [loader  (or loader classloader/+base+)
         coords    (if (or (not (vector? coords))
                           (artifact/coord? coords))
                     [coords]
                     coords)
         coords  (if nodeps
                   coords
                   (collect-dependencies aether coords {:return :resolved
                                                        :print {:hierarchy false}}))
         unloaded (if-not simulate (deps/unload coords loader :same))
         cleaned  (mapcat (fn [coord]
                            (case clean
                              :none     nil
                              :artifact (deps/clean coord (assoc opts :full false))
                              :full     (deps/clean coord (assoc opts :full true))
                              nil))
                          coords)]
     {:artifacts coords
      :unloaded unloaded
      :cleaned cleaned})))
link
(push '[[joda-time "2.9"]]) => (contains {:artifacts sequential? :unloaded sequential? :cleaned sequential?}) (pull '[[joda-time "2.10"]])

resolve-dependencies ^

[coords] [coords opts] [{:keys [system session repositories]} coords opts]
Added 3.0

resolves maven dependencies for a set of coordinates

v 3.0
(defn resolve-dependencies
  ([coords]
   (resolve-dependencies coords {}))
  ([coords opts]
   (resolve-dependencies (base/aether) coords opts))
  ([{:keys [^RepositorySystem system session repositories]} coords opts]
   (binding [listener/*progress* (atom [])
             listener/*pairs* (atom {})]
     (let [opts   (collection/merge-nested {:type :default
                                   :return :resolved
                                   :print {:hierarchy true
                                           :title true
                                           :timing true}}
                                  opts)
           reqm   (cond (and (sequential? coords)
                             (not (artifact/coord? coords)))
                        {:dependencies (mapv artifact->dependency coords)}

                        :else
                        {:root (artifact->dependency coords)})
           request (request/dependency-request
                    (assoc reqm :repositories repositories))]
       (if (-> opts :print :title)
         (print/print-title "RESOLVING DEPENDENCIES")
         (print/print "n"))
       (-> (.resolveDependencies system session request)
           (result/return-deps @listener/*progress* opts))))))
link
(resolve-dependencies '[prismatic/schema "1.1.3"] {:type :coord}) => '[[prismatic/schema "1.1.3"]] (vec (sort (resolve-dependencies '[midje "1.6.3"] {:type :coord}))) => '[[clj-time/clj-time "0.6.0"] [colorize/colorize "0.1.1"] [commons-codec/commons-codec "1.9"] [dynapath/dynapath "0.2.0"] [gui-diff/gui-diff "0.5.0"] [joda-time/joda-time "2.2"] [midje/midje "1.6.3"] [net.cgrand/parsley "0.9.1"] [net.cgrand/regex "1.1.0"] [ordered/ordered "1.2.0"] [org.clojars.trptcolin/sjacket "0.1.3"] [org.clojure/core.unify "0.5.2"] [org.clojure/math.combinatorics "0.0.7"] [org.clojure/tools.macro "0.1.5"] [org.clojure/tools.namespace "0.2.4"] [slingshot/slingshot "0.10.3"] [swiss-arrows/swiss-arrows "1.0.0"] [utilize/utilize "0.2.3"]]

resolve-versions ^

[coords] [coords opts] [{:keys [system session repositories]} coords opts]
Added 3.0

checks for given version of artifacts

v 3.0
(defn resolve-versions
  ([coords]
   (resolve-versions coords {}))
  ([coords opts]
   (resolve-versions (base/aether) coords opts))
  ([{:keys [^RepositorySystem system session repositories]} coords opts]
   (binding [listener/*progress* (atom [])
             listener/*pairs* (atom {})]
     (let [opts   (collection/merge-nested {:type :default
                                   :print {:title true
                                           :timing true}}
                                  opts)]
       (if (-> opts :print :title)
         (print/print-title "RESOLVE VERSIONS")
         (print/print "n"))
       (-> (keep (fn [coord]
                   (let [request (request/version-request {:artifact (artifact/artifact coord)
                                                           :repositories repositories})]
                     (try (.resolveVersion system session request)
                          (catch Throwable t
                            (print/println "Not Resolved:" coord)))))
                 coords)
           (result/return @listener/*progress* opts))))))
link
(resolve-versions '[[lein-monolith "LATEST"] [org.clojure/clojure "LATEST"]]) => (contains-in [{:group "lein-monolith", :artifact "lein-monolith", :version string?} {:group "org.clojure", :artifact "clojure", :version string?}])


+defaults+ ^

NONE
(defonce +defaults+)
link

aether ^

[] [config]
Added 3.0

creates an `Aether` object

v 3.0
(defn aether
  ([] (aether {}))
  ([config]
   (let [system  (system/repository-system)
         session (->> (select-keys config [:local-repo])
                      (session/session system))]
     (-> +defaults+
         (merge {:system system
                 :session session}
                (select-keys config [:repositories]))
         (map->Aether)))))
link
(aether) => (contains-in {:repositories (contains [{:id "clojars", :type "default", :url "https://clojars.org/repo"} {:id "central", :type "default", :url "https://repo1.maven.org/maven2/"}] :in-any-order :gaps-ok), :system org.eclipse.aether.RepositorySystem :session org.eclipse.aether.RepositorySystemSession})


+metadata-nature+ ^

NONE
(defonce +metadata-nature+ Metadata$Nature/RELEASE)
link

+metadata-type+ ^

NONE
(defonce +metadata-type+)
link

artifact-eclipse ^

[x] [_ x]
Added 3.0

creates an eclipse artifact

v 3.0
(invoke/definvoke artifact-eclipse
  [:method {:multi protocol.classloader/-artifact
            :val   :eclipse}]
  ([x]
   (artifact-eclipse nil x))
  ([_ x]
   (let [{:keys [group artifact classifier
                 extension version
                 properties file]}
         (artifact/rep x)]
     (DefaultArtifact. ^String group ^String artifact ^String classifier
                       ^String extension ^String version
                       ^java.util.Map properties
                       ^File (if file (java.io.File. (str file)))))))
link
(artifact-eclipse "hara:hara:jar:2.8.4") => DefaultArtifact

artifact-eclipse-metadata ^

[x] [_ x]
Added 3.0

creates an eclipse metadata instance

v 3.0
(invoke/definvoke artifact-eclipse-metadata
  [:method {:multi protocol.classloader/-artifact
            :val   :eclipse.metadata}]
  ([x]
   (artifact-eclipse-metadata nil x))
  ([_ x]
   (let [{:keys [group artifact classifier
                 extension version
                 properties file]}
         (artifact/rep x)]
     (DefaultMetadata. group artifact version +metadata-type+
                       +metadata-nature+ properties
                       (if file (java.io.File. (str file)))))))
link
(artifact-eclipse-metadata "hara:hara:jar:2.8.4") => DefaultMetadata

rep-eclipse ^

[artifact]
Added 3.0

creates a rep from eclipse artifact

v 3.0
(invoke/definvoke rep-eclipse
  [:method {:multi protocol.classloader/-rep
            :val   Artifact}]
  ([^Artifact artifact]
   (artifact/->Rep (.getGroupId artifact)
                   (.getArtifactId artifact)
                   (.getExtension artifact)
                   (.getClassifier artifact)
                   (.getVersion artifact)
                   (.getProperties artifact)
                   (str (.getFile artifact))
                   nil
                   nil)))
link
(str (rep-eclipse (object/from-data "hara:hara:2.8.4" DefaultArtifact))) => "hara:hara:jar:2.8.4"

rep-eclipse-metadata ^

[metadata]
Added 3.0

creates a rep from an eclipse metadata instance

v 3.0
(invoke/definvoke rep-eclipse-metadata
  [:method {:multi protocol.classloader/-rep
            :val   Metadata}]
  ([^Metadata metadata]
   (artifact/->Rep (.getGroupId metadata)
                   (.getArtifactId metadata)
                   nil
                   nil
                   (.getVersion metadata)
                   (.getProperties metadata)
                   (str (.getFile metadata))
                   nil
                   nil)))
link
(str (rep-eclipse-metadata (object/from-data "hara:hara:2.8.4" DefaultMetadata))) => "hara:hara:2.8.4"


artifact-exclusion ^

[x] [_ x]
Added 3.0

creates an artifact exclusion

v 3.0
(invoke/definvoke artifact-exclusion
  [:method {:multi protocol.classloader/-artifact
            :val   :eclipse.exclusion}]
  ([x]
   (artifact-exclusion nil x))
  ([_ x]
   (let [{:keys [group artifact classifier extension]}
         (jvm.artifact/rep x)]
     (Exclusion. group artifact classifier extension))))
link
(artifact-exclusion "hara:hara:jar:2.8.4") => Exclusion

artifact-map ^

NONE
(def artifact-map)
link

rep-exclusion ^

[exclusion]
Added 3.0

creates a rep from an exclusion

v 3.0
(invoke/definvoke rep-exclusion
  [:method {:multi protocol.classloader/-rep
            :val   Exclusion}]
  ([^Exclusion exclusion]
   (jvm.artifact/->Rep (.getGroupId exclusion)
                       (.getArtifactId exclusion)
                       (.getExtension exclusion)
                       (.getClassifier exclusion)
                       nil
                       nil
                       nil
                       nil
                       nil)))
link
(str (rep-exclusion (artifact-exclusion "hara:hara"))) => "hara:hara:jar:"


+default-local-repo+ ^

NONE
(defonce +default-local-repo+
  (-> (System/getProperty "user.home")
      (fs/path ".m2" "repository")
      (str)))
link

local-repo ^

[] [path]
Added 3.0

creates a `LocalRepository` from a string

v 3.0
(defn local-repo
  ([]
   (local-repo +default-local-repo+))
  ([^String path]
   (LocalRepository. path)))
link
(local-repo) => LocalRepository ;; #local "<.m2/repository>" ;; hooks into std.object (-> (local-repo "/tmp") (object/to-data)) => "/tmp"




    artifact-request ^

    [{:keys [artifact repositories], :as m}]
    Added 3.0

    creates an `ArtifactRequest` object from map

    v 3.0
    (defn artifact-request
      ([{:keys [artifact repositories] :as m}]
       (object/from-data {:artifact artifact
                          :repositories repositories}
                         ArtifactRequest)))
    link
    (artifact-request {:artifact "hara:hara:2.4.8" :repositories [{:id "clojars" :authentication {:username "zcaudate" :password "hello"} :url "https://clojars.org/repo/"}]}) => (partial instance? ArtifactRequest) ;;=> #req.artifact{:artifact "hara:hara:jar:2.4.8", ;; :repositories [{:id "clojars", ;; :url "https://clojars.org/repo/" ;; :authentication {:username "zcaudate", :password "hello"}}], ;; :request-context ""}

    collect-map ^

    NONE
    (def collect-map)
    link

    collect-request ^

    [{:keys [root repositories dependencies], :as m}]
    Added 3.0

    creates a `CollectRequest` object from map

    v 3.0
    (defn collect-request
      ([{:keys [root repositories dependencies] :as m}]
       (object/from-data {:root root
                          :dependencies dependencies
                          :repositories repositories}
                         CollectRequest)))
    link
    (collect-request {:root {:artifact "hara:hara:2.4.8"} :repositories [{:id "clojars" :url "https://clojars.org/repo/"}]}) => (partial instance? CollectRequest) ;;=> #req.collect{:root {:artifact "hara:hara:jar:2.4.8", ;; :exclusions [], ;; :optional false, ;; :scope "", ;; :optional? false} ;; :repositories [{:id "clojars", ;; :url "https://clojars.org/repo/"}]}

    dependency-request ^

    [{:keys [root dependencies repositories], :as m}]
    Added 3.0

    creates a `DependencyRequest` object from map

    v 3.0
    (defn dependency-request
      ([{:keys [root dependencies repositories] :as m}]
       (object/from-data {:root root
                          :dependencies dependencies
                          :repositories repositories}
                         DependencyRequest)))
    link
    (dependency-request {:root {:artifact "hara:hara:2.4.8"} :repositories [{:id "clojars" :url "https://clojars.org/repo/"}]}) => (partial instance? DependencyRequest) ;;=> #req.dependency{:root {:artifact "hara:hara:jar:2.4.8", ;; :exclusions [], ;; :optional false, ;; :scope "", ;; :optional? false} ;; :repositories [{:id "clojars", ;; :url "https://clojars.org/repo/"}]}

    deploy-map ^

    NONE
    (def deploy-map)
    link

    deploy-request ^

    [{:keys [artifacts repository], :as m}]
    Added 3.0

    creates a `DeployRequest` object from map

    v 3.0
    (defn deploy-request
      ([{:keys [artifacts repository] :as m}]
       (env/do:prn
        (object/from-data {:artifacts artifacts
                           :repository repository}
                          DeployRequest))))
    link
    (deploy-request {:artifacts [{:group "hara" :artifact "std.string" :version "2.4.8" :extension "jar" :file "hara-string.jar"}] :repository {:id "clojars" :url "https://clojars.org/repo/" :authentication {:username "zcaudate" :password "hello"}}}) => (partial instance? DeployRequest) ;;=> #req.deploy{:artifacts ["hara:std.string:jar:2.4.8"] ;; :repository {:id "clojars", ;; :authentication {:username "zcaudate", :password "hello"} ;; :url "https://clojars.org/repo/"}}

    install-map ^

    NONE
    (def install-map)
    link

    install-request ^

    [{:keys [artifacts], :as m}]
    Added 3.0

    creates a `InstallRequest` object from map

    v 3.0
    (defn install-request
      ([{:keys [artifacts] :as m}]
       (object/from-data {:artifacts artifacts}
                         InstallRequest)))
    link
    (install-request {:artifacts [{:group "hara" :artifact "std.string" :version "2.4.8" :extension "jar" :file "hara-string.jar"} {:group "hara" :artifact "std.string" :version "2.4.8" :extension "pom" :file "hara-string.pom"}]}) => (partial instance? InstallRequest) ;;=> #req.install{:artifacts ["hara:std.string:jar:2.4.8" ;; "hara:std.string:pom:2.4.8"] ;; :metadata []}

    metadata-request ^

    [{:keys [metadata repository], :as m}]
    Added 3.0

    constructs a metadat request

    v 3.0
    (defn metadata-request
      ([{:keys [metadata repository] :as m}]
       (object/from-data {:metadata metadata
                          :repository repository}
                         MetadataRequest)))
    link
    (metadata-request {:metadata {:group "hara" :artifact "std.string" :version "2.4.8"} :repository {:id "clojars" :url "https://clojars.org/repo/" :authentication {:username "zcaudate" :password "hello"}}}) => (partial instance? org.eclipse.aether.resolution.MetadataRequest)

    range-request ^

    [{:keys [artifact repositories], :as m}]
    Added 3.0

    constructs a range request

    v 3.0
    (defn range-request
      ([{:keys [artifact repositories] :as m}]
       (object/from-data {:artifact artifact
                          :repositories repositories}
                         VersionRangeRequest)))
    link
    (range-request {:artifact {:group "hara" :artifact "std.string" :version "2.4.8"} :repositories [{:id "clojars" :url "https://clojars.org/repo/" :authentication {:username "zcaudate" :password "hello"}}]}) => (partial instance? org.eclipse.aether.resolution.VersionRangeRequest)

    version-request ^

    [{:keys [artifact repositories], :as m}]
    Added 3.0

    constructs a version request

    v 3.0
    (defn version-request
      ([{:keys [artifact repositories] :as m}]
       (object/from-data {:artifact artifact
                          :repositories repositories}
                         VersionRequest)))
    link
    (version-request {:artifact {:group "hara" :artifact "std.string" :version "2.4.8"} :repositories [{:id "clojars" :url "https://clojars.org/repo/" :authentication {:username "zcaudate" :password "hello"}}]}) => (partial instance? org.eclipse.aether.resolution.VersionRequest)


    clojure-core? ^

    [node]
    Added 3.0

    checks if artifact represents clojure.core

    v 3.0
    (defn clojure-core?
      ([node]
       (let [{:keys [group artifact]} (jvm.artifact/artifact node)]
         (and (= group "org.clojure")
              (= artifact "clojure")))))
    link
    (clojure-core? '[org.clojure/clojure "1.2.0"]) => true

    dependency-graph ^

    [node] [node type] [node type pred]
    Added 3.0

    creates a dependency graph for the results

    v 3.0
    (defn dependency-graph
      ([node]
       (dependency-graph node
                         :default))
      ([node type]
       (dependency-graph node
                         (or type :default)
                         (comp not clojure-core?)))
      ([^DependencyNode node type pred]
       (let [artifact (.getArtifact node)
             artifact (if artifact
                        (jvm.artifact/artifact type artifact))
             children (->> (.getChildren node)
                           (filter (fn [^DependencyNode child]
                                     (-> child (.getArtifact) pred))))]
         (apply vector artifact (mapv #(dependency-graph % type pred) children)))))
    link
    (let [node (doto (DefaultDependencyNode. (DefaultArtifact. "g:a:1.0")) (.setChildren [(DefaultDependencyNode. (DefaultArtifact. "g:b:1.0"))]))] (dependency-graph node :coord)) => ['[g/a "1.0"] ['[g/b "1.0"]]]

    flatten-tree ^

    [x]
    Added 3.0

    converts a tree structure into a vector

    v 3.0
    (defn flatten-tree
      ([x]
       (let [arr? (fn [x] (and (sequential? x)
                               (not (jvm.artifact/coord? x))))]
         (filter (complement arr?)
                 (rest (tree-seq arr? seq x))))))
    link
    (flatten-tree '[[a "1.1"] [[b "1.1"] [[c "1.1"] [d "1.1"]]]]) => '[[a "1.1"] [b "1.1"] [c "1.1"] [d "1.1"]]

    print-tree ^

    [tree]
    Added 3.0

    prints a tree structure

    v 3.0
    (defn print-tree
      ([tree]
       (print/print-tree-graph tree;; "" jvm.artifact/coord?
                               )))
    link
    (-> (print-tree '[[a "1.1"] [[b "1.1"] [[c "1.1"] [d "1.1"]]]]) (with-out-str)) => string?

    prioritise ^

    [results] [results type]
    Added 3.0

    gives the higher version library more priority

    v 3.0
    (defn prioritise
      ([results]
       (prioritise results :default))
      ([results type]
       (->> (reduce (fn [out {:keys [group artifact version] :as result}]
                      (if-let [current (get-in out [group artifact])]
                        (if (version/newer? version (:version current))
                          (assoc-in out [group artifact] result)
                          out)
                        (assoc-in out [group artifact] result)))
                    {}
                    (map jvm.artifact/artifact results))
            (vals)
            (mapcat vals)
            (remove clojure-core?)
            (mapv #(jvm.artifact/artifact type %)))))
    link
    (prioritise '[[a "3.0"] [a "1.2"] [a "1.1"]] :coord) => '[[a/a "3.0"]]

    return ^

    [result events {:keys [return print type], :as opts}]
    Added 3.0

    returns a summary of install and deploy results

    v 3.0
    (defn return
      ([result events {:keys [return print type] :as  opts}]
       (let [output (->> (summary result opts)
                         (filterv identity))]
         (print/print "n")
         (when (:timing print)
           (print/print-subtitle
            (if-not (empty? events)
              (format "TIME (%.2fs, %d events)"
                      (/ (- (:time (last events))
                            (:time (first events)))
                         1000.0)
                      (count events))
              "(DONE)")))
         output)))
    link
    (return [] [] {:return :default}) => []

    return-deps ^

    [result events {:keys [return print type], :as opts}]
    Added 3.0

    returns a summary of resolve and collect results

    v 3.0
    (defn return-deps
      ([result events {:keys [return print type] :as  opts}]
       (let [output (->> (summary result opts)
                         (filterv identity))]
         (print/print "n")
         (if (:timing print)
           (print/print-subtitle
            (if-not (empty? events)
              (format "TIME (%.2fs, %d events)"
                      (/ (- (:time (last events))
                            (:time (first events)))
                         1000.0)
                      (count events))
              "(DONE)")))
    
         (when (:hierarchy print)
           (print/println "")
           (print-tree output))
    
         (case return
           :hierarchy output
           :resolved (prioritise (flatten-tree output) type)))))
    link
    (return-deps [] [] {:return :resolved}) => []

    summary ^

    Added 3.0

    creates a summary for the different types of results

    v 3.0
    (defmulti summary
      (fn [result opts] (type result)))
    link
    (summary [] {}) => []


    session ^

    [system {:keys [local-repo listeners], :as opts}]
    Added 3.0

    creates a session from a system:

    v 3.0
    (defn session
      ([^RepositorySystem system {:keys [local-repo listeners] :as opts}]
       (let [session (doto (MavenRepositorySystemUtils/newSession)
                       (.setConfigProperty ConflictResolver/CONFIG_PROP_VERBOSE true)
                       (.setConfigProperty DependencyManagerUtils/CONFIG_PROP_VERBOSE true)
                       (.setRepositoryListener (or (:repository listeners)
                                                   listener/+default-repository-listener+))
                       (.setTransferListener   (or (:transfer listeners)
                                                   listener/blank-transfer-listener)))
             manager (.newLocalRepositoryManager system
                                                 session
                                                 (-> (or local-repo local/+default-local-repo+)
                                                     (local/local-repo)))
             _ (.setLocalRepositoryManager session manager)]
         session)))
    link
    (session (system/repository-system) {}) => org.eclipse.aether.RepositorySystemSession