Paul Selles

Computers and cats

Category Archives: Bash

TFS and Git Can Play Together

If you find yourself in a situation where you are using both TFS and Git for source control then you may be tempted to duplicate your efforts and write separate scripts for both. Before you get carried away, hear me out. My company uses both TFS and Git, and I have created a couple of scripts to help interact with both environments.

All the scripts that I have written find the project root directory and do all the work from there. Consequently, all my builds, testing, and deployments will be defined relative to the project root directory.  The root directory for our Git project is based off the TopLevel, and for TFS the root directory is based off the ProjectCollection.

Since we are dealing with Git and TFS I feel like I should provide a solution for both bash and PowerShell.

First bash:

#!/bin/bash

# Find and move into project directory
if [ $(git rev-parse --is-inside-work-tree 2> /dev/null) ]
then 
	echo -e "33[1;35mBuilding in git33[0m"
	path=$(git rev-parse --show-toplevel)
else
	echo -e "33[1;35mBuilding in tfs33[0m"
	tfpath=`C:/Program\ Files\ \(x86\)/Microsoft\ Visual\ Studio\ 11.0/Common7/IDE/tf.exe info $/`
	tfpath=${tfpath##*Local path : }
	tfpath=${tfpath%% Server path:*}
	path=$tfpath
fi

pushd $path

## Your script goes here
# Go ahead build, test, deploy
# Seriouly enjoy yourself

# Return to starting directory
popd

In the above script it may be unnecessary to include the full path to tf.exe if it already exists in your windows environment %PATH%. I find it helpful to include bash related scripts within my bash environment $PATH. A simple way to include custom scripts is the navigate to your scripts directory and type in the following command:

> echo “export PATH=\${PATH}:${PWD}” >> ~/.bashrc

This will append to your .bashrc script which is used when you open a new interactive shell.

Now for the PowerShell solution:

function Get-VsCommonTools
{

	# Array of valid VS Common Tools environment variable versions,
	# ensure that the path is not null.
	$VsCommonToolsPaths = @(@($env:VS110COMNTOOLS,$env:VS100COMNTOOLS) | Where-Object {$_ -ne $null})
	if ($VsCommonToolsPaths.Count -ne 0) {$VsCommonToolsPaths[0]}
	else {Write-Error "Unable to find Visual Studio Common Tool Path."}
}
################################################################################
function Get-Tf
{

	$TfPath = Get-VsCommonTools

	if (Test-Path "${TfPath}..\IDE\tf.exe")
	{
		return "${TfPath}..\IDE\tf.exe"
	}

	Write-Error "Could not find tf.exe"
}
################################################################################
function Get-Git
{

	# Array of valid VS Common Tools environment variable versions,
	# ensure that the path is not null.
	$ProgramFilesPaths = @(@($env:PROGRAMFILES,${env:PROGRAMFILES(X86)}) | Where-Object {Test-Path (Join-Path $_ "\Git\cmd\git.exe")})
	if ($ProgramFilesPaths.Count -ne 0) {(Join-Path $ProgramFilesPaths[0] "\Git\cmd\git.exe")}
	else {Write-Error "Unable to find Git Path."}
}
################################################################################
function Get-RootDirectory
{
	$Tf = Get-Tf
	$Git = Get-Git

	if (& $Git rev-parse --is-inside-work-tree 2> NULL) { $RootDirectory = & $Git rev-parse --show-toplevel }
	else { if ([String](& $Tf info $/) -match "\s*Local\s*path\s*:\s*(?[^\s]+)") { $RootDirectory = $matches["LocalPath"] } }

	if (-not $RootDirectory) { Write-Error "Could not find root directory"; return }

	$RootDirectory
}

In the above script we have four functions. The first function will get the latest visual studio common tools path, as mentioned above. This is unnecessary if tf.exe is within your %PATH% windows environment variable. The next two functions are to get the local path for both tf.exe and git.exe. Once again, these two functions can be referenced in %PATH% instead. The final function Get-RootDirectory will return root directory of the currently active project.

The Powershell script is slightly different than the bash script, though it achieves the same results, to determine if the current working directory is within Git or Tfs. Using these two scripts, I am able to work with one set of build, testing, and deployment scripts for the code in either Git or Tfs. I hope you find them as useful as I have.

%d bloggers like this: