Merge commit 'danlarkin/build-jar-in-memory'

This commit is contained in:
Phil Hagelberg 2009-11-24 22:20:18 -08:00
commit 39f6ab8be1
2 changed files with 79 additions and 34 deletions

View file

@ -1,19 +1,50 @@
(ns leiningen.jar (ns leiningen.jar
"Create a jar containing the compiled code and original source." "Create a jar containing the compiled code and original source."
(:require [leiningen.compile :as compile] (:require [leiningen.compile :as compile])
[lancet]) (:use [leiningen.pom :only [make-pom make-pom-properties]]
(:use [leiningen.pom :only [pom]] [clojure.contrib.duck-streams :only [to-byte-array copy]]
[clojure.contrib.duck-streams :only [spit]] [clojure.contrib.str-utils :only [str-join re-sub]]
[clojure.contrib.str-utils :only [str-join]])) [clojure.contrib.java-utils :only [file]])
(:import [java.util.jar Manifest JarEntry JarOutputStream]
[java.io BufferedOutputStream FileOutputStream
ByteArrayInputStream]))
(defn make-manifest [project] (defn make-manifest [project]
(doto (str (:root project) "/classes/Manifest.txt") (Manifest.
(spit (str-join "\n" (ByteArrayInputStream.
["Created-By: Leiningen" (to-byte-array
(str "Built-By: " (System/getProperty "user.name")) (str (str-join "\n"
(str "Build-Jdk: " (System/getProperty "java.version")) ["Manifest-Version: 1.0" ; DO NOT REMOVE!
(when-let [main (:main project)] "Created-By: Leiningen"
(str "Main-Class: " main))])))) (str "Built-By: " (System/getProperty "user.name"))
(str "Build-Jdk: " (System/getProperty "java.version"))
(when-let [main (:main project)]
(str "Main-Class: " main))])
"\n")))))
(defmulti copy-to-jar (fn [project jar-os spec] (:type spec)))
(defmethod copy-to-jar :path [project jar-os spec]
(doseq [child (file-seq (file (:path spec)))]
(when-not (.isDirectory child)
(let [path (str child)
path (re-sub (re-pattern (str "^" (:root project))) "" path)
path (re-sub #"^/classes" "" path)
path (re-sub #"^/src" "" path)
path (re-sub #"^/" "" path)]
(.putNextEntry jar-os (JarEntry. path))
(copy child jar-os)))))
(defmethod copy-to-jar :bytes [project jar-os spec]
(.putNextEntry jar-os (JarEntry. (:path spec)))
(copy (ByteArrayInputStream. (:bytes spec)) jar-os))
(defn write-jar [project out-filename filespecs]
(with-open [jar-os (JarOutputStream. (BufferedOutputStream.
(FileOutputStream. out-filename))
(make-manifest project))]
(doseq [filespec filespecs]
(copy-to-jar project jar-os filespec))))
(defn jar (defn jar
"Create a $PROJECT.jar file containing the compiled .class files as well as "Create a $PROJECT.jar file containing the compiled .class files as well as
@ -21,17 +52,21 @@ the source .clj files. If project.clj contains a :main symbol, it will be used
as the main-class for an executable jar." as the main-class for an executable jar."
([project jar-name] ([project jar-name]
(compile/compile project) (compile/compile project)
(pom project "pom-generated.xml" true)
(let [jar-file (str (:root project) "/" jar-name) (let [jar-file (str (:root project) "/" jar-name)
filesets [{:dir *compile-path*} filespecs [{:type :bytes
{:dir (str (:root project) "/src")} :path (format "meta-inf/maven/%s/%s/pom.xml"
;; TODO: place in META-INF/maven/$groupId/$artifactId/pom.xml (:group project)
;; TODO: pom.properties (:name project))
{:file (str (:root project) "/pom-generated.xml")} :bytes (make-pom project)}
{:file (str (:root project) "/project.clj")}]] {:type :bytes
:path (format "meta-inf/maven/%s/%s/pom.properties"
(:group project)
(:name project))
:bytes (make-pom-properties project)}
{:type :path :path *compile-path*}
{:type :path :path (str (:root project) "/src")}
{:type :path :path (str (:root project) "/project.clj")}]]
;; TODO: support slim, etc ;; TODO: support slim, etc
(apply lancet/jar {:jarfile jar-file (write-jar project jar-file filespecs)
:manifest (make-manifest project)}
(map lancet/fileset filesets))
jar-file)) jar-file))
([project] (jar project (str (:name project) ".jar")))) ([project] (jar project (str (:name project) ".jar"))))

View file

@ -1,9 +1,9 @@
(ns leiningen.pom (ns leiningen.pom
"Write a pom.xml file to disk for Maven interop." "Write a pom.xml file to disk for Maven interop."
(:require [lancet]) (:use [clojure.contrib.duck-streams :only [reader copy]]
(:use [clojure.contrib.duck-streams :only [reader writer]] [clojure.contrib.java-utils :only [file as-properties]])
[clojure.contrib.java-utils :only [file]]) (:import [java.io StringWriter]
(:import [org.apache.maven.model Model Parent Dependency Repository Scm] [org.apache.maven.model Model Parent Dependency Repository Scm]
[org.apache.maven.project MavenProject] [org.apache.maven.project MavenProject]
[org.apache.maven.artifact.ant Pom])) [org.apache.maven.artifact.ant Pom]))
@ -102,15 +102,25 @@
(.setScm model scm)) (.setScm model scm))
model)) model))
(defn make-pom [project] (defn make-pom
(doto (Pom.) ([project] (make-pom project false))
(.setProject lancet/ant-project) ([project disclaimer?]
(.setMavenProject (MavenProject. (make-model project))))) (with-open [w (StringWriter.)]
(.writeModel (MavenProject. (make-model project)) w)
(when disclaimer?
(.write w disclaimer))
(.getBytes (str w)))))
(defn make-pom-properties [project]
(with-open [w (StringWriter.)]
(.store (as-properties {:version (:version project)
:groupId (:group project)
:artifactId (:name project)})
w "Leiningen")
(.getBytes (str w))))
(defn pom [project & [pom-location silently?]] (defn pom [project & [pom-location silently?]]
(let [pom-file (file (:root project) (or pom-location "pom.xml"))] (let [pom-file (file (:root project) (or pom-location "pom.xml"))]
(with-open [w (writer pom-file)] (copy (make-pom project true) pom-file)
(.writeModel (MavenProject. (make-model project)) w) (when-not silently? (println "Wrote" (.getName pom-file)))
(.write w disclaimer)
(when-not silently? (println "Wrote" (.getName pom-file))))
(.getAbsolutePath pom-file))) (.getAbsolutePath pom-file)))