Sony Vaio T2XP

4 months ago I bought my latest computer – a Sony Vaio T2XP laptop. It was Jim Webber’s fault – when I met him earlier in the year he pulled out an earlier model (the TR) which completely dwarfed my Dell D600. I immediately challenged him as to its practicality, and almost as soon as I had was forced to eat my words. My model, being somewhat more up to date, has a fast but power-savvy processor (1.2 GHz ULV), 1GB RAM (upgraded from the standard 512MB), 60GB hard disk, an internal DVD re-writer, firewire, USB, etc.

However, what people notice first about it is the size – its tiny (the same width as a 12″ Powerbook, but widescreen form factor so not as deep) and very light (about 1.2 kgs, I think). Then they notice the screen – a gorgeous little 1280×768 number that uses Sony’s X-Black technology (the same as the PSP.)

So what I have is a machine I can carry everywhere, use in economy on a plane (which I am proving today for the first time as I type this blog entry), and yet which is powerful enough to happily do .NET development on. Oh, and did I say it has a (better than) 6 hour battery life? And standby comes back in less than 5 seconds? And it has a really nice clicky Sony keyboard and a trackpad that actually works?

About the only thing I can’t do is play World of Warcraft on it since the 3D graphics aren’t all that, but with the amount of time some of my colleagues are spending on WoW at the moment maybe that’s a good thing.

Automated SSH with passwords

A few months ago, I talked about setting up automated Subversion access using SSH. This is especially important if you are using an automated build server. (Couldn’t resist the shameless plug 🙂 )

One requirement of that discussion was that you needed to be using key-based authentication for your SSH access. So what if you’re not using keys? This is exactly the situation that has arisen this week with adding a new project to CCNetLive . We want to build a new project, from a new Subversion server, using SSH and password-based authentication, without messing up the SSH configuration for the existing projects on the machine (so no project-specific machine-global settings are allowed.) So how to do this?

I went through various attempts at doing this before realising how easy Subversion makes it!

First of all, make sure your new SSH connection is working correctly. In Windows, this means using Putty to connect using your SSH user name and password, and saving the server’s key. This is a vital step otherwise your connection will hang later as in the background it will be asking you to confirm the identity of the server.

Next, find your user’s Subversion config file. On Windows, this is normally in something like C:\Windows\Documents And Settings\Your UserName\Application Data\Subversion\. Find the [tunnels] section, and add a line something like:

myprojectssh = c:\tools\putty\plink.exe -l YourSSHUser -pw YourSSHPassword

The myprojectssh is the name of your Subversion scheme and you can use this scheme instead of the normal ssh scheme, so you would use a command something like svn checkout svn+myprojectssh://mysvnhost.com/my/project/root . Notice you don’t need to re-specify your user name. Obviously, you should change myprojectssh, YourSSHUser and YourSSHPassword for your setup, as well as the location of plink. The double back-slashes are important – check the note that should be in your Subversion config file for more details.

This Subversion scheme works because the whole -l abc -pw xyz part gets passed through to Plink, and plink understands what -l and -pw mean. If your command line SSH client uses different parameters for users and passwords you should substitute them as necessary.

There’s a couple of things to note with all this. Firstly, your SSH credentials are being stored unencrypted in a text file on your machine, so you should make sure your Subversion config file is secured somehow. It may be enough to make sure its only visible by the individual user, but you might also want to consider using an encrypted disk. Secondly, this solution should only be used where you can’t use SSH keys for some reason. Key-based SSH authentication is a far better option, security wise, than password-based authentication.

PDC, DDD and MVP

So 3 acronymns and 3 Microsoft developer community oriented updates.

Firstly, I’m off to Microsoft PDC next month. As with most conferences I expect the interesting stuff to happen in the corridors between sessions and there’s certainly a lot of great people going to be there to chat to. However, I’m also looking forward to hearing the latest gossip from MS about Vista and VS 2005. At the moment I’m somewhat cynical about what’s actually going to be left in Vista that won’t be available under Windows XP eventually (Avalon, Indigo, IE7, etc.) but I’m going with an open a mind as I can.

Of course, I’m definitely looking forward to meeting the MSBuild guys to see what their plans are.

Next up, I’m getting more involved with the London .NET community. I helped out at last month’s meeting by being on a panel answering questions about Agile Development, and I’m also going to be at DeveloperDeveloperDeveloper Day on the 22nd October. I’ve submitted a few sessions, but will wait to see if anyone’s interested in hearing me before I say I’m actually presenting. 🙂

