Skip to content

Git / Git-tfs / Nuget Gotcha

I would like to start by saying that git, git-tfs and Nuget are all technologies that have made developing software much easier. However I am writing this to explain how to avoid one pitfall. First let’s set the stage:

  1. I was using the sample .gitignore file that can be found here
  2. I was using git-tfs to make integrating with TFS easier.
  3. I wanted to use a better mocking framework than RhinoMocks and had decided to try out NSubstitute.

Of course, like any sane developer I installed NSubstitute using it’s Nuget gallery. I wrote my unit tests and checked in my code. By the way, I highly recommend NSubstitute over RhinoMocks. I had automated builds in place, and I watched it go as it builds my latest check-in.

However it choked and didn’t even compile. I checked the output to find a lone error stating that the NSubstitute.dll could not be found, but it worked on my machine. The problem was that I didn’t check it into git which kept git-tfs ignorant of it and hence TFS. The reason is that the .gitignore file I used included the following:

# Compiled source #
###################
*.com
*.class
*.dll
*.exe
*.o
*.so

The intent of this section makes perfect sense, and it is certainly a best practice not to check-in binaries. However in this case, we actually wanted to check-in dependent binaries. The problem was that the above .gitignore file does not discriminate between binaries in:

solutionFolder/packages/

vs.

solutionFolder/ProjectFolder/bin/

I ended up modifying my .gitignore file to simply have the following:

bin/

I hope this saves others some time and stress.

Tee is great

Even today, amidst promised integration and automation, when all else fails you still need to tap into the power of the terminal (command line/batch for Windows). I needed a way of piping output to both the console and a file from my batch file.

There are numerous references online that explain how to redirect console streams(e.g. Batch How To…Display & Redirect Output). There are actually three different types of streams:

  1. Standard Output
  2. Standard Error
  3. Console

In my case, I wanted the first two to be present in a file and in the console. The file allows for inspecting the output at a later time, while the console informs the user of their progress and any errors as they occur.

Output redirection follows The Highlander Principle(there can be only one). Each of the output streams can go to a single destination. That is, before you introduce tee into the mix.

call process.bat 2>&1 | "%ProgramFiles(x86)%\GnuWin32\bin\tee.exe" -a output.log

There are several aspects of the above statement to notice:

  • The 2>&1 part redirects the Standard Output and Standard Error while preserving the console.
  • The latter part calls tee.exe, which receives the redirected output.
  • The -a specifies output to a file. The next argument is that files name.

Tee is one of the many useful, compact and self-contained programs that are part of the GnuWin32 package. I have found them particularly useful when going beyond the basics of batch commands and utilities.

Two Kinds of Shortcuts

While contemplating some shortcuts I have taken, I realized there are two distinct categories. They are Debit Shortcuts and Credit Shortcuts.

Credit Shortcuts allow you to defer payment. Think of these as taking out a loan with interest.

“I’ll do it later”

usually punctuates these shortcuts. Over time these add up to a significant liability in your code.

A great example of this is a manual or multiple step deployment. Initially it’s cheaper than creating a cohesive install, but it will cost you dearly if it continues to live on(and these typically grow over time as well).

Debit Shortcuts cost you an initial investment, but potentially yield more and more as time passes. Not all of them yield dividends, but at most you lose the initial investment. Typically investments in code will snowball in a positive direction. A great example of this is abstraction.

Creating an abstraction bears some cost, but using the abstraction provides a benefit to the consumer. A great example is automating your build process. Hopefully you are doing daily builds! Imagine saddling one team member with the manual task of creating a build every time a manager, customer, tester and/or installer wants to see your progress.

By the same token, there is a significant cost associated with unnecessary abstraction. In the end, it generalizes to return on investment. When you favor Debit Shortcuts, you set roadblocks further down your path. When you load up on Credit Shortcuts, you may be in the red on some but overall you are creating a more productive future.

NSIS: Copy File Only If Greater Version

Dictating an install order frustrates anyone that has to deploy your software. Machines are made to follow the same instructions identically over and over again, but people are not. I am presenting the below Nullsoft script to prevent anyone from caring about install order(the code must be forwards compatible).

The macro only replaces the file if it is a greater version than the one already present. If they are equal or the existing file is later, then no action is taken.

!macro CopyIfGreaterVersion existingFile installFile
	Var /GLOBAL existingVersion
	Var /GLOBAL newVersion

	${GetFileVersion} ${existingFile} $existingVersion
	${GetFileVersion} ${installFile} $newVersion

 	${VersionCompare} $existingVersion $newVersion $R0

	${If} $R0 == 2
	  File ${installFile}
	${Else}
	  ;DetailPrint "The existing file below is up to date."
	  ;DetailPrint ${existingFile}
	${EndIf}
