Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Merge pull request #57 from hugoduncan/feature/add-resolve-artifacts

Add resolve-artifacts to resolve non-transitively
  • Loading branch information...
commit bb3770fb466d93c9b8c8401de753f68258e50f15 2 parents 147325f + b1e5116
Chas Emerick authored May 02, 2013
137  src/main/clojure/cemerick/pomegranate/aether.clj
@@ -16,7 +16,8 @@
16 16
            (org.sonatype.aether.util.repository DefaultProxySelector DefaultMirrorSelector)
17 17
            (org.sonatype.aether.graph Dependency Exclusion DependencyNode)
18 18
            (org.sonatype.aether.collection CollectRequest)
19  
-           (org.sonatype.aether.resolution DependencyRequest ArtifactRequest)
  19
+           (org.sonatype.aether.resolution DependencyRequest ArtifactRequest
  20
+                                           ArtifactResult VersionRequest)
20 21
            (org.sonatype.aether.util.graph PreorderNodeListGenerator)
21 22
            (org.sonatype.aether.util.artifact DefaultArtifact SubArtifact
22 23
                                               ArtifactProperties)
@@ -211,13 +212,17 @@
211 212
     [spec]
212 213
     spec))
213 214
 
  215
+(defn- artifact
  216
+  [[group-artifact version & {:keys [scope optional exclusions]} :as dep-spec]]
  217
+  (DefaultArtifact. (coordinate-string dep-spec)))
  218
+
214 219
 (defn- dependency
215 220
   [[group-artifact version & {:keys [scope optional exclusions]
216 221
                               :as opts
217 222
                               :or {scope "compile"
218 223
                                    optional false}}
219 224
     :as dep-spec]]
220  
-  (Dependency. (DefaultArtifact. (coordinate-string dep-spec))
  225
+  (Dependency. (artifact dep-spec)
221 226
                scope
222 227
                optional
223 228
                (map (comp exclusion normalize-exclusion-spec) exclusions)))
@@ -481,6 +486,134 @@ kwarg to the repository kwarg.
481 486
           (.setRepositoryManager (boolean repo-manager))
482 487
           (.setContentType (or content-type "default"))))))))
483 488
 
  489