And finally, I got made a Solutions Architect MVP! I’m not sure who nominated me but many thanks to whoever it was! I don’t hang-out much in the usual forums that a lot of MVPs frequent but I certainly hope to carry on blogging about the agile .NET world and helping out with the London .NET group.

CruiseControl.NET 1.0 RC1 Released

We’ve decided to break with our traditions on the CruiseControl.NET project and try to actually release a version 1.0! We’re not quite there yet, but have just released our first release candidate for 1.0 .

I’ll do a more detailed blog entry once 1.0 goes final (which we hope will be in the next few weeks), but until then please go and read the Release Notes.

If you do try out RC1, please email me, or the CCNet User’s mailing list with any problems / glitches / etc. with either the application or the documentation.

Extending a .NET Development Tree – Versioning

The next area we’re going to look at is adding support for versioning. The .NET documentation has some fairly clear guidelines about versioning which you can read here.

Versioned assemblies can be generated on 2 types of occasion – during ‘interactive’ development and also when the automated build is used to generate distributions. For the first of these, you don’t care too much (at least initially) exactly what the name of the version is, as long as it doesn’t conflict with your distribution versions. These distribution versions though will have more structure around them, specifically:

  • The format of the version should consist of the 4 period-separated integers specified by .NET conventions
  • Version names should be unique for each distribution you publish
  • Version names should fit a specified standard for your project and organisation
  • All assemblies for one project for one distribution instance should have the same version name

These are all fine ideas, but how does it fit in with our project tree? Let’s take a look.

At the moment each Visual Studio project in our Sycamore solution has an AssemblyInfo.cs file with a bunch of default content that Visual Studio generates for us. We’re going to get rid of most of this. First of all, edit each project’s AssemblyInfo.cs file, and set the content to be something like the following:

[assembly : AssemblyTitle("My Assembly Name")]

[assembly : AssemblyDescription("")]

[assembly : AssemblyConfiguration("")]

These 3 assembly attributes are all optional, but I tend to leave them in as a hint to be filled in later.

We said above that all the assemblies for a given project should have the same version for a given distribution. To help us implement this, we are going to store all the versioning information for the entire solution in one file, called CommonAssemblyInfo.cs and saved in the src folder of our project tree. Its best to actually create this file outside of Visual Studio, and then include it as a link for every project in the solution. To do this, choose ‘Add Existing Item…’ from the project context menu, select the CommonAssemblyInfo.cs file you just created and then choose ‘Link File’ from the ‘Open’ button drop down menu.

By now you should have this file linked in every project, and the next step is to add some content to it. I tend to use the following format:

[assembly: AssemblyVersionAttribute("0")]

[assembly: AssemblyCopyrightAttribute("Copyright  2005 Sherwood Forest Inc.")]

[assembly: AssemblyCompanyAttribute("Sherwood Forest")]

[assembly: AssemblyProductAttribute("Sycamore")]

If you compile the project now and look at some of the output DLLs in Windows Explorer you should see this metadata. The AssemblyVersionAttribute value here is fine for initial interactive development, but you may need to customise it for your own environmental standards.

That’s enough for interactive builds, but what about automated builds, specifically when we want to publish distributions? An initial thought may be just to save our ‘real’ version number in the Source Control version of the CommonAssemblyInfo.cs file, but the problem with that is then our interactive development will produce assemblies with version numbers identical to our published distributions, which is far from ideal.

The next idea is that we edit the CommonAssemblyInfo.cs file every time we want to publish a distribution, but that’s manual work and as such doomed to failure. It would be much better to automate this, so that’s what we’re going to do. Specifcally, at build time, we are going to generate a new CommonAssemblyInfo.cs source file (this technique is known as code gen.) NAnt has a useful task for code genning AssemblyInfo type files called <asminfo>. To generate the same type of file we have stored in Source Control, we use the following target:

<target name="set-version">

<ifnot test="${property::exists('version')}">

<property name="version" value="${default.version}" />

</ifnot>

<asminfo output="srcCommonAssemblyInfo.cs" language="CSharp">

<imports>

<import namespace="System.Reflection" />

</imports>

<attributes>

<attribute type="AssemblyVersionAttribute" value="${version}" />

<attribute type="AssemblyCopyrightAttribute" value="Copyright  2005 Sherwood Forest Inc." />

<attribute type="AssemblyCompanyAttribute" value="Sherwood Forest" />

<attribute type="AssemblyProductAttribute" value="Sycamore" />

</attributes>

</asminfo>

<echo message="Version set to ${version}" />

</target>

You’ll notice here that version is a property which you can set externally, but defaults to a property called default.version. We need to add this default property to the build script, and also update our full target:

<property name="default.version" value="0" />

<target name="full" depends="clean, set-version, test, dist"

description="Compiles, tests, and produces versioned distributions" />

We can now build a versioned distribution as follows:

c:develSycamore>go -D:version=1.1.0.0 full

We can now build .NET-version standardized applications – great! But there’s still a manual process here – wouldn’t it be better if these distributions were generated automatically for us somewhere? The good news is they can be, but we’ll be looking at that next time.

To summarise this part:

  • Make your published distributions contain properly versioned assemblies
  • Define versioning information in a project-common source file
  • Code-gen your versioning file at automated-build time
  • Add the version name as a parameter to your automated build process

Extending a .NET Development Tree – Basic Distributions

If you read my thoughts on setting up a .NET development tree you might be interested to know how we can extend these ideas to gain even more value from automation and configuration on our .NET projects. This series of entries should help you with these investigations.

In this first entry I’m going to talk about Distributions. Distributions are one kind of artifact produced by running the automated build of your project tree. They are typically a bundling of compiled code, dependencies, configuration and documentation that enables someone to get started using your application, or update an existing copy of your application. Distributions tend to take the form of file archives (such as Zip files) or installers (such as MSI files.)

Console applications tend to allow the simplest kind of distribution. Our Sycamore example project that we created in the original article has a console application so we’re going to use this to generate an example distribution.

First of all, we’re going to add a full target to our build script. A ‘full’ build is a concept that means ‘run an end-to-end development build, and produce all artifacts’. For Sycamore’s build it looks like this:

<target name="full" depends="clean, test, dist"	description="Compiles, tests, and produces distributions" />

So far, so good. Now we need to actually create our dist target. Here it is, and I’ll explain it afterwards:

<target name="dist">

<copy todir="${build.dir}dist">

<fileset basedir="${build.dir}DebugSycamoreConsole">

<include name="***"/>

<exclude name="***.pdb" />

</fileset>

</copy>

<zip zipfile="${build.dir}Sycamore.zip">

<fileset basedir="${build.dir}dist">

<include name="***" />

</fileset>

</zip>

</target>

There are 2 clear sections to this target. The first is to setup the file tree of our distribution. In our case, we just want the Sycamore application. We specifically don’t want the .pdb debugging file. (Note to those thinking Why didn’t you just use a release build? – I’m just using the .pdb as an example of a file produced by the compile step that we don’t want in our distribution.)

One of the nice side-effects of using the Visual Studio solution/project files for defining our automated build is that all required dependencies will already be copied to the build output folder, ready for us to copy to the dist folder. In fact you can even use the pre- and post- build scripting enabled for projects in Visual Studio (but make sure that your exclude list filters out any build event batch files!) In this first section you could also add extra <copy /> sections to include documentation, license files, etc.

Once the file tree is complete, we can create the actual distribution file. In our case, we use a simple Zip file, which is appropriate for XCopy Deployment. Since all the hard work has been done in the first part of the target, the <zip /> call is very simple.

Distributions typically get much more complicated than this. Deciding exactly what files to include is something you’ll need to think carefully about. Also, you need to decide to what extent your distribution should be environment specific. For example, you may want to produce a distribution of a web application, the configuration of which has already been setup to for your production database. The benefit of this is less work for your deployment team. The drawback is that you won’t be able to deploy this distribution somewhere else. Typically, your development distributions will be environment generic, and you may introduce post-development builds to deploy and configure your application for specific environments, but that really is subject for a much bigger discussion!

Distributions are also tied in to a versioning strategy, and stored on a server somewhere, but that is also out of scope for this particular entry.

To summarise this part:

  • Produce distributions to enable your project to be used elsewhere.
  • Your distributions should be generated by a full development build.
  • Distributions should include a combination of code, dependencies, configuration and documentation.
  • Separate out the work of deciding what should be in your distribution, and creating the distribution file itself.

CruiseControl.NET 0.9 Released

A bit of a late night blog this, but its worth it. We’ve just finished off CruiseControl.NET 0.9!

Big changes in this release:

– An installer! Not just a file distribution, it also sets up your windows service and sets up your IIS settings for the Dashboard.

– Arbitrary task workflow.

