1 | ;;;; The ABCL specific overrides in ASDF. |
---|
2 | ;;;; |
---|
3 | ;;;; Done separate from asdf.lisp for stability. |
---|
4 | (require :asdf) |
---|
5 | (in-package :asdf) |
---|
6 | |
---|
7 | (defclass iri (component) |
---|
8 | ((schema :initform nil) |
---|
9 | (authority :initform nil) |
---|
10 | (path :initform nil) |
---|
11 | (query :initform nil) |
---|
12 | (fragment :initform nil))) |
---|
13 | |
---|
14 | (defclass mvn (iri) |
---|
15 | ((group-id :initarg :group-id :initform nil) |
---|
16 | (artifact-id :initarg :artifact-id :initform nil) |
---|
17 | (repository :initform "http://repo1.maven.org/maven2/") ;;; XXX unimplmented |
---|
18 | ;; inherited from ASDF:COMPONENT ??? what are the CL semantics on overriding -- ME 2012-04-01 |
---|
19 | #+nil (version :initform nil))) |
---|
20 | |
---|
21 | #+nil |
---|
22 | (defmethod find-component ((component iri) path) |
---|
23 | component) |
---|
24 | |
---|
25 | |
---|
26 | ;;; We intercept compilation to ensure that load-op will succeed |
---|
27 | (defmethod perform ((op compile-op) (c mvn)) |
---|
28 | (abcl-asdf:resolve |
---|
29 | (ensure-parsed-mvn c))) |
---|
30 | |
---|
31 | (defmethod perform ((operation load-op) (c mvn)) |
---|
32 | (java:add-to-classpath |
---|
33 | (abcl-asdf:as-classpath |
---|
34 | (abcl-asdf:resolve |
---|
35 | (ensure-parsed-mvn c))))) |
---|
36 | |
---|
37 | ;;; A Maven URI has the form "mvn:group-id/artifact-id/version" |
---|
38 | ;;; |
---|
39 | ;;; Sometimes people write "group-id:artifact-id:version" to refer to |
---|
40 | ;;; Maven artifacts. One can use ABCL-ASDF:RESOLVE directly for |
---|
41 | ;;; serialized references to artifacts of this form. |
---|
42 | ;;; |
---|
43 | ;;; Currently we "stuff" the group-id/artifact-id into the 'name' and |
---|
44 | ;;; use the component 'version' for the version. Parts of ASDF |
---|
45 | ;;; *reallY* want ASDF:VERSION to be a triple of intergers, and never |
---|
46 | ;;; anything more, so that is part of the motivation behind this effort. |
---|
47 | (defparameter *mvn-repositories* nil |
---|
48 | "A list of all Maven repositories encountered in the lifetime of this instance of the implementation.") |
---|
49 | |
---|
50 | #+nil |
---|
51 | (defmethod slot-missing ((class mvn) object slot-name operation &optional new-value) |
---|
52 | (setf (slot-value object slot-name) |
---|
53 | (if new-value |
---|
54 | new-value |
---|
55 | nil))) |
---|
56 | |
---|
57 | (defun ensure-parsed-mvn (component) |
---|
58 | (with-slots (name group-id artifact-id |
---|
59 | version schema path repository) |
---|
60 | component |
---|
61 | (when (null asdf::artifact-id) |
---|
62 | (let ((parsed (abcl-asdf::split-string name "/")) |
---|
63 | (asdf-version-p (slot-boundp component 'version)) |
---|
64 | (default-version "LATEST")) |
---|
65 | (cond ((= (length parsed) 3) |
---|
66 | (setf |
---|
67 | group-id (first parsed) |
---|
68 | artifact-id (second parsed) |
---|
69 | version (third parsed))) |
---|
70 | ((= (length parsed) 2) |
---|
71 | (setf |
---|
72 | group-id (first parsed) |
---|
73 | artifact-id (second parsed) |
---|
74 | version (if asdf-version-p |
---|
75 | version |
---|
76 | default-version))) |
---|
77 | (t |
---|
78 | (error "Failed to construct a mvn reference from name '~A' and version '~A'" |
---|
79 | name version))) |
---|
80 | (setf schema "mvn") |
---|
81 | (pushnew repository *mvn-repositories*) |
---|
82 | ;;; Always normalized path "on the way out" to contain group-id/artifact-id/version |
---|
83 | (setf path (format nil "~A/~A/~A" group-id artifact-id version)))) |
---|
84 | component)) |
---|
85 | |
---|
86 | (export `(mvn iri ensure-parsed-mvn |
---|
87 | group-id artifact-id version) 'asdf) |
---|
88 | |
---|
89 | (defmethod source-file-type ((component iri) (system system)) |
---|
90 | nil) |
---|
91 | |
---|
92 | (defmethod component-relative-pathname ((component iri)) |
---|
93 | nil) |
---|
94 | |
---|
95 | (in-package #:abcl-asdf) |
---|
96 | |
---|
97 | (defgeneric resolve (something) |
---|
98 | (:documentation "Returns a string in JVM CLASSPATH format as entries delimited by classpath separator string.")) |
---|
99 | |
---|
100 | (defmethod resolve ((mvn-component asdf::mvn)) |
---|
101 | "Resolve all runtime dependencies of MVN-COMPONENT. |
---|
102 | |
---|
103 | Returns a string in JVM CLASSPATH format as entries delimited by classpath separator string." |
---|
104 | |
---|
105 | (with-slots (asdf::group-id asdf::artifact-id asdf::version) mvn-component |
---|
106 | (resolve-dependencies asdf::group-id asdf::artifact-id asdf::version))) |
---|
107 | |
---|
108 | (defun as-classpath (classpath) |
---|
109 | "Break apart the JVM CLASSPATH string into a list of its consituents." |
---|
110 | (split-string classpath |
---|
111 | (java:jfield "java.io.File" "pathSeparator"))) |
---|
112 | |
---|
113 | (defun split-string (string split-char) |
---|
114 | (loop :for i = 0 :then (1+ j) |
---|
115 | :as j = (position split-char string :test #'string-equal :start i) |
---|
116 | :collect (subseq string i j) |
---|
117 | :while j)) |
---|