versioning with teamcity and nant

I'm using TeamCity to run my builds for a few projects and find it very easy, reliable and intuitive. It integrates with Subversion and NAnt with little effort but one of the missing tasks I had was to version my assemblies with the build number, so I took it upon myself this week to sort that out.

TeamCity provides a build number pattern when you configure a build so I simply set that to "{0}" so I can provide the current build number - this becomes a nant property called ${build.number}.

Next thing to look at was changing the AssemblyInfo.cs file within each .csproj so that it picked up the assembly info and file info strings from a controlled place. My initial idea was to have nant poke an xml file before it was then embedded as part of the compilation, but this naturally didn't work as it needs to be a compile time constant. So I went with this:

using MyProject.Core.Build;
[assembly: AssemblyVersion(Build.Version)]
[assembly: AssemblyFileVersion(Build.FileVersion)]

This uses a very simple static class I created for this purpose:

namespace MyProject.Core.Build
{
    public static class Build
    {
        public const string Version = "0.1.0";
        public const string FileVersion = "0.1.0";
    }
}

That was it for C# code, time to modify the nant build file so that it replaces the version number from the build before it compiles:

    <property name="version.file" value="${project::get-base-directory()}
\..\product\MyProject.Core\Build\Build.cs"
/> <property name="build.number" value="0" overwrite="false"/> <target name="compile" depends="init" description="compiles the application"> <move file="${version.file}" tofile="${version.file}.bak"/> <copy file="${version.file}.bak" tofile="${version.file}"> <filterchain> <replacestring from=".0" to=".${build.number}" /> </filterchain> </copy> <delete file="${version.file}.bak"/> <loadtasks assembly="c:\dev\thirdparty\nantcontrib-0.85\bin\NAnt.Contrib.Tasks.dll" /> <msbuild project="../product/MyProject.sln"> <!-- this property enables MSBuild 3.5 --> <property name="teamcity_dotnet_use_msbuild_v35" value="true"/> <property name="OutputPath" value="${build.dir}"/> </msbuild> </target>

This first creates a backup of the C# file and then uses the copy command to copy it back over the original whilst it replaces the ".0" string with the TeamCity provided build number property. It then deletes the back up file it created.
There are other ways of using NAnt to replace tokens, but this works out of the box without adding additional tasks in.
At the start of the script if this build is not being run by TeamCity a default value of "0" is being provided.

And that is it! My assemblies are all built now using the build number - I get the current major and minor version from the constant string and the build number from the continuous integration process.

Posted at at 7:12 AM on Monday, September 28, 2009 by Posted by Justin Davies | 0 comments Links to this post   | Filed under: ,

writing a windows live writer plugin

Recently, I had the need to write a plugin for windows live writer so that I could highlight some code and click a tool item to get it formatted ready for publishing to my blog.
Surely this was going to be a relatively involved exercise, right?image

It was very simple - in fact it was so easy I thought I'd illustrate it here in a small post.

The first thing I did was to create a new C# class library and import the code formatting classes - I'm using the CSharpFormat by Manoli. Here's what the final version of the project looks like:

I'm referencing the WindowsLive.Writer.Api.dll assembly that resides at
"C:\Program Files\Windows Live\Writer\" and I have only one file called CSharpContentSource which is illustrated below.

This class is decorated with two attributes - the first, "WriterPlugin", defines a guid identifier for the plugin and the second, "InsertableContentSource", addes the appropriate behaviour for inserting content into live writer. Note that the string in the constructor is the menu text that will appear in live writer.
The class inherits from the ContentSource class and there is one method overriden  - CreateContent.

When this method is called, the content parameter contains the currently highlighted text - as it is a ref parameter we can change what will appear in the live writer application when our method completes.

using Manoli.Utils.CSharpFormat;
using WindowsLive.Writer.Api;
using System.Windows.Forms;