– Lots of updates to the Dashboard (more plugins, more configurable, completely re-skinnable.)

The Dashboard updates were my favourite. I’ve already mentioned on this blog the fun I had with NVelocity and removing all the Web Forms code. I haven’t even mentioned yet the other fun I had combining Dependency Injection ideas with de-serialization. 🙂

Read the release notes here and download it here.

Tree Surgeon 1.0

This week I released ‘version 1’ of Tree Surgeon, my application that will generate a .NET development tree for you.

The main updates since 0.1 are a GUI, an installer, and an update of the included version of NAnt.

Over time, I plan on adding some more patterns, including versioning, continuous integration support and distributable generation.

Scaling Continuous Integration talk in London

Next week Steve Freeman and I will be presenting a session in London on Scaling Continuous Integration. This is basically about how you can get the benefits of CI on larger projects.

If you’re in London and are interested in this, it will be taking place next Wednesday evening (6th April). Its totally free to come along, you just need to be able to make it to the ThoughtWorks office on High Holburn. For more details on logistics, please look here.

We’ll also be presenting this as a tutorial at SPA 2005 in a couple of week’s time.

On Subversion

I’ve recently started using the Subversion Source Control system a lot more. It really has got pretty stable now and I feel happy about telling people that they should consider migrating to Subversion from CVS (or in fact pretty much any other Source Control tool) as soon as they can. Atomic checkins, offline features, scalibility, useful and easy tags and branching, and lots of other good stuff all make it a compelling tool.

One thing that has helped Subversion recently is the improved documentation available. An example of this is Mike Mason‘s new book Pragmatic Version Control Using Subversion. I have to say right now that I’m an old friend and colleague of Mike’s and also reviewed the book, so I am completely biased, but I think its a brilliant tutorial to getting started with Subversion, and a handy reference to have around.

Mike’s also recently helped me out with a couple of things that weren’t in the book, so I wanted to share them here.

Firstly, if you’ve been following my blog recently you’ll know I’ve been using Cygwin a lot more. One of the things that Mike does very well is show how powerful and easy the svn command line client is. I was using the standard Windows download of Subversion with Cygwin, but apparently this is a really bad idea. Apart from not using the right kind of paths, you can apparently also get file corruption.

Anyway, this is easy to change – open up the Cygwin installer and choose to use its version of Subversion – its in the devel folder. Cygwin will automatically update your path so that your Cygwin version of svn is used rather than the previous one you installed. You’ll also need to repeat any changes you made to your Subversion config file – the Cygwin version will appear in the ~/.subversion/ directory. If you’ve already setup Putty, Plink and Pageant to manage your SSH identity this will still work – my config file has one change to support this:

[tunnels]

ssh = $SVN_SSH /c/tools/putty/PLINK.EXE

The second thing is to do with deletes. During the course of a development episode, I might well delete some old files. When I perform a svn status I will get a bunch of files showing as ! meaning that they have been removed by something other than a Subversion request. In fact I’ll get output a bit like this:

$ svn st

A      src/Core/Generators/NewGenerator.cs

!      src/Core/Generators/StandardDotNetUpperCaseGuidGenerator.cs

!      src/Core/Generators/IGuidGenerator.cs

Typically I then manually run a svn rm command for each of these, but this can get a little tedious after you’ve done it once. So since I’m using Cygwin, I can use some script to get the shell to do it automatically for me:

$ svn st | awk '$1 == "!"' | cut -c 2- | xargs svn rm

D         src/Core/Generators/StandardDotNetUpperCaseGuidGenerator.cs

D         src/Core/Generators/IGuidGenerator.cs

Now I don’t want to have to remember to do this every time, so I add this to the .profile file in my Cygwin home directory:

alias svnrmdeleted='svn st | awk "$1 == \"!\"" | cut -c 2- | xargs svn rm'

Now to remove from Subversion all deleted files I just type svnrmdeleted .

UpdateMatt Ryall came back with the update to the above using awk rather than grep. (Otherwise you might end up deleting files with actual “!”‘s in the name). He also grappled the required escaping to get the alias to work. (Thanks Matt!)

Update – Dan Bodart has since told me how to do this in plain Windows shell (Thanks Dan!):

  • for /f "usebackq tokens=2" %i in (`"svn st | findstr !"`) do svn rm %i

So, in summary – go use Subversion! Even if you are mostly a Windows user then try using its command line and ask some friendly UNIX- (or Windows Script-) savvy people how to automate some things you do often.