!macroend

# create a default section.
Section
	setOutPath "C:\test\"

	!insertmacro CopyIfGreaterVersion "C:\test\A.exe" "A.exe"

SectionEnd

The following definitions and references must be used at the top of the file to prevent compilation errors.

  1. !include LogicLib.nsh
  2. VersionCompare
  3. GetFileVersion

Visual Studio 2012: Impressions

Visual Studio 2012 Logo
I had the opportunity to participate in a demo as well as start using Visual Studio 2012, and here is what I came away with.

I liked:

  • TFS Web access looks kind of usable, which is in stark contrast to 2010.
  • Product Backlog Items’ or PBI’s can be hierarchical.
  • Allows for the manual exlusion of files from pending changes
  • Allows the user to define exclusion rules as well. This sounds vaguely like something else that I’ve heard of.
  • Typescript provides strongly typed javascript that gets compiled down into standard javascript.
  • Code clone analysis is done with the IL which is nice.
  • Unit tests can be created from an action recording.
  • Built in Nuget integration

I didn’t like:

  • They moved Undo... under source control, rather than directly in the right click menu. This is something I use everyday. Why did they do this?
  • The monochromatic toolbars, but this can be fixed. Even so, they could have done a better job with the defaults.
  • Removed the Create Unit Tests option that set up a skeleton(test assembly, class, and method). This is reportedly due to the fact that they got rid of private accessors, but I think they still could have saved me some typing.
  • Microsoft Fakes is only available for VS 2012 Ultimate! I have no idea why they are trying to incentivize creating .NET code without unit tests.
  • DataDrivenUnit Tests make it easy to tie unit tests to the database. I don’t like this, because it allows your tests to fail without any bugs in the code.

These set the wrong precedent:

  • Shelve changeset/suspend work looks great at first glance, but really encourages context switching. The cost of context switching has absolutely nothing to do with the ide.
  • Request a code review. This feature shouldn’t be necessary. A developer should turn to their colleague and ask them to review their code. This seems to facilitate (read encourage) working in silos.
  • TFS and VS 2012 seem bent on facilitating remote development, communication, and work.
  • I like that you can associate a code review with a changeset, but it seems like this may contribute to finger pointing. X reviewed Y’s code and neither of them caught the error, so they are at fault.
  • Code metrics seemed like a very useful thing, but they have a very high tolerance for what I would consider bad code.
  • Layer diagrams enforce architecture. Seems like they are trying to achieve productivity through massive parallelism like an ant hill does.

Conclusion
They heard and didn’t hear their user base but sided with the check writers(non-developers/users in most cases). The look and feel appears to be the side effect of mobile fervor without anyone else being quite as excited. All of the features to encourage cheaper developers and a heavy organizational structure certainly cater to thosee assigned with cutting development costs. In the end, it is a continuance of what the ide has always been.

Orlando GiveCamp 2012

I had the opportunity to participate in GiveCamp Orlando. For those who don’t know, GiveCamp is a weekend of fun, excitement and helping your community. My group worked with Second Harvest of Central Florida.

They wanted to improve the way users received information about nearby food banks. The existing process included the following steps:

  1. Send an e-mail with your location
  2. The e-mail is read
  3. A reply is sent with all the locations that can provide assistance
  4. Receive an e-mail with all the nearby locations

The process needed to be automated to distribute information quickly and release volunteers and staff to contribute in other ways. Our solution integrated Google Maps with their existing site. This required using php, which I was not familiar with. However you never know exactly what technology stack the customer already has, until you discover it.

Everyone on the team was great, and we produced valuable software that works and can be found here. I cannot thank all of the sponsors and everyone that worked hard to make GiveCamp a success. I have taken away some personal lessons from the experience about what I would repeat and avoid.

Repeat

  • Deliver working software in 3 days
  • Work with a talented and motivated team
  • Speak directly with the customer

Avoid

  • Work without source control
  • Not verifying that my wireless worked on my laptop
  • Work on an unfamiliar technology stack with a 3 day schedule

I highly recommend the experience to anyone interested, and I look forward to volunteering again next year.

Finding the Best Technology

I have squandered days at a time searching for the best technology. After sucesses with imperfect frameworks and libraries, I understand this pursuit of a mythical beast for what it is. Whenever you find the latest and greatest, it is promptly replaced by a better one years later, or it wasn’t even that good to begin with.

It’s like finding the largest prime number. Congratulations, you just found the largest prime number, but the good people at seti@home are charging toward the next largest prime number.

Striving for the right approach helps, but falling for the lures of any particular technology invites disaster. Architecting clear and logical separations in your code where older technologies can be swapped with newer ones represents the only sound approach.

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: