So I decided to take the Horn project for a test drive after repaving a number of machines to Windows 7 RTM and waiting for things to install.
After Horn’s initial announcement this year I was excited, but it didn’t really do anything at that stage (and I didn’t have enough time to assist with the dev work / patches)... so I put it on the back burner. But I found myself need to rebuild Rhino Tools, Castle and NHibernate today from trunk and thought I would give it a try.
At any rate, this is a post covering my “noob” observations as I walk through building horn, and then using horn to build Rhino Tools.
As a little background, Horn was started by the Scotland ALT.Net group
, it was kicked off on the scotaltdotnet google code
project, and later moved to the hornget project
, also on google code. The projects Initial mission statement is to “take control of building a common set of open source packages that are probably similar to many in the ALT.NET space
” which I think it’s coming close to realising, but they also have a grander vision of “providing a standard mechanism for easy installation of .Net Packages” –
something I definitely think .Net needs, and that dynamic languages lord over us currently with their gem’s and egg’s (and incidentally it is a much trickier problem to solve when you need to produce compiled assemblies, think signing vs. unsigned, ability to specify x86/x64/any platform flags and the way in which assembly versioning in .Net works).
Assuming you have the Subversion command line tools installed (or tortoise svn) - it’s pretty easy. First off check out the horn trunk…
svn checkout http://hornget.googlecode.com/svn/trunk/ hornget-read-only
Once all the files have been pulled down, you need to then build horn, using the following batch file:
hornbuild.bat will execute Nant, and the total build takes about 15 to 20 seconds. It dumps the outputs into a buildnet-3.5debug folder, including horn.exe which is the command line client (Horn package manager). I would assume as Horn matures we will see an installer / binary release on the horn website, which should hopefully make this even easier.
Now jump into the outputs directory...and run horn for the first time.
At which point you will be rewarded with the usage screen:
THE HORN PACKAGE MANAGER
Usage : horn -install:
-rebuildonly Do not check for the latest source code.
-version: The specific version of a package.
Now it's just a matter of building the project you want.. in this case let's build rhino tools (which in turn will build Nhibernate and some parts of the castle project). Might pay to go make a coffee at this point, as there's going to be a lot going on while you wait patiently.
Oh, and expect to see a lot of this if your connection to the various project’s SVN repositories is slow..
Reading the current revision for castle
Also, as an aside - there's a cyclic relationship between Castle and NHibernate (i.e. Nhibernate relies on Castle Core & Dynamic Proxy, while Castle relies on NHibernate to build) - it's not truly cyclic as such though, just that if you attempt to build either set of project in it's entirety, you will need the outputs of the other. In Horn things like dynamic proxy are broken out into separate projects ie. "castle.tools" rather then just "castle" (though a castle package exists as well, which does build castle in it’s entirety).
It seems to handle this scenario well, and this was certainly a failing of most home-grown solutions I’ve put together over the years which relied on nant or msbuild files… Right, so after about 5 minutes, you should see the horn executable run to completion, like this:
Total time: 46.6 seconds.
HORN HAS FINISHED INSTALLING rhino.
Note: The "BUILD SUCCEEDED" message is from rhino tools, which was the last project to be built, rather then telling us how long the process took in total.
At this point Horn has finished doing it's job, but... if you do a quick directory search, you probably won't find any output binaries. What gives? Well Horn in fact stores all it's files under a directory against the user's profile. So in the case of windows 7 / Vista, that means I can just change directory to find them:
If we grab a quick directory listing... we can see there's a few folders in there.
C:Usersalex.horn>dir * /A
Volume in drive C has no label.
Volume Serial Number is 6AFA-976C
Directory of C:Usersalex.horn
12/08/2009 09:39 p.m. .
12/08/2009 09:39 p.m. ..
12/08/2009 09:37 p.m. .svn
10/08/2009 03:47 p.m. buildengines
10/08/2009 03:47 p.m. builders
10/08/2009 03:47 p.m. esbs
10/08/2009 03:46 p.m. frameworks
10/08/2009 03:47 p.m. ioc
10/08/2009 03:46 p.m. languages
10/08/2009 03:46 p.m. loggers
10/08/2009 03:46 p.m. mappers
10/08/2009 03:47 p.m. mocks
10/08/2009 03:47 p.m. orm
12/08/2009 09:45 p.m. result
12/08/2009 09:37 p.m. 15 revision.horn
10/08/2009 03:47 p.m. web
10/08/2009 03:47 p.m. wpf
1 File(s) 15 bytes
16 Dir(s) 578,876,366,848 bytes free
Notice the .svn folder, the .horn directory is actually populated from this subversion repository
, which stores all the package descriptions etc. (I’m not entirely clear on the terminology here, documentation is fairly sparse on the website – they’re almost more like package build scripts, because they’re a DSL outlining the steps required to build the outputs, required dependencies and so on).
The one folder not under version control is "result" - which is where our outputs are actually stored. So let's take a quick look...
Volume in drive C has no label.
Volume Serial Number is 6AFA-976C
Directory of C:Usersalex.hornresult
12/08/2009 09:45 p.m. .
12/08/2009 09:45 p.m. ..
10/08/2009 03:56 p.m. 1,997 ABC.hbm.xml
10/08/2009 03:48 p.m. 110,592 adodb.dll
10/08/2009 04:07 p.m. 568 AnotherBus.config
10/08/2009 03:48 p.m. 40,960 anrControls.Markdown.NET.dll
10/08/2009 03:58 p.m. 106,496 antlr.runtime.dll
10/08/2009 04:01 p.m. 116,736 Antlr3.Runtime.dll
10/08/2009 03:59 p.m. 40,960 Bamboo.Prevalence.dll
10/08/2009 03:59 p.m. 6,656 Bamboo.Prevalence.Util.dll
10/08/2009 04:01 p.m. 40,960 Boo.Lang.CodeDom.dll
10/08/2009 04:01 p.m. 753,664 Boo.Lang.Compiler.dll
10/08/2009 04:01 p.m. 118,784 Boo.Lang.dll
10/08/2009 04:01 p.m. 32,768 Boo.Lang.Extensions.dll
10/08/2009 04:01 p.m. 86,016 Boo.Lang.Interpreter.dll
10/08/2009 04:01 p.m. 425,984 Boo.Lang.Parser.dll
10/08/2009 03:48 p.m. 28,672 Boo.Lang.PatternMatching.dll
10/08/2009 04:01 p.m. 81,920 Boo.Lang.Useful.dll
10/08/2009 04:01 p.m. 32,768 Boo.Microsoft.Build.Tasks.dll
10/08/2009 04:01 p.m. 28,672 Boo.NAnt.Tasks.dll
10/08/2009 04:07 p.m. 393 BusOnTransactionalQueue.config
10/08/2009 04:07 p.m. 405 BusWithLogging.config
10/08/2009 03:48 p.m. 45,056 Cassini.dll
12/08/2009 09:43 p.m. 249,856 Castle.ActiveRecord.dll
12/08/2009 09:43 p.m. 6,656 Castle.ActiveRecord.Linq.dll
12/08/2009 09:43 p.m. 17,920 Castle.ActiveRecord.Linq.pdb
12/08/2009 09:43 p.m. 4,736 Castle.ActiveRecord.Linq.xml
12/08/2009 09:43 p.m. 960,000 Castle.ActiveRecord.pdb
10/08/2009 04:02 p.m. 543,085 Castle.ActiveRecord.XML
12/08/2009 09:42 p.m. 49,152 Castle.Components.Binder.dll
12/08/2009 09:42 p.m. 138,752 Castle.Components.Binder.pdb
12/08/2009 09:42 p.m. 17,275 Castle.Components.Binder.xml
... And the list goes ...
353 File(s) 67,002,734 bytes
2 Dir(s) 578,875,887,616 bytes free
Not bad for what was effectively just a single command line.
Where to from here
I strongly suggest giving Horn a go – not just because it’s useful, but I think that it fills a real hole in the .Net developer open source space, removing one of the barriers to entry – making it easier for people to develop applications against the trunk, or a specific version, of many popular open source projects, will definitely drive up adoption of these projects.
It’s worth noting that currently “Horn” is considered a “developer-only” release at the moment, though I think it’s current state is useful enough to warrant giving it a try, and providing feedback to the Horn dev team etc. so umm… Check it out, if you haven’t already. I think you’ll be pleasantly surprised.