Permalink
Browse files

Copy pom.xml generation from depot

Take some code from depot
Take the git scm code from lein 1.x
Update sample.project.clj with multiple source/test directories and extensions
Creates a similiar pom for sample.project.clj as lein 1.x
Use build-helper-maven-plugin for multiple source directories
  • Loading branch information...
1 parent d4e86d2 commit ef2b0f0b9b0b1e1d2550ddd605ed973478332e70 @xeqi xeqi committed Jan 20, 2012
Showing with 267 additions and 47 deletions.
  1. +3 −1 project.clj
  2. +20 −9 sample.project.clj
  3. +2 −6 src/leiningen/jar.clj
  4. +234 −22 src/leiningen/pom.clj
  5. +6 −7 test/leiningen/test/pom.clj
  6. +2 −2 todo.org
View
@@ -8,7 +8,9 @@
:dependencies [[leiningen-core "2.0.0-SNAPSHOT"]
[clucy "0.2.2"]
[lancet "1.0.1"]
- [stencil "0.2.0"]]
+ [stencil "0.2.0"]
+ [useful "0.7.6-alpha1"]
+ [org.clojars.ninjudd/data.xml "0.0.1-SNAPSHOT"]]
:test-selectors {:default (complement :busted)}
:eval-in-leiningen true)
View
@@ -128,12 +128,15 @@
:username "milgrim" :password "locative.1"}
"snapshots" "http://blueant.com/archiva/internal/snapshots"}
;; If you'd rather use a different directory structure, you can set these.
- :source-path "src/main/clojure"
+ :source-path ["src" "src/main/clojure"]
:compile-path "target/classes" ; for .class files
:library-path "target/dependency" ; for .jar files
- :test-path "src/test/clojure"
- :resources-path "src/main/resource" ; non-code files included in classpath/jar
+ :test-path ["test" "src/test/clojure"]
+ :resources-path ["src/main/resource"] ; non-code files included in classpath/jar
+
+ ;;TODO: does dev-resources-path still do anything w/ profiles?
:dev-resources-path "src/test/resource" ; added to dev classpath but not jar
+
:native-path "src/native" ; where to look for native dependencies
:target-dir "target/ " ; where to place the project's jar file
:extra-classpath-dirs ["script"] ; more classpath entries not included in jar
@@ -156,14 +159,22 @@
;; If your project is a Leiningen plugin, set this to skip the subprocess step
:eval-in-leiningen false
;; Set parent for working with in a multi-module maven project
- :parent [org.example/parent "0.0.1" :relative-path "../parent/pom.xml"])
+ :parent [org.example/parent "0.0.1" :relative-path "../parent/pom.xml"]
+ ;; You can add extensions to the build process (such as add an ftp
+ ;; provider for the Wagon transport mechanism), as well as make
+ ;; plugins active which make changes to the build lifecycle.
+ :extensions [[org.apache.maven.wagon/wagon-webdav "1.0-beta-2"]
+ [foo/bar-baz "1.0"]])
+
+
+;;TODO: does the prepend-tasks function still exist?
;; You can use Robert Hooke to modify behaviour of any task function,
;; but the prepend-tasks function is shorthand that is more convenient
;; on tasks that take a single project argument.
-(use '[leiningen.core :only [prepend-tasks]]
- '[leiningen.deps :only [deps]]
- '[leiningen.clean :only [clean]]
- '[leiningen.pom :only [pom]])
+;; (use '[leiningen.core :only [prepend-tasks]]
+;; '[leiningen.deps :only [deps]]
+;; '[leiningen.clean :only [clean]]
+;; '[leiningen.pom :only [pom]])
-(prepend-tasks #'deps clean pom)
+;; (prepend-tasks #'deps clean pom)
View
@@ -4,7 +4,7 @@
[leiningen.core.classpath :as classpath]
[clojure.string :as string]
[clojure.java.io :as io])
- (:use [leiningen.pom :only [make-pom make-pom-properties]]
+ (:use [leiningen.pom :only [make-pom]]
[leiningen.deps :only [deps]])
(:import (java.util.jar Manifest JarEntry JarOutputStream)
(java.util.regex Pattern)
@@ -146,11 +146,7 @@
:path (format "META-INF/maven/%s/%s/pom.xml"
(:group project) (:name project))
;; TODO: use pom here
- :bytes (or (make-pom project) (.getBytes ""))}
- {:type :bytes
- :path (format "META-INF/maven/%s/%s/pom.properties"
- (:group project) (:name project))
- :bytes (make-pom-properties project)}
+ :bytes (.getBytes (or (make-pom project) ""))}
{:type :path :path (str (:root project) "/project.clj")}]
[{:type :path :path (:compile-path project)}
{:type :paths :paths (:resources-path project)}]
View
@@ -1,21 +1,242 @@
(ns leiningen.pom
"Write a pom.xml file to disk for Maven interop."
- (:use [leiningen.core.main :only [abort]]
- [clojure.java.io :only [copy file]])
- (:import (java.io StringWriter ByteArrayOutputStream)
- (java.util Properties)))
+ (:use [useful.string :only [camelize dasherize]])
+ (:require [leiningen.core.main :as main]
+ [leiningen.core.project :as project]
+ [clojure.java.io :as io]
+ [clojure.string :as s]
+ [clojure.data.xml :as xml]))
-(declare make-model)
+;; git scm
+
+(defn- read-git-ref
+ "Reads the commit SHA1 for a git ref path."
+ [git-dir ref-path]
+ (.trim (slurp (str (io/file git-dir ref-path)))))
+
+(defn- read-git-head
+ "Reads the value of HEAD and returns a commit SHA1."
+ [git-dir]
+ (let [head (.trim (slurp (str (io/file git-dir "HEAD"))))]
+ (if-let [ref-path (second (re-find #"ref: (\S+)" head))]
+ (read-git-ref git-dir ref-path)
+ head)))
+
+(defn- read-git-origin
+ "Reads the URL for the remote origin repository."
+ [git-dir]
+ (with-open [rdr (io/reader (io/file git-dir "config"))]
+ (->> (map #(.trim %) (line-seq rdr))
+ (drop-while #(not= "[remote \"origin\"]" %))
+ (next)
+ (take-while #(not (.startsWith % "[")))
+ (map #(re-matches #"url\s*=\s*(\S*)\s*" %))
+ (filter identity)
+ (first)
+ (second))))
+
+(defn- parse-github-url
+ "Parses a GitHub URL returning a [username repo] pair."
+ [url]
+ (when url
+ (next
+ (or
+ (re-matches #"(?:git@)?github.com:([^/]+)/([^/]+).git" url)
+ (re-matches #"[^:]+://(?:git@)?github.com/([^/]+)/([^/]+).git" url)))))
+
+(defn- github-urls [url]
+ (when-let [[user repo] (parse-github-url url)]
+ {:public-clone (str "git://github.com/" user "/" repo ".git")
+ :dev-clone (str "ssh://git@github.com/" user "/" repo ".git")
+ :browse (str "https://github.com/" user "/" repo)}))
+
+(defn- make-git-scm [git-dir]
+ (try
+ (let [origin (read-git-origin git-dir)
+ head (read-git-head git-dir)
+ urls (github-urls origin)]
+ [:scm
+ (when (:public-clone urls)
+ [:connection (str "scm:git:" (:public-clone urls))])
+ (when (:dev-clone urls)
+ [:developerConnection (str "scm:git:" (:dev-clone urls))])
+ [:tag head]
+ [:url (:browse urls)]])
+ (catch java.io.FileNotFoundException e
+ nil)))
(def #^{:doc "A notice to place at the bottom of generated files."} disclaimer
"\n<!-- This file was autogenerated by Leiningen.
Please do not edit it directly; instead edit project.clj and regenerate it.
It should not be considered canonical data. For more information see
https://github.com/technomancy/leiningen -->\n")
+(defn make-test-scope [[dep version opts]]
+ [dep version (assoc opts :scope "test")])
+
+(defn pomify [key]
+ (->> key name camelize keyword))
+
+(defmulti xml-tags
+ (fn [tag value] (keyword "leiningen.pom" (name tag))))
+
+(defmethod xml-tags :default
+ ([tag value]
+ (when value
+ [(pomify tag) value])))
+
+(defmethod xml-tags ::list
+ ([tag values]
+ [(pomify tag) (map (partial xml-tags
+ (-> tag name (s/replace #"ies$" "y") keyword))
+ values)]))
+
+(doseq [c [::dependencies ::repositories]]
+ (derive c ::list))
+
+(defmethod xml-tags ::exclusions
+ [tag values]
+ (when values
+ [:exclusions
+ (map
+ (fn [dep]
+ [:exclusion (map (partial apply xml-tags)
+ {:group-id (namespace dep)
+ :artifact-id (name dep)})])
+ values)]))
+
+(defmethod xml-tags ::dependency
+ ([_ [dep version & opts]]
+ (let [opts (apply hash-map opts)]
+ [:dependency
+ (map (partial apply xml-tags)
+ {:group-id (or (namespace dep) (name dep))
+ :artifact-id (name dep)
+ :version version
+ :classifier (:classifier opts)
+ :exclusions (:exclusions opts)
+ :scope (:scope opts)})])))
+
+(defmethod xml-tags ::repository
+ ([_ [id opts]]
+ [:repository [:id id] [:url (:url opts)]]))
+
+(defmethod xml-tags ::license
+ ([_ opts]
+ [:licenses
+ [:license (for [key [:name :url :distribution :comments]
+ :let [val (get opts key)] :when val]
+ [key (name val)])]]))
+
+(defmethod xml-tags ::build
+ ([_ project]
+ (let [dev-project (project/merge-profiles project [:dev])
+ [src & extra-src] (:source-path project)
+ [test & extra-test] (:test-path dev-project)]
+ [:build
+ [:sourceDirectory src]
+ [:testSourceDirectory test]
+ (if-let [resources (:resources-path project)]
+ (when (not (empty? resources))
+ (vec (concat [:resources]
+ (map (fn [x] [:resource [:directory x]]) resources)))))
+ (if-let [resources (:resources-path dev-project)]
+ (when (not (empty? resources))
+ (vec (concat [:testResources]
+ (map (fn [x] [:testResource [:directory x]]) resources)))))
+ (if-let [extensions (:extensions project)]
+ (when (not (empty? extensions))
+ (vec (concat [:extensions]
+ (map (fn [[dep version]] [:extension
+ [:artifactId (name dep)]
+ [:groupId (or (namespace dep) (name dep))]
+ [:version version]])
+ extensions)))))
+ (when (or (not (empty? extra-src))
+ (not (empty? extra-test)))
+ [:plugins
+ [:plugin
+ [:groupId "org.codehaus.mojo"]
+ [:artifactId "build-helper-maven-plugin"]
+ [:version "1.7"]
+ [:executions
+ (when (not (empty? extra-src))
+ [:execution
+ [:id "add-source"]
+ [:phase "generate-sources"]
+ [:goals [:goal "add-source"]]
+ [:configuration
+ (vec (concat [:sources]
+ (map (fn [x] [:source x]) extra-src)))]])
+ (when (not (empty? extra-src))
+ [:execution
+ [:id "add-test-source"]
+ [:phase "generate-test-sources"]
+ [:goals [:goal "add-test-source"]]
+ [:configuration
+ (vec (concat [:sources]
+ (map (fn [x] [:source x]) extra-test)))]])]]])])))
+
+(defmethod xml-tags ::parent
+ ([_ [dep version & opts]]
+ (let [opts (apply hash-map opts)]
+ [:parent
+ [:artifactId (name dep)]
+ [:groupId (or (namespace dep) (name dep))]
+ [:version version]
+ [:relativePath (:relative-path opts)]])))
+
+(defmethod xml-tags ::mailing-list
+ ([_ opts]
+ [:mailingLists
+ [:mailingList
+ [:name (:name opts)]
+ [:subscribe (:subscribe opts)]
+ [:unsubscribe (:unsubscribe opts)]
+ [:post (:post opts)]
+ [:archive (:archive opts)]
+ (if-let [other-archives (:other-archives opts)]
+ (when other-archives
+ (vec (concat [:otherArchives]
+ (map (fn [x] [:otherArchive x]) other-archives)))))]]))
+
+(defn add-exclusions [exclusions [dep version & opts]]
+ (concat [dep version]
+ (apply concat (update-in (apply hash-map opts)
+ [:exclusions]
+ #(concat exclusions %)))))
+
+(defmethod xml-tags ::project
+ ([_ project]
+ (list
+ [:project {:xsi:schemaLocation "http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.0.xsd"
+ :xmlns "http://maven.apache.org/POM/4.0.0"
+ :xmlns:xsi "http://www.w3.org/2001/XMLSchema-instance"}
+ [:modelVersion "4.0.0"]
+ (when (:parent project) (xml-tags :parent (:parent project)))
+ [:groupId (:group project)]
+ [:artifactId (:name project)]
+ [:version (:version project)]
+ [:name (:name project)]
+ [:description (:description project)]
+ [:url (:url project)]
+ (xml-tags :license (:license project))
+ (when (:mailing-list project)
+ (xml-tags :mailing-list (:mailing-list project)))
+ (make-git-scm (io/file (:root project) ".git"))
+ (xml-tags :build project)
+ (xml-tags :repositories (:repositories project))
+ (xml-tags :dependencies (map (partial add-exclusions (:exclusions project))
+ (concat
+ (:dependencies project)
+ (map make-test-scope (:dev-dependencies project)))))])))
+
(defn snapshot? [project]
(re-find #"SNAPSHOT" (:version project)))
+(defn ^{:dynamic true} abort [& msg]
+ (main/abort msg))
+
(defn check-for-snapshot-deps [project]
(when (and (not (snapshot? project))
(not (System/getenv "LEIN_SNAPSHOTS_IN_RELEASE"))
@@ -28,27 +249,18 @@
([project] (make-pom project false))
([project disclaimer?]
(check-for-snapshot-deps 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 [baos (ByteArrayOutputStream.)]
- (.store (doto (Properties.)
- (.setProperty "version" (:version project))
- (.setProperty "groupId" (:group project))
- (.setProperty "artifactId" (:name project)))
- baos "Leiningen")
- (.getBytes (str baos))))
+ (str
+ (with-out-str
+ (xml/emit (xml/sexp-as-element (xml-tags :project (:without-profiles (meta project))))
+ :indent 2))
+ (when disclaimer? disclaimer))))
(defn ^{:help-arglists '([])} pom
"Write a pom.xml file to disk for Maven interop."
([project pom-location silently?]
- (let [pom-file (file (:root project) pom-location)
- original-project (:without-profiles (meta project))]
- (copy (make-pom original-project true) pom-file)
+ (let [pom-file (io/file (:root project) pom-location)]
+ (with-open [pom-writer (io/writer pom-file)]
+ (.write pom-writer (make-pom project true)))
(when-not silently? (println "Wrote" (.getName pom-file)))
(.getAbsolutePath pom-file)))
([project pom-location] (pom project pom-location false))
@@ -1,7 +1,6 @@
(ns leiningen.test.pom
(:use [clojure.test]
[clojure.java.io :only [file delete-file]]
- [leiningen.core :only [read-project defproject]]
[leiningen.pom :only [pom]]
[leiningen.test.helper :only [sample-project]]))
@@ -13,9 +12,9 @@
(deftest test-snapshot-checking
(let [aborted? (atom false)]
- (binding [leiningen.core/abort #(reset! aborted? %&)]
- (pom (assoc sample-project :version "1.0"
- :dependencies [['clojure "1.0.0-SNAPSHOT"]]))
- (is @aborted?))))
-
-(doseq [[_ var] (ns-publics *ns*)] (alter-meta! var assoc :busted true))
+ (binding [leiningen.pom/abort #(reset! aborted? %&)]
+ (let [project (assoc sample-project :version "1.0"
+ :dependencies [['clojure "1.0.0-SNAPSHOT"]])]
+ (pom (with-meta project
+ {:without-profiles project})))
+ (is @aborted?))))
Oops, something went wrong.

0 comments on commit ef2b0f0

Please sign in to comment.