posted under category: Software Quality on February 20, 2009 by Nathan
I have this open-source toy project I've been playing on, SQL Surfer. It's a little web-based SQL IDE with an amazing build process. How could I not share it with you?
The idea was pretty simple. When I work on my program, I want to see it like a normal program, multiple files, separate CSS and JS, included cfms, conditionals based on the server version, but when I release it, I want it in one, single file: easy to distribute, easy to throw on a server, no install, no folder structure to preserve, no dependencies to remember. It seems that basically no one has ever done this, but it's not too difficult.
The way it works, is, when I get to a point of wanting to make a release, I just run the Ant build file. One click. Ant does what it does best, preps the build, cleans out the output folder, in the end, it zips the results and whatnot, but I couldn't pull off the dynamic file embedding with plain Ant XML, so that's where Groovy comes in. I've got Groovy searching for included files (cfinclude, script, style, etc) and embedding the files in place of including them. Plus, while I was mashing files together, it seemed logical to compress them, even if just a little.
The result is a mashup of my entire application, nearly obfuscated into a single, gigantic, single-file, working application.
Actually, it goes a little further still. I wanted to have a version to take advantage of ColdFusion 8's new <cfdbinfo> tag, which, by the way, is awesome, but I also wanted to stay compatible with CF 6 and 7, even with a lesser experience. When you type a new CF tag into an older version, you get a compile error. That makes it hard to develop and hard to release. My solution was to drop in
<cfif left(server.ColdFusion.productVersion,1) GTE 8>, followed by a cfinclude, css or js reference, then, Ant makes 2 files for 2 releases and my Groovy build file has 2 functions, removeCF8 for removing the if blocks, and removeIfCF8 for just the if statements and embedding the files.
The actual result is 2 files, all mashed up and working perfectly for different server versions.
Going overboard, I also embed EditArea, for the code editor. Of course EditArea doesn't care about an all-in-one-file project. I use Groovy to insert EditArea into the main file as well as change EditArea itself, at build time, to point to the embedded parts in the CF application instead of its own directory structure.
Taking it beyond reality, I realize now that I could probably include a framework like Barney Boisvert's excellent FB3 Lite, and then potentially images in b64. The only challenge that this approach leaves me with is CFCs. I love my objects, but I haven't figured out how exactly to embed them.
Ouch. Even just typing that last sentence makes my head explode with ideas. Taking it way too far, I could probably embed the components I use onto the main file, stripping out the cfcomponent tags, then to recreate them, create instances of the generic coldfusion component, WEB-INF.cftags.component, and re-constitute them with duck typing and method injection... Yeah, maybe some day, if I get really into it.
You can check out the source code right now and compile it yourself, but to hear about it first hand, visit the AZCFUG Feb meeting, 2/25/09, where I'll be showing it off. If you miss it, don't sweat it, I'll have the slides out by the next day. I'm undecided on having a connect meeting for it. If we choose to, I'll post it up here.