I’ve been working on continuous integration and automated builds/deployment lately.  I put together a MSBuild script that does a whole bunch of typical stuff including getting code from my repository, compiling, and running tests.  I also want to create a Tag in my Subversion repository so I know which code was deployed.  That wasn’t too hard to do either.  The tricky part was that I want my build to fail if I try to make a Tag that already exists!

I fumbled around with this for a while trying a wide variety of ideas.  In the end, it turned out to be pretty simple.  There may be better ways to accomplish this, but here is how I am doing it…

I’m using the SvnClient task (it’s part of the MSBuild.Community.Tasks download) and executing a command:  “ls $(SvnRepository)/tags/$(SvnTagName)”.  Of course, my MSBuild script already has the variables $(SvnRepository) which is the path to my repository and $(SvnTagName) which is the name of the Tag I hope to create.  You may have to tweak this stuff depending on the layout of your SVN repository.  The command “ls” will actually list the contents of my Tag.  Since I know my tag just has a few folders in it (it isn’t a recursive task), it isn’t too harmful if it succeeds.  If the Tag does not exist in my repository, the command actually fails.  Oddly, I actually want this task to fail!  Yes, in my case, I am hoping the task does not find the Tag with the specified name.  When the task is executed, it returns an ExitCode which is 0 for success or 1 for failure.  Next I just check the returned code and if it is successful I generate an error.  Sure this feels a bit odd.  I don’t love using this kind of logic, hoping for an error to occur. I’d much rather have some subversion command I could execute to see if the Tag exists but I couldn’t find anything like that.  Here is the actual xml from my Build file to check for the Tag:

<Target Name="CheckSvn">
  <Message Text="*** Checking to see if the tag already exists"/>
  <!-- this task will look up the tag supplied.  
    If it exists it will return a code of 0 
    Technically this is a success but for this instance, 
    it is a failure because we don't want to find it! -->
  <SvnClient Command="ls $(SvnRepository)/tags/$(SvnTagName)" 
             Username="xxx" password="xxx" ContinueOnError="true">
    <Output TaskParameter="ExitCode" PropertyName="CommandResult"/>
  </SvnClient>
  <Message Text="*** ExitCode = $(CommandResult)"/>
  <Error Condition="$(CommandResult)=='0'" Text="This Tag already exists!"/>
  <Message Text="*** Finished Checking to see if the tag already exists"/>
</Target>

Working with MSBuild is becoming a love/hate relationship for me.  I really love the power of what you can do to automate tasks.  But it can be a real pain to write, test, and debug these scripts.  I hope my sharing this code will make your life a little easier.

You’ve heard about LINQ to SQL, LINQ to Objects and LINQ to XML right?  Well how about LINQ to String?  Well technically there is no such thing.  But you use LINQ on a string!  You may not have realized this before but it works.  LINQ can be used to query IEnumerable<T> and a string is actually a collection of chars.  So yup, you can actually query the string itself.  Here are a few simple examples but you certainly do a lot more than this…

public void LinqToStringSample()
{
    string letters = "keuiwierqewefqwfwefcjlkjkl";

    //count all 'e'
    int count = letters.Count(l => l == 'e');

    //order
    var ordered = letters.OrderBy(l => l);
    
}

I recently gave an “Introduction To LINQ” presentation at the Microsoft event:  Data Access Firestarter.  That session was recorded and posted on MSDN’s Channel 9.  Here is the link so you can check it out.  If you want the content, you can get it from this post.  I’m really excited to be on Channel 9, it is such a great source of content!

I also gave the same talk at Philly.Net Code Camp this past Saturday.  That talk was also recorded and is available via Live Meeting replay.  I think it will be on Channel 9 too.  Both sessions went pretty well. 

I do feel the need to make a correction though!  In the presentation at Code Camp I answered a question incorrectly.  It was a subtle error, but one just the same.  The question was “Can you use LINQ to SQL against other databases?”.  I’m not really sure why I gave the wrong answer because I have been doing this stuff for a long time and I really do know the right answer.  My incorrect answer was that you can do LINQ to SQL as long as you have a provider to the other database.  This is completely wrong!  You can certainly do LINQ to a wide variety of data sources, including Oracle, but that isn’t “LINQ to SQL”.  LINQ to SQL is specifically an implementation of LINQ to a SQL Server Database.  I hope that makes sense.