While NuGet provides all the power needed to explicitly control every aspect of a package (something the exacting control freak in me really appreciates), a simple project like this doesn’t need anything more than the standard conventions.

In a piece of recursion fit for a Christopher Nolan film, the easiest way to install the NuGet command line tooling so that we have it available to use from our build script is to use NuGet itself - from inside Visual Studio.

Now we can work out how to do it by hand, our usual prelude to automation. With a bit of work (details below), we end up with this command:

PS> .\packages\NuGet.CommandLine.4.1.0\tools\nuget.exe 
        pack .\src\Niche.CommandLine\Niche.CommandLine.csproj 
        -version 9.9.9 
        -outputdirectory .\build\packages 
        -basePath .\build 
        -properties Configuration=Debug

(The options are wrapped for readability; if you’re trying this out for yourself, they all need to be on the same line.)

In order for this to work, I needed to review of the packages.config file to ensure that the dependencies were nice and tidy. I removed some dependencies not currently required, and flagged a few that are only needed during development so they’re not forced upon library consumers.

If you look at the full packages.config file from the repo, you’ll see a large number of static code analysis packages, tools that I’m trying out to see how well they work. None of these are required to run the CommandLineProcessor itself, so I’ve marked all of them as developmentDependency="true".

Not everything associated with a NuGet package can be derived by convention, so we need a nuspec file with some key details listed:

<?xml version="1.0"?>
<package >
  <metadata>
    <id>Niche.CommandLineProcessor</id>
    <version>$version$</version>
    <authors>bevan@nichesoftware.co.nz</authors>
    <owners>bevan@nichesoftware.co.nz</owners>
    <projectUrl>
    https://github.com/theunrepentantgeek/Niche.CommandLineProcessor
   </projectUrl>
    <requireLicenseAcceptance>false</requireLicenseAcceptance>
    <description>
      Convention based argument handling for console applications
    </description>
    <copyright>Copyright 2017</copyright>
    <tags>command line command-line option parser args arguments</tags>
  </metadata>
  <files>
    <file src="..\docs\ReadMe.txt" target="."/>
  </files>
</package>

The ReadMe.txt file that’s included will be automatically opened, by Visual Studio, when the package is installed as a quick reference reminder of the conventions used by the project.

We can now write the usual psake task to locate nuget.exe for us:

Task Requires.NuGet { 

    $script:nugetExe =
        resolve-path ".\packages\NuGet.CommandLine.*\tools\nuget.exe"

    if ($nugetExe -eq $null)
    {
        throw "Failed to find nuget.exe"
    }

    Write-Host "Found Nuget here: $nugetExe"
}

As before, we’re using a wildcard (*) for the version number so that we will always find it, regardless of the exact version available.

Next, a simple task to build the actual package:

Task Compile.NuGet -Depends Requires.NuGet, Requires.BuildType,
    Requires.BuildDir, Compile.Assembly, Configure.PackagesFolder {

    $nugetFolder = join-path $packagesFolder Niche.CommandLine
    mkdir $nugetFolder | Out-Null

    $csprojFile = resolve-path .\src\Niche.CommandLine\Niche.CommandLine.csproj

    exec {
        & $nugetExe pack $csprojFile -version $semver10 -outputdirectory $packagesFolder -basePath $buildDir -properties Configuration=$buildType
    }
}

Most of this task is stuff we’ve seen before.

We use the $semver10 version reference because these packages are going to be shared via NuGet.org; if we were using our own internal server, we’d use the semver 2.0 variable instead.

Comments

blog comments powered by Disqus
Next Post
Sharpen The Saw #12  25 Sep 2017
Prior Post
Sharpen The Saw #11  18 Sep 2017
Related Posts
Coverage History with Psake  18 Nov 2017
Tracking time with Psake  11 Nov 2017
The day my Psake build broke  04 Nov 2017
NuGet, .NET Core and Psake  28 Oct 2017
.NET Core with Psake  21 Oct 2017
Test Coverage Reporting with Psake  07 Oct 2017
Test Coverage with Psake  30 Sep 2017
Semantic versioning with Psake  16 Sep 2017
Versioning with Psake  09 Sep 2017
Launch Scripts for Psake  02 Sep 2017
More powershell posts »
Related Pages
September 2017 archive