pax_global_header00006660000000000000000000000064133547344440014525gustar00rootroot0000000000000052 comment=14f2f2517553223344a6913fe59f02847fe9f060 pomegranate-14f2f2517553223344a6913fe59f02847fe9f060/000077500000000000000000000000001335473444400204015ustar00rootroot00000000000000pomegranate-14f2f2517553223344a6913fe59f02847fe9f060/.gitignore000066400000000000000000000002331335473444400223670ustar00rootroot00000000000000# emacs + vi backup files *~ .*.sw* # various IDE junk *.ipr *.iml *.iws .project .classpath .settings target classes it-repo tmp .externalToolBuilders pomegranate-14f2f2517553223344a6913fe59f02847fe9f060/.travis.yml000066400000000000000000000002011335473444400225030ustar00rootroot00000000000000language: clojure install: mvn install --quiet -DskipTests=true script: mvn test jdk: - openjdk7 - oraclejdk8 - oraclejdk9 pomegranate-14f2f2517553223344a6913fe59f02847fe9f060/CHANGES.md000066400000000000000000000056251335473444400220030ustar00rootroot00000000000000## [Pomegranate](http://github.com/cemerick/pomegranate) changelog ### [`1.1.0`](https://github.com/cemerick/pomegranate/milestone/9?closed=1) * Upgrade Maven Resolver dependencies (gh-103) ### [`1.0.0`](https://github.com/cemerick/pomegranate/milestone/8?closed=1) * Ensures JDK 9 compatibility via dynapath 1.0.0; a non-trivial breaking change given the effect of the change there to avoid JDK 9's warnings re: reflective calls into non-public methods, etc (`URLClassLoader`s are no longer modifiable by default) (gh-92) ### [`0.4.0`](https://github.com/cemerick/pomegranate/issues?q=milestone%3A0.4.0+is%3Aclosed) * Non-TLS HTTP repositories are unsupported; using a "bare" HTTP repository now requires registering a "wagon" for the insecure transport method (gh-83) * Switched/upgraded from Sonatype Aether to Maven-resolver (gh-80) * Upgraded to Maven `3.5.0` (gh-83) * `add-dependencies` now allows you to specify which `ClassLoader` to modify (gh-63) * Repository names can now be any `Named` value (strings, keywords, or symbols) (gh-84) * Some previously-internal functions are now marked as public: `merge-versions-from-managed-coords` (gh-74), and `dependency` and `make-repository` (gh-69) ### [`0.3.1`](https://github.com/cemerick/pomegranate/issues?q=milestone%3A0.3.1+is%3Aclosed) * Add support for "managed" dependencies in `resolve-dependencies` (gh-72) ### [`0.3.0`](https://github.com/cemerick/pomegranate/issues?milestone=5&page=1&state=closed) * Added `cemerick.pomegranate.aether/resolve-artifacts`, which allows for the resolution of a sequence of artifacts, without doing transitive resolution on their dependencies. (gh-57) * Provide an error if a registered wagon factory fails to instantiate (gh-58) ### `0.2.0` _This release contains breaking changes from `0.1.3`_, though it's expected that the affected APIs are rarely used. **Dynamic classpath support (`cemerick.pomegranate`)** * The `URLClasspath` protocol has been removed in favor of using [dynapath](https://github.com/tobias/dynapath/)'s `DynamicClasspath` protocol. (gh-43) *breaking change* * `classloader-hierarchy` now starts at the current thread context classloader instead of Clojure's "baseLoader". *breaking change* * New `resources` and `classloader-resources` fns for determining from which classloader(s) a given resource is available (gh-48) **Aether API (`cemerick.pomegranate.aether` and friends)** * `install-artifacts` and `deploy-artifacts` are now generalized to operate over multiple files (vs. the prior assumptions re: an artifact + a POM) (gh-52) * `resolve-dependencies*` now available that returns the bare Aether results of dependency resolution, _sans_ Clojure-friendly graphification (gh-50) * `resolve-dependencies`, `install-artifacts`, and `deploy-artifacts` now accept an optional `:repository-session-fn` to potentially modify the Aether `RespositorySystemSession` prior to its use (gh-56) pomegranate-14f2f2517553223344a6913fe59f02847fe9f060/README.md000066400000000000000000000132471335473444400216670ustar00rootroot00000000000000# Pomegranate [![Travis CI status](https://secure.travis-ci.org/cemerick/pomegranate.png)](https://travis-ci.org/cemerick/pomegranate/builds) [Pomegranate](https://github.com/cemerick/pomegranate) is a library that provides: 1. A sane Clojure API for [Maven-resolver](https://maven.apache.org/resolver/) (originally called Aether). 2. A re-implementation of [`add-classpath`](https://clojure.github.com/clojure/clojure.core-api.html#clojure.core/add-classpath) (deprecated in Clojure core) that: * is a little more comprehensive than core's `add-classpath` — it should work as expected in more circumstances, and * optionally uses Maven-resolver to add a Maven artifact (and all of its transitive dependencies) to your Clojure runtime's classpath dynamically. Insofar as most useful Clojure libraries have dependencies, any reasonable implementation of the `add-classpath` concept must seamlessly support resolving those dependencies IMO. ## "Installation" Pomegranate is available in Maven central. Add it to your Leiningen `project.clj`: ```clojure [com.cemerick/pomegranate "1.1.0"] ``` or to your Maven project's `pom.xml`: ```xml com.cemerick pomegranate 1.1.0 ``` ## `add-classpath` usage Just to set a stage: you're at the REPL, and you've got some useful data that you'd like to munge and analyze in various ways. Maybe it's something you've generated locally, maybe it's data on a production machine and you're logged in via [nREPL](https://github.com/clojure/tools.nrepl). In any case, you'd like to work with the data, but realize that you don't have the libraries you need do what you want. Your choices at this point are: 1. Dump the data to disk via `pr` (assuming it's just Clojure data structures!), and start up a new Clojure process with the appropriate libraries on the classpath. This can really suck if the data is in a remote environment. 2. There is no second choice. You _could_ use `add-claspath`, but the library you want has 12 bajillion dependencies, and there's no way you're going to hunt them down manually. Let's say we want to use [Incanter](https://github.com/liebke/incanter) (which has roughly 40 dependencies — far too many for us to reasonably locate and add via `add-classpath` manually): ```clojure => (require '(incanter core stats charts)) # ``` Looks bleak. Assuming you've got Pomegranate on your classpath already, you can do this though: ```clojure => (use '[cemerick.pomegranate :only (add-dependencies)]) nil => (add-dependencies :coordinates '[[incanter "1.2.3"]] :repositories (merge cemerick.pomegranate.aether/maven-central {"clojars" "https://clojars.org/repo"})) ;...add-dependencies returns full dependency graph... => (require '(incanter core stats charts)) nil ``` Now you can analyze and chart away, Incanter having been added to your runtime. Note that `add-dependencies` may crunch along for a while — it may need to download dependencies, so you're waiting on the network. All resolved dependencies are stored in the default local repository (`~/.m2/repository`), and if they are found there, then they are not downloaded. The arguments to `add-dependencies` look like Leiningen-style notation, and they are. Please note that **there are a number of scenarios in which `add-dependencies` will not work, or will not work as you'd expect**. Many of these are due to the nature of JVM classloaders (e.g. adding jars containing conflicting versions of a particular dependency will rarely end well), which Pomegranate does not currently attempt to hide. Thus, `add-classpath` and `add-dependencies` should be considered escape hatches to be used when necessary, rather than a regular part of your development workflow. #### `URLClassLoader` modifiability Starting with pomegranate `1.0.0`, `java.net.URLClassLoader`s are not modifiable by default. This is to accommodate new reflection policy starting with JDK 9 (which currently issues an ugly warning on reflective access to non-public methods, but future releases will simply fail). If you are in a situation where you are using pomegranate but do not have a `clojure.lang.DynamicClassLoader` visible in your classloader hierarchy, you will need to explicitly enable the `java.net.URLClassLoader` support in [dynapath](https://github.com/tobias/dynapath) (upon which pomegranate relies for such things). ## Status of Aether support Pomegranate is being used by [Leiningen v2.x](https://leiningen.org) as its sole dependency resolution library. This has prompted rapid maturation of the scope and quality of Aether support. That said, specific API points remain subject to change as we find the right abstractions and conventions. #### Supported features * dependency resolution * common dependency graph/hierarchy manipulation ops * local installation * remote deployment * repository authentication for all of the above * HTTP proxy configuration * offline mode * transfer listeners (with a sane Clojure fn veneer) #### Not there yet * repository listeners * options to retrieve a single artifact (e.g. for obtaining source/javadoc) * tests; there's halfway decent coverage, but nowhere near the kind of comprehensive combinatorial testing that maven dependency resolution demands ## Changelog See the `CHANGES.md` file at the top level of the repo. ## License Copyright © 2011-2017 [Chas Emerick](https://cemerick.com) and all other contributors. Licensed under the EPL. (See the file epl-v10.html.) pomegranate-14f2f2517553223344a6913fe59f02847fe9f060/epl-v10.html000066400000000000000000000311631335473444400224570ustar00rootroot00000000000000 Eclipse Public License - Version 1.0

Eclipse Public License - v 1.0

THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT.

1. DEFINITIONS

"Contribution" means:

a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and

b) in the case of each subsequent Contributor:

i) changes to the Program, and

ii) additions to the Program;

where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program.

"Contributor" means any person or entity that distributes the Program.

"Licensed Patents" mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program.

"Program" means the Contributions distributed in accordance with this Agreement.

"Recipient" means anyone who receives the Program under this Agreement, including all Contributors.

2. GRANT OF RIGHTS

a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form.

b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder.

c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program.

d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement.

3. REQUIREMENTS

A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that:

a) it complies with the terms and conditions of this Agreement; and

b) its license agreement:

i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose;

ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits;

iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and

iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange.

When the Program is made available in source code form:

a) it must be made available under this Agreement; and

b) a copy of this Agreement must be included with each copy of the Program.

Contributors may not remove or alter any copyright notices contained within the Program.

Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution.

4. COMMERCIAL DISTRIBUTION

Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense.

For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages.

5. NO WARRANTY

EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement , including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations.

6. DISCLAIMER OF LIABILITY

EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.

7. GENERAL

If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable.

If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed.

All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive.

Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. The Eclipse Foundation is the initial Agreement Steward. The Eclipse Foundation may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved.

This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation.

