Juggling versions of Clojure?
(Standard disclaimer: Clojure is a new hobby.)
EDIT: also try rake clojure:new:repl
I am looking forward to trying datatypes on Pokerepl. However, that means using the new branch of Clojure, and indirectly, more work on my part to clone/track/build/deploy the new branch.
Almost everyone would and should use Leiningen to experiment with the new branch. Simply update your project.clj something like this:
[org.clojure/clojure-contrib "1.1.0-new-SNAPSHOT"]]
At the moment though, updating ~/.clojure was beyond the ken of any automated tool I knew of. So I wrote a Rakefile and gave it a cheesy name... juggling Clojure... hmm... howzabout Clojuggle? Well... yeah... sorry for that.
Back to the point: automating thorough (~/.m2 and ~/.clojure) updates and deployments of various versions of Clojure. Supporting common tasks (wipe, clone, build, &c.) for several branches of several repositories means a thousand tasks will bloom and make the tool hard to use.
Ruby and the Rake API make it easy to define or show tasks only when relevant. I really enjoyed writing this code. Anyways, typing rake brings you to this:
Welcome! Try 'rake -T' for a list of useful tasks, or try
rake clojure:master:all clojure-contrib:master:all
The default task provides some basic usage. Let's take a look at the initial set of tasks:
rake clojure-contrib:master:all # Do everything for master branch of clojure-contrib
rake clojure-contrib:new:all # Do everything for new branch of clojure-contrib
rake clojure:master:all # Do everything for master branch of clojure
rake clojure:new:all # Do everything for new branch of clojure
rake default # HOWTO use this file
Fine, let's give it a whirl.
# oodles of lines omitted
ci-build:
BUILD SUCCESSFUL
Total time: 25 seconds
rm -f /.../.clojure/clojure.jar
ln -s /.../clojuggle/src/clojure-new/clojure.jar /.../.clojure/clojure.jar
real 0m55.306s
user 1m10.544s
sys 0m6.873s
Three subtle points here. First, the "ci-build" line is the clue that the local Maven2 repository was updated:
total 8
drwxr-xr-x 7 seths staff 238 Jan 3 17:57 1.1.0-new-SNAPSHOT
-rw-r--r-- 1 seths staff 322 Jan 3 17:57 maven-metadata-local.xml
Point #2: the ~/.clojure directory has a symlink pointing into the clojuggle/src/clojure-new directory.
total 8
lrwxr-xr-x 1 seths staff 70 Jan 3 17:57 clojure.jar -> /.../clojuggle/src/clojure-new/clojure.jar
Point #3: a few more commands have surfaced from the Rakefile (e.g. clojure:new:update)
# ... omitted
rake clojure:blast:it # Removes files for clojure from $HOME/.clojure and .m2
rake clojure:new:publish # Push build to local m2 repo and ~/.clojure
rake clojure:new:update # Update the new branch of clojure
So that's all well and good, but what if you wanted to support Technomancy's fork of Clojure? You would do two things. First this:
technomancy-clojure:
clone-from: git://github.com/technomancy/clojure.git
branches: [master, new]
use-jar: clojure.jar
And then something like this:
# ... omitted
rake technomancy-clojure:master:all # Do everything for master branch of technomancy-clojure
rake technomancy-clojure:new:all # Do everything for new branch of technomancy-clojure
DANGER!
Do NOT use this tool to develop on various versions of Clojure. The wipe task always deletes files, so eventually you will lose changes unintentionally. Eventually 'git status' will be used to prevent wiping changes but not yet.
Penultimately, despite all this I still don't have the new branch working with Slime/Swank. It doesn't help that the pom.xml of contrib on the new branch wants 1.1.0-alpha of Clojure. Minor nits though that can be worked out.
Finally, if anyone is still reading and cares about these sort of things, I picked Ruby, v3 of the GPL, and Mercurial/BitBucket because I have strong feelings about those things.
Please respond in some way if you have any questions!
tl;dr: Leiningen is great -- try using it with the new branch of Clojure!
introducing jawarepl
JAWAREPL is a JAva Web Application Read Eval Print Loop. It loads a Spring-based Java .war file into groovysh, and then makes its fully actived Spring beans easy to use.
Here's a quick example. It uses 'petclinic', one of the sample apps included with Spring:
$ groovysh . /Users/moi/Documents/code/jawarepl/jawarepl.groovy inst = new JAWAREPL();
Here's how you configure it:
inst.war_path = "/path/to/petclinic/dist/petclinic.war"; inst.context_paths = [ "WEB-INF/applicationContext-hibernate.xml" ]; ctx = inst.context;
After that, the sky's the limit! Start grabbing beans out and call all the methods you want. Put this into groovysh:
clinic = ctx.getBean("clinic");
clinic.vets.each {
println "vet = ${it.lastName}, ${it.firstName}";
it.specialties.each {
println " $it";
}
}
And this should come out:
vet = Carter, James
vet = Douglas, Linda
dentistry
surgery
vet = Jenkins, Sharon
vet = Leary, Helen
radiology
vet = Ortega, Rafael
surgery
vet = Stevens, Henry
radiology
Just to demonstrate that it's not only for reading data, here is another sample where it adds a visit to the petclinic.
owner = clinic.findOwners("Schroeder")[0];
owner.pets.visits.each { println "$it.date, $it.description" }
[2009-01-24, 2009-01-24], [JAWAREPL test, JAWAREPL test]
visit = new org.springframework.samples.petclinic.Visit();
visit.date = new Date();
visit.pet = pets[0];
visit.description = "JAWAREPL test2";
clinic.storeVisit(visit);
...
Hibernate: insert into visits (visit_date, description, pet_id) values (?, ?, ?)
owner = clinic.findOwners("Schroeder")[0];
owner.pets.visits.each { println "$it.date, $it.description" }
[2009-01-24, 2009-01-24, 2009-01-24], [JAWAREPL test,
JAWAREPL test2, JAWAREPL test]
More detailed instructions are available on bitbucket.
JAWAREPL has been tested on three of the sample Spring apps and a basic Grails app. Those are pretty trivial samples and even so, it was a minor task to make them all work; the Grails war had none of the GORM mojo stitched in so it was really not very useful (patches anyone?) That being said, I would not expect a complex war file to load smoothly. I seem to recall some sort of mock/mini JNDI provider in Spring if that what goes wrong. I will try to look at any bug reports, or much better yet patches.


