How to use a tool installed by Nuget in your build scripts


My last post covered tips for people creating Nuget packages. This one is important for people consuming Nuget packages.

Some Nuget packages include executables in their tools folder. It is very easy to use these tools within Visual Studio because Nuget makes them available in the path of the Package Manager Console. However, they are very difficult to use outside of Visual Studio, especially in a build script. The problem is the name of the folder containing the installed package includes the version number of the package. If you install NUnit 2.5.1, the nunit-console.exe will be in packages\NUnit.2.5.1\tools. However, if you later upgrade to NUnit.2.5.2, the path to nunit-console.exe will change to packages\NUnit.2.5.2\tools. You will need to change your build scripts every time you upgrade your version of NUnit. That is unacceptable.

The solution is to create a helper that can figure out where the tool lives. If you are using rake for build automation, it is fairly straightforward:

If not, you may want to create a batch file in the root of your project that calls your tool. You can create a tool specific batch file:

Or, if you have lots of tools from different packages, you might just want a generic batch file that allows you to specify the executable name:

Tips for building Nuget packages
Run QUnit tests under Continuous Integration with NQUnit

Comments

Commenting is closed.

ray2k Jun 26, 2011

top-of-my-head powershell version, save as nunit.ps1 in root directory
$filename = $args[0]$scriptDir = [System.IO.Path]::GetDirectoryName($myInvocation.MyCommand.Definition)$packagesDir = Join-Path $scriptDir "source\packages"$exePath = dir $packagesDir -recurse | where { $_.PSIsContainer -eq $false -and $_.Name -eq $filename } | foreach { $_.FullName } | sort -descending | select -first 1$argString = ""for($count = 1; $count -lt $args.Length; $count++){    $argString = $argString + $args[$count]}$cmdline = $exePath + " " + $argStringInvoke-Expression $cmdline

Then your build can call powershell.exe full-path-to-nunit.ps1 nunit-console.exe arg1 arg2 arg3 '`"arg with spaces`"'
Probably a billion ways to do this. Thanks for occupying my Sunday morning :)

Mark Dec 18, 2012

I found an easier fix. Apparently 'CD" does work with wildcards. So in your build event you do:
CD "$(SolutionDir)packages\MyAwesomeTool*\tools"
CALL MyAwesomeTool.cmd

Frederic Malenfant Apr 13, 2018

Wow, 5 years ago... and you have my solution! We need to run post-build-events to the "latest" nuget of typescript, and your "cd wildcard" solution still do the job, even in visual studio 2017! Thank you.

Roman Baeriswyl Jun 2, 2017

Just stumbled uppon this. It is even easier if you pass "-ExcludeVersion" to the nuget.exe command. With that, the version number is not part of the path anymore and therefore is very static.