3
\$\begingroup\$

I've been creating some NuGet packages recenly and to automate the process I created the following script that:

  • reads the package id from the script name
  • reads the package version from the nuspec file
  • can rebuild the solution, create a package and upload it by specifying the jklparameters where:

    • j - 0/1 - disables/enables project rebuild
    • k - 0/1 - disables/enables package creation
    • l - 0/1 - disables/enables package upload to the server

Usage:

./MyPackage.ps1 110

This would create a package called MyPackage with rebuilding the solution but not uploading it to the server yet

param([String]$cmd)

$build = $cmd.Substring(0,1) -eq "1"
$pack = $cmd.Substring(1,1) -eq "1"
$push = $cmd.Substring(2,1) -eq "1"

$packageId=[System.IO.Path]::GetFileNameWithoutExtension($MyInvocation.MyCommand.Definition)

[xml]$nuspec = Get-Content $PSScriptRoot\$packageId.nuspec
$version = $nuspec.SelectSingleNode("//package/metadata/version").InnerText

if ($build)
{
    msbuild `
        /t:Rebuild `
        /nologo `
        /p:Configuration=Release `
        /p:TargetFrameworkVersion=v4.5.2 `
        /p:Platform="Any CPU" `
        /p:OutDir="$PSScriptRoot\lib\net452" `
        `"$PSScriptRoot\..\Foo.sln`"
}

if ($pack)
{
    nuget pack `
        $PSScriptRoot\$packageId.nuspec `
        -properties configuration=release `
        -outputdirectory C:\NuGet\packages\
}

if ($push)
{
    nuget push `
        C:\NuGet\packages\$packageId.$version.nupkg `
        -configfile $PSScriptRoot\NuGet.config
}
\$\endgroup\$
  • \$\begingroup\$ I don't understand the rationale for the "110"-style parameter. That seems very user-unfriendly. What is the reason for it? \$\endgroup\$ – Dangph Jul 26 '16 at 11:34
  • \$\begingroup\$ @Dangph it's explained in the question. Each position enables respectively build|pack|push - it's quicker to type and easy to remember because this is the order of package creation so 110 means build|pack|don't push or 001 means don't build|don't pack|push \$\endgroup\$ – t3chb0t Jul 26 '16 at 11:37
1
\$\begingroup\$

Parameters

You could achieve something similar by making real parameters with boolean values such that you can type MyPackage.ps1 1 1 0; feeding 3 positional, named, parameters at a cost of two presses of the space bar.

It's not that much slower to type and makes it a lot easier to understand the code (in my opinion).

In addition, you're easily able to add parameter help.

param(
    [Parameter(Mandatory = $true, Position = 1)]
    [Boolean]$Build,

    [Parameter(Mandatory = $true, Position = 2)]
    [Boolean]$Pack,

    [Parameter(Mandatory = $true, Position = 3)]
    [Boolean]$Push
)

Make $Build default to true perhaps and you have a "Control+Shift+B"-able script.

Ticks

I'd consider killing off those ` you have everywhere. A misplaced space after one would break those very easily.

I would generate arguments as an array and feed the call operator. For calls to internal PowerShell commands I would favour splatting for long parameter lists.

$packArgs = @(
    'pack'
    "$PSScriptRoot\$packageId.nuspec"
    "-properties", "configuration=release"
    "-outputdirectory", "C:\NuGet\packages\"
)
& nuget $packArgs

XML handler

Perhaps consider using Select-Xml as it can read directly from a file.

GetFileNameWithoutExtension

There's an alternative perhaps:

([System.IO.FileInfo]$pscommandpath).BaseName

Or, of course, the original but derived from $pscommandpath.

Alternative approaches

This is a simple build script, but had you looked at psake? https://github.com/psake/psake.

\$\endgroup\$
  • \$\begingroup\$ Thank you for the suggestions. I really need to implement them. As to psake... this requires a longer study ;-] \$\endgroup\$ – t3chb0t Aug 8 '16 at 20:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.