Commits

Anonymous committed c41094e

First version of new build system.

  • Participants
  • Parent commits c20a504

Comments (0)

Files changed (41)

 local.properties
 clojure
 dist/*
+*/targets/*
-<!--
-  Copyright (c) 2008 Krešimir Šojat. All rights reserved.  The use and
-  distribution terms for this software are covered by the Common
-  Public License 1.0 (http://www.opensource.org/licenses/cpl1.0.php)
-  which can be found in the file CPL.TXT at the root of this
-  distribution.  By using this software in any fashion, you are
-  agreeing to be bound by the terms of this license.  You must not
-  remove this notice, or any other, from this software.
--->
-<project name='neman' basedir='.' xmlns:ivy='antlib:org.apache.ivy.ant'>
+<project name='neman' xmlns:ivy='antlib:org.apache.ivy.ant'>
 
-    <import file='${basedir}/common.xml'/>
-    <import file='${common.dir}/common.xml' optional='true'/>
+    <property file='${basedir}/zg/ivy.properties'/>
 
-    <property name='build.classes' location='${build}/classes'/>
-    <property name='build.jar'     location='${build}/neman.jar'/>
-
-    <!--
-    Neman targets.
-    -->
-
-    <target name='resolve' depends='ivy-install' unless='skip.resolve'>
-        <ivy:settings file='${basedir}/ivysettings.xml'/>
-        <ivy:resolve file='${basedir}/ivy.xml'/>
-        <ivy:retrieve/>
+    <target name='ivy-download' unless='skip.ivy'>
+        <mkdir dir='${ivy.jar.dir}'/>
+        <get
+            src='${ivy.jar.src}' dest='${ivy.jar.dst}' usetimestamp='yes'/>
     </target>
 
-    <target name='build' depends='resolve, build-docs'>
-        <mkdir dir='${build.classes}'/>
-
-        <path id='clojure.compiler.classpath'>
-            <fileset dir='${lib}'>
-                <include name='**/*.jar'/>
-            </fileset>
+    <target name='ivy-install' depends='ivy-download'>
+        <path id='ivy.lib.path'>
+            <fileset dir='${ivy.jar.dir}' includes='*.jar'/>
         </path>
-
-        <java classname='clojure.lang.Compile'
-            classpath='${build.classes}:${src}'
-            classpathref='clojure.compiler.classpath'>
-            <sysproperty key='clojure.compile.path' value='${build.classes}'/>
-            <arg value='net.ksojat.neman.cli'/>
-            <arg value='net.ksojat.neman.core'/>
-            <arg value='net.ksojat.neman.jetty'/>
-            <arg value='net.ksojat.neman.json'/>
-            <arg value='net.ksojat.neman.web'/>
-            <arg value='net.ksojat.neman.xml'/>
-            <arg value='net.ksojat.neman.storage'/>
-            <arg value='net.ksojat.neman.textile'/>
-            <arg value='net.ksojat.neman.css'/>
-            <arg value='net.ksojat.neman.cells'/>
-	    <arg value='net.ksojat.neman.swing'/>
-        </java>
-
-        <jar destfile='${build.jar}'>
-            <zipfileset dir='${build.classes}'/>
-        </jar>
-
+        <taskdef
+            resource='org/apache/ivy/ant/antlib.xml'
+            uri='antlib:org.apache.ivy.ant'
+            classpathref='ivy.lib.path'/>
     </target>
 
-    <target name='dist' depends='dist-docs'/>
-
-    <target name='publish' depends='build'>
-        <ivy:publish
-            forcedeliver='true'
-            overwrite='true'
-            resolver='neman'
-            status='release'
-            pubrevision='0.0.1'
-            artifactspattern='${build}/[artifact].[ext]'/>
+    <target name='buildlist' depends='ivy-install'>
+        <ivy:buildlist reference='build-path' skipbuildwithoutivy='true'>
+            <fileset dir='neman' includes='**/build.xml'/>
+        </ivy:buildlist>
     </target>
 
-    <target name='test' depends='build'>
-        <path id='test.classpath'>
-            <fileset dir='${lib}'>
-                <include name='**/*.jar'/>
-            </fileset>
-        </path>
+    <!-- Toplevel task for all subprojects. -->
 
