On Aug 10, 2009, at 11:45 AM, J. McConnell wrote:

> On Mon, Aug 10, 2009 at 9:07 AM, Chas Emerick  
> <cemer...@snowtide.com> wrote:
> Looks like a good start.  I initially didn't grok what was going on,  
> until I realized that you were aiming for an "actual" ant library.
>
> Yes, I wasn't very familiar with Ant Tasks (as in  
> org.apache.tools.ant.Task) or macros until I looked into this, but I  
> already had a few lines of Clojure code that I was using to detect  
> test failures that I wanted to make use of for better reporting. So,  
> I figured I'd go the Task route using gen-class. I imagine the fact  
> that the tasks are written in Clojure will prove useful in terms of  
> tighter integration with clojure.test and whatnot in the future.

I considered taking your route, but ended up choosing to use macros  
instead -- primarily because I didn't necessary want to learn too much  
about ant internals, and because I wanted to be able to upgrade our  
version of clojure without worrying about maintaining an ant plugin  
(e.g. IIUC, the ant plugin would need to have its own clojure jar at  
hand?).

>   We have a couple of ant macros that do all of our clojure building  
> for us (including auto-detecting namespaces within source  
> directories, compiling only those clojure files that have changed  
> since the last build, etc).  I wonder if there'd be space for us to  
> add those to this though, as its charter and approach are pretty  
> different than just "a couple of macros" :-)
>
> Hmmm ... like I said, I'm not really familiar with Ant macros  
> (though perhaps I should be), but it'd be nice if this could work.  
> Perhaps a macro could generate the list of namespaces to compile/ 
> test and pass that to the task? Eventually the task should probably  
> support both of those features, definitely the latter.

You don't need macros to generate the list of namespaces -- filters  
and such can do it just fine, although the result is a little  
byzantine -- and I'll bet that, in a real ant plugin, you'd have  
direct access to the APIs underlying filters, etc., so that generating  
the namespace list would be simpler.  Anyway, I've pasted our clojure  
compilation macro below, FWIW.  I've been meaning to blog about it a  
couple of times, but that todo keeps slipping down my list, so this  
will have to do for now.

Note that all of our builds are within a netbeans environment, which  
explains the fiddly jvm stuff going on.  Also note that we assume a  
1:1 correspondence between clj files and namespaces (which is  
decidedly not correct in general, although it is for our codebases);  
using clojure.contrib.find-namespaces would lead to a more generally- 
correct result.

> Maybe I can make it down to one of the Western Mass Dev meetings one  
> of these days (I'm in North Adams) and we can hack something up :)

Ah-ha, a wmassdevs lurker! :-D  For sure, come on down!  I think our  
next meeting is this Thursday, though I'm not entirely sure of that.

Cheers,

- Chas

-------

Sample usage:

<do-compile-clj classpath="${complete.classpath.here}" src-root="src"
                 classes-root="${build.classes.dir}" nsid="clj-ns"/>

Actual macro:

<macrodef name="do-compile-clj" description="Compiles all clojure  
files from one source root dir to one destination classes dir">
   <attribute name="classpath" description="base classpath for  
compilation; src-root and classes-root will be added to this as well"/>
   <attribute name="src-root" description="clojure source root  
directory"/>
   <attribute name="classes-root" description="destination classfile  
directory"/>
   <attribute name="nsid" description="prefix appended to .namespaces  
to form the name of the property that will hold a list of all libs  
compiled from src.root after the macro is finished"/>
   <sequential>
     <!-- here, we're handling the two different ways that netbeans  
presents the current Java platform/executable
        platform.java is standard for j2se projects;
        nbjdk.java is standard for RCP projects (iff nbjdk.active is  
set by the containing suite!) -->
     <condition property="platform.java" value="${platform.java}">
       <isset property="platform.java"/>
     </condition>
     <property name="platform.java" value="${nbjdk.java}"/>

     <!-- this could be simplified somewhat using clojure.contrib.find- 
namespaces -->
     <fileset id="namespace.list" dir="@{src-root}" excludes="$ 
{excludes}" includes="**/*.clj">
       <!-- only compile clojure files that have changed since the  
last compile -->
       <depend targetdir="/${basedir}/@{classes-root}">
         <mapper type="glob" from="*.clj" to="*__init.class"/>
       </depend>
     </fileset>

     <pathconvert targetos="unix" pathsep=" "  
property="@{nsid}.namespaces" refid="namespace.list">
       <chainedmapper>
         <filtermapper>
           <replacestring from="\" to="/"/>
           <replacestring from="_" to="-"/>
           <replacestring from="${basedir}/@{src-root}/" to=""/>
         </filtermapper>
         <packagemapper from="*.clj" to="*"/>
       </chainedmapper>
     </pathconvert>

     <java classname="clojure.lang.Compile" failonerror="true"  
fork="true"
           classpath="@{classpath}:@{src-root}:@{classes-root}" jvm="$ 
{platform.java}" >
       <sysproperty key="clojure.compile.path" value="@{classes-root}"/>
       <sysproperty key="clojure.compile.warn-on-reflection"  
value="true"/>
       <arg line="$...@{nsid}.namespaces}"/>
     </java>
   </sequential>
</macrodef>
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to