Pentia.Publish-NuGetPackage.psm1
<#
.SYNOPSIS Downloads the latest nuget.exe from the web and saves it to "<current directory>\.pentia\nuget.exe". #> function Install-NuGetExe { [CmdletBinding()] param () if (Test-NuGetInstall) { Write-Verbose "nuget.exe is already installed." return } $saveToPath = Get-NuGetPath Write-Verbose "Downloading nuget.exe to '$saveToPath'" $sourceNugetExe = "https://dist.nuget.org/win-x86-commandline/latest/nuget.exe" $directoryPath = Split-Path -Path $saveToPath -Parent New-Item -ItemType Directory -Force -Path $directoryPath | Out-Null Invoke-WebRequest $sourceNugetExe -OutFile $saveToPath } function Test-NuGetInstall { Get-NuGetPath | Test-Path } function Get-NuGetPath { $localNuGetExePath = [System.IO.Path]::Combine("$PWD", ".pentia", "nuget.exe") $globalNuGetExePath = Get-GlobalNuGetPath if ([string]::IsNullOrWhiteSpace($globalNuGetExePath)) { return $localNuGetExePath } $globalNuGetExePath } function Get-GlobalNuGetPath { $latestGlobalNuGetExePath = Get-Command "nuget.exe" -ErrorAction SilentlyContinue | Sort-Object -Property "Version" -Descending | Select-Object -ExpandProperty "Source" -First 1 $latestGlobalNuGetExePath } <# .SYNOPSIS A thin wrapper for "NuGet.exe restore [...]". See https://docs.microsoft.com/en-us/nuget/tools/cli-ref-restore. .PARAMETER NuGetExePath Path to NuGet.exe. Defaults to "<current directory>\.pentia\nuget.exe". .PARAMETER SolutionDirectory Specifies the solution folder. Not valid when restoring packages for a solution. .PARAMETER OutputDirectory Specifies the folder in which packages are installed. If no folder is specified, the current folder is used. .PARAMETER ConfigFile The NuGet configuration file to apply. If not specified, %AppData%\NuGet\NuGet.Config is used. .PARAMETER NoCache Prevents NuGet from using packages from local machine caches. #> function Restore-NuGetPackage { [CmdletBinding()] param ( [Parameter(Mandatory = $false)] [string]$NuGetExePath = (Get-NuGetPath), [Parameter(Mandatory = $false)] [string]$SolutionDirectory, [Parameter(Mandatory = $false)] [string]$OutputDirectory, [Parameter(Mandatory = $false)] [string]$ConfigFile, [switch]$NoCache ) $builder = New-Object OptionBuilder $builder.Command = "restore" $builder.SolutionDirectory = $SolutionDirectory $builder.OutputDirectory = $OutputDirectory $builder.ConfigFile = $ConfigFile $builder.NoCache = $NoCache $options = $builder.Build() & "$NuGetExePath" $options if ($LASTEXITCODE -ne 0) { throw "NuGet command failed." } } <# .SYNOPSIS A thin wrapper for "NuGet.exe install [...]". See https://docs.microsoft.com/en-us/nuget/tools/cli-ref-install. .PARAMETER NuGetExePath Path to NuGet.exe. Defaults to "<current directory>\.pentia\nuget.exe". .PARAMETER PackageId The package to install. Can't be used with "PackageConfigFile". .PARAMETER PackageVersion The package version to install. Defaults to latest version. .PARAMETER PackageConfigFile The package.config file specifying which packages to install. Can't be used with "PackageId" and "PackageVersion". .PARAMETER SolutionDirectory Specifies the solution folder. Not valid when restoring packages for a solution. .PARAMETER OutputDirectory Specifies the folder in which packages are installed. If no folder is specified, the current folder is used. .PARAMETER ConfigFile The NuGet configuration file to apply. If not specified, %AppData%\NuGet\NuGet.Config is used. .PARAMETER NoCache Prevents NuGet from using packages from local machine caches. #> function Install-NuGetPackage { [CmdletBinding()] param ( [Parameter(Mandatory = $false)] [string]$NuGetExePath = (Get-NuGetPath), [Parameter(ParameterSetName = "InstallByPackageId", Mandatory = $true)] [string]$PackageId, [Parameter(ParameterSetName = "InstallByPackageId", Mandatory = $false)] [string]$PackageVersion, [Parameter(ParameterSetName = "InstallByPackageConfig", Mandatory = $true)] [string]$PackageConfigFile, [Parameter(Mandatory = $false)] [string]$SolutionDirectory, [Parameter(Mandatory = $false)] [string]$OutputDirectory, [Parameter(Mandatory = $false)] [string]$ConfigFile, [switch]$NoCache ) $builder = New-Object InstallOptionBuilder $builder.Command = "install" $builder.PackageId = $PackageId $builder.PackageVersion = $PackageVersion $builder.PackageConfigFile = $PackageConfigFile $builder.SolutionDirectory = $SolutionDirectory $builder.OutputDirectory = $OutputDirectory $builder.ConfigFile = $ConfigFile $builder.NoCache = $NoCache $options = $builder.Build() & "$NuGetExePath" $options if ($LASTEXITCODE -ne 0) { throw "NuGet command failed." } } Class OptionBuilder { [string]$Command [string]$SolutionDirectory [string]$OutputDirectory [string]$ConfigFile [bool]$NoCache Hidden [System.Collections.ArrayList]$Options OptionBuilder () { $this.Options = @() } [System.Collections.ArrayList] Build() { $this.AddParameter($this.Command) $this.AddParameter("-SolutionDirectory", $this.SolutionDirectory) $this.AddParameter("-OutputDirectory", $this.OutputDirectory) $this.AddParameter("-ConfigFile", $this.ConfigFile) if ($this.NoCache) { $this.AddParameter("-NoCache") } $this.AddParameter("-NonInteractive") return $this.Options } Hidden [void] AddParameter([string]$ParameterName) { $this.Options.Add($ParameterName) } Hidden [void] AddParameter([string]$ParameterName, [string]$ParameterValue) { if (-not [string]::IsNullOrWhiteSpace($ParameterValue)) { $this.Options.Add($ParameterName) $this.Options.Add($ParameterValue) } } } Class InstallOptionBuilder : OptionBuilder { [string]$PackageId [string]$PackageVersion [string]$PackageConfigFile [System.Collections.ArrayList] Build() { ([OptionBuilder]$this).Build() $this.InsertParameter(1, $this.PackageId) $this.AddParameter("-Version", $this.PackageVersion) $this.InsertParameter(1, $this.PackageConfigFile) return $this.Options } Hidden [void] InsertParameter([int]$Index, [string]$ParameterValue) { if (-not [string]::IsNullOrWhiteSpace($ParameterValue)) { $this.Options.Insert($Index, $ParameterValue) } } } <# .SYNOPSIS Publishes the contents of a runtime dependency package to a website, using NuGet. .DESCRIPTION Publishes the contents of a runtime dependency package to a website, using NuGet. Packages are expected to be NuGet-packages and contain any of the following folders: - <package>/Webroot - <package>/Data All of the above are optional. The following steps are performed during package publishing: 1. Check if the required package is cached locally. 1.1 If the package isn't found locally, it's installed from a registered package source, or from the $PackageSource parameter. 2. Copy the contents of the "<package>\Webroot"-folder to the "<WebrootOutputPath>". 3. Copy the contents of the "<package>\Data"-folder to the "<DataOutputPath>". .PARAMETER PackageName The name of the package to publish. .PARAMETER PackageVersion The exact version of the package to publish. .PARAMETER PackageOutputPath The location of the installed NuGet packages (e.g. "<solution root>/.pentia/runtime-dependencies/"). .PARAMETER WebrootOutputPath The path where the contents of "<package>\Webroot" will be copied to. .PARAMETER DataOutputPath The path where the contents of "<package>\Data" will be copied to. #> function Publish-NuGetPackage { [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [string]$PackageName, [Parameter(Mandatory = $true)] [string]$PackageVersion, [Parameter(Mandatory = $true)] [string]$PackageOutputPath, [Parameter(Mandatory = $true)] [string]$WebrootOutputPath, [Parameter(Mandatory = $true)] [string]$DataOutputPath ) $packagePath = [System.IO.Path]::Combine($PackageOutputPath, "$PackageName.$PackageVersion") $packageWebrootPath = [System.IO.Path]::Combine($PackagePath, "webroot") Copy-PackageFolder -SourceFriendlyName "webroot" -Source $packageWebrootPath -Target $WebrootOutputPath $packageDataPath = [System.IO.Path]::Combine($PackagePath, "data") Copy-PackageFolder -SourceFriendlyName "data" -Source $packageDataPath -Target $DataOutputPath } function Copy-PackageFolder { [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [string]$SourceFriendlyName, [Parameter(Mandatory = $true)] [string]$Source, [Parameter(Mandatory = $true)] [string]$Target ) Write-Verbose "Checking if package has a $SourceFriendlyName folder '$Source'." if (Test-Path -Path $Source -PathType Container) { Write-Verbose "Copying $SourceFriendlyName files from '$Source' to '$Target'." robocopy "$Source" "$Target" *.* /E /MT 64 /NFL /NP /NDL /NJH | Write-Verbose } else { Write-Verbose "No $SourceFriendlyName folder found." } } Export-ModuleMember -Function Install-NuGetExe, Restore-NuGetPackage, Install-NuGetPackage, Publish-NuGetPackage |