2D Head with a clock as an eyeball.
 Friday, March 14, 2008

Hey y'all, long time no see. Life has thrown me a few curve balls which impeded my blogability, but rather than boring you with details lets just get into straight into it.

Recently I've had a few queries regarding a check in policy I eluded to in this post. Today I hope to clarify how one might go about implementing a check in policy which ensures that Option Strict is turned on for VB projects.

Rather than rehashing a perfectly good walk through, I suggest you read this article from MSDN to get the basics of Check In Policy creation.

Once we have our check in policy project and have derived a class from Microsoft.TeamFoundation.VersionControl.Client.PolicyBase it is time to start overriding the behaviour of the base rule.

Imports Microsoft.TeamFoundation.VersionControl.Client

<Serializable()> _
Public Class OptionStrictPolicy
    Inherits PolicyBase

Once we are over that little hurdle we want to:

* Get the set of pending changes that have been selected by the user to check in

* For each pending change determine the project file that the change belongs to

* For each VB project determine if Option Strict has been turned on

* For each project that hasn't got option strict turned on, create a policy warning.

For extra fun I'll do this all with VS2008 & VB9. I love my C# but to be honest VB9 kicks its ass when dealing with XML.

1: Get the set of pending changes that have been selected by the user to check in

Everything from here on out extends the Evaluate method of PolicyBase. Getting the set pending changes selected by the user is a cinch. I've filtered by vb code files, but you could just as easily go for more file types.

Public Overrides Function Evaluate() As PolicyFailure()

  Dim pendingChanges = PendingCheckin.PendingChanges.CheckedPendingChanges
  Dim vbCodeFiles = _
    From c In pendingChanges _
    Let extension = Path.GetExtension(c.FileName) _
    Where extension = _VBFileExtension OrElse extension = _VBProjectFileExtension _
    Select c.LocalOrServerFolder, c.FileName

2: For each pending change determine the project file that the change belongs to

This step is a little trickier and basically involves drilling up the folder structure until we find a project file, and then checking the project file for a compilation reference to the pending change. This seems like a good place to refactor into a recursive function...

*SIDE NOTE* Am thinking of starting a petition to all relevant Dictionary makers to make the word "Refactor" a real word. Whose with me?

I'm sure we are all capable of looking for .vbproj files recursively up the folder chain. However we do need to allow for the possibility that there may be two vbproj files in a folder and if so, is our pending change referenced by either of them? To do this I need to go through the project file looking for <Compile> tags that include my pending change. For example in C# we might do it like this

var doc = XDocument.Load(XmlReader.Create(projectFilename));
var compileItems = from e in doc.Descendants()
    where e.Name.LocalName == "Compile"
    select e;
    
    return (from c in compileItems
      where c.Attribute("Include") != null && c.Attribute("Include").Value.Contains(filename)
      select c).Any();

But since Im using VB today I can do it like this...

Dim doc = XDocument.Load(XmlReader.Create(projectFilename))
Return doc...<Compile>.@Include.Contains(filename)

Not bad...but for this to work I do need to import the namespace of the project file schema, since the syntax that allows for <Compile> is checking qualified names, not local names.

Imports <xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

3: For each VB project determine if Option Strict has been turned on

Once I have a list of projects that are loosely associated with a check in, I can easily check for the existence of OptionStrict tags in the vbproj file. OptionStrict still defaults to off, so a lack of OptionStrict tags implies the setting is OFF. However it is perfectly valid to have an OptionStrict tag that is set to OFF so I need to account for those.

Private Shared Function IsOptionStrictOn(ByVal project As XDocument) As Boolean
    Return project...<OptionStrict>.Value = "On"
End Function

 

4. For each project that hasn't got option strict turned on, create a policy warning.

Creating policy warnings is a breeze and you can return as many as you want, in this scenario I want to ensure that one is created for each project that is in violation of my rule. The final Evaluate function looks like this...