namespace LiveWriterCodeFormatting.LiveWriter
{
    [WriterPlugin("FE7AEF3C-7645-4fe0-9086-D1DB40C0D007", "CSharpFormatter")]
    [InsertableContentSource("CSharp formatting")]
    public class CSharpContentSource : ContentSource
    {
        public override DialogResult CreateContent(IWin32Window dialogOwner, ref string content)
        {
            var format = new CSharpFormat();

            if(!string.IsNullOrEmpty(content))
            {
                var newContent = format.FormatCode(content);
                content = "<div class=\"codeBlock\">" + newContent + "</div>";
            }                

            return DialogResult.OK;
        }       
    }
}

In the method CreateContent I am simply taking the current content and formatting it through the format classes. I'm then adding my own blog requirements for css formatting and setting the content.
Simple stuff.

Lastly, if I introduce a post build event in project properties so that it copies the built assembly to the windows live writer plugins folder, each time I build it will auto install. The post build event is simply:
XCOPY /D /Y /R "$(TargetPath)" "C:\Program Files\Windows Live\Writer\Plugins\"

When I'm writing a post I can now use the Insert tool bar button to select my plugin option:

Posted at at 8:50 AM on Thursday, September 24, 2009 by Posted by Justin Davies | 0 comments Links to this post   | Filed under:

procrastination costs

Recently, I have been quiet on the blogging front. As with any blog, my plan was to start with nothing, post regularly and try and obtain a small readership and go from there, but that soon became unachievable.

This was primarily down to the way I was blogging - I couldn't get live writer to work with my blog and because I really liked the tool I would write posts in writer than at some point manually copy them into my blogger post editor in the browser.

Then came the laborious task of formatting the C# code in my posts. I use the CSharpFormat code by Jean-Claude Manoli and find it great for formatting. But I had to run a web browser, copy the code into a textbox, press the format button then paste the formatted result back into the blogger editor. Laborious.

So I decided to do something about it and it took half a day to get live writer up and running with my blog. One sorted.

Then I decided to look into writing a live writer plugin that would allow me to format code using the CSharpFormat code I'm used to. That was far, far easier than I thought and I aim to illustrate just how simple it was.

In summary, procrastination clearly costs - if only I had spent that one day sorting my pain points out earlier I'd have been a less stressful author. I'm sure there's a lesson there.

Agile is supposed to discourage decision deferral, debt of all kinds and the broken windows syndrome. I need to do some more work on that.

Posted at at 8:00 AM on Monday, September 21, 2009 by Posted by Justin Davies | 0 comments Links to this post   | Filed under:

more iterative context specification code

In this series I've been exploring two user stories and writing context specification driven code - I continue on from the last post where I had reworked some specifications. You can catch up on the series here.

I now want to add the observations for obtaining the new balance date from the view, so start with a new observation (new code shown in italics):

[Observations]
public class when_saving_a_new_balance_but_balance_input_is_invalid : BalancePresenterSpecification
{
    private context c = () => balanceView.Stub(v => v.NewBalanceIsValid()).Return(false);

    because b = () => sut.SaveCurrentBalance();

    [Observation]
    public void should_not_obtain_new_balance_amount_from_the_view()
    {
        balanceView.was_never_told_to(v => v.GetNewBalanceAmount());
    }

    [Observation]
    public void should_not_obtain_new_balance_date_from_the_view()
    {
        balanceView.was_never_told_to(v => v.GetNewBalanceDate());
    }
}

Here, I am observing that the new balance date is not obtained from the balance view in this context where the input is invalid. This test passes straight away... the main problem with negative assertions such as this, so in the SaveCurrentBalance method I put in some temporary code on the first line to call the GetNewBalanceDate method.
This allows me to validate that the test is correct and doesn't produce a false positive. I get a Rhino Mocks ExpectationViolationException so all is good and I remove that temporary code.

Now for the context where the balance input is valid (new code in italics):

[Observations]
public class when_saving_a_new_balance_and_balance_input_is_valid : BalancePresenterSpecification
{
    private context c = () => balanceView.Stub(v => v.NewBalanceIsValid()).Return(true);

    because b = () => sut.SaveCurrentBalance();

