I’ve been working on an ActionScript library that can load revision history from Subversion (SVN) repositories. This is something that I’ve had in the back of my mind for about a year now and finally sat down and figured out a way to do it. I remember seeing a post way back in September of 2006 on Ted Patrick’s blog talking about someone who had written a SVN library using the Socket class. As far as I could tell, this was the only mention of the project, and it was never released publicly. So I decided to figure out how I could read SVN revision history with AS3. I’m releasing the library in its current state (more on that in a second) as an open source project.
Quick demo and the code
Since I know people don’t like reading, I’ll post the code at the beginning of this post and show some screenshots and a demo AIR app that uses the library. If you want to tune out after this, it’s cool, I understand.
Download as3svnlib source code, or just the compiled swc file.
Since this uses socket communication on port 80, which is off limits under normal circumstances due to Flash player security restrictions, you have to run the demo as an AIR app. Lame, I know. You can install this tiny AIR app to try out the library if you want. The demo app will let you enter the URL of a repository and load the last few revisions. The repository must be publicly accessible for the demo to work (note that the library itself allows you to use basic authentication, but I didn’t build support for that into the simple demo).
The screenshot below shows the bare-bones example AIR app. You can enter a URL for a SVN repo and then you can load the latest revision number or you can load the last 50 revisions. That’s all you can do in the app, but with the library you can get more detailed information about all the revisions and you can decide exactly which revisions you want to load (or load all of them).
You can download the example AIR app if you want to see if it works with your SVN repo (again, note that this demo app won’t work with URLs behind authentication, but read below about how to do that). View-source is enabled on the AIR app itself once you install it, or you can view the source of the example here.
The scope of this library
My immediate goal was to load revision history, complete with commiter name, date, comment, and ideally more detailed information about which files were affected or scope of the changes. I was not looking to build a full SVN client capable of committing changes or doing diffs or anything fancy like that.
How I went about it
I first started thinking I would implement a legit SVN client that would connect to a server using a socket connection and use the SVN protocol to communicate. I read up on the protocol and it didn’t seem all that complex, especially if I was going to limit myself to read-only operations. However, when I first started down this road I realized I didn’t know shit about doing socket communication in ActionScript. So I downloaded as3httpclientlib (current source is at github here), which is an AS3 library for doing HTTP communication written by Gabriel Handford. My goal was to use that project to learn how to do my own socket stuff and then build my SVN library.
But once I got my head around the http client stuff I learned something even more important. Turns out that most SVN installations include an Apache server that lets you browse the repo with a web interface. What’s even more interesting is that Subversion uses the WebDAV protocol as well, which is a protocol based on HTTP for source control. Suddenly I had a new option that didn’t require writing my own full-on SVN client. Fuck yeah! Less work for me!
So I extended as3httpclientlib and added in some basic support for WebDav (namely the PROPFIND request and a basic REPORT request). Then I added in support for some custom reports that Subversion uses, namely log-report. All the reports that Subversion supports via WebDav are documented here. When you request a report you send a custom HTTP request to the server and fill the request body with some XML that defines what kind of report you want. Then the server sends back its response in XML.
Then I was able to use simple XML parsing to read my list of revisions, which included revision number, creator name, date, comment, and details about all the files that were added, removed, modified, etc. Easy breezy.
Most basic use of the library
To use the library you interact with the SVNClient class. This class is used to fire off all your requests (either to get the latest revision number or to get specific sets of revisions). All requests are asynchronous, so you need to add an event listener to the SVNClient class, then send off your request, and then handle the result.
Or here’s another very simple example that uses all MXML:
Accessing repositories with authentication
The library supports using basic HTTP authentication to access repositories as well. Essentially all you have to do is pass the username and password into the SVNClient constructor, so instead of just calling
var client:SVNClient = new SVNClient(), you would call something like
var client:SVNClient = new SVNClient("username", "password");. Note that just like with all browser HTTP basic authentication, the password is sent using a Base 64 hash that is easily decoded.
But for a more secure connection, thanks to the SSL stuff that’s included in the as3crypto library and used in the as3httpclientlib library, you can also access SVN repos using HTTPS. If there are repositories that use Digest (as opposed to Basic) HTTP authentication, I do not currently support that. Frankly, I don’t have any repos I use that use digest authentication, so I don’t have any way to test it (or desire to write it).
If I was going to build a full featured SVN client I would probably still try to do a custom socket approach that spoke the SVN protocol. The WebDav interface seems a bit limited compared to “real” Subversion commands, and I would be worried that it wouldn’t be good enough. However, WebDav does support stuff like updating files and committing changesets, so I think you could add in some basic committing functionality and still use the WebDav approach. I don’t have any immediate plans to do any of this, for now I’m happy with the capability of reading from a repository (I’ll write more later about an application I’m working on that uses this library). But if you’re interested in taking this code and adding in more support for things like checking out full revisions, committing changes, etc., please be my guest.
Since this uses the as3crypto library, which is licensed under the New BSD license, I’m not entirely sure what that means for my code. I’d like to say mine’s MIT, but if I have to say it’s New BSD (which is almost just as flexible), then I guess I’ll say it’s New BSD. I think that really just means that I need to include the license file that contains copyright information in it when I redistribute the as3crypto library (which I have done). So you can pretty much do whatever you want.