source: trunk/abcl/contrib/abcl-asdf/maven-embedder.lisp @ 13362

Last change on this file since 13362 was 13362, checked in by Mark Evenson, 10 years ago

Dynamically find location of mvn libraries based on 'mvn' in PATH.

Will not work under win32 without an analog for UNIX 'which'.

Require maven-3.0.3 or greater as the Aether API for maven-3.0.2 does
not seem to have the same classes (ugh!).

Still does not seem to resolve dependencies that are not already
present in the local repository.

File size: 6.5 KB
Line 
1;;; Use the Aether system in a default maven distribution to download
2;;; and install dependencies.
3;;;
4;;; https://docs.sonatype.org/display/AETHER/Home
5;;;
6
7(in-package :abcl-asdf)
8
9(require :abcl-contrib)
10(require :jss)
11
12#|
13Test:
14
15(resolve "org.slf4j" "slf4j-api" "1.6.1")
16|#
17
18(defvar *mavens* '("/opt/local/bin/mvn3" "mvn3" "mvn"))
19
20(defun find-mvn () 
21  (dolist (mvn-path *mavens*)
22    (let ((mvn 
23           (handler-case 
24               (truename (read-line (sys::process-output 
25                                     (sys::run-program "which" `(,mvn-path)))))
26             ('end-of-file () 
27               nil))))
28      (when mvn
29        (return-from find-mvn mvn)))))
30
31(defun find-mvn-libs ()
32  (let ((mvn (find-mvn)))
33    (unless mvn
34      (warn "Failed to find Maven3 libraries.")
35      (return-from find-mvn-libs))
36    (truename (make-pathname 
37               :defaults (merge-pathnames "../lib/" mvn)
38               :name nil :type nil))))
39
40(defparameter *mvn-libs-directory*
41  nil
42  "Location of 'maven-core-3.<m>.<p>.jar', 'maven-embedder-3.<m>.<p>.jar' etc.")
43
44(defun mvn-version ()
45  (let ((line
46         (read-line (sys::process-output (sys::run-program 
47                                          (namestring (find-mvn)) '("-version")))))
48        (prefix "Apache Maven "))
49
50    (unless (eql (search prefix line) 0)
51      (return-from mvn-version nil))
52    (let ((version (subseq line (length prefix))))
53      version)))
54
55;;; XXX will break with release of Maven 3.1.x
56(defun ensure-mvn-version ()
57  "Return t if Maven version is 3.0.3 or greater."
58  (let ((version-string (mvn-version)))
59    (and (search "3.0" version-string)
60         (>= (parse-integer (subseq version-string 
61                                    4 (search " (" version-string)))
62             3))))
63
64(defparameter *init* nil)
65
66(defun init ()
67  (unless *mvn-libs-directory*
68    (setf *mvn-libs-directory* (find-mvn-libs)))
69  (unless (probe-file *mvn-libs-directory*)
70    (error "You must download maven-3.0.3 from http://maven.apache.org/download.html, then set ABCL-ASDF:*MVN-DIRECTORY* appropiately."))
71  (unless (ensure-mvn-version)
72    (error "We need maven-3.0.3 or later."))
73  (jss:add-directory-jars-to-class-path *mvn-libs-directory* nil)
74  (setf *init* t))
75
76(defun repository-system ()
77  (unless *init* (init))
78  (let ((locator 
79         (java:jnew "org.apache.maven.repository.internal.DefaultServiceLocator"))
80        (wagon-class 
81         (java:jclass "org.sonatype.aether.connector.wagon.WagonProvider"))
82        (wagon-provider 
83         (jss:find-java-class "LightweightHttpWagon"))
84        (repository-connector-factory-class
85         (java:jclass "org.sonatype.aether.connector.wagon.WagonRepositoryConnector"))
86        (wagon-repository-connector-factory-class
87         (java:jclass "org.sonatype.aether.connector.wagon.WagonRepositoryConnectorFactory"))
88        (repository-system-class
89         (java:jclass "org.sonatype.aether.RepositorySystem")))
90    (#"setService" locator wagon-class wagon-provider)
91    (#"addService" locator 
92                   repository-connector-factory-class
93                   wagon-repository-connector-factory-class)
94    (#"getService" locator repository-system-class)))
95
96#|
97private static RepositorySystem newRepositorySystem()
98{
99  DefaultServiceLocator locator = new DefaultServiceLocator();
100  locator.setServices( WagonProvider.class, new ManualWagonProvider() );
101  locator.addService( RepositoryConnectorFactory.class, WagonRepositoryConnectorFactory.class );
102
103  return locator.getService( RepositorySystem.class );
104}
105|#
106
107(defun new-session (repository-system)
108  (let ((session 
109         (java:jnew (jss:find-java-class "MavenRepositorySystemSession")))
110        (local-repository 
111         (java:jnew (jss:find-java-class "LocalRepository")
112                  (namestring (merge-pathnames ".m2/repository/"
113                                               (user-homedir-pathname))))))
114    (#"setLocalRepositoryManager" 
115     session
116     (#"newLocalRepositoryManager" repository-system local-repository))))
117
118#|
119private static RepositorySystemSession newSession( RepositorySystem system )
120{
121  MavenRepositorySystemSession session = new MavenRepositorySystemSession();
122
123  LocalRepository localRepo = new LocalRepository( "target/local-repo" );
124  session.setLocalRepositoryManager( system.newLocalRepositoryManager( localRepo ) );
125 
126  return session;
127}
128|#
129
130(defun resolve (group-id artifact-id version)
131  (unless *init* (init))
132  (let* ((system 
133          (repository-system))
134         (session 
135          (new-session system))
136         (artifact
137          (java:jnew (jss:find-java-class "aether.util.artifact.DefaultArtifact")
138                     (format nil "~A:~A:~A"
139                             group-id artifact-id version)))
140         (dependency 
141          (java:jnew (jss:find-java-class "aether.graph.Dependency")
142                     artifact "compile"))
143         (central
144          (java:jnew (jss:find-java-class "RemoteRepository")
145                     "central" "default" 
146                     "http://repo1.maven.org/maven2/"))
147         (collect-request (java:jnew (jss:find-java-class "CollectRequest"))))
148    (#"setRoot" collect-request dependency)
149    (#"addRepository" collect-request central)
150    (let* ((node 
151            (#"getRoot" (#"collectDependencies" system session collect-request)))
152           (dependency-request 
153            (java:jnew (jss:find-java-class "DependencyRequest")
154                       node java:+null+))
155           (nlg 
156            (java:jnew (jss:find-java-class "PreorderNodeListGenerator"))))
157      (#"resolveDependencies" system session dependency-request)
158      (#"accept" node nlg)
159      (#"getClassPath" nlg))))
160
161#|
162public static void main( String[] args )
163  throws Exception
164{
165  RepositorySystem repoSystem = newRepositorySystem();
166
167  RepositorySystemSession session = newSession( repoSystem );
168
169  Dependency dependency =
170    new Dependency( new DefaultArtifact( "org.apache.maven:maven-profile:2.2.1" ), "compile" );
171  RemoteRepository central = new RemoteRepository( "central", "default", "http://repo1.maven.org/maven2/" );
172
173  CollectRequest collectRequest = new CollectRequest();
174  collectRequest.setRoot( dependency );
175  collectRequest.addRepository( central );
176  DependencyNode node = repoSystem.collectDependencies( session, collectRequest ).getRoot();
177
178  DependencyRequest dependencyRequest = new DependencyRequest( node, null );
179
180  repoSystem.resolveDependencies( session, dependencyRequest  );
181
182  PreorderNodeListGenerator nlg = new PreorderNodeListGenerator();
183  node.accept( nlg );
184  System.out.println( nlg.getClassPath() );
185}
186|#
187
Note: See TracBrowser for help on using the repository browser.