Public Overrides Function Evaluate() As Microsoft.TeamFoundation.VersionControl.Client.PolicyFailure()
  Dim pendingChanges = PendingCheckin.PendingChanges.CheckedPendingChanges

  Dim vbCodeFiles = From c In pendingChanges _
    Let extension = Path.GetExtension(c.FileName) _
    Where extension = _VBFileExtension OrElse extension = _VBProjectFileExtension _
    Select c.LocalOrServerFolder, c.FileName

  Dim vbProjects = From c In vbCodeFiles _
    Select GetProjectFile(c.LocalOrServerFolder, c.FileName)

  Dim strictOffprojects = From p In vbProjects _
    Where Not IsOptionStrictOn(p)

  Dim policyFailures = New List(Of PolicyFailure)
  Dim messageFormat = "Please turn option strict on in the project file: {0}"

  For Each s In strictOffprojects.Distinct
    policyFailures.Add(New PolicyFailure(String.Format(CultureInfo.InvariantCulture, messageFormat, s), Me))
  Next

  Return policyFailures.ToArray()
End Function

 

So there you have it, VB9 to make coding an Option Strict ON policy nice and easy. Seems appropriate doesn't it?


Filed under:  |  |  |  | 
 Wednesday, December 19, 2007

Yes, I still use XSLT, hopefully in another post soon I'll elaborate as to what the hell for. For those of you in a similar boat to me, here is a short primer on using extension objects.

Some things, like interacting with the system environment, are hard to achieve using XSLT/XPATH 1.0. On the other hand its fantastic at declaratively transforming XML documents.

The .NET framework, even with the introduction of XLINQ, is fantastic at interacting with the environment, but its relatively poor for transforming XML.

The solution might be to marry the two together, but how?

Enter the extension object

Microsoft has saw fit to bestow upon us the power of the CLR inside the MSXSL Parser.

This approach obviously couples the usage of our XSLT to being executed via the MSXSL Parser, so for some people is not an option, however I am under the impression that Saxon for .NET allows a very similar approach if you need.

Another downside is that the Visual Studio XSLT debugger will not run your extended transforms, so you have to find alternative means to assess your output. However, for the seasoned XSLT hand coder, this should not be a problem.

So, to begin, this is how we inject our custom extensions object into a compiled transform.

XSLTexample1

Note that the URN provided is arbitrary, as long as you reference it correctly in your XSLT. It should look a little like this:

XSLTExample2

The extension object itself can be an instance of any class you wish to use. By declaring a function in your extension class you can use that function like any other XPath function from your XSLT.

XSLTExample4

This should open up a world of possibilities for XSL transformations. Oh, and extra points are awarded to those who figure out what I am trying to do from the examples ;)


Filed under:  |  | 

Last week I checked into changeset 10,000...

Today I created work item 1337!


Filed under:
 Monday, November 26, 2007

Darren Neimke points out that working from home may appear rosy to those who are forced to commute to a place of business most days of the week, though it can be a mixed blessing. He also points out that what works for some, will not work for others.

I have been working from home for a few days each week for the last few years and am in complete agreement. In order to stay fresh, I have had to develop strategies to combat homework wariness and I thought now was a good time to share. I feel it is a matter of setting the mood, staying motivated, focused & above all, connected with your team.

Setting the mood:

I like a well lit, dust free, cool room to work in. Airflow is good; fresh oxygen for the brain. I don't need a grand hall, but I find small crowded rooms to be harder to work in (might as well work in a cubicle!).

I have found it completely necessary to have office space at home. Its great to change it up and code in public, though I find it equally invigorating to come to work in a clean and organised home office environ. By having a place at home that is purely for work, I no longer have the problem of feeling like I'm always working. As a result I have a PC for work and a PC for play.

I do not like having the TV or radio on, I see it as nasty distraction that should be purged from existence. Though some calm, soothing metal & hard rock can really help me focus. YMMV of course ;)

Say no to your TV.

Staying motivated:

