abcl-asdf.lisp 2.79 KB
Newer Older
1
(in-package :asdf)
2 3 4 5 6 7
(defclass iri (component) 
  ((schema :initform nil)
   (authority :initform nil)
   (path :initform nil)
   (query :initform nil)
   (fragment :initform nil)))
8

9 10 11 12 13 14 15
(defclass mvn (iri) 
  ((group-id :initform nil)
   (artifact-id :initform nil)))

#+nil
(defmethod find-component ((component iri) path)
  component)
16

17
;;; We intercept compilation to ensure that load-op will succeed
18
(defmethod perform ((op compile-op) (c mvn))
19
  (maybe-parse-mvn c)
20
  (abcl-asdf:resolve c))
21
     
22
(defmethod perform ((operation load-op) (c mvn))
23 24 25
  (maybe-parse-mvn c)
  (java:add-to-classpath 
   (abcl-asdf:as-classpath 
26
    (abcl-asdf:resolve c))))
27 28 29 30 31 32 33

;;; A Maven URI has the form "mvn:group-id/artifact-id/version"
;;;
;;; Currently we "stuff" the group-id/artifact-id into the 'name' and
;;; use the component 'version' for the version string.
(defun maybe-parse-mvn (component)
  (with-slots (asdf::name asdf::group-id asdf::artifact-id
34 35
               asdf::version asdf::schema asdf::path) 
      component
36
    (when (null asdf::artifact-id) 
37 38 39 40
      (let ((parsed (abcl-asdf::split-string name "/")))
         (unless (or (= (length parsed) 3)
                     (and (= (length parsed) 2)
                          asdf::version))
41
          (error "Failed to construct a mvn reference from name '~A' and version '~A'"
42 43 44 45 46 47 48 49 50 51 52
                 asdf::name 
                 (if asdf::version
                     asdf::version
                     "UNSPECIFED")))
         (setf asdf::group-id (first parsed)
               asdf::artifact-id (second parsed)
               asdf::schema "mvn"
               asdf::version (if (third parsed)
                                 (third parsed)
                                 "LATEST"))
         (setf asdf::path (format nil "~A/~A" asdf::name asdf::version))))))
53 54 55 56 57 58

(defmethod source-file-type ((component iri) (system system))
  nil)

(defmethod component-relative-pathname ((component iri))
  nil)
59

60
(in-package #:abcl-asdf)
61

62
(defgeneric resolve (something)
63
 (:documentation "Returns a string in JVM CLASSPATH format as entries delimited by classpath separator string."))
64

65
(defmethod resolve ((mvn-component asdf::mvn))
66 67 68 69
  "Resolve all runtime dependencies of MVN-COMPONENT.

Returns a string in JVM CLASSPATH format as entries delimited by classpath separator string."
  
70 71 72
  (with-slots (asdf::group-id asdf::artifact-id asdf::version) mvn-component
    (resolve-dependencies asdf::group-id asdf::artifact-id asdf::version)))

73
(defun as-classpath (classpath)
74
  "Break apart the JVM CLASSPATH string into a list of its consituents."
75 76
  (split-string classpath 
                (java:jfield "java.io.File" "pathSeparator")))
77

78 79 80 81
(defun split-string (string split-char)
  (loop :for i = 0 :then (1+ j)
     :as j = (position split-char string :test #'string-equal :start i)
     :collect (subseq string i j)
82
     :while j))