On a bit of my own time last evening, I was looking over the beta version of Broadchoice Workspace (which is pretty durn cool in and of itself, even if it has a ways to go before it’s completely ready for prime time) and decided to post the suggestion that they integrate document versioning into the product. For the things I’d use it for, versioning would be pretty important.
My suggestion was to do something like integrate SVNKit (the only pure Java library for accessing Subversion servers) into an application and, programmatically, create a new repo folder and a new working copy in the webroot to hold uploaded files it’s practically built-in versioning, really.
Incidentally, if you use Subversion and Eclipse, it’s likely that you have used SVNKit because it’s one of two ways (and until relatively recently the ONLY way on OSX) to get Subclipse working… SVNKit is bundled with Subclipse. More on getting it running in a minute, but first, some thoughts…
Think of this in terms of something simple, like an image gallery. As you add images, they’re added to source control if they’re not already under source control. If they are, then nothing’s done at upload.
Then using cfthread you fire a commit for every file you upload with an atomic commit message. When you go to do back-ups on the server, you don’t back up the working copy, you back up the repository. This would give you the ability to use files from disk as though nothing unusual was happening, but it would also allow you to do clever things like have preconfigured repository locations that your application depends on and, onApplicationStart(), are checked for. If they’re missing, they’re simply checked out to the correct folder under the webroot, most likely.
The possibilities really are endless. Let’s take blogCFC as an example (kudos to Ray). Let’s say when you go to download the application, what you really get is an installer that asks you where you want the root folder of the application set up, or the webroot into which you want it installed, and your CF Admin password. It then goes on to use SVNKit to checkout the source from the server, CF’s AdminAPI to create the datasource, and cfquery to create the db tables. One of the first functions I played with last night was Repository.getRepositoryVersion(), which returns the current repo version from the SVN server. Since you can also get the repository version of the working copy, we now have a pretty foolproof built-in mechanism to manage either auto-updates or a “check for updates” button in the admin section of the application. Now imagine what it would be like if something like this were added into the CF Administrator under a ColdFusion Applications section. The UI gives you fields for the install destination, the SVN Repository information (URL, repo path, username and password) and a radio button for doing an export from the repo or a checkout. If Adobe were to get really clever, they could publish a whole application distribution system that allows you to include a post-checkout file that could create databases and DSNs, create tables and folders within that DSN, add mappings, etc. And since you’re already inside the CF Admin when you do this, you’re a trusted user! Beyond that, CF Admin would give you buttons to check for updates, replace from repo, the ability to specify an interval for background updates, and the reload URL for the application to be fired off once an update has been pulled from the repo. And if you’ve got write privileges to the repository, it could even let you commit local changes to the server.
You know what would happen if Adobe did this? People would complain that they can’t swap SVN out for CVS or Perforce. OK, I kid (sort of). I think something like this would make sites like RIAForge.org into powerhouse software distribution systems and gives ColdFusion an even greater claim to “make hard things (like installing server software) easy”. Seriously, though… it’s things like this that get my imagination running and my coding juices flowing and make me really want to see things like this put to heavy use in the ColdFusion world.
As for usage, there are 2 things you need:
- SVNKit’s latest binary distribution
- The JavaLoader library on RIAForge, from Mark Mandel or, if you’re using Transfer, you can use transfer.com.util.javaloader.JavaLoader instead… it’s the exact same project in a slightly different package.
Next, you’ll simply need a code block that looks something like this:
<cfset cpRoot = "/path/to/download/svnkit-126.96.36.19906/"> <cfset classPath = [cpRoot & "svnkit.jar",cpRoot & "svnkit-cli.jar",cpRoot & "trilead.jar",cpRoot & "jna.jar"]> <cfset loader = createObject("component","JavaLoader").init(classPath)> <cfset loader.create("org.tmatesoft.svn.core.internal.io.svn.SVNRepositoryFactoryImpl").setup()> <cfset svnDavRepoFactory = loader.create("org.tmatesoft.svn.core.internal.io.dav.DAVRepositoryFactory").setup()> <cfset svnRepoFactory = loader.create("org.tmatesoft.svn.core.io.SVNRepositoryFactory")> <cfset svnRepoUrl = loader.create("org.tmatesoft.svn.core.SVNURL").parseURIEncoded("http://svn.alagad.com/FooBarFiddleProject")> <cfset svnWcUtil = loader.create("org.tmatesoft.svn.core.wc.SVNWCUtil")> <cfset svnAuthManager = svnWcUtil.createDefaultAuthenticationManager("username","password")> <cfset repository = svnRepoFactory.create(svnRepoUrl)> <cfset repository.setAuthenticationManager(svnAuthManager)> <cfset latestRevision = repository.getLatestRevision()> <cfdump var="#variables#" />
At the very least, if you check out a working copy of the application on production, it would be mind-numbingly easy to set this up so that it does an SVN update as part of the application reload routine. So all in one step you update from the repo if the working copy’s revision number is lower than that of the server, clear the trusted cache, and reload the frameworks and libraries necessary to run the application.
Kick me in the knee and call me a geek… I like it, and I can’t wait for an opportunity to use this in a project. Yeah, I get excited about int’restin stuff.