+(defn resolve-artifacts*
  490
+  "Resolves artifacts for the coordinates kwarg, using repositories from the
  491
+   `:repositories` kwarg.
  492
+
  493
+   Retrieval of dependencies can be disabled by providing `:retrieve false` as a
  494
+   kwarg.
  495
+
  496
+   Returns an sequence of either `org.sonatype.aether.VersionResult`
  497
+   if `:retrieve false`, or `org.sonatype.aether.ArtifactResult` if
  498
+   `:retrieve true` (the default).
  499
+
  500
+   If you don't want to mess with the Aether implementation classes, then use
  501
+   `resolve-artifacts` instead.
  502
+
  503
+    :coordinates - [[group/name \"version\" & settings] ..]
  504
+      settings:
  505
+      :extension  - the maven extension (type) to require
  506
+      :classifier - the maven classifier to require
  507
+      :scope      - the maven scope for the dependency (default \"compile\")
  508
+      :optional   - is the dependency optional? (default \"false\")
  509
+      :exclusions - which sub-dependencies to skip : [group/name & settings]
  510
+        settings:
  511
+        :classifier (default \"*\")
  512
+        :extension  (default \"*\")
  513
+
  514
+    :repositories - {name url ..} | {name settings ..}
  515
+      (defaults to {\"central\" \"http://repo1.maven.org/maven2/\"}
  516
+      settings:
  517
+      :url - URL of the repository
  518
+      :snapshots - use snapshots versions? (default true)
  519
+      :releases - use release versions? (default true)
  520
+      :username - username to log in with
  521
+      :password - password to log in with
  522
+      :passphrase - passphrase to log in wth
  523
+      :private-key-file - private key file to log in with
  524
+      :update - :daily (default) | :always | :never
  525
+      :checksum - :fail (default) | :ignore | :warn
  526
+
  527
+    :local-repo - path to the local repository (defaults to ~/.m2/repository)
  528
+    :offline? - if true, no remote repositories will be contacted
  529
+    :transfer-listener - the transfer listener that will be notifed of dependency
  530
+      resolution and deployment events.
  531
+      Can be:
  532
+        - nil (the default), i.e. no notification of events
  533
+        - :stdout, corresponding to a default listener implementation that writes
  534
+            notifications and progress indicators to stdout, suitable for an
  535
+            interactive console program
  536
+        - a function of one argument, which will be called with a map derived from
  537
+            each event.
  538
+        - an instance of org.sonatype.aether.transfer.TransferListener
  539
+
  540
+    :proxy - proxy configuration, can be nil, the host scheme and type must match
  541
+      :host - proxy hostname
  542
+      :type - http  (default) | http | https
  543
+      :port - proxy port
  544
+      :non-proxy-hosts - The list of hosts to exclude from proxying, may be null
  545
+      :username - username to log in with, may be null
  546
+      :password - password to log in with, may be null
  547
+      :passphrase - passphrase to log in wth, may be null
  548
+      :private-key-file - private key file to log in with, may be null
  549
+
  550
+    :mirrors - {matches settings ..}
  551
+      matches - a string or regex that will be used to match the mirror to
  552
+                candidate repositories. Attempts will be made to match the
  553
+                string/regex to repository names and URLs, with exact string
  554
+                matches preferred. Wildcard mirrors can be specified with
  555
+                a match-all regex such as #\".+\".  Excluding a repository
  556
+                from mirroring can be done by mapping a string or regex matching
  557
+                the repository in question to nil.
  558
+      settings include these keys, and all those supported by :repositories:
  559
+      :name         - name/id of the mirror
  560
+      :repo-manager - whether the mirror is a repository manager"
  561
+
  562
+  [& {:keys [repositories coordinates files retrieve local-repo
  563
+             transfer-listener offline? proxy mirrors repository-session-fn]
  564
+      :or {retrieve true}}]
  565
+  (let [repositories (or repositories maven-central)
  566
+        system (repository-system)
  567
+        mirror-selector-fn (memoize (partial mirror-selector-fn mirrors))
  568
+        mirror-selector (mirror-selector mirror-selector-fn proxy)
  569
+        session ((or repository-session-fn
  570
+                     repository-session)
  571
+                 {:repository-system system
  572
+                  :local-repo local-repo
  573
+                  :offline? offline?
  574
+                  :transfer-listener transfer-listener
  575
+                  :mirror-selector mirror-selector})
  576
+        deps (->> coordinates
  577
+                  (map #(if-let [local-file (get files %)]
  578
+                          (.setArtifact
  579
+                           (artifact %)
  580
+                           (-> (artifact %)
  581
+                               .getArtifact
  582
+                               (.setProperties
  583
+                                {ArtifactProperties/LOCAL_PATH
  584
+                                 (.getPath (io/file local-file))})))
  585
+                          (artifact %)))
  586
+                  vec)
  587
+        repositories (vec (map #(let [repo (make-repository % proxy)]
  588
+                                  (-> session
  589
+                                      (.getMirrorSelector)
  590
+                                      (.getMirror repo)
  591
+                                      (or repo)))
  592
+                               repositories))]
  593
+    (if retrieve
  594
+      (.resolveArtifacts
  595
+       system session (map #(ArtifactRequest. % repositories nil) deps))
  596
+      (doall
  597
+       (for [dep deps]
  598
+         (.resolveVersion
  599
+          system session (VersionRequest. dep repositories nil)))))))
  600
+
  601
+(defn resolve-artifacts
  602
+  "Same as `resolve-artifacts*`, but returns a sequence of dependencies; each
  603
+   artifact's metadata contains the source Aether result object, and the
  604
+   artifact's :file on disk."
  605
+  [& args]
  606
+  (let [{:keys [coordinates]} (apply hash-map args)]
  607
+    (->> (apply resolve-artifacts* args)
  608
+         (map
  609
+          (fn [coord result]
  610
+            {:pre [coord result]}
  611
+            (let [m (when (instance? ArtifactResult result)
  612
+                      {:file (.. ^ArtifactResult result getArtifact getFile)})]
  613
+              (with-meta coord
  614
+                (merge {:result result} m))))
  615
+          coordinates))))
  616
+
484 617
 (defn resolve-dependencies*
485 618
   "Collects dependencies for the coordinates kwarg, using repositories from the
486 619
    `:repositories` kwarg.
18  src/test/clojure/cemerick/pomegranate/aether_test.clj
@@ -52,14 +52,28 @@
52 52
                      [logkit "1.0.1"] nil}}]
53 53
     (is (= graph (aether/resolve-dependencies :coordinates deps :retrieve false :local-repo tmp-local-repo-dir)))
54 54
     (is (not (some #(-> % .getName (.endsWith ".jar")) (file-seq tmp-local-repo-dir))))
55  
-    
  55
+
56 56
     (doseq [[dep _] (aether/resolve-dependencies :coordinates deps :local-repo tmp-local-repo-dir)]
57 57
       (is (-> dep meta :file))
58 58
       (is (-> dep meta :file .exists)))
59 59
     (is (some #(-> % .getName (.endsWith ".jar")) (file-seq tmp-local-repo-dir)))
60  
-    
  60
+
61 61
     (is (= hierarchy (aether/dependency-hierarchy deps graph)))))
62 62
 
  63
+(deftest live-artifact-resolution
  64
+  (let [deps '[[commons-logging "1.1"]]]
  65
+    (is (= deps (aether/resolve-artifacts
  66
+                 :coordinates deps :retrieve false
  67
+                 :local-repo tmp-local-repo-dir)))
  68
+    (is (not (some #(-> % .getName (.endsWith ".jar"))
  69
+                   (file-seq tmp-local-repo-dir))))
  70
+    (doseq [dep (aether/resolve-artifacts
  71
+                     :coordinates deps :local-repo tmp-local-repo-dir)]
  72
+      (is (-> dep meta :file))
  73
+      (is (-> dep meta :file .exists)))
  74
+    (is (some #(-> % .getName (.endsWith ".jar"))
  75
+              (file-seq tmp-local-repo-dir)))))
  76
+
63 77
 (deftest impl-detail-types
64 78
   (let [args [:coordinates '[[commons-logging "1.1"]] :local-repo tmp-local-repo-dir]]
65 79
     (is (instance? org.sonatype.aether.resolution.DependencyResult

0 notes on commit bb3770f

Please sign in to comment.
Something went wrong with that request. Please try again.