pomegranate-14f2f2517553223344a6913fe59f02847fe9f060/pom.xml000066400000000000000000000076061335473444400217270ustar00rootroot00000000000000 4.0.0 com.cemerick pomegranate 1.1.0 pomegranate http://github.com/cemerick/pomegranate org.clojure pom.contrib 0.0.20 Chas Emerick http://cemerick.com cemerick@snowtide.com -5 scm:git:git@github.com:cemerick/pomegranate.git scm:git:git@github.com:cemerick/pomegranate.git git@github.com:cemerick/pomegranate.git 1.3.0 3.5.3 1.0.3 3.0.0 org.apache.maven maven-resolver-provider ${mavenVersion} org.apache.maven.resolver maven-resolver-transport-file ${resolverVersion} org.apache.maven.resolver maven-resolver-transport-http ${resolverVersion} org.apache.maven.resolver maven-resolver-transport-wagon ${resolverVersion} org.apache.maven.resolver maven-resolver-connector-basic ${resolverVersion} org.tcrawley dynapath 1.0.0 org.apache.maven.wagon wagon-provider-api ${wagonVersion} org.apache.maven.wagon wagon-http ${wagonVersion} org.apache.maven.wagon wagon-ssh ${wagonVersion} true org.apache.httpcomponents httpclient 4.5.3 org.slf4j slf4j-simple 1.7.22 test src/main/clojure pomegranate-14f2f2517553223344a6913fe59f02847fe9f060/src/000077500000000000000000000000001335473444400211705ustar00rootroot00000000000000pomegranate-14f2f2517553223344a6913fe59f02847fe9f060/src/main/000077500000000000000000000000001335473444400221145ustar00rootroot00000000000000pomegranate-14f2f2517553223344a6913fe59f02847fe9f060/src/main/clojure/000077500000000000000000000000001335473444400235575ustar00rootroot00000000000000pomegranate-14f2f2517553223344a6913fe59f02847fe9f060/src/main/clojure/cemerick/000077500000000000000000000000001335473444400253415ustar00rootroot00000000000000pomegranate-14f2f2517553223344a6913fe59f02847fe9f060/src/main/clojure/cemerick/pomegranate.clj000066400000000000000000000127411335473444400303420ustar00rootroot00000000000000(ns cemerick.pomegranate (:import (clojure.lang DynamicClassLoader) (java.net URL URLClassLoader)) (:require [clojure.java.io :as io] [cemerick.pomegranate.aether :as aether] [dynapath.util :as dp]) (:refer-clojure :exclude (add-classpath))) ;; call-method pulled from clojure.contrib.reflect, (c) 2010 Stuart Halloway & Contributors (defn- call-method "Calls a private or protected method. params is a vector of classes which correspond to the arguments to the method e obj is nil for static methods, the instance object otherwise. The method-name is given a symbol or a keyword (something Named)." [klass method-name params obj & args] (-> klass (.getDeclaredMethod (name method-name) (into-array Class params)) (doto (.setAccessible true)) (.invoke obj (into-array Object args)))) (defn classloader-hierarchy "Returns a seq of classloaders, with the tip of the hierarchy first. Uses the current thread context ClassLoader as the tip ClassLoader if one is not provided." ([] (classloader-hierarchy (.. Thread currentThread getContextClassLoader))) ([tip] (->> tip (iterate #(.getParent %)) (take-while boolean)))) (defn modifiable-classloader? "Returns true iff the given ClassLoader is of a type that satisfies the dynapath.dynamic-classpath/DynamicClasspath protocol, and it can be modified." [cl] (dp/addable-classpath? cl)) (defn add-classpath "A corollary to the (deprecated) `add-classpath` in clojure.core. This implementation requires a java.io.File or String path to a jar file or directory, and will attempt to add that path to the right classloader (with the search rooted at the current thread's context classloader)." ([jar-or-dir classloader] (if-not (dp/add-classpath-url classloader (.toURL (.toURI (io/file jar-or-dir)))) (throw (IllegalStateException. (str classloader " is not a modifiable classloader"))))) ([jar-or-dir] (let [classloaders (classloader-hierarchy)] (if-let [cl (last (filter modifiable-classloader? classloaders))] (add-classpath jar-or-dir cl) (throw (IllegalStateException. (str "Could not find a suitable classloader to modify from " classloaders))))))) (defn add-dependencies "Resolves a set of dependencies, optionally against a set of additional Maven repositories, and adds all of the resulting artifacts (jar files) to the current runtime via `add-classpath`: (add-dependencies :classloader your-classloader :coordinates '[[incanter \"1.2.3\"]] :repositories (merge cemerick.pomegranate.aether/maven-central {\"clojars\" \"https://clojars.org/repo\"})) Note that the `:classloader` kwarg is optional; if not provided then resolved dependencies will be added to the closest modifiable classloader in the current thread's hierarchy, as per `add-classpath`. Otherwise, acceptable arguments are the same as those for `cemerick.pomegranate.aether/resolve-dependencies`; returns the dependency graph returned from that function. Note that Maven central is used as the sole repository if none are specified. If :repositories are provided, then you must merge in the `maven-central` map from the cemerick.pomegranate.aether namespace yourself." [& args] (let [classloader (-> (apply hash-map args) :classloader ; replace with some-> when we bump the clojure dep (#(when % [%]))) deps (apply aether/resolve-dependencies args)] (doseq [artifact-file (aether/dependency-files deps)] (apply add-classpath artifact-file classloader)) deps)) (defn get-classpath "Returns the effective classpath (i.e. _not_ the value of (System/getProperty \"java.class.path\") as a seq of URL strings. Produces the classpath from all classloaders by default, or from a collection of classloaders if provided. This allows you to easily look at subsets of the current classloader hierarchy, e.g.: (get-classpath (drop 2 (classloader-hierarchy)))" ([classloaders] (->> (reverse classloaders) (mapcat #(dp/classpath-urls %)) (map str))) ([] (get-classpath (classloader-hierarchy)))) (defn classloader-resources "Returns a sequence of [classloader url-seq] pairs representing all of the resources of the specified name on the classpath of each classloader. If no classloaders are given, uses the classloader-heirarchy, in which case the order of pairs will be such that the first url mentioned will in most circumstances match what clojure.java.io/resource returns." ([classloaders resource-name] (for [classloader (reverse classloaders)] [classloader (enumeration-seq (.getResources ^ClassLoader classloader resource-name))])) ([resource-name] (classloader-resources (classloader-hierarchy) resource-name))) (defn resources "Returns a sequence of URLs representing all of the resources of the specified name on the effective classpath. This can be useful for finding name collisions among items on the classpath. In most circumstances, the first of the returned sequence will be the same as what clojure.java.io/resource returns." ([classloaders resource-name] (distinct (mapcat second (classloader-resources classloaders resource-name)))) ([resource-name] (resources (classloader-hierarchy) resource-name))) pomegranate-14f2f2517553223344a6913fe59f02847fe9f060/src/main/clojure/cemerick/pomegranate/000077500000000000000000000000001335473444400276435ustar00rootroot00000000000000aether.clj000066400000000000000000001147451335473444400315420ustar00rootroot00000000000000pomegranate-14f2f2517553223344a6913fe59f02847fe9f060/src/main/clojure/cemerick/pomegranate(ns cemerick.pomegranate.aether (:refer-clojure :exclude [type proxy]) (:require [clojure.java.io :as io] clojure.set [clojure.string :as str] clojure.stacktrace) (:import (org.eclipse.aether RepositorySystem) (org.eclipse.aether.transport.wagon WagonTransporterFactory WagonProvider) (org.eclipse.aether.transport.file FileTransporterFactory) (org.eclipse.aether.transfer TransferListener) (org.eclipse.aether.artifact Artifact) (org.eclipse.aether.spi.connector RepositoryConnectorFactory) (org.eclipse.aether.spi.connector.transport TransporterFactory) (org.eclipse.aether.repository Proxy Authentication RepositoryPolicy LocalRepository RemoteRepository RemoteRepository$Builder MirrorSelector) (org.eclipse.aether.util.repository DefaultProxySelector AuthenticationBuilder) (org.eclipse.aether.graph Dependency Exclusion DependencyNode) (org.eclipse.aether.collection CollectRequest) (org.eclipse.aether.resolution DependencyRequest ArtifactRequest ArtifactResult VersionRequest) (org.eclipse.aether.artifact DefaultArtifact ArtifactProperties) (org.eclipse.aether.util.artifact SubArtifact) (org.eclipse.aether.deployment DeployRequest) (org.eclipse.aether.installation InstallRequest) (org.eclipse.aether.util.version GenericVersionScheme) (org.eclipse.aether.connector.basic BasicRepositoryConnectorFactory) (org.eclipse.aether.impl DefaultServiceLocator$ErrorHandler) (org.apache.maven.repository.internal MavenRepositorySystemUtils))) (def ^{:private true} default-local-repo (io/file (System/getProperty "user.home") ".m2" "repository")) (def maven-central {"central" "https://repo1.maven.org/maven2/"}) ;; Using HttpWagon (which uses apache httpclient) because the "LightweightHttpWagon" ;; (which just uses JDK HTTP) reliably flakes if you attempt to resolve SNAPSHOT ;; artifacts from an HTTPS password-protected repository (like a nexus instance) ;; when other un-authenticated repositories are included in the resolution. ;; My theory is that the JDK HTTP impl is screwing up connection pooling or something, ;; and reusing the same connection handle for the HTTPS repo as it used for e.g. ;; central, without updating the authentication info. ;; In any case, HttpWagon is what Maven 3 uses, and it works. (def ^{:private true} wagon-factories (atom {"https" #(org.apache.maven.wagon.providers.http.HttpWagon.) "http" #(throw (Exception. "Tried to use insecure HTTP repository."))})) (defn register-wagon-factory! "Registers a new no-arg factory function for the given scheme. The function must return an implementation of org.apache.maven.wagon.Wagon." [scheme factory-fn] (swap! wagon-factories (fn [m] (when-let [fn (and (not= scheme "http") (m scheme))] (println (format "Warning: replacing existing support for %s repositories (%s) with %s" scheme fn factory-fn))) (assoc m scheme factory-fn)))) (deftype PomegranateWagonProvider [] WagonProvider (release [_ wagon]) (lookup [_ role-hint] (when-let [f (get @wagon-factories role-hint)] (try (f) (catch Exception e (clojure.stacktrace/print-cause-trace e) (throw e)))))) (deftype TransferListenerProxy [listener-fn] TransferListener (transferCorrupted [_ e] (listener-fn e)) (transferFailed [_ e] (listener-fn e)) (transferInitiated [_ e] (listener-fn e)) (transferProgressed [_ e] (listener-fn e)) (transferStarted [_ e] (listener-fn e)) (transferSucceeded [_ e] (listener-fn e))) (defn- transfer-event [^org.eclipse.aether.transfer.TransferEvent e] ;; INITIATED, STARTED, PROGRESSED, CORRUPTED, SUCCEEDED, FAILED {:type (-> e .getType .name str/lower-case keyword) ;; :get :put :method (-> e .getRequestType str/lower-case keyword) :transferred (.getTransferredBytes e) :error (.getException e) :data-buffer (.getDataBuffer e) :data-length (.getDataLength e) :resource (let [r (.getResource e)] {:repository (.getRepositoryUrl r) :name (.getResourceName r) :file (.getFile r) :size (.getContentLength r) :transfer-start-time (.getTransferStartTime r) :trace (.getTrace r)})}) (defn- default-listener-fn [{:keys [type method transferred resource error] :as evt}] (let [{:keys [name size repository transfer-start-time]} resource] (case type :started (do (print (case method :get "Retrieving" :put "Sending") name (if (neg? size) "" (format "(%sk)" (Math/round (double (max 1 (/ size 1024))))))) (when (< 70 (+ 10 (count name) (count repository))) (println) (print " ")) (println (case method :get "from" :put "to") repository)) (:corrupted :failed) (when error (println (.getMessage error))) nil))) (defn- repository-system [] (let [error-handler (clojure.core/proxy [DefaultServiceLocator$ErrorHandler] [] (serviceCreationFailed [type-clazz impl-clazz ^Throwable e] (clojure.stacktrace/print-cause-trace e)))] (.getService (doto (MavenRepositorySystemUtils/newServiceLocator) (.setService TransporterFactory WagonTransporterFactory) (.setService WagonProvider PomegranateWagonProvider) (.addService RepositoryConnectorFactory BasicRepositoryConnectorFactory) (.addService TransporterFactory FileTransporterFactory) (.setErrorHandler error-handler)) RepositorySystem))) (defn- construct-transfer-listener [transfer-listener] (cond (instance? TransferListener transfer-listener) transfer-listener (= transfer-listener :stdout) (TransferListenerProxy. (comp default-listener-fn transfer-event)) (fn? transfer-listener) (TransferListenerProxy. (comp transfer-listener transfer-event)) :else (TransferListenerProxy. (fn [_])))) (defn repository-session [{:keys [repository-system local-repo offline? transfer-listener mirror-selector]}] (let [session (org.apache.maven.repository.internal.MavenRepositorySystemUtils/newSession)] (doto session (.setLocalRepositoryManager (.newLocalRepositoryManager repository-system session (LocalRepository. (io/file (or local-repo default-local-repo))))) (.setMirrorSelector mirror-selector) (.setOffline (boolean offline?)) (.setTransferListener (construct-transfer-listener transfer-listener))))) (def update-policies {:daily RepositoryPolicy/UPDATE_POLICY_DAILY :always RepositoryPolicy/UPDATE_POLICY_ALWAYS :never RepositoryPolicy/UPDATE_POLICY_NEVER}) (def checksum-policies {:fail RepositoryPolicy/CHECKSUM_POLICY_FAIL :ignore RepositoryPolicy/CHECKSUM_POLICY_IGNORE :warn RepositoryPolicy/CHECKSUM_POLICY_WARN}) (defn- policy [policy-settings enabled?] (RepositoryPolicy. (boolean enabled?) (update-policies (:update policy-settings :daily)) (checksum-policies (:checksum policy-settings :fail)))) (defn- set-policies [repo-builder settings] (doto repo-builder (.setSnapshotPolicy (policy settings (:snapshots settings true))) (.setReleasePolicy (policy settings (:releases settings true))))) (defn- authentication [{:keys [username password passphrase private-key-file] :as settings}] (-> (AuthenticationBuilder.) (.addUsername username) (.addPassword password) (.addPrivateKey private-key-file passphrase) .build)) (defn- set-authentication [repo-builder {:keys [username password passphrase private-key-file] :as settings}] (if (or username password private-key-file passphrase) (.setAuthentication repo-builder (authentication settings)) repo-builder)) (defn- set-proxy [repo-builder {:keys [type host port non-proxy-hosts] :or {type "http"} :as proxy}] (if (and host port) (let [prx-sel (doto (DefaultProxySelector.) (.add (Proxy. type host port (authentication proxy)) non-proxy-hosts)) prx (.getProxy prx-sel (.build repo-builder))] ; ugg. ;; Don't know how to get around "building" the repo for this (.setProxy repo-builder prx)) repo-builder)) (defn make-repository "Produces an Aether RemoteRepository instance from Pomegranate-style repository information" [[id settings] proxy] (let [settings-map (if (string? settings) {:url settings} settings)] (.build (doto (RemoteRepository$Builder. (and id (name id)) (:type settings-map "default") (str (:url settings-map))) (set-policies settings-map) (set-authentication settings-map) (set-proxy proxy))))) (defn- group [group-artifact] (or (namespace group-artifact) (name group-artifact))) (defn- coordinate-string "Produces a coordinate string with a format of :[:[:]]:> given a lein-style dependency spec. :extension defaults to jar." [[group-artifact version & {:keys [classifier extension] :or {extension "jar"}}]] (->> [(group group-artifact) (name group-artifact) extension classifier version] (remove nil?) (interpose \:) (apply str))) (defn- exclusion [[group-artifact & {:as opts}]] (Exclusion. (group group-artifact) (name group-artifact) (:classifier opts "*") (:extension opts "*"))) (defn- normalize-exclusion-spec [spec] (if (symbol? spec) [spec] spec)) (defn- artifact [[group-artifact version & {:keys [scope optional exclusions]} :as dep-spec]] (DefaultArtifact. (coordinate-string dep-spec))) (defn dependency "Produces an Aether Dependency instance from Pomegranate-style dependency information" [[group-artifact version & {:keys [scope optional exclusions] :as opts :or {scope "compile" optional false}} :as dep-spec]] (Dependency. (artifact dep-spec) scope optional (map (comp exclusion normalize-exclusion-spec) exclusions))) (declare dep-spec*) (defn- exclusion-spec "Given an Aether Exclusion, returns a lein-style exclusion vector with the :exclusion in its metadata." [^Exclusion ex] (with-meta (-> ex bean dep-spec*) {:exclusion ex})) (defn- dep-spec "Given an Aether Dependency, returns a lein-style dependency vector with the :dependency and its corresponding artifact's :file in its metadata." [^Dependency dep] (let [artifact (.getArtifact dep)] (-> (merge (bean dep) (bean artifact)) dep-spec* (with-meta {:dependency dep :file (.getFile artifact)})))) (defn- dep-spec* "Base function for producing lein-style dependency spec vectors for dependencies and exclusions." [{:keys [groupId artifactId version classifier extension scope optional exclusions] :or {version nil scope "compile" optional false exclusions nil}}] (let [group-artifact (apply symbol (if (= groupId artifactId) [artifactId] [groupId artifactId]))] (vec (concat [group-artifact] (when version [version]) (when (and (seq classifier) (not= "*" classifier)) [:classifier classifier]) (when (and (seq extension) (not (#{"*" "jar"} extension))) [:extension extension]) (when optional [:optional true]) (when (not= scope "compile") [:scope scope]) (when (seq exclusions) [:exclusions (vec (map exclusion-spec exclusions))]))))) (defn- create-artifact [files artifact] (if-let [file (get files artifact)] (-> (coordinate-string artifact) DefaultArtifact. (.setFile (io/file file))) (throw (IllegalArgumentException. (str "No file provided for artifact " artifact))))) (defn deploy-artifacts "Deploy the artifacts kwarg to the repository kwarg. :files - map from artifact vectors to file paths or java.io.File objects where the file to be deployed for each artifact is to be found An artifact vector is e.g. '[group/artifact \"1.0.0\"] or '[group/artifact \"1.0.0\" :extension \"pom\"]. All artifacts should have the same version and group and artifact IDs :repository - {name url} | {name settings} settings: :url - URL of the repository :snapshots - use snapshots versions? (default true) :releases - use release versions? (default true) :username - username to log in with :password - password to log in with :passphrase - passphrase to log in wth :private-key-file - private key file to log in with :update - :daily (default) | :always | :never :checksum - :fail (default) | :ignore | :warn :local-repo - path to the local repository (defaults to ~/.m2/repository) :transfer-listener - same as provided to resolve-dependencies :proxy - proxy configuration, can be nil, the host scheme and type must match :host - proxy hostname :type - http (default) | http | https :port - proxy port :non-proxy-hosts - The list of hosts to exclude from proxying, may be null :username - username to log in with, may be null :password - password to log in with, may be null :passphrase - passphrase to log in wth, may be null :private-key-file - private key file to log in with, may be null" [& {:keys [files repository local-repo transfer-listener proxy repository-session-fn]}] (when (empty? files) (throw (IllegalArgumentException. "Must provide valid :files to deploy-artifacts"))) (when (->> (keys files) (map (fn [[ga v]] [(if (namespace ga) ga (symbol (str ga) (str ga))) v])) set count (< 1)) (throw (IllegalArgumentException. (str "Provided artifacts have varying version, group, or artifact IDs: " (keys files))))) (let [system (repository-system) session ((or repository-session-fn repository-session) {:repository-system system :local-repo local-repo :offline? false :transfer-listener transfer-listener})] (.deploy system session (doto (DeployRequest.) (.setArtifacts (vec (map (partial create-artifact files) (keys files)))) (.setRepository (first (map #(make-repository % proxy) repository))))))) (defn install-artifacts "Deploy the file kwarg using the coordinates kwarg to the repository kwarg. :files - same as with deploy-artifacts :local-repo - path to the local repository (defaults to ~/.m2/repository) :transfer-listener - same as provided to resolve-dependencies" [& {:keys [files local-repo transfer-listener repository-session-fn]}] (let [system (repository-system) session ((or repository-session-fn repository-session) {:repository-system system :local-repo local-repo :offline? false :transfer-listener transfer-listener})] (.install system session (doto (InstallRequest.) (.setArtifacts (vec (map (partial create-artifact files) (keys files)))))))) (defn- artifacts-for "Takes a coordinates map, an a map from partial coordinates to " [coordinates file-map] (zipmap (map (partial into coordinates) (keys file-map)) (vals file-map))) (defn- optional-artifact "Takes a coordinates map, an a map from partial coordinates to " [artifact-coords path] (when path {artifact-coords path})) (defn deploy "Deploy the jar-file kwarg using the pom-file kwarg and coordinates kwarg to the repository kwarg. :coordinates - [group/name \"version\"] :artifact-map - a map from partial coordinates to file path or File :jar-file - a file pointing to the jar :pom-file - a file pointing to the pom :repository - {name url} | {name settings} settings: :url - URL of the repository :snapshots - use snapshots versions? (default true) :releases - use release versions? (default true) :username - username to log in with :password - password to log in with :passphrase - passphrase to log in wth :private-key-file - private key file to log in with :update - :daily (default) | :always | :never :checksum - :fail (default) | :ignore | :warn :local-repo - path to the local repository (defaults to ~/.m2/repository) :transfer-listener - same as provided to resolve-dependencies :proxy - proxy configuration, can be nil, the host scheme and type must match :host - proxy hostname :type - http (default) | http | https :port - proxy port :non-proxy-hosts - The list of hosts to exclude from proxying, may be null :username - username to log in with, may be null :password - password to log in with, may be null :passphrase - passphrase to log in wth, may be null :private-key-file - private key file to log in with, may be null" [& {:keys [coordinates artifact-map jar-file pom-file] :as opts}] (when (empty? coordinates) (throw (IllegalArgumentException. "Must provide valid :coordinates to deploy"))) (apply deploy-artifacts (apply concat (assoc opts :files (artifacts-for coordinates (merge artifact-map (optional-artifact [:extension "pom"] pom-file) (optional-artifact [] jar-file))))))) (defn install "Install the artifacts specified by the jar-file or file-map and pom-file kwargs using the coordinates kwarg. :coordinates - [group/name \"version\"] :artifact-map - a map from partial coordinates to file path or File :jar-file - a file pointing to the jar :pom-file - a file pointing to the pom :local-repo - path to the local repository (defaults to ~/.m2/repository) :transfer-listener - same as provided to resolve-dependencies" [& {:keys [coordinates artifact-map jar-file pom-file] :as opts}] (when (empty? coordinates) (throw (IllegalArgumentException. "Must provide valid :coordinates to install"))) (apply install-artifacts (apply concat (assoc opts :files (artifacts-for coordinates (merge artifact-map (optional-artifact [:extension "pom"] pom-file) (optional-artifact [] jar-file))))))) (defn- dependency-graph ([node] (reduce (fn [g ^DependencyNode n] (if-let [dep (.getDependency n)] (update-in g [(dep-spec dep)] clojure.set/union (->> (.getChildren n) (map #(.getDependency %)) (map dep-spec) set)) g)) {} (tree-seq (constantly true) #(seq (.getChildren %)) node)))) (defn- mirror-selector-fn "Default mirror selection function. The first argument should be a map like that described as the :mirrors argument in resolve-dependencies. The second argument should be a repository spec, also as described in resolve-dependencies. Will return the mirror spec that matches the provided repository spec." [mirrors {:keys [name url snapshots releases]}] (let [mirrors (filter (fn [[matcher mirror-spec]] (or (and (string? matcher) (or (= matcher name) (= matcher url))) (and (instance? java.util.regex.Pattern matcher) (or (re-matches matcher name) (re-matches matcher url))))) mirrors)] (case (count mirrors) 0 nil 1 (-> mirrors first second) (if (some nil? (map second mirrors)) ;; wildcard override nil (throw (IllegalArgumentException. (str "Multiple mirrors configured to match repository " {name url} ": " (into {} (map #(update-in % [1] select-keys [:name :url]) mirrors))))))))) (defn- mirror-selector "Returns a MirrorSelector that delegates matching of mirrors to given remote repositories to the provided function. Any returned repository specifications are turned into RemoteRepository instances, and configured to use the provided proxy." [mirror-selector-fn proxy] (reify MirrorSelector (getMirror [_ repo] (let [repo-spec {:name (.getId repo) :url (.getUrl repo) :snapshots (-> repo (.getPolicy true) .isEnabled) :releases (-> repo (.getPolicy false) .isEnabled)} {:keys [name repo-manager content-type] :as mirror-spec} (mirror-selector-fn repo-spec)] (when-let [mirror (and mirror-spec (make-repository [name mirror-spec] proxy))] (-> (RemoteRepository$Builder. mirror) (.setMirroredRepositories [repo]) (.setRepositoryManager (boolean repo-manager)) (.setContentType (or content-type "default")) (.build))))))) (defn resolve-artifacts* "Resolves artifacts for the coordinates kwarg, using repositories from the `:repositories` kwarg. Retrieval of dependencies can be disabled by providing `:retrieve false` as a kwarg. Returns an sequence of either `org.eclipse.aether.VersionResult` if `:retrieve false`, or `org.eclipse.aether.ArtifactResult` if `:retrieve true` (the default). If you don't want to mess with the Aether implementation classes, then use `resolve-artifacts` instead. :coordinates - [[group/name \"version\" & settings] ..] settings: :extension - the maven extension (type) to require :classifier - the maven classifier to require :scope - the maven scope for the dependency (default \"compile\") :optional - is the dependency optional? (default \"false\") :exclusions - which sub-dependencies to skip : [group/name & settings] settings: :classifier (default \"*\") :extension (default \"*\") :repositories - {name url ..} | {name settings ..} (defaults to {\"central\" \"https://repo1.maven.org/maven2/\"} settings: :url - URL of the repository :snapshots - use snapshots versions? (default true) :releases - use release versions? (default true) :username - username to log in with :password - password to log in with :passphrase - passphrase to log in wth :private-key-file - private key file to log in with :update - :daily (default) | :always | :never :checksum - :fail (default) | :ignore | :warn :local-repo - path to the local repository (defaults to ~/.m2/repository) :offline? - if true, no remote repositories will be contacted :transfer-listener - the transfer listener that will be notifed of dependency resolution and deployment events. Can be: - nil (the default), i.e. no notification of events - :stdout, corresponding to a default listener implementation that writes notifications and progress indicators to stdout, suitable for an interactive console program - a function of one argument, which will be called with a map derived from each event. - an instance of org.eclipse.aether.transfer.TransferListener :proxy - proxy configuration, can be nil, the host scheme and type must match :host - proxy hostname :type - http (default) | http | https :port - proxy port :non-proxy-hosts - The list of hosts to exclude from proxying, may be null :username - username to log in with, may be null :password - password to log in with, may be null :passphrase - passphrase to log in wth, may be null :private-key-file - private key file to log in with, may be null :mirrors - {matches settings ..} matches - a string or regex that will be used to match the mirror to candidate repositories. Attempts will be made to match the string/regex to repository names and URLs, with exact string matches preferred. Wildcard mirrors can be specified with a match-all regex such as #\".+\". Excluding a repository from mirroring can be done by mapping a string or regex matching the repository in question to nil. settings include these keys, and all those supported by :repositories: :name - name/id of the mirror :repo-manager - whether the mirror is a repository manager" [& {:keys [repositories coordinates files retrieve local-repo transfer-listener offline? proxy mirrors repository-session-fn] :or {retrieve true}}] (let [repositories (or repositories maven-central) system (repository-system) mirror-selector-fn (memoize (partial mirror-selector-fn mirrors)) mirror-selector (mirror-selector mirror-selector-fn proxy) session ((or repository-session-fn repository-session) {:repository-system system :local-repo local-repo :offline? offline? :transfer-listener transfer-listener :mirror-selector mirror-selector}) deps (->> coordinates (map #(if-let [local-file (get files %)] (-> (artifact %) (.setProperties {ArtifactProperties/LOCAL_PATH (.getPath (io/file local-file))})) (artifact %))) vec) repositories (vec (map #(let [repo (make-repository % proxy)] (-> session (.getMirrorSelector) (.getMirror repo) (or repo))) repositories))] (if retrieve (.resolveArtifacts system session (map #(ArtifactRequest. % repositories nil) deps)) (doall (for [dep deps] (.resolveVersion system session (VersionRequest. dep repositories nil))))))) (defn resolve-artifacts "Same as `resolve-artifacts*`, but returns a sequence of dependencies; each artifact's metadata contains the source Aether result object, and the artifact's :file on disk." [& args] (let [{:keys [coordinates]} (apply hash-map args)] (->> (apply resolve-artifacts* args) (map (fn [coord result] {:pre [coord result]} (let [m (when (instance? ArtifactResult result) {:file (.. ^ArtifactResult result getArtifact getFile)})] (with-meta coord (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) som (apply hash-map sopts)] (and (= (group dep) (group sdep)) (= (name dep) (name sdep)) (= (:extension om "jar") (:extension som "jar")) (= (: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 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 managed-coordinates vector as necessary." [coordinates managed-coordinates] (vec (map (partial add-version-from-managed-coords-if-missing managed-coordinates) coordinates))) (defn- coords->Dependencies "Converts a coordinates vector to the maven representation, as Dependency objects." [files coordinates] (->> coordinates (map #(if-let [local-file (get files %)] (.setArtifact (dependency %) (-> (dependency %) .getArtifact (.setProperties {ArtifactProperties/LOCAL_PATH (.getPath (io/file local-file))}))) (dependency %))) vec)) (defn resolve-dependencies* "Collects dependencies for the coordinates kwarg, using repositories from the `:repositories` kwarg. Retrieval of dependencies can be disabled by providing `:retrieve false` as a kwarg. Returns an instance of either `org.eclipse.aether.collection.CollectResult` if `:retrieve false` or `org.eclipse.aether.resolution.DependencyResult` if `:retrieve true` (the default). If you don't want to mess with the Aether implementation classes, then use `resolve-dependencies` instead. :coordinates - [[group/name <\"version\"> & settings] ..] settings: :extension - the maven extension (type) to require :classifier - the maven classifier to require :scope - the maven scope for the dependency (default \"compile\") :optional - is the dependency optional? (default \"false\") :exclusions - which sub-dependencies to skip : [group/name & settings] settings: :classifier (default \"*\") :extension (default \"*\") :managed-coordinates - [[group/name \"version\"] ..] Used to determine version numbers for any entries in `:coordinates` that don't explicitly specify them. :repositories - {name url ..} | {name settings ..} (defaults to {\"central\" \"https://repo1.maven.org/maven2/\"} settings: :url - URL of the repository :snapshots - use snapshots versions? (default true) :releases - use release versions? (default true) :username - username to log in with :password - password to log in with :passphrase - passphrase to log in wth :private-key-file - private key file to log in with :update - :daily (default) | :always | :never :checksum - :fail (default) | :ignore | :warn :local-repo - path to the local repository (defaults to ~/.m2/repository) :offline? - if true, no remote repositories will be contacted :transfer-listener - the transfer listener that will be notifed of dependency resolution and deployment events. Can be: - nil (the default), i.e. no notification of events - :stdout, corresponding to a default listener implementation that writes notifications and progress indicators to stdout, suitable for an interactive console program - a function of one argument, which will be called with a map derived from each event. - an instance of org.eclipse.aether.transfer.TransferListener :proxy - proxy configuration, can be nil, the host scheme and type must match :host - proxy hostname :type - http (default) | http | https :port - proxy port :non-proxy-hosts - The list of hosts to exclude from proxying, may be null :username - username to log in with, may be null :password - password to log in with, may be null :passphrase - passphrase to log in wth, may be null :private-key-file - private key file to log in with, may be null :mirrors - {matches settings ..} matches - a string or regex that will be used to match the mirror to candidate repositories. Attempts will be made to match the string/regex to repository names and URLs, with exact string matches preferred. Wildcard mirrors can be specified with a match-all regex such as #\".+\". Excluding a repository from mirroring can be done by mapping a string or regex matching the repository in question to nil. settings include these keys, and all those supported by :repositories: :name - name/id of the mirror :repo-manager - whether the mirror is a repository manager" [& {:keys [repositories coordinates managed-coordinates files retrieve local-repo transfer-listener offline? proxy mirrors repository-session-fn] :or {retrieve true}}] (let [repositories (or repositories maven-central) system (repository-system) mirror-selector-fn (memoize (partial mirror-selector-fn mirrors)) mirror-selector (mirror-selector mirror-selector-fn proxy) session ((or repository-session-fn repository-session) {:repository-system system :local-repo local-repo :offline? offline? :transfer-listener transfer-listener :mirror-selector mirror-selector}) coordinates (merge-versions-from-managed-coords coordinates managed-coordinates) deps (coords->Dependencies files coordinates) managed-deps (coords->Dependencies files managed-coordinates) collect-request (doto (CollectRequest. deps managed-deps (vec (map #(let [repo (make-repository % proxy)] (-> session (.getMirrorSelector) (.getMirror repo) (or repo))) repositories))) (.setRequestContext "runtime"))] (if retrieve (.resolveDependencies system session (DependencyRequest. collect-request nil)) (.collectDependencies system session collect-request)))) (defn resolve-dependencies "Same as `resolve-dependencies*`, but returns a graph of dependencies; each dependency's metadata contains the source Aether Dependency object, and the dependency's :file on disk. Please refer to `resolve-dependencies*` for details on usage, or use it if you need access to Aether dependency resolution objects." [& args] (-> (apply resolve-dependencies* args) .getRoot dependency-graph)) (defn dependency-files "Given a dependency graph obtained from `resolve-dependencies`, returns a seq of files from the dependencies' metadata." [graph] (->> graph keys (map (comp :file meta)) (remove nil?))) (defn- exclusion= [spec1 spec2] (let [[dep & opts] (normalize-exclusion-spec spec1) [sdep & sopts] (normalize-exclusion-spec spec2) om (apply hash-map opts) som (apply hash-map sopts)] (and (= (group dep) (group sdep)) (= (name dep) (name sdep)) (= (:extension om "*") (:extension som "*")) (= (:classifier om "*") (:classifier som "*")) spec2))) (defn- exclusions-match? [excs sexcs] (if-let [ex (first excs)] (if-let [match (some (partial exclusion= ex) sexcs)] (recur (next excs) (remove #{match} sexcs)) false) (empty? sexcs))) (defn within? "Determines if the first coordinate would be a version in the second coordinate. The first coordinate is not allowed to contain a version range." [[dep version & opts :as coord] [sdep sversion & sopts :as scoord]] (let [om (apply hash-map opts) som (apply hash-map sopts)] (and (coordinates-match? coord scoord) (= (:scope om "compile") (:scope som "compile")) (= (:optional om false) (:optional som false)) (exclusions-match? (:exclusions om) (:exclusions som)) (or (= version sversion) (if-let [[_ ver] (re-find #"^(.*)-SNAPSHOT$" sversion)] (re-find (re-pattern (str "^" ver "-\\d+\\.\\d+-\\d+$")) version) (let [gsv (GenericVersionScheme.) vc (.parseVersionConstraint gsv sversion) v (.parseVersion gsv version)] (.containsVersion vc v))))))) (defn dependency-hierarchy "Returns a dependency hierarchy based on the provided dependency graph (as returned by `resolve-dependencies`) and the coordinates that should be the root(s) of the hierarchy. Siblings are sorted alphabetically." [root-coordinates dep-graph] (let [root-specs (map (comp dep-spec dependency) root-coordinates) hierarchy (for [root (filter #(some (fn [root] (within? % root)) root-specs) (keys dep-graph))] [root (dependency-hierarchy (dep-graph root) dep-graph)])] (when (seq hierarchy) (into (sorted-map-by #(apply compare (map coordinate-string %&))) hierarchy)))) pomegranate-14f2f2517553223344a6913fe59f02847fe9f060/src/test/000077500000000000000000000000001335473444400221475ustar00rootroot00000000000000pomegranate-14f2f2517553223344a6913fe59f02847fe9f060/src/test/clojure/000077500000000000000000000000001335473444400236125ustar00rootroot00000000000000pomegranate-14f2f2517553223344a6913fe59f02847fe9f060/src/test/clojure/cemerick/000077500000000000000000000000001335473444400253745ustar00rootroot00000000000000pomegranate-14f2f2517553223344a6913fe59f02847fe9f060/src/test/clojure/cemerick/pomegranate/000077500000000000000000000000001335473444400276765ustar00rootroot00000000000000aether_test.clj000066400000000000000000001010701335473444400326170ustar00rootroot00000000000000pomegranate-14f2f2517553223344a6913fe59f02847fe9f060/src/test/clojure/cemerick/pomegranate(ns cemerick.pomegranate.aether-test (:require [cemerick.pomegranate.aether :as aether] [clojure.java.io :as io]) (:use [clojure.test])) (deftest dependency-roundtripping (are [x] (= x (#'aether/dep-spec (#'aether/dependency x))) '[ring "1.0.0" :optional true] '[com.cemerick/pomegranate "0.0.1" :classifier "sources"] '[demo/demo2 "1.0.0" :exclusions [[demo :classifier "jdk5"]]])) (def tmp-dir (io/file (System/getProperty "java.io.tmpdir") "pomegranate-test-tmp")) (def tmp-remote-repo-dir (.getAbsolutePath (io/file tmp-dir "remote-repo"))) (def tmp-local-repo-dir (io/file tmp-dir "local-repo")) (def tmp-local-repo2-dir (io/file tmp-dir "local-repo2")) (def test-remote-repo {"central" "https://repo1.maven.org/maven2/"}) (def test-repo {:test-repo "file://test-repo"}) (def tmp-remote-repo {"tmp-remote-repo" (str "file://" tmp-remote-repo-dir)}) (defn delete-recursive [dir] (when (.isDirectory dir) (doseq [file (.listFiles dir)] (delete-recursive file))) (.delete dir)) (defn- clear-tmp [f] (delete-recursive (io/file tmp-dir)) (f)) (use-fixtures :each clear-tmp) (defn file-path-eq [file1 file2] (= (.getAbsolutePath file1) (.getAbsolutePath file2))) (deftest live-resolution (let [deps '[[commons-logging "1.1"]] graph '{[javax.servlet/servlet-api "2.3"] nil, [avalon-framework "4.1.3"] nil, [logkit "1.0.1"] nil, [log4j "1.2.12"] nil, [commons-logging "1.1"] #{[javax.servlet/servlet-api "2.3"] [avalon-framework "4.1.3"] [logkit "1.0.1"] [log4j "1.2.12"]}} hierarchy '{[commons-logging "1.1"] {[avalon-framework "4.1.3"] nil, [javax.servlet/servlet-api "2.3"] nil, [log4j "1.2.12"] nil, [logkit "1.0.1"] nil}}] (is (= graph (aether/resolve-dependencies :coordinates deps :retrieve false :local-repo tmp-local-repo-dir))) (is (not (some #(-> % .getName (.endsWith ".jar")) (file-seq tmp-local-repo-dir)))) (doseq [[dep _] (aether/resolve-dependencies :coordinates deps :local-repo tmp-local-repo-dir)] (is (-> dep meta :file)) (is (-> dep meta :file .exists))) (is (some #(-> % .getName (.endsWith ".jar")) (file-seq tmp-local-repo-dir))) (is (= hierarchy (aether/dependency-hierarchy deps graph))))) (deftest live-artifact-resolution (let [deps '[[commons-logging "1.1"]]] (is (= deps (aether/resolve-artifacts :coordinates deps :retrieve false :local-repo tmp-local-repo-dir))) (is (= 1 (count (aether/resolve-artifacts :coordinates '[[demo "1.0.0"]] :retrieve false :files {'[demo "1.0.0"] (io/file "test-repo" "demo" "demo" "1.0.0" "demo-1.0.0.jar")} :local-repo tmp-local-repo-dir)))) (is (not (some #(-> % .getName (.endsWith ".jar")) (file-seq tmp-local-repo-dir)))) (doseq [dep (aether/resolve-artifacts :coordinates deps :local-repo tmp-local-repo-dir)] (is (-> dep meta :file)) (is (-> dep meta :file .exists))) (is (some #(-> % .getName (.endsWith ".jar")) (file-seq tmp-local-repo-dir))))) (deftest impl-detail-types (let [args [:coordinates '[[commons-logging "1.1"]] :local-repo tmp-local-repo-dir]] (is (instance? org.eclipse.aether.resolution.DependencyResult (apply aether/resolve-dependencies* args))) (is (instance? org.eclipse.aether.collection.CollectResult (apply aether/resolve-dependencies* :retrieve false args))))) (deftest resolve-deps-with-mirror (let [deps (aether/resolve-dependencies :repositories {"clojars" "https://clojars.org/repo"} :coordinates '[[javax.servlet/servlet-api "2.5"]] :mirrors {"clojars" {:url "https://maven-central.storage-download.googleapis.com/repos/central/data"}} :local-repo tmp-local-repo-dir)] (is (= 1 (count deps))) (is (= (.getAbsolutePath (io/file tmp-dir "local-repo" "javax" "servlet" "servlet-api" "2.5" "servlet-api-2.5.jar")) (.getAbsolutePath (first (aether/dependency-files deps))))))) (deftest resolve-deps-with-wildcard-mirror (let [deps (aether/resolve-dependencies :repositories {"clojars" "https://clojars.org/repo"} :coordinates '[[javax.servlet/servlet-api "2.5"]] :mirrors {#".+" {:url "https://maven-central.storage-download.googleapis.com/repos/central/data"}} :local-repo tmp-local-repo-dir)] (is (= 1 (count deps))) (is (= (.getAbsolutePath (io/file tmp-dir "local-repo" "javax" "servlet" "servlet-api" "2.5" "servlet-api-2.5.jar")) (.getAbsolutePath (first (aether/dependency-files deps))))))) (deftest resolve-deps-with-wildcard-override-mirror (let [deps (aether/resolve-dependencies :repositories test-remote-repo :coordinates '[[javax.servlet/servlet-api "2.5"]] :mirrors {#".+" {:url "https://clojars.org/repo"} (ffirst test-remote-repo) nil} :local-repo tmp-local-repo-dir)] (is (= 1 (count deps))) (is (= (.getAbsolutePath (io/file tmp-dir "local-repo" "javax" "servlet" "servlet-api" "2.5" "servlet-api-2.5.jar")) (.getAbsolutePath (first (aether/dependency-files deps))))))) (deftest resolve-deps (let [deps (aether/resolve-dependencies :repositories test-repo :coordinates '[[demo/demo "1.0.0"]] :local-repo tmp-local-repo-dir)] (is (= 1 (count deps))) (is (= (.getAbsolutePath (io/file tmp-dir "local-repo" "demo" "demo" "1.0.0" "demo-1.0.0.jar")) (.getAbsolutePath (first (aether/dependency-files deps))))))) (deftest resolve-deps-with-deps (let [deps (aether/resolve-dependencies :repositories test-repo :coordinates '[[demo/demo2 "1.0.0"]] :local-repo tmp-local-repo-dir) files (aether/dependency-files deps)] (is (= 2 (count files))) (is (= 1 (count (filter #(file-path-eq % (io/file tmp-dir "local-repo" "demo" "demo" "1.0.0" "demo-1.0.0.jar")) files)))) (is (= 1 (count (filter #(file-path-eq % (io/file tmp-dir "local-repo" "demo" "demo2" "1.0.0" "demo2-1.0.0.jar")) files)))))) (deftest resolve-unmanaged-dependencies (let [deps (aether/resolve-dependencies :repositories {} :coordinates '[[demo "1.0.0"]] :files {'[demo "1.0.0"] (io/file "test-repo" "demo" "demo" "1.0.0" "demo-1.0.0.jar")} :local-repo tmp-local-repo-dir) files (aether/dependency-files deps)] (is (= 1 (count files))) (is (= nil (:file (meta (first files))))))) (deftest resolve-deps-with-exclusions (let [deps (aether/resolve-dependencies :repositories test-repo :coordinates '[[demo/demo2 "1.0.0" :exclusions [demo/demo]]] :local-repo tmp-local-repo-dir)] (is (= 1 (count deps))) (is (= (.getAbsolutePath (io/file tmp-dir "local-repo" "demo" "demo2" "1.0.0" "demo2-1.0.0.jar")) (.getAbsolutePath (first (aether/dependency-files deps))))))) (deftest resolve-deps-with-classifiers (let [deps (aether/resolve-dependencies :repositories test-repo :coordinates '[[demo/demo "1.0.1" :classifier "test"]] :local-repo tmp-local-repo-dir)] (is (= 1 (count deps))) (is (= (.getAbsolutePath (io/file tmp-dir "local-repo" "demo" "demo" "1.0.1" "demo-1.0.1-test.jar")) (.getAbsolutePath (first (aether/dependency-files deps))))))) (deftest resolve-managed-dependencies (testing "supports coordinates w/o version number, with managed coordinates" (let [deps (aether/resolve-dependencies :repositories test-repo :coordinates '[[demo/demo]] :managed-coordinates '[[demo/demo "1.0.0"]] :local-repo tmp-local-repo-dir) files (aether/dependency-files deps)] (is (= 1 (count files))) (is (= 1 (count (filter #(file-path-eq % (io/file tmp-dir "local-repo" "demo" "demo" "1.0.0" "demo-1.0.0.jar")) files)))))) (testing "supports coordinates w/o version number, with managed coordinates, w/o group-id" (let [deps (aether/resolve-dependencies :repositories test-repo :coordinates '[[demo/demo]] :managed-coordinates '[[demo "1.0.0"]] :local-repo tmp-local-repo-dir) files (aether/dependency-files deps)] (is (= 1 (count files))) (is (= 1 (count (filter #(file-path-eq % (io/file tmp-dir "local-repo" "demo" "demo" "1.0.0" "demo-1.0.0.jar")) files))))) (let [deps (aether/resolve-dependencies :repositories test-repo :coordinates '[[demo]] :managed-coordinates '[[demo/demo "1.0.0"]] :local-repo tmp-local-repo-dir) files (aether/dependency-files deps)] (is (= 1 (count files))) (is (= 1 (count (filter #(file-path-eq % (io/file tmp-dir "local-repo" "demo" "demo" "1.0.0" "demo-1.0.0.jar")) files)))))) (testing "supports coordinates w/nil version number, with managed coordinates" (let [deps (aether/resolve-dependencies :repositories test-repo :coordinates '[[demo/demo nil]] :managed-coordinates '[[demo/demo "1.0.0"]] :local-repo tmp-local-repo-dir) files (aether/dependency-files deps)] (is (= 1 (count files))) (is (= 1 (count (filter #(file-path-eq % (io/file tmp-dir "local-repo" "demo" "demo" "1.0.0" "demo-1.0.0.jar")) files)))))) (testing "supports coordinates w/nil version number and kwargs, with managed coordinates" (let [deps (aether/resolve-dependencies :repositories test-repo :coordinates '[[demo/demo2 nil :exclusions [demo/demo]]] :managed-coordinates '[[demo/demo2 "1.0.0"]] :local-repo tmp-local-repo-dir) files (aether/dependency-files deps)] (is (= 1 (count files))) (is (= 1 (count (filter #(file-path-eq % (io/file tmp-dir "local-repo" "demo" "demo2" "1.0.0" "demo2-1.0.0.jar")) files)))))) (testing "error if missing version number w/o managed coordinates" (is (thrown-with-msg? IllegalArgumentException #"Provided artifact is missing a version: \[demo/demo\]" (aether/resolve-dependencies :repositories test-repo :coordinates '[[demo/demo]] :local-repo tmp-local-repo-dir)))) (testing "error if nil version number w/o managed coordinates" (is (thrown-with-msg? IllegalArgumentException #"Provided artifact is missing a version: \[demo/demo nil\]" (aether/resolve-dependencies :repositories test-repo :coordinates '[[demo/demo nil]] :local-repo tmp-local-repo-dir)))) (testing "coordinates version number overrides managed coordinates version" (let [deps (aether/resolve-dependencies :repositories test-repo :coordinates '[[demo/demo "1.0.0"]] :managed-coordinates '[[demo/demo "0.0.1"]] :local-repo tmp-local-repo-dir) files (aether/dependency-files deps)] (is (= 1 (count files))) (is (= 1 (count (filter #(file-path-eq % (io/file tmp-dir "local-repo" "demo" "demo" "1.0.0" "demo-1.0.0.jar")) files)))))) (testing "managed coordinates version is honored for transitive deps" (let [deps (aether/resolve-dependencies :repositories test-repo :coordinates '[[demo/demo2 "1.0.0"]] :managed-coordinates '[[demo/demo "1.0.1"]] :local-repo tmp-local-repo-dir) files (aether/dependency-files deps)] (is (= 2 (count files))) (is (= 1 (count (filter #(file-path-eq % (io/file tmp-dir "local-repo" "demo" "demo2" "1.0.0" "demo2-1.0.0.jar")) files)))) (is (= 1 (count (filter #(file-path-eq % (io/file tmp-dir "local-repo" "demo" "demo" "1.0.1" "demo-1.0.1.jar")) files)))))) (testing "unused entries in managed coordinates are not resolved" (let [deps (aether/resolve-dependencies :repositories test-repo :coordinates '[[demo/demo]] :managed-coordinates '[[demo/demo "1.0.0"] [demo/demo2 "1.0.0"]] :local-repo tmp-local-repo-dir) files (aether/dependency-files deps)] (is (= 1 (count files))) (is (= 1 (count (filter #(file-path-eq % (io/file tmp-dir "local-repo" "demo" "demo" "1.0.0" "demo-1.0.0.jar")) files)))))) (testing "exclusions in managed coordinates are honored" (let [deps (aether/resolve-dependencies :repositories test-repo :coordinates '[[demo/demo2]] :managed-coordinates '[[demo/demo2 "1.0.0" :exclusions [demo/demo]]] :local-repo tmp-local-repo-dir) files (aether/dependency-files deps)] (is (= 1 (count files))) (is (= 1 (count (filter #(file-path-eq % (io/file tmp-dir "local-repo" "demo" "demo2" "1.0.0" "demo2-1.0.0.jar")) files)))))) (testing "classifiers in managed coordinates are honored" (let [deps (aether/resolve-dependencies :repositories test-repo :coordinates '[[demo/demo] [demo/demo nil :classifier "test"]] :managed-coordinates '[[demo/demo "1.0.0"] [demo/demo "1.0.1" :classifier "test"]] :local-repo tmp-local-repo-dir) files (aether/dependency-files deps)] (is (= 2 (count files))) (is (= 1 (count (filter #(file-path-eq % (io/file tmp-dir "local-repo" "demo" "demo" "1.0.0" "demo-1.0.0.jar")) files)))) (is (= 1 (count (filter #(file-path-eq % (io/file tmp-dir "local-repo" "demo" "demo" "1.0.1" "demo-1.0.1-test.jar")) files))))))) (deftest deploy-jar (aether/deploy :coordinates '[group/artifact "1.0.0"] :jar-file (io/file "test-repo" "demo" "demo" "1.0.0" "demo-1.0.0.jar") :repository tmp-remote-repo :local-repo tmp-local-repo-dir) (is (= 3 (count (.list (io/file tmp-remote-repo-dir "group" "artifact" "1.0.0")))))) (deftest deploy-jar-with-pom (aether/deploy :coordinates '[group/artifact "1.0.0"] :jar-file (io/file "test-repo" "demo" "demo" "1.0.0" "demo-1.0.0.jar") :pom-file (io/file "test-repo" "demo" "demo" "1.0.0" "demo-1.0.0.pom") :repository tmp-remote-repo :local-repo tmp-local-repo-dir) (is (= 6 (count (.list (io/file tmp-remote-repo-dir "group" "artifact" "1.0.0")))))) (deftest deploy-jar-with-artifact-map (let [repo-file (partial io/file "test-repo" "demo" "demo" "1.0.0")] (aether/deploy :coordinates '[group/artifact "1.0.0"] :artifact-map {[] (repo-file "demo-1.0.0.pom") [:extension "pom"] (repo-file "demo-1.0.0.pom")} :repository tmp-remote-repo :local-repo tmp-local-repo-dir)) (is (= 6 (count (.list (io/file tmp-remote-repo-dir "group" "artifact" "1.0.0")))))) (deftest install-jar (aether/install :coordinates '[group/artifact "1.0.0"] :jar-file (io/file "test-repo" "demo" "demo" "1.0.0" "demo-1.0.0.jar") :pom-file (io/file "test-repo" "demo" "demo" "1.0.0" "demo-1.0.0.pom") :local-repo tmp-local-repo-dir) (is (= 3 (count (.list (io/file tmp-local-repo-dir "group" "artifact" "1.0.0")))))) (deftest install-jar-with-artifact-map (let [repo-file (partial io/file "test-repo" "demo" "demo" "1.0.0")] (aether/install :coordinates '[group/artifact "1.0.0"] :artifact-map {[] (repo-file "demo-1.0.0.jar") [:extension "pom"] (repo-file "demo-1.0.0.pom")} :local-repo tmp-local-repo-dir)) (is (= 3 (count (.list (io/file tmp-local-repo-dir "group" "artifact" "1.0.0")))))) (java.lang.System/setProperty "aether.checksums.forSignature" "true") (deftest deploy-artifacts (aether/deploy-artifacts :artifacts '[[demo "1.0.0"] [demo "1.0.0" :extension "jar.asc"] [demo "1.0.0" :extension "pom"] [demo "1.0.0" :extension "pom.asc"]] ;; note: the .asc files in the test-repo are dummies, but it doesn't matter for this test :files {'[demo "1.0.0"] (io/file "test-repo" "demo" "demo" "1.0.0" "demo-1.0.0.jar") '[demo "1.0.0" :extension "jar.asc"] (io/file "test-repo" "demo" "demo" "1.0.0" "demo-1.0.0.jar.asc") '[demo "1.0.0" :extension "pom"] (io/file "test-repo" "demo" "demo" "1.0.0" "demo-1.0.0.pom") '[demo "1.0.0" :extension "pom.asc"] (io/file "test-repo" "demo" "demo" "1.0.0" "demo-1.0.0.pom.asc")} :repository tmp-remote-repo :local-repo tmp-local-repo-dir) (is (= #{"demo-1.0.0.pom.md5" "demo-1.0.0.pom.sha1" "demo-1.0.0.pom" "demo-1.0.0.pom.asc.md5" "demo-1.0.0.pom.asc.sha1" "demo-1.0.0.pom.asc" "demo-1.0.0.jar.md5" "demo-1.0.0.jar.sha1" "demo-1.0.0.jar" "demo-1.0.0.jar.asc.md5" "demo-1.0.0.jar.asc.sha1" "demo-1.0.0.jar.asc"} (set (.list (io/file tmp-remote-repo-dir "demo" "demo" "1.0.0")))) "Should deploy correctly demo \"1.0.0\"") (is (= '{[demo "1.0.0"] nil} (aether/resolve-dependencies :repositories tmp-remote-repo :coordinates '[[demo "1.0.0"]] :local-repo tmp-local-repo2-dir))) (is (= '{[demo "1.0.0" :extension "pom"] nil} (aether/resolve-dependencies :repositories tmp-remote-repo :coordinates '[[demo "1.0.0" :extension "pom"]] :local-repo tmp-local-repo2-dir))) (is (= '{[demo "1.0.0" :extension "jar.asc"] nil} (aether/resolve-dependencies :repositories tmp-remote-repo :coordinates '[[demo "1.0.0" :extension "jar.asc"]] :local-repo tmp-local-repo2-dir))) (is (= '{[demo "1.0.0" :extension "pom.asc"] nil} (aether/resolve-dependencies :repositories tmp-remote-repo :coordinates '[[demo "1.0.0" :extension "pom.asc"]] :local-repo tmp-local-repo2-dir)))) (deftest install-artifacts (aether/install-artifacts :artifacts '[[demo "1.0.0"] [demo "1.0.0" :extension "jar.asc"] [demo "1.0.0" :extension "pom"] [demo "1.0.0" :extension "pom.asc"]] ;; note: the .asc files in the test-repo are dummies, but it doesn't matter for this test :files {'[demo "1.0.0"] (io/file "test-repo" "demo" "demo" "1.0.0" "demo-1.0.0.jar") '[demo "1.0.0" :extension "jar.asc"] (io/file "test-repo" "demo" "demo" "1.0.0" "demo-1.0.0.jar.asc") '[demo "1.0.0" :extension "pom"] (io/file "test-repo" "demo" "demo" "1.0.0" "demo-1.0.0.pom") '[demo "1.0.0" :extension "pom.asc"] (io/file "test-repo" "demo" "demo" "1.0.0" "demo-1.0.0.pom.asc")} :local-repo tmp-local-repo-dir) (is (= #{"demo-1.0.0.jar" "demo-1.0.0.pom" "demo-1.0.0.jar.asc" "demo-1.0.0.pom.asc" "_remote.repositories"} (set (.list (io/file tmp-local-repo-dir "demo" "demo" "1.0.0")))))) (deftest deploy-exceptions (is (thrown-with-msg? IllegalArgumentException #"Provided artifacts have varying" (aether/deploy-artifacts :artifacts '[[demo "1.0.0"] [group/demo "1.0.0" :extension "jar.asc"]] :files {'[demo "1.0.0"] (io/file "test-repo" "demo" "demo" "1.0.0" "demo-1.0.0.jar") '[group/demo "1.0.0" :extension "jar.asc"] (io/file "test-repo" "demo" "demo" "1.0.0" "demo-1.0.0.jar.asc")} :repository tmp-remote-repo :local-repo tmp-local-repo-dir))) (is (thrown-with-msg? IllegalArgumentException #"Provided artifacts have varying version, group, or artifact IDs" (aether/deploy-artifacts :artifacts '[[demo "1.0.0"] [demo/artifact "1.0.0" :extension "jar.asc"]] :files {'[demo "1.0.0"] (io/file "test-repo" "demo" "demo" "1.0.0" "demo-1.0.0.jar") '[demo/artifact "1.0.0" :extension "jar.asc"] (io/file "test-repo" "demo" "demo" "1.0.0" "demo-1.0.0.jar.asc")} :repository tmp-remote-repo :local-repo tmp-local-repo-dir))) (is (thrown-with-msg? IllegalArgumentException #"Provided artifacts have varying version, group, or artifact IDs" (aether/deploy-artifacts :artifacts '[[demo "1.0.0"] [demo "1.1.0" :extension "jar.asc"]] :files {'[demo "1.0.0"] (io/file "test-repo" "demo" "demo" "1.0.0" "demo-1.0.0.jar") '[demo "1.1.0" :extension "jar.asc"] (io/file "test-repo" "demo" "demo" "1.0.0" "demo-1.0.0.jar.asc")} :repository tmp-remote-repo :local-repo tmp-local-repo-dir))) (is (thrown-with-msg? IllegalArgumentException #"Provided artifacts have varying version, group, or artifact IDs" (aether/deploy-artifacts :files {'[demo "1.0.0"] (io/file "test-repo" "demo" "demo" "1.0.0" "demo-1.0.0.jar") '[demo "1.1.0" :extension "jar.asc"] (io/file "test-repo" "demo" "demo" "1.0.0" "demo-1.0.0.jar")} :repository tmp-remote-repo :local-repo tmp-local-repo-dir)))) (deftest within?-comparisons (is (aether/within? '[demo "0.0.1"] '[demo "0.0.1"])) (is (aether/within? '[demo "0.0.1"] '[demo/demo "0.0.1"])) (is (aether/within? '[demo/demo "0.0.1"] '[demo "0.0.1"])) (is (aether/within? '[demo "0.0.1"] '[demo "[0.0.1,2.0.0)"])) (is (not (aether/within? '[demo "2.0.0"] '[demo "[0.0.1,2.0.0)"]))) (is (not (aether/within? '[demo "0.0.1"] '[demo "(0.0.1,2.0.0)"]))) (is (aether/within? '[demo "0.0.1-SNAPSHOT"] '[demo/demo "0.0.1-SNAPSHOT"])) (is (aether/within? '[demo "0.0.1-SNAPSHOT"] '[demo "0.0.1-SNAPSHOT"])) (is (aether/within? '[demo "0.0.1-20120403.012847-1"] '[demo "0.0.1-SNAPSHOT"])) (is (not (aether/within? '[demo "0.0.1-SNAPSHOT"] '[demo "0.0.1-20120403.012847-10"]))) (is (aether/within? '[demo "0.0.1"] '[demo "0.0.1" :extension "jar"])) (is (aether/within? '[demo "0.0.1" :extension "jar"] '[demo "0.0.1"])) (is (not (aether/within? '[demo "0.0.1" :extension "pom"] '[demo "0.0.1"]))) (is (not (aether/within? '[demo "0.0.1"] '[demo "0.0.1":extension "pom"]))) (is (aether/within? '[demo "0.0.1" :classifier "sources"] '[demo "0.0.1" :classifier "sources"])) (is (not (aether/within? '[demo "0.0.1"] '[demo "0.0.1" :classifier "sources"]))) (is (not (aether/within? '[demo "0.0.1" :classifier "sources"] '[demo "0.0.1"]))) (is (aether/within? '[demo "0.0.1"] '[demo "0.0.1" :scope "compile"])) (is (aether/within? '[demo "0.0.1" :scope "compile"] '[demo "0.0.1"])) (is (aether/within? '[demo "0.0.1" :scope "compile"] '[demo "0.0.1" :scope "compile"])) (is (not (aether/within? '[demo "0.0.1" :scope "compile"] '[demo "0.0.1" :scope "test"]))) (is (not (aether/within? '[demo "0.0.1" :scope "test"] '[demo "0.0.1" :scope "compile"]))) (is (aether/within? '[demo "0.0.1"] '[demo "0.0.1" :optional false])) (is (aether/within? '[demo "0.0.1" :optional false] '[demo "0.0.1"])) (is (aether/within? '[demo "0.0.1" :optional true] '[demo "0.0.1" :optional true])) (is (not (aether/within? '[demo "0.0.1" :optional true] '[demo "0.0.1"]))) (is (not (aether/within? '[demo "0.0.1"] '[demo "0.0.1":optional true]))) (is (aether/within? '[demo "0.0.1" :exclusions []] '[demo "0.0.1"])) (is (aether/within? '[demo "0.0.1"] '[demo "0.0.1" :exclusions []])) (is (aether/within? '[demo "0.0.1" :exclusions [[demo2]]] '[demo "0.0.1" :exclusions [[demo2]]])) (is (not (aether/within? '[demo "0.0.1" :exclusions [[demo2]]] '[demo "0.0.1"]))) (is (not (aether/within? '[demo "0.0.1"] '[demo "0.0.1" :exclusions [[demo2]]]))) (is (not (aether/within? '[demo "0.0.1" :exclusions [demo2]] '[demo "0.0.1"]))) (is (not (aether/within? '[demo "0.0.1"] '[demo "0.0.1" :exclusions [demo2]]))) (is (aether/within? '[demo "0.0.1" :exclusions [[demo2] [demo3]]] '[demo "0.0.1" :exclusions [[demo2] [demo3]]])) (is (aether/within? '[demo "0.0.1" :exclusions [[demo3] [demo2]]] '[demo "0.0.1" :exclusions [[demo2] [demo3]]])) (is (not (aether/within? '[demo "0.0.1" :exclusions [[demo2]]] '[demo "0.0.1" :exclusions [[demo2] [demo3]]]))) (is (not (aether/within? '[demo "0.0.1" :exclusions [[demo2] [demo3]]] '[demo "0.0.1" :exclusions [[demo2]]]))) (is (aether/within? '[demo "0.0.1" :exclusions [[demo2]]] '[demo "0.0.1" :exclusions [[demo2 :classifier "*"]]])) (is (aether/within? '[demo "0.0.1" :exclusions [[demo2 :classifier "*"]]] '[demo "0.0.1" :exclusions [[demo2]]])) (is (not (aether/within? '[demo "0.0.1" :exclusions [[demo2 :classifier "*"]]] '[demo "0.0.1" :exclusions [[demo2 :classifier "sources"]]]))) (is (not (aether/within? '[demo "0.0.1" :exclusions [[demo2 :classifier "sources"]]] '[demo "0.0.1" :exclusions [[demo2 :classifier "*"]]]))) (is (aether/within? '[demo "0.0.1" :exclusions [[demo2]]] '[demo "0.0.1" :exclusions [[demo2 :extension "*"]]])) (is (aether/within? '[demo "0.0.1" :exclusions [[demo2 :extension "*"]]] '[demo "0.0.1" :exclusions [[demo2]]])) (is (not (aether/within? '[demo "0.0.1" :exclusions [[demo2 :extension "*"]]] '[demo "0.0.1" :exclusions [[demo2 :extension "jar"]]]))) (is (not (aether/within? '[demo "0.0.1" :exclusions [[demo2 :extension "jar"]]] '[demo "0.0.1" :exclusions [[demo2 :extension "*"]]])))) (deftest dependency-hierarchy-matching (let [coords '[[demo/demo2 "[0.0.1,2.0.0)"] [tester "0.1.0-SNAPSHOT"]] deps (aether/resolve-dependencies :repositories test-repo :coordinates coords :local-repo tmp-local-repo-dir)] (is (= {['demo/demo2 "1.0.0"] {['demo "1.0.0"] nil} ['tester "0.1.0-20120403.012847-1"] nil} (aether/dependency-hierarchy coords deps))))) (deftest make-repository-proxy-settings (let [repo (first test-remote-repo) proxy {:type "https" :host "squid" :port 3128}] (testing "plain proxy" (let [repo-proxy (->> proxy (aether/make-repository repo) .getProxy bean)] (is (= proxy (select-keys repo-proxy (keys proxy)))) (is (not (:authentication repo-proxy))))) (testing "authentication" (let [repo-proxy (->> (assoc proxy :username "me" :password "123456") (aether/make-repository repo) .getProxy bean)] (is (= proxy (select-keys repo-proxy (keys proxy)))) (is (:authentication repo-proxy)))))) ;; taken from the test suite for the pendantic lib by Nelson Morris (defn get-versions [name repo] (let [name (symbol name)] (map second (filter #(= name (first %)) (keys repo))))) (defn make-pom-string [name version deps] (str " 4.0.0 " name " " name " jar " version " " name "" (if-not (empty? deps) (apply str "" (clojure.string/join "\n" (for [[n v] deps] (str " " n " "n" "v" "))) "")) " ")) (defn make-metadata [name versions] (str " " name " " name " " (clojure.string/join "\n" (for [v versions] (str ""v""))) " 20120810193549 ")) (def fake-repo '{[a "1"] [] [a "2"] [] [aa "2"] [[a "2"]]}) (deftest register-fake-wagon (aether/register-wagon-factory! "fake" #(reify org.apache.maven.wagon.Wagon (getRepository [_] (proxy [org.apache.maven.wagon.repository.Repository] [])) (^void connect [_ ^org.apache.maven.wagon.repository.Repository _ ^org.apache.maven.wagon.authentication.AuthenticationInfo _ ^org.apache.maven.wagon.proxy.ProxyInfoProvider _]) (disconnect [_]) (removeTransferListener [_ _]) (addTransferListener [_ _]) (setTimeout [_ _]) (setInteractive [_ _]) (get [_ name file] (let [[n _ version] (clojure.string/split name #"/")] (if (= name (str n "/" n "/maven-metadata.xml")) (if-let [versions (get-versions n fake-repo)] (spit file (make-metadata n versions)) (spit file "")) (if-let [deps (fake-repo [(symbol n) version])] (if (re-find #".pom$" name) (spit file (make-pom-string n version deps)) (spit file "")) (throw (org.apache.maven.wagon.ResourceDoesNotExistException. "")))))))) (let [tmp-local-repo-dir (io/file tmp-dir "local-repo")] (aether/resolve-dependencies :coordinates '[[a "1"]] :repositories {"test-repo" {:url "fake://ss" :checksum :ignore}} :local-repo tmp-local-repo-dir) (is (= #{"local-repo" "a" "1" "a-1.pom" "_remote.repositories" "a-1.jar"} (set (map (memfn getName) (file-seq tmp-local-repo-dir))))))) (comment "tests needed for: repository authentication repository policies dependency options (scope/optional) exclusion options (classifier/extension)") pomegranate-14f2f2517553223344a6913fe59f02847fe9f060/src/test/clojure/cemerick/pomegranate_test.clj000066400000000000000000000012131335473444400314240ustar00rootroot00000000000000(ns cemerick.pomegranate-test (:require [cemerick.pomegranate :as p] clojure.java.io) (:use clojure.test)) (deftest resources (is (= (first (p/resources "META-INF/MANIFEST.MF")) (clojure.java.io/resource "META-INF/MANIFEST.MF"))) ; the last classloader should be ext, for e.g. $JAVA_HOME/lib/ext/* (is (->> (p/resources [(last (p/classloader-hierarchy))] "META-INF/MANIFEST.MF") (map str) (filter #(.contains % "clojure")) empty?)) (is (->> (p/resources (butlast (p/classloader-hierarchy)) "META-INF/MANIFEST.MF") (map str) (filter #(.contains % "clojure")) seq)))pomegranate-14f2f2517553223344a6913fe59f02847fe9f060/test-repo/000077500000000000000000000000001335473444400223235ustar00rootroot00000000000000pomegranate-14f2f2517553223344a6913fe59f02847fe9f060/test-repo/demo/000077500000000000000000000000001335473444400232475ustar00rootroot00000000000000pomegranate-14f2f2517553223344a6913fe59f02847fe9f060/test-repo/demo/demo/000077500000000000000000000000001335473444400241735ustar00rootroot00000000000000pomegranate-14f2f2517553223344a6913fe59f02847fe9f060/test-repo/demo/demo/1.0.0/000077500000000000000000000000001335473444400246275ustar00rootroot00000000000000pomegranate-14f2f2517553223344a6913fe59f02847fe9f060/test-repo/demo/demo/1.0.0/demo-1.0.0.jar000066400000000000000000000000001335473444400266710ustar00rootroot00000000000000pomegranate-14f2f2517553223344a6913fe59f02847fe9f060/test-repo/demo/demo/1.0.0/demo-1.0.0.jar.asc000066400000000000000000000001711335473444400274470ustar00rootroot00000000000000This file here only to test deployment operations; the fact that this isn't a signature file shouldn't cause any issues. demo-1.0.0.jar.asc.md5000066400000000000000000000000651335473444400300560ustar00rootroot00000000000000pomegranate-14f2f2517553223344a6913fe59f02847fe9f060/test-repo/demo/demo/1.0.0b5f91153fbd3dc8bc29e98c73d46655f demo-1.0.0.jar.asc demo-1.0.0.jar.asc.sha1000066400000000000000000000000751335473444400302260ustar00rootroot00000000000000pomegranate-14f2f2517553223344a6913fe59f02847fe9f060/test-repo/demo/demo/1.0.0d94055dca4e0f2bcc455e278287dcf0e7c4034e1 demo-1.0.0.jar.asc pomegranate-14f2f2517553223344a6913fe59f02847fe9f060/test-repo/demo/demo/1.0.0/demo-1.0.0.jar.md5000066400000000000000000000000401335473444400273610ustar00rootroot00000000000000d41d8cd98f00b204e9800998ecf8427epomegranate-14f2f2517553223344a6913fe59f02847fe9f060/test-repo/demo/demo/1.0.0/demo-1.0.0.jar.sha1000066400000000000000000000000501335473444400275310ustar00rootroot00000000000000da39a3ee5e6b4b0d3255bfef95601890afd80709pomegranate-14f2f2517553223344a6913fe59f02847fe9f060/test-repo/demo/demo/1.0.0/demo-1.0.0.pom000066400000000000000000000007041335473444400267230ustar00rootroot00000000000000 4.0.0 demo demo 1.0.0 POM was created from install:install-file pomegranate-14f2f2517553223344a6913fe59f02847fe9f060/test-repo/demo/demo/1.0.0/demo-1.0.0.pom.asc000066400000000000000000000001711335473444400274660ustar00rootroot00000000000000This file here only to test deployment operations; the fact that this isn't a signature file shouldn't cause any issues. demo-1.0.0.pom.asc.md5000066400000000000000000000000651335473444400300750ustar00rootroot00000000000000pomegranate-14f2f2517553223344a6913fe59f02847fe9f060/test-repo/demo/demo/1.0.0b5f91153fbd3dc8bc29e98c73d46655f demo-1.0.0.pom.asc demo-1.0.0.pom.asc.sha1000066400000000000000000000000751335473444400302450ustar00rootroot00000000000000pomegranate-14f2f2517553223344a6913fe59f02847fe9f060/test-repo/demo/demo/1.0.0d94055dca4e0f2bcc455e278287dcf0e7c4034e1 demo-1.0.0.pom.asc pomegranate-14f2f2517553223344a6913fe59f02847fe9f060/test-repo/demo/demo/1.0.0/demo-1.0.0.pom.md5000066400000000000000000000000401335473444400274000ustar00rootroot000000000000005689f1eaf926240885eb9976e5269e5dpomegranate-14f2f2517553223344a6913fe59f02847fe9f060/test-repo/demo/demo/1.0.0/demo-1.0.0.pom.sha1000066400000000000000000000000501335473444400275500ustar00rootroot00000000000000eb4ff44542c69c5271390dad76a96bfd15b4858apomegranate-14f2f2517553223344a6913fe59f02847fe9f060/test-repo/demo/demo/1.0.1/000077500000000000000000000000001335473444400246305ustar00rootroot00000000000000pomegranate-14f2f2517553223344a6913fe59f02847fe9f060/test-repo/demo/demo/1.0.1/demo-1.0.1-test.jar000066400000000000000000000026211335473444400276630ustar00rootroot00000000000000PK EFH META-INF/PKEFHMETA-INF/MANIFEST.MFMLK-. K-*ϳR03r*)uRH.(LNzdT[r9&:$&g*&)Yr9%gd!LI(-VIrrPK#‹nPK EFHMETA-INF/maven/PK EFHMETA-INF/maven/demo/PK EFHMETA-INF/maven/demo/demo/PK:FH META-INF/maven/demo/demo/pom.xmlSn0+wV= JZRի .!l?D* ~f ƺjkxRMjڳіf'((Fqh(Y= n |QHE|+:7 )F[02:8'\U_LHmB aYw[NrVs , kz77^ ~e`eS3+~MUZ3ج܄=۫lzܻ=z\$ldY7\Kꖙt QLȄgm?X }DCi 4.0.0 demo demo 1.0.1 jar org.apache.maven.plugins maven-jar-plugin 2.6 test-jar pomegranate-14f2f2517553223344a6913fe59f02847fe9f060/test-repo/demo/demo/1.0.1/demo-1.0.1.pom.md5000066400000000000000000000000401335473444400274020ustar00rootroot00000000000000f446abedf7d50932d78ba5c18b0f0af1pomegranate-14f2f2517553223344a6913fe59f02847fe9f060/test-repo/demo/demo/1.0.1/demo-1.0.1.pom.sha1000066400000000000000000000000501335473444400275520ustar00rootroot000000000000001b3cb49c9986afc15b5267979a10fdf50afb54e9pomegranate-14f2f2517553223344a6913fe59f02847fe9f060/test-repo/demo/demo/maven-metadata.xml000066400000000000000000000004771335473444400276110ustar00rootroot00000000000000 demo demo 1.0.1 1.0.0 1.0.1 20160207024909 pomegranate-14f2f2517553223344a6913fe59f02847fe9f060/test-repo/demo/demo/maven-metadata.xml.md5000066400000000000000000000000401335473444400302570ustar00rootroot00000000000000e6f14a2cc8e218d3449163ec25257d60pomegranate-14f2f2517553223344a6913fe59f02847fe9f060/test-repo/demo/demo/maven-metadata.xml.sha1000066400000000000000000000000501335473444400304270ustar00rootroot0000000000000085569d708319d8377dddcd3f680fc37a391b7c81pomegranate-14f2f2517553223344a6913fe59f02847fe9f060/test-repo/demo/demo2/000077500000000000000000000000001335473444400242555ustar00rootroot00000000000000pomegranate-14f2f2517553223344a6913fe59f02847fe9f060/test-repo/demo/demo2/1.0.0/000077500000000000000000000000001335473444400247115ustar00rootroot00000000000000pomegranate-14f2f2517553223344a6913fe59f02847fe9f060/test-repo/demo/demo2/1.0.0/demo2-1.0.0.jar000066400000000000000000000000001335473444400270350ustar00rootroot00000000000000pomegranate-14f2f2517553223344a6913fe59f02847fe9f060/test-repo/demo/demo2/1.0.0/demo2-1.0.0.jar.md5000066400000000000000000000000401335473444400275250ustar00rootroot00000000000000d41d8cd98f00b204e9800998ecf8427epomegranate-14f2f2517553223344a6913fe59f02847fe9f060/test-repo/demo/demo2/1.0.0/demo2-1.0.0.jar.sha1000066400000000000000000000000501335473444400276750ustar00rootroot00000000000000da39a3ee5e6b4b0d3255bfef95601890afd80709pomegranate-14f2f2517553223344a6913fe59f02847fe9f060/test-repo/demo/demo2/1.0.0/demo2-1.0.0.pom000066400000000000000000000011551335473444400270700ustar00rootroot00000000000000 4.0.0 demo demo2 1.0.0 POM was created from install:install-file demo demo 1.0.0 pomegranate-14f2f2517553223344a6913fe59f02847fe9f060/test-repo/demo/demo2/1.0.0/demo2-1.0.0.pom.md5000066400000000000000000000000401335473444400275440ustar00rootroot0000000000000079893caa8e0888232ed9dfe56e396172pomegranate-14f2f2517553223344a6913fe59f02847fe9f060/test-repo/demo/demo2/1.0.0/demo2-1.0.0.pom.sha1000066400000000000000000000000501335473444400277140ustar00rootroot00000000000000d2a795ccaccf9ade57f7938c390368eeb2e842e7pomegranate-14f2f2517553223344a6913fe59f02847fe9f060/test-repo/demo/demo2/maven-metadata.xml000066400000000000000000000004411335473444400276620ustar00rootroot00000000000000 demo demo2 1.0.0 1.0.0 20120403045648 pomegranate-14f2f2517553223344a6913fe59f02847fe9f060/test-repo/demo/demo2/maven-metadata.xml.md5000066400000000000000000000000401335473444400303410ustar00rootroot000000000000008550a6918ed8fe0cf9ff6e08e61c4d8cpomegranate-14f2f2517553223344a6913fe59f02847fe9f060/test-repo/demo/demo2/maven-metadata.xml.sha1000066400000000000000000000000501335473444400305110ustar00rootroot00000000000000c38f519e44c887aa563201af58779379cbee4b18pomegranate-14f2f2517553223344a6913fe59f02847fe9f060/test-repo/tester/000077500000000000000000000000001335473444400236315ustar00rootroot00000000000000pomegranate-14f2f2517553223344a6913fe59f02847fe9f060/test-repo/tester/tester/000077500000000000000000000000001335473444400251375ustar00rootroot00000000000000pomegranate-14f2f2517553223344a6913fe59f02847fe9f060/test-repo/tester/tester/0.1.0-SNAPSHOT/000077500000000000000000000000001335473444400270305ustar00rootroot00000000000000maven-metadata.xml000066400000000000000000000013721335473444400323620ustar00rootroot00000000000000pomegranate-14f2f2517553223344a6913fe59f02847fe9f060/test-repo/tester/tester/0.1.0-SNAPSHOT tester tester 0.1.0-SNAPSHOT 20120403.012847 1 20120403012847 jar 0.1.0-20120403.012847-1 20120403012847 pom 0.1.0-20120403.012847-1 20120403012847 maven-metadata.xml.md5000066400000000000000000000000401335473444400330350ustar00rootroot00000000000000pomegranate-14f2f2517553223344a6913fe59f02847fe9f060/test-repo/tester/tester/0.1.0-SNAPSHOT32f77845f3013e9010130dd3c5056d35maven-metadata.xml.sha1000066400000000000000000000000501335473444400332050ustar00rootroot00000000000000pomegranate-14f2f2517553223344a6913fe59f02847fe9f060/test-repo/tester/tester/0.1.0-SNAPSHOT34f980dd6a45ef4ad423c27315015580f5e8c996tester-0.1.0-20120403.012847-1.jar000066400000000000000000000032231335473444400332020ustar00rootroot00000000000000pomegranate-14f2f2517553223344a6913fe59f02847fe9f060/test-repo/tester/tester/0.1.0-SNAPSHOTPK @META-INF/MANIFEST.MFMLK-. K-*ϳR03r*)uR(KL/J+r.JM,IM fe楧)errPK39QRPK @$META-INF/maven/tester/tester/pom.xml]o 8.PMjUJhR|a@8iV/x/徖ZiQ*+6K~IBr|뽙l`-n`uE!{'f.kМDWc.9I} ,m()<.봋P31ʇ4 Vԣh b¬όQm",{4.0.0testertester0.1.0-SNAPSHOTtesterFIXME: write descriptionhttp://example.com/FIXMEEclipse Public Licensehttp://www.eclipse.org/legal/epl-v10.html/workspace/tester/src/workspace/tester/test/workspace/tester/resources/workspace/tester/resourcescentralhttp://repo1.maven.org/maven2clojarshttp://clojars.org/repo/snapshotsfile:///tmp/snapshots tester-0.1.0-20120403.012847-1.pom.md5000066400000000000000000000000401335473444400336770ustar00rootroot00000000000000pomegranate-14f2f2517553223344a6913fe59f02847fe9f060/test-repo/tester/tester/0.1.0-SNAPSHOTf5550306172f01752d6483dd88528271tester-0.1.0-20120403.012847-1.pom.sha1000066400000000000000000000000501335473444400340470ustar00rootroot00000000000000pomegranate-14f2f2517553223344a6913fe59f02847fe9f060/test-repo/tester/tester/0.1.0-SNAPSHOTeb42a597bcb2ec429e5ba36ed9b16100a1e9a336pomegranate-14f2f2517553223344a6913fe59f02847fe9f060/test-repo/tester/tester/maven-metadata.xml000066400000000000000000000004201335473444400305410ustar00rootroot00000000000000 tester tester 0.1.0-SNAPSHOT 20120403012847 pomegranate-14f2f2517553223344a6913fe59f02847fe9f060/test-repo/tester/tester/maven-metadata.xml.md5000066400000000000000000000000401335473444400312230ustar00rootroot000000000000000748c7d4b7b9b6dc951840d798be8fdapomegranate-14f2f2517553223344a6913fe59f02847fe9f060/test-repo/tester/tester/maven-metadata.xml.sha1000066400000000000000000000000501335473444400313730ustar00rootroot0000000000000023c0ae6c73dc4c080e18d7664a88e9d6936b9521