-        <clojure
-            file='${test}/test.clj'
-            classpath='${build.classes}:${src}'
-            classpathref='test.classpath'/>
+    <macrodef name='subproject'>
+        <attribute name='target'/>
+        <sequential>
+            <subant target='@{target}' buildpathref='build-path'/>
+        </sequential>
+    </macrodef>
+
+    <target name='publish-all' depends='buildlist'>
+        <subproject target='publish'/>
+    </target>
+
+    <target name='test-all' depends='buildlist'>
+        <subproject target='test'/>
+    </target>
+
+    <target name='clean' depends='buildlist'>
+        <subproject target='clean'/>
+        <ivy:cleancache/>
     </target>
 </project>
     <property name='doc.dist'       location='${dist}/docs'/>
     <property name='doc.stylesheet' value='style.css'/>
 
-    <import file='${common.dir}/common.xml' optional='true'/>
 
     <property file='${basedir}/local.properties'/>
     <property file='${basedir}/build.properties'/>

docs/readme.textile

Empty file removed.

neman/cells/build.properties

+# Common build targets and tasks.
+zg.dir=${basedir}/../../zg
+zg.xml=${zg.dir}/zg.xml

neman/cells/build.xml

-<project name='neman-cells' basedir='.' xmlns:ivy='antlib:org.apache.ivy.ant'>
+<project name='cells' basedir='.' xmlns:ivy='antlib:org.apache.ivy.ant'>
     <property file='${basedir}/local.properties'/>
     <property file='${basedir}/build.properties'/>
 

neman/cells/docs/cells.textile

Empty file added.

neman/cells/ivy.xml

 <ivy-module version='2.0'>
     <info
-        organsiation='net.ksojat'
-        module='neman'/>
+        organisation='net.ksojat.neman'
+        module='cells'/>
     <publications>
         <artifact name='cells' type='jar' ext='jar'/>
     </publications>

neman/core/build.properties

+# Common build targets and tasks.
+zg.dir=${basedir}/../../zg
+zg.xml=${zg.dir}/zg.xml

neman/core/build.xml

-<project name='neman-core' basedir='.' xmlns:ivy='antlib:org.apache.ivy.ant'>
+<project name='core' basedir='.' xmlns:ivy='antlib:org.apache.ivy.ant'>
     <property file='${basedir}/local.properties'/>
     <property file='${basedir}/build.properties'/>
 

neman/core/docs/core.textile

Empty file added.

neman/core/ivy.xml

 <ivy-module version='2.0'>
     <info
-        organisation='net.ksojat'
-        module='neman'/>
+        organisation='net.ksojat.neman'
+        module='core'/>
     <publications>
         <artifact name='core' type='jar' ext='jar'/>
     </publications>

neman/json/build.properties

+# Common build targets and tasks.
+zg.dir=${basedir}/../../zg
+zg.xml=${zg.dir}/zg.xml

neman/json/build.xml

-<project name='neman-json' basedir='.' xmlns:ivy='antlib:org.apache.ivy.ant'>
+<project name='json' basedir='.' xmlns:ivy='antlib:org.apache.ivy.ant'>
     <property file='${basedir}/local.properties'/>
     <property file='${basedir}/build.properties'/>
 

neman/json/docs/json.textile

Empty file added.

neman/json/ivy.xml

 <ivy-module version='2.0'>
     <info
-        organisation='net.ksojat'
-        module='neman'/>
+        organisation='net.ksojat.neman'
+        module='json'/>
     <publications>
         <artifact name='json' type='jar' ext='jar'/>
     </publications>
     <dependencies>
-        <!-- TODO: Add neman-core -->
         <dependency org='clojure' name='clojure' rev='svn1205'>
             <artifact name='clojure' type='jar'/>
         </dependency>
+        <dependency name='core' rev='0.0.2'/>
         <dependency org='org.codehaus' name='jackson' rev='0.9.2'>
             <artifact
                 name='jackson'

neman/swing/build.properties

+# Common build targets and tasks.
+zg.dir=${basedir}/../../zg
+zg.xml=${zg.dir}/zg.xml

