Part way through writing this series, I decided to convert the Niche.CommandLine project to .NET Core, which of course required a bunch of changes to the Psake build script. Let’s look at what was required.

Output Folder

After converting the .csproj files to the new style required by .NET Core, I found each project had reverted to building into the default bin folder underneath the project file.

Fortunately, I didn’t need to go through all the files and reconfigure them by hand. Instead, I created a single Directory.build.props file in the root of the repo to redirect all the outputs:

<Project>
 <PropertyGroup>
   <OutputPath>$(SolutionDir)\build\$(MSBuildProjectName)\$(Configuration)\</OutputPath>
 </PropertyGroup>
</Project>

This one file is automatically picked up by msbuild as each project is built, redirecting the build outputs into a folder structure of my choice. I wish we’d had this facility years ago.

Testing

To run the unit tests, I needed to switch from the previous xUnit test runner (xunit.console.runner.exe) to dotnet xunit because the old one doesn’t work with .NET Core assemblies. Doing this required a number of changes. Firstly, a new task to locate the dotnet executable:

Task Requires.DotNet {
    $script:dotnetExe = (get-command dotnet).Source

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

    Write-Host "Found dotnet here: $dotnetExe"
}

The get-command cmdlet searches through the PATH to find and return the full path to the application.

To run the tests themselves, the Unit.Tests task needs to change as follows:

Task Unit.Tests -Depends Requires.dotNet,
    Configure.TestResultsFolder, Compile.Assembly
{
    $testProjects = Get-ChildItem -Path $srcDir\*.Tests\*.Tests.csproj
    foreach($testProject in $testProjects) 
    {
        Write-Header $testProject.Name

        $reportFile = 
            [System.IO.Path]::ChangeExtension($testProject.Name, ".xunit.xml")
        $reportPath = join-path $testResultsFolder $reportFile

        Write-Host "Test report: $reportPath"

        pushd $testProject.Directory.FullName
        exec {
            & $dotnetExe xunit -nobuild -configuration $buildType -xml $reportPath
        }
        popd
    }
}

The Write-Header function just outputs a subheading so that the output of the build remains easy to read with each step clearly differentiated.

The foreach loop in this is also new - I’m planning on splitting the console logger out into a separate assembly so it can be deprecated (because the last thing anyone really needs is yet another logging framework). Adding the loop means that any additional testing assemblies will automatically be included.

One oddity here is that dotnet xunit has to be run in the right directory - there’s no way to pass a reference to the project. This is why the task above uses pushd and popd to move into the output bin directory before execution.

For better performance (since we’ve just done the required builds ourselves), we specify the -nobuild option.

Versioning

Previously we generated a VersionInfo.cs file to inject the version details into the final assembly.

For a .NET Core project, it’s very much simpler to inject the version - all we need to do is to override the Version property on the command line for msbuild.

Task Compile.Assembly -Depends Requires.BuildType,
    Requires.MSBuild, Requires.BuildDir
{
    exec { 
        & $msbuildExe /p:Configuration=$buildType 
            /verbosity:minimal
            /fileLogger
            /flp:verbosity=detailed`;logfile=$buildDir\Niche.CommandLine.msbuild.log 
            /p:Version=$semver20
            .\Niche.CommandLine.sln
    }
}

All in all, I found the change to .NET Core to be a lot simpler than I expected.

Comments

blog comments powered by Disqus