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 -~----------~----~----~----~------~----~------~--~---