neman/swing/build.xml

-<project name='neman-swing' basedir='.' xmlns:ivy='antlib:org.apache.ivy.ant'>
+<project name='swing' basedir='.' xmlns:ivy='antlib:org.apache.ivy.ant'>
     <property file='${basedir}/local.properties'/>
     <property file='${basedir}/build.properties'/>
 

neman/swing/ivy.xml

 <ivy-module version='2.0'>
     <info
-        organsiation='net.ksojat'
-        module='neman'/>
+        organisation='net.ksojat.neman'
+        module='swing'/>
     <publications>
         <artifact name='swing' type='jar' ext='jar'/>
     </publications>
         <dependency org='clojure' name='clojure' rev='svn1205'>
             <artifact name='clojure' type='jar' ext='jar'/>
         </dependency>
-        <!-- TODO: Add core -->
+        <dependency name='core' rev='0.0.2'/>
     </dependencies>
 </ivy-module>

neman/utils/build.properties

+# Common build targets and tasks.
+zg.dir=${basedir}/../../zg
+zg.xml=${zg.dir}/zg.xml

neman/utils/build.xml

-<project name='neman-utils' basedir='.' xmlns:ivy='antlib:org.apache.ivy.ant'>
+<project name='utils' basedir='.' xmlns:ivy='antlib:org.apache.ivy.ant'>
     <property file='${basedir}/local.properties'/>
     <property file='${basedir}/build.properties'/>
 

neman/utils/ivy.xml

 <ivy-module version='2.0'>
     <info
-        organisation='net.ksojat'
-        module='neman'/>
+        organisation='net.ksojat.neman'
+        module='utils'/>
     <publications>
         <artifact name='utils' type='jar' ext='jar'/>
     </publications>
         <dependency org='clojure' name='clojure' rev='svn1205'>
             <artifact name='clojure' type='jar' ext='jar'/>
         </dependency>
-        <!-- TODO: Add core -->
+        <dependency name='core' rev='0.0.2'/>
+        <dependency name='xml' rev='0.0.2'/>
         <dependency org='net.java' name='textile-j' rev='2.2'/>
         <dependency org='commons-cli' name='commons-cli' rev='1.1'>
             <exclude org='junit'/>

neman/web/build.properties

+# Common build targets and tasks.
+zg.dir=${basedir}/../../zg
+zg.xml=${zg.dir}/zg.xml

neman/web/build.xml

-<project name='neman-web' basedir='.' xmlns:ivy='antlib:org.apache.ivy.ant'>
+<project name='web' basedir='.' xmlns:ivy='antlib:org.apache.ivy.ant'>
     <property file='${basedir}/local.properties'/>
     <property file='${basedir}/build.properties'/>
 

neman/web/docs/web.textile

Empty file added.

neman/web/ivy.xml

 <ivy-module version='2.0'>
     <info
-        organisation='net.ksojat'
-        module='neman'/>
+        organisation='net.ksojat.neman'
+        module='web'/>
     <publications>
         <artifact name='web' type='jar' ext='jar'/>
     </publications>
         <dependency org='clojure' name='clojure' rev='svn1205'>
             <artifact name='clojure' type='jar' ext='jar'/>
         </dependency>
-        <!-- TODO: Add core -->
+        <dependency name='core' rev='0.0.2'/>
+        <dependency name='cells' rev='0.0.2'/>
         <dependency org='org.mortbay.jetty' name='jetty' rev='6.1.11'/>
         <dependency org='org.mortbay.jetty' name='jetty-plus' rev='6.1.11'/>
     </dependencies>

neman/web/tests/test.clj