    [Observation]
    public void should_obtain_new_balance_amount_from_the_view()
    {
        balanceView.was_told_to(v => v.GetNewBalanceAmount());
    }

    [Observation]
    public void should_obtain_new_balance_date_from_the_view()
    {
        balanceView.was_told_to(v => v.GetNewBalanceDate());
    }
}

Here, I'm observing that when the context is valid the new balance date was obtained from the view. This test fails, which is great, so I now implement the real code:

public void SaveCurrentBalance()
{
    bool newBalanceIsValid = balanceView.NewBalanceIsValid();
    if (newBalanceIsValid)
    {
        amount = balanceView.GetNewBalanceAmount();
        date = balanceView.GetNewBalanceDate();
    }
}

I now have some code working to retrieve the data, but there are a couple of things I don't like about this. Firstly the retrieval of data is happening through method calls as opposed to properties and I really do think as it is merely data I am obtaining that they should be property "get" calls. Secondly the syntax doesn't read right: "the balance view was told to get balance amount"; this is not correct because it is the presenter that is getting the balance amount.

Now I'm not proposing that this library force my hand in implementation details such as whether to use a property method call, but I think it does add huge value by providing clarity on a shaky syntax between the two objects (presenter and the view).

So how do I go about changing this? My personal opinion is that it is important to keep the code I've just written in place - jumping in and removing bits of specification code and production code may negate some of my context-first process and leave me with holes in my code coverage. Instead I'll complement each incorrect one before then removing the old code.
I start with the interface on the view and have two new properties (new code in italics):

public interface IBalanceView
{
    void SetBalance(Balance balance);
    bool NewBalanceIsValid();
    Double GetNewBalanceAmount();
    DateTime GetNewBalanceDate();
    Double NewBalanceAmount { get; }
    DateTime NewBalanceDate { get; }
}

I can now use these in some new observations in my contexts (note, I've omitted the context and becaused delegates and the previous observations for brevity)

[Observations]
public class when_saving_a_new_balance_and_balance_input_is_valid : BalancePresenterSpecification
{
    ...(code omitted)...

    [Observation]
    public void should_obtain_new_balance_amount_from_the_view()
    {
        balanceView.was_told_to(v => v.GetNewBalanceAmount());
        balanceView.AssertWasCalled(v => { var ignored = v.NewBalanceAmount; });
    }
}

I've left the old line in place for now, but underneath it I now have an assertion that the NewBalanceAmount property was read - using an assignment in the anonymous delegate.

My test predictably fails so I now implement this code (new code in italics):

public void SaveCurrentBalance()
{
    Double amount;

    bool newBalanceIsValid = balanceView.NewBalanceIsValid();
    if (newBalanceIsValid)
    {
        amount = balanceView.NewBalanceAmount;
        balanceView.GetNewBalanceAmount();
        balanceView.GetNewBalanceDate();
    }
}

The tests pass and I can now start to remove the code that I no longer need. I comment out the line above that calls GetNewBalanceAmount() and then re-run my tests - this way I can locate which tests are affected by proposed removal. One them fails - "should_obtain_new_balance_amount_from_the_view" and this is because I had left both assertions in. I can now remove the invalid one and re-run the tests and they pass. Now I want to remove the interface contract for this on the view so I comment the line out on the interface and build the project - there is one specification that fails so I clean that up:

[Observations]
public class when_saving_a_new_balance_but_balance_input_is_invalid : BalancePresenterSpecification
{
    ...(code omitted)...

    because b = () => sut.SaveCurrentBalance();

    [Observation]
    public void should_not_obtain_new_balance_amount_from_the_view()
    {
        balanceView.AssertWasNotCalled(v => { var amount = v.NewBalanceAmount; } );
    }
}

I follow the same process for the GetBalanceDate() changes and make all the amendments step-by-step as I did above and once finished I have a clean interface, clean specifications and my tests pass.

Posted at at 7:29 AM on Friday, September 18, 2009 by Posted by Justin Davies | 0 comments Links to this post   | Filed under: ,