Flex/Flash/Actionscript

Accessing SVN Repositories with ActionScript

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.

Demo
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).
screenshot053
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.

<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml"
	creationComplete="getLatest()">
	<mx:Script>
		<![CDATA[
			import com.dougmccune.subversion.SVNRevision;
			import com.dougmccune.subversion.events.SVNRevisionListEvent;
			import com.dougmccune.subversion.SVNClient;

			private var client:SVNClient;

			private function getLatest():void {
				client = new SVNClient();
				client.addEventListener(SVNRevisionListEvent.REVISIONS_LOADED, revisionsLoadedHandler);
				client.getLatestRevisions("http://opensource.adobe.com/svn/opensource/flex", 25);
			}

			private function revisionsLoadedHandler(event:SVNRevisionListEvent):void {
				for each(var revision:SVNRevision in event.revisions) {
					trace("Revision #" + revision.revisionNumber + " committed by " + revision.creatorName);
				}
			}
		]]>

	</mx:Script>
</mx:WindowedApplication>

Or here’s another very simple example that uses all MXML:

<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml"
	xmlns:subversion="com.dougmccune.subversion.*"
	layout="vertical">

	<subversion:SVNClient id="client" revisionsLoaded="grid.dataProvider = event.revisions" />

	<mx:HBox width="100%">
		<mx:TextInput width="100%" id="repoInput" text="http://opensource.adobe.com/svn/opensource/flex" />
		<mx:Button label="Load" click="client.getLatestRevisions(repoInput.text, 25)" />
	</mx:HBox>

	<mx:DataGrid id="grid" width="100%" height="100%">
		<mx:columns>
			<mx:DataGridColumn dataField="revisionNumber" headerText="#" width="40" />
			<mx:DataGridColumn dataField="creatorName" />
			<mx:DataGridColumn dataField="date" />
			<mx:DataGridColumn dataField="comment" showDataTips="true" />

		</mx:columns>
	</mx:DataGrid>

</mx:WindowedApplication>

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).

Going further
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.

License
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.

Standard

10 thoughts on “Accessing SVN Repositories with ActionScript

  1. Apologies to anyone who left previous comments on this post. I had a database failure with my hosting provider and lost about 15 comments total. The issue has been resolved and comments from now on should be good to go (although I don’t think I’ll be trying to restore the lost ones, since I don’t have a backup that was that recent). So just be aware that I’m not censoring comments in any way :) say whatever the fuck you want.

  2. Pingback: API SVN en ActionScript | tweenpix

  3. I think my head is going to explode, this is crazy. Its amazing to see all the “real” applications possible with AS 3 and Flash Player 9/10, as I joke around with other Flash devs we have been sitting at the programmers kid table for a very long time. Looks like we are getting a better seat. I would love to see this in AIR, could be an interesting browser. The only GUI SVN client I have liked so far is http://versionsapp.com but you can’t do branches so I find it almost useless, but its pretty. Thanks for the evening inspiration…

  4. FlashDev2007 says:

    Hello,

    This is really inspiring, I would like to build an AIR app to get the revision number (which is working), but also update an actionscript class with the revision number then get it to check the file back in, is this possible?

    Thanks

  5. Pingback: Cat H1N1 » Blog Archive » SVNStalker POC

  6. Combo says:

    Hi!

    Thx a lot for this project, it’s amazing!

    I work on a project in AIR and i would like to use your SVN library. I can get the lastest revision of my server but now, i am looking for how to download this revision in a specific folder on my local machine. Is it possible? What method should i use?

    Thx.

  7. solar says:

    Hello, I came here via Google search for webdav/flex. Thanks for the project and the inspiration. I need webdav in Flex, and I could draw some information from you post and your code. Thanks!

  8. Thanks this got me where I needed to go re: AIR and WebDAV.

    I only needed to pull files from a webfolder, so I just used the as3httpclientlib directly but with your PropFind subclass.

    BTW, here’s an updated version of your deNamespace function, which strips namespaces that includes numbers in it:

    http://pastebin.com/135gLETH

  9. Pingback: Accessing SVN Repositories with ActionScript | prinjumon

Comments are closed.