+;; Copyright (c) 2008 Krešimir Šojat. All rights reserved.  The use and
+;; distribution terms for this software are covered by the Common
+;; Public License 1.0 (http://www.opensource.org/licenses/cpl1.0.php)
+;; which can be found in the file CPL.TXT at the root of this
+;; distribution.  By using this software in any fashion, you are
+;; agreeing to be bound by the terms of this license.  You must not
+;; remove this notice, or any other, from this software.
+
+(ns user
+  (:require
+    (net.ksojat.neman [web :as web]))
+  (:use clojure.contrib.test-is))
+
+(deftest web-convertor
+  (is (thrown? Exception (web/convertor :default))))
+
+(deftest web-is-view
+  (let [v (web/view [] "test view")]
+    (are (= _1 _2)
+      (web/view? v)  true
+      (web/view? {}) false)))
+
+(deftest web-call-view
+  (let [v (web/view [a b] "test view")]
+    (are (thrown? _1 _2)
+      Exception (web/call-view v {'a 1})))
+  (let [v (web/partial (web/view [x] "test view") {'x 100})]
+    (is (thrown? Exception (web/call-view v {'x 200})))))
+
+(deftest web-partial-view
+  (let [v0 (web/view [a] "test view")
+        v1 (web/partial v0 {'a 100})]
+    (is (thrown? Exception (web/partial v1 {'a 200}))
+    (is (thrown? Exception (web/partial v1 {'b 100}))))))
+
+(deftest web-rule-parsing
+  (are (= _1 _2)
+    (web/rule-parts "/index/<name>") '(["/index/" "name"])
+    (web/rule-parts "/show-page")    '(["/show-page" nil])
+    (web/rule-parts "<name>")        '(["" "name"])
+    (web/rule-parts "<name")         nil
+    (web/rule-parts "name>")         nil))
+
+(deftest web-rule-regex
+  (are (= _1 _2)
+    (web/rule-regex "/login" {}) #"/login"))
+
+(deftest web-rule-names
+  (are (= _1 _2)
+    ('a 'b) (web/rule-names "<a><b>")
+    '()     (web/rule-names "/show")
+    '()     (web/rule-names "")))
+
+(deftest web-absolute-url-for
+  (binding [web/*rules* {[:test :view] "/test/view/<a>"}
+            web/*paths* {:test {:view (web/view [a] "hi")}}]
+    ; TODO
+    ))
+
+(run-all-tests)

neman/webapps/_ivy.xml

+<ivy-module version='2.0'>
+    <info
+        organisation='net.ksojat'
+        module='neman'/>
+    <publications>
+        <artifact name='webapps' type='jar' ext='jar'/>
+    </publications>
+    <dependencies>
+        <dependency org='clojure' name='clojure' rev='svn1205'>
+            <artifact name='clojure' type='jar'/>
+        </dependency>
+        <!-- TODO: Add web, xml and core to list -->
+    </dependencies>
+</ivy-module>

neman/webapps/build.properties

+# Common build targets and tasks.
+zg.dir=${basedir}/../../zg
+zg.xml=${zg.dir}/zg.xml

neman/webapps/build.xml

-<project name='neman-webapps' basedir='.' xmlns:ivy='antlib:org.apache.ivy.ant'>
+<project name='webapps' basedir='.' xmlns:ivy='antlib:org.apache.ivy.ant'>
     <property file='${basedir}/local.properties'/>
     <property file='${basedir}/build.properties'/>
 

neman/xml/build.properties

+# Common build targets and tasks.
+zg.dir=${basedir}/../../zg
+zg.xml=${zg.dir}/zg.xml

neman/xml/build.xml

-<project name='neman-xml' basedir='.' xmlns:ivy='antlib:org.apache.ivy.ant'>
+<project name='xml' basedir='.' xmlns:ivy='antlib:org.apache.ivy.ant'>
     <property file='${basedir}/local.properties'/>
     <property file='${basedir}/build.properties'/>
 

neman/xml/docs/xml.textile

Empty file added.

neman/xml/ivy.xml

 <ivy-module version='2.0'>
     <info
-        organisation='net.ksojat'
-        module='neman'/>
+        organisation='net.ksojat.neman'
+        module='xml'/>
     <publications>
         <artifact name='xml' type='jar' ext='jar'/>
     </publications>
         <dependency org='clojure' name='clojure' rev='svn1205'>
             <artifact name='clojure' type='jar'/>
         </dependency>
-        <!-- TODO: Add core -->
+        <dependency name='core' rev='0.0.2'>
+        </dependency>
         <dependency org='org.jdom' name='jdom' rev='1.1'/>
     </dependencies>
 </ivy-module>

neman/xml/tests/JDOMTest.java

+
+import java.io.FileWriter;
+import org.jdom.Document;
+import org.jdom.Element;
+import org.jdom.output.XMLOutputter;
+
+public class JDOMTest {
+
+    public static void main(String[] args) {
+        Document doc = new Document();
+
+        Element html = new Element("html");
+        doc.setRootElement(html);
+
+        Element body = new Element("body");
+        html.addContent(body);
+
+        Element div1 = new Element("div");
+        body.addContent(div1);
+
+        Element ul = new Element("ul");
+        div1.addContent(ul);
+
+        Element li = new Element("li");
+        ul.addContent(li);
+
+        Element a = new Element("a");
+        li.addContent(a);
+        a.addContent("xxxxxx");
+
+        Element div2 = new Element("div");
+        div1.addContent(div2);
+        /*div2.addContent("zzzzz");*/
+
+        Element div3 = new Element ("div");
+        body.addContent(div3);
+        div3.addContent("qqqq");
+
+        try {
+            FileWriter w = new FileWriter("jout.html");
+            (new XMLOutputter()).output(doc, w);
+            w.close();
+        } catch(Exception e) {}
+    }
+}
+
+<!--
+  Copyright (c) 2008 Krešimir Šojat. All rights reserved.  The use and
+  distribution terms for this software are covered by the Common
+  Public License 1.0 (http://www.opensource.org/licenses/cpl1.0.php)
+  which can be found in the file CPL.TXT at the root of this
+  distribution.  By using this software in any fashion, you are
+  agreeing to be bound by the terms of this license.  You must not
+  remove this notice, or any other, from this software.
+-->
+<project name='neman' basedir='.' xmlns:ivy='antlib:org.apache.ivy.ant'>
+
+    <import file='${basedir}/common.xml'/>
+    <import file='${common.dir}/common.xml' optional='true'/>
+
+    <property name='build.classes' location='${build}/classes'/>
+    <property name='build.jar'     location='${build}/neman.jar'/>
+
+    <!--
+    Neman targets.
+    -->
+
+    <target name='resolve' depends='ivy-install' unless='skip.resolve'>
+        <ivy:settings file='${basedir}/ivysettings.xml'/>
+        <ivy:resolve file='${basedir}/ivy.xml'/>
+        <ivy:retrieve/>
+    </target>
+
+    <target name='build' depends='resolve, build-docs'>
+        <mkdir dir='${build.classes}'/>
+
+        <path id='clojure.compiler.classpath'>
+            <fileset dir='${lib}'>
+                <include name='**/*.jar'/>
+            </fileset>
+        </path>
+
+        <java classname='clojure.lang.Compile'
+            classpath='${build.classes}:${src}'
+            classpathref='clojure.compiler.classpath'>
+            <sysproperty key='clojure.compile.path' value='${build.classes}'/>
+            <arg value='net.ksojat.neman.cli'/>
+            <arg value='net.ksojat.neman.core'/>
+            <arg value='net.ksojat.neman.jetty'/>
+            <arg value='net.ksojat.neman.json'/>
+            <arg value='net.ksojat.neman.web'/>
+            <arg value='net.ksojat.neman.xml'/>
+            <arg value='net.ksojat.neman.storage'/>
+            <arg value='net.ksojat.neman.textile'/>
+            <arg value='net.ksojat.neman.css'/>
+            <arg value='net.ksojat.neman.cells'/>
+	    <arg value='net.ksojat.neman.swing'/>
+        </java>
+
+        <jar destfile='${build.jar}'>
+            <zipfileset dir='${build.classes}'/>
+        </jar>
+
+    </target>
+
+    <target name='dist' depends='dist-docs'/>
+
+    <target name='publish' depends='build'>
+        <ivy:publish
+            forcedeliver='true'
+            overwrite='true'
+            resolver='neman'
+            status='release'
+            pubrevision='0.0.1'
+            artifactspattern='${build}/[artifact].[ext]'/>
+    </target>
+
+    <target name='test' depends='build'>
+        <path id='test.classpath'>
+            <fileset dir='${lib}'>
+                <include name='**/*.jar'/>
+            </fileset>
+        </path>
+
+        <clojure
+            file='${test}/test.clj'
+            classpath='${build.classes}:${src}'
+            classpathref='test.classpath'/>
+    </target>
+</project>

tests/JDOMTest.java

-
-import java.io.FileWriter;
-import org.jdom.Document;
-import org.jdom.Element;
-import org.jdom.output.XMLOutputter;
-
-public class JDOMTest {
-
-    public static void main(String[] args) {
-        Document doc = new Document();
-
-        Element html = new Element("html");
-        doc.setRootElement(html);
-
-        Element body = new Element("body");
-        html.addContent(body);
-
-        Element div1 = new Element("div");
-        body.addContent(div1);
-
-        Element ul = new Element("ul");
-        div1.addContent(ul);
-
-        Element li = new Element("li");
-        ul.addContent(li);
-
-        Element a = new Element("a");
-        li.addContent(a);
-        a.addContent("xxxxxx");
-
-        Element div2 = new Element("div");
-        div1.addContent(div2);
-        /*div2.addContent("zzzzz");*/
-
-        Element div3 = new Element ("div");
-        body.addContent(div3);
-        div3.addContent("qqqq");
-
-        try {
-            FileWriter w = new FileWriter("jout.html");
-            (new XMLOutputter()).output(doc, w);
-            w.close();
-        } catch(Exception e) {}
-    }
-}
-

tests/test.clj

-;; Copyright (c) 2008 Krešimir Šojat. All rights reserved.  The use and
-;; distribution terms for this software are covered by the Common
-;; Public License 1.0 (http://www.opensource.org/licenses/cpl1.0.php)
-;; which can be found in the file CPL.TXT at the root of this
-;; distribution.  By using this software in any fashion, you are
-;; agreeing to be bound by the terms of this license.  You must not
-;; remove this notice, or any other, from this software.
-
-(ns user
-  (:require
-    (net.ksojat.neman [web :as web]))
-  (:use clojure.contrib.test-is))
-
-(deftest web-convertor
-  (is (thrown? Exception (web/convertor :default))))
-
-(deftest web-is-view
-  (let [v (web/view [] "test view")]
-    (are (= _1 _2)
-      (web/view? v)  true
-      (web/view? {}) false)))
-
-(deftest web-call-view
-  (let [v (web/view [a b] "test view")]
-    (are (thrown? _1 _2)
-      Exception (web/call-view v {'a 1})))
-  (let [v (web/partial (web/view [x] "test view") {'x 100})]
-    (is (thrown? Exception (web/call-view v {'x 200})))))
-
-(deftest web-partial-view
-  (let [v0 (web/view [a] "test view")
-        v1 (web/partial v0 {'a 100})]
-    (is (thrown? Exception (web/partial v1 {'a 200}))
-    (is (thrown? Exception (web/partial v1 {'b 100}))))))
-
-(deftest web-rule-parsing
-  (are (= _1 _2)
-    (web/rule-parts "/index/<name>") '(["/index/" "name"])
-    (web/rule-parts "/show-page")    '(["/show-page" nil])
-    (web/rule-parts "<name>")        '(["" "name"])
-    (web/rule-parts "<name")         nil
-    (web/rule-parts "name>")         nil))
-
-(deftest web-rule-regex
-  (are (= _1 _2)
-    (web/rule-regex "/login" {}) #"/login"))
-
-(deftest web-rule-names
-  (are (= _1 _2)
-    ('a 'b) (web/rule-names "<a><b>")
-    '()     (web/rule-names "/show")
-    '()     (web/rule-names "")))
-
-(deftest web-absolute-url-for
-  (binding [web/*rules* {[:test :view] "/test/view/<a>"}
-            web/*paths* {:test {:view (web/view [a] "hi")}}]
-    ; TODO
-    ))
-
-(run-all-tests)

zg/ivy.properties

+# Apache Ivy.
+ivy.version=2.0.0-beta1
+ivy.jar.dir=${user.home}/.ivy2/jars
+ivy.jar.src=http://www.apache.org/dist/ant/ivy/${ivy.version}/ivy.jar
+ivy.jar.dst=${ivy.jar.dir}/ivy.jar
+
+ivy.local.default.root=${user.home}/.ivy2/local
+ivy.local.default.ivy.pattern=[organisation]/[module]/[revision]/ivys/ivy.xml
+ivy.local.default.artifact.pattern=[organisation]/[module]/[revision]/jars/[artifact].[ext]
+src=${basedir}/src
+lib=${basedir}/../../lib
+resources=${basedir}/resources
+doc=${basedir}/docs
+tests=${basedir}/tests
+repository=${basedir}/../../repository
+
+target=${basedir}/targets
+target.classes=${target}/classes
+target.resources=${target}/resources
+target.jar=${target}/${ant.project.name}.jar
+target.doc=${target}/docs
+
+<project name='zg' xmlns:ivy='antlib:org.apache.ivy.ant'>
+    <property file='${zg.dir}/zg.properties'/>
+    <property file='${zg.dir}/ivy.properties'/>
+
+    <!--
+        Tasks to compile and run Clojure programs.
+    -->
+
+    <macrodef name='clojure' description='Execute Clojure program.'>
+        <attribute name='classpath'    default=''/>
+        <attribute name='classpathref' default=''/>
+        <attribute name='file'/>
+        <element   name='args' optional='yes' implicit='true'/>
+        <sequential>
+            <java
+                fork='true'
+                classname='clojure.lang.Script'
+                classpath='@{classpath}'
+                classpathref='@{classpathref}'>
+                <arg value='@{file}'/>
+                <arg value='--'/>
+                <args/>
+            </java>
+        </sequential>
+    </macrodef>
+
+    <scriptdef language='javascript' name='baseclojurec'>
+    <attribute name='srcdir'/>
+    <attribute name='destdir'/>
+
+    <attribute name='classpath'/>
+    <attribute name='classpathref'/>
+
+    <![CDATA[
+    importClass(java.io.File);
+    importClass(java.io.BufferedReader);
+    importClass(java.io.FileInputStream);
+    importClass(java.io.InputStreamReader);
+    importClass(org.apache.tools.ant.types.Path);
+    importClass(org.apache.tools.ant.types.Reference);
+    importClass(org.apache.tools.ant.types.Environment);
+
+    var newPath = function(path) {
+        return new Path(project, path);
+    }
+
+    var newReference = function(id) {
+        return new Reference(project, id);
+    }
+
+    var newEnvironmentVariable = function(opts) {
+        var v = new Environment.Variable();
+        v.setKey(opts['key']);
+        if(opts['value']) v.setValue(opts['value']);
+        if(opts['path'])  v.setPath(opts['path']);
+        return v;
+    }
+
+    var makeClojureCompilePath = function(dir) {
+        return newEnvironmentVariable
+            ({key: 'clojure.compile.path', path: dir});
+    }
+
+    var srcDir       = new File(attributes.get('srcdir'));
+    var destDir      = new File(attributes.get('destdir'));
+    var compilePath  = makeClojureCompilePath(newPath(destDir));
+
+    var classpath = null;
+    var stdClasspath = attributes.get('srcdir') + ':' + attributes.get('destdir');
+    if(attributes.get('classpath') != '') {
+        classpath = newPath(stdClasspath + ':' + attributes.get('classpath'));
+    } else {
+        classpath = newPath(stdClasspath);
+    }
+
+    var classpathref = null;
+    if(attributes.get('classpathref')) {
+        classpathref = newReference(attributes.get('classpathref'));
+    }
+
+    // Check does file  contain namespace declaration.
+    var hasNS = function(file) {
+        if(!file.exists() || !file.canRead()) {
+            project.log("Failed to open file: " + file.getName());
+            return false;
+        }
+
+        var is = new FileInputStream(file);
+        var reader = new BufferedReader(new InputStreamReader(is));
+
+        while(true) {
+            var line = reader.readLine();
+            if(line == null) {
+                break;
+            }
+
+            // TODO: Match using regex
+            if(line.indexOf("(ns ") != -1 || line.endsWith("(ns")) {
+                reader.close();
+                return true;
+            }
+        }
+        reader.close();
+        return false;
+    }
+
+    // Scan directory for Clojure files.
+    var findLibs = function(dir) {
+        var fs = project.createDataType('fileset');
+        fs.setDir(dir);
+        fs.setIncludes('**/*.clj');
+
+        var clj = fs.getDirectoryScanner(project).getIncludedFiles();
+        var lib = Array();
+        for(var i = 0; i < clj.length; i++) {
+            if(!hasNS(new File(dir, clj[i]))) {
+                continue;
+            }
+
+            var extPos = clj[i].lastIndexOf('.');
+            var name = clj[i].substring(0, extPos).replace(File.separatorChar, '.');
+            lib.push(name);
+        }
+        return lib;
+    }
+
+    libs = findLibs(srcDir);
+
+    var compile = project.createTask('java');
+    compile.setFork(true);
+    compile.setClassname('clojure.lang.Compile');
+    if(classpath) {
+        compile.setClasspath(classpath);
+    }
+
+    if(classpathref) {
+        compile.setClasspathRef(classpathref);
+    }
+    compile.addSysproperty(compilePath);
+
+    for(var i = 0; i < libs.length; i++) {
+        var arg = compile.createArg();
+        arg.setLine(libs[i]);
+    }
+
+    var result = compile.executeJava();
+    if(result == 1) {
+        var fail = project.createTask('fail');
+        fail.setMessage('Error compiling Clojure files.');
+        fail.perform();
+    }
+    ]]>
+    </scriptdef>
+
+    <macrodef name='clojurec'>
+        <attribute name='srcdir'/>
+        <attribute name='destdir'/>
+
+        <attribute name='classpath' default=''/>
+        <attribute name='classpathref' default=''/>
+
+        <sequential>
+            <baseclojurec
+                srcdir='@{srcdir}' destdir='@{destdir}'
+                classpath='@{classpath}' classpathref='@{classpathref}'/>
+        </sequential>
+    </macrodef>
+
+    <!-- TODO: Ivy jars. -->
+
+    <target name='ivy-download' unless='skip.ivy'>
+        <mkdir dir='${ivy.jar.dir}'/>
+        <get
+            src='${ivy.jar.src}' dest='${ivy.jar.dst}' usetimestamp='yes'/>
+    </target>
+
+    <target name='ivy-install' depends='ivy-download'>
+        <path id='ivy.lib.path'>
+            <fileset dir='${ivy.jar.dir}' includes='*.jar'/>
+        </path>
+        <taskdef
+            resource='org/apache/ivy/ant/antlib.xml'
+            uri='antlib:org.apache.ivy.ant'
+            classpathref='ivy.lib.path'/>
+    </target>
+
+    <target name='resolve' depends='ivy-install'>
+    	<ivy:retrieve pattern="${lib}/[artifact].[ext]" />
+    </target>
+
+    <target name='report'>
+    </target>
+
+    <target name='build' depends='resolve'>
+        <mkdir dir='${target.classes}'/>
+        <mkdir dir='${target.resources}'/>
+        <mkdir dir='${target.doc}'/>
+
+        <path id='clojure.compile.classpath'>
+            <fileset dir='${lib}'>
+                <include name='**/*.jar'/>
+            </fileset>
+        </path>
+
+        <clojurec srcdir='${src}' destdir='${target.classes}' classpathref='clojure.compile.classpath'/>
+
+        <jar destfile='${target.jar}'>
+            <zipfileset dir='${target.classes}'/>
+            <zipfileset dir='${target.resources}'/>
+        </jar>
+    </target>
+
+    <target name='publish' depends='build'>
+        <ivy:publish
+            artifactspattern='${target}/[artifact].[ext]'
+            resolver='local'
+            pubrevision='0.0.2'
+            status='release'
+            overwrite='true'
+            forcedeliver='true'/>
+    </target>
+
+    <target name='dist'>
+    </target>
+
+    <target name='test'>
+    </target>
+
+    <target name='clean'>
+        <delete includeemptydirs='yes'>
+            <fileset dir='${target}'/>
+        </delete>
+    </target>
+</project>