I find that a lack of structure saps my motivation. I think the best way to ensure I stay on track is to develop a routine and stick to it, just like I would if I had to go to the office.

Sticking to a routine will ensure that the home hat is removed and the work hat is firmly in place. Getting out of bed 5 minutes before I am required to interface with others over MSN will only makes me grumpier. I highly recommend having a decent lunch break and getting outside for some exercise to pump the blood back into your brain after a plate of homemade sushi rolls.

Enjoy the perks of working from home. 

Staying focused:

There are many potential distractions; partners, house work, XBox Live etc. can be phenomenally distracting. Avoiding the temptations of home can be easy for some, harder for others. In the past when my wife was at home with me, she would incorrectly assume that because I am home, I am capable of participating in household chores and errands while on the job.

Making clear boundaries with your spouse or family members about work times and expectations is paramount. Its also useful to have these boundaries for yourself. While 36 hour coding stints have a hero like quality about them, its fair to say that they are ultimately counter productive. My wife and I settled on the following arrangement:

  • Between 8am - 6pm we can communicate on issues, but I wont be able to action upon them until after work.
  • We can convene at lunch time, however since it is my lunch break I expect to have some downtime.
  • After 6pm I pledge to cease working unless there is a emergency. Oh, and blogging isn't working :)

In essence our relationship is treated as though I am actually in the office. I'd have to say that avoiding the XBox is easy in comparison.

 

Staying connected:

Try to stay in contact with your fellow employees as much as you can by whatever means necessary. Staying in the loop really helps to keep you motivated. If you are in the dark, you might miss out on another task, or not realise there is an urgent situation that requires your attention.

Stay in touch by whatever means necessary.

I also think it is important to have face time with my colleagues. While I am a complete MSN addict, I do find that it is far easier and more efficient to converse about complex issues via the spoken word. Since I actually work at the office about 75% of the time, this is not a problem for me.

I am yet to try webcam communication, and I would be interested to hear from anybody who uses it for work. However a brief trial of teamspeak proved to me that you just need to *be there* sometimes. It was great for 'thinking out loud' and discussing more complex issues, however it does require everyone involved to have a microphone + headset, which during our trial, was not possible. Much cheaper than call conferencing though.

 

In summary I treat myself and those around me at home like I am at work in order to keep a clear separation, although I balance this by treating myself to the perks of being at home and having more time. I might take a slightly longer break and spread the day out, or treat myself to a stint on the couch, or go down to the beachfront to read some blogs. Staying connected with my colleagues helps to define this balance and maintain my focus.

I hope that for those of you working from home or considering it as an option will find my experiences useful. How do you like to roll at home?


Filed under:
 Thursday, November 01, 2007

Perhaps I've lost my mind... perhaps I'm a little too open minded... but why is there so much press out there on Resharper vs Refactor?

After investigating both CodeRush and Resharper I finally decided to purchase Resharper 3.0. I have been happily using Refactor Pro! 2.x for the past year or so, but I recently stretched it's capabilities.

I like Refactor; the simplicity of using Ctrl+~ is intoxicating. However, since embracing test driven development along with using a model view presenter pattern for my UI design I've found it lacking.

The main things that tipped me over the edge happened to fall into the refactoring and navigation categories:

Create a new class/interface declaration from an unknown initialization.

 

This is perhaps the single most productive feature anybody doing TDD could desire, just declare willy nilly and fix up the red bits as you go with Alt+Enter. Intellisense works with types you haven't implemented yet.

Create a new field/local/property/method from an unknown word.

Once again allowing you to code with the knowledge of what does and doesn't exist (yet) using red highlighting, and to instantiate as late as possible into the design of your test.

Force a type to implement the interface of the variable type it is being assigned to.

I don't have to worry about switching over to the class code file to slot in the interface - all taken care of inline.

Walking thru usages via Ctrl+Shift+F12.

When programming behind interfaces, getting around can get a little tedious with the standard VS2005 UI. F12 doesn't cut it, especially in mixed language solutions. The advanced usage tools make it easy to hop around implementations.

But perhaps the one feature that wins it, that sets up a whole lot of other cool features for Resharper, is background compilation for C#. As far as I'm concerned, the compilation tax for C# is a major productivity drain when in comparison to VB.

Perhaps I'm weird in that I can't stand CodeRush, but I love Refactor Pro for its insanely creative refactorings. There are plenty of refactorings that Resharper doesn't do. However, when it comes to a fully fledged productivity suite - I seem to fly with Resharper without thinking. CodeRush, despite its name, seems to slow me down more than anything.

Whats even weirder is that it feels like Resharper begins where Refactor finishes - they seem to co-exist in near perfect harmony. And yes it still feels like fitting Ford parts to my Holden.

I think I've just exploded in a fit of non-conformity.


Filed under:  |  | 
 Monday, October 22, 2007

I hate strings. I like strong typing. Its that simple. I guess that is why I have a slight aversion to web development. Too many string literals make me nervous. It's not paranoia if every string literal *is* out to get you, right?

MIME-version: happyThankfully, the .NET framework comes to the rescue more often than not and I have often found myself using the System.Net.Mime namespace to alleviate my paranoia about string like "text/xml".

Or is it "text\xml"?  XD

In particular the MediaTypeNames class has a lovely declarative series of classes and string constants that define some of the most common mime types used today. Whilst not comprehensive by any stretch, it covers the standard cases. For example if you intend to use the "text/xml" type, then the syntax is as follows:

 

 

using System.Net.Mime;
.
.
.
string textXml = MediaTypeNames.Text.Xml; //look Mum, no strings!

Of course this is just a bit of a buck pass to the framework; it all boils down to a string literal eventually, but it lets me sleep better at night nonetheless.


Filed under:  | 
 Wednesday, October 17, 2007

I scared myself this morning, I thought I had managed to get the testing policy to ignore inconclusive test results and allow check in for change sets that had no business doing so. Scaredy cat - untitled by jthorvath

We use sub lists, that is to say we have a few master test lists that are parents to several sub lists of tests. It seems to make dealing with many tests a little easier. When you initially set up the testing check in policy for a team project you select which test lists you want it to ensure pass before the user can check in.

We started with a single list, and added sub lists at whim and will, wherever the need arose basically. However what we didn't realise was that, if you don't go and update the testing policy to watch your shiny sub list, any failures or inconclusive results will bypass the policy check. 

It would be nice, although its not imperative, if the testing policy could automate this process so we plebs don't have to remember. If you happen to agree, then submit your vote to Microsoft connect here.


Filed under:
 Tuesday, October 16, 2007

Hooly dooly batman, as it turns out, if all goes well between now and April/May 2008 we will be the proud and bewildered parents of identical monochorionic, diamniotic twins.

Interestingly, according to the repository of all knowledge, identical twins do not occur as a hereditary predisposition (as with fraternal twins), but rather as a random event distributed evenly across all populations. I don't think I will ever look at GUIDs the same way ever again!

I'm such a stunned mullet I can barely type, but needless to say my wife and I are absolutely ecstatic at the thought of having two bundles of joy. I didn't think I could get any happier. Wish us luck, we're gonna need it :)


Filed under:
 Sunday, October 14, 2007
Thinking girl by tigerpuppala_2

I forget every now and again that VSTS Test runner does not run your shiny test suite in place, it makes a new folder for each test run and....well you know the story.

 So this post is really just here to remind me that if I want to read in a file or have some other file system dependancy in a test then I really must apply the DeploymentItemAttribute to my test as well as setting it to copy to the output directory in some fashion. Oh, and I can get fancy by using the OutputDirectory property of said attribute if need be.

*sigh* If I say it often enough I will remember...

...I will use DeploymentItem and not scratch my head as every test fails...

...I will use DeploymentItem and not scratch my head as every test fails...

...I will use DeploymentItem and not scratch my head as every test fails...


Filed under:
© Copyright 2008 Jim Burger