build/Build-RenderKitPackage.ps1
|
[CmdletBinding()] param( [string]$RepositoryRoot = (Split-Path -Parent $PSScriptRoot), [string]$OutputRoot = (Join-Path (Split-Path -Parent $PSScriptRoot) 'artifacts'), [switch]$SkipPackage ) Set-StrictMode -Version Latest $ErrorActionPreference = 'Stop' function ConvertTo-RenderKitStringLiteral { [CmdletBinding()] param( [Parameter(Mandatory)] [AllowEmptyString()] [string]$Value ) return "'{0}'" -f $Value.Replace("'", "''") } function ConvertTo-RenderKitArrayLiteral { [CmdletBinding()] [OutputType([System.String])] param( [AllowEmptyCollection()] [string[]]$Value ) if (-not $Value -or $Value.Count -eq 0) { return '@()' } $quotedValues = foreach ($item in $Value) { " {0}" -f (ConvertTo-RenderKitStringLiteral -Value $item) } return "@(`r`n{0}`r`n)" -f ($quotedValues -join "`r`n") } function ConvertTo-RenderKitXmlLiteral { [CmdletBinding()] [OutputType([System.String])] param( [AllowEmptyString()] [string]$Value ) return [System.Security.SecurityElement]::Escape($Value) } function Get-RenderKitSourceFiles { [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseSingularNouns', '', Justification = 'Function never gets only one file, so Get-RenderKitSourceFiles is actually correct')] [CmdletBinding()] [OutputType([System.Object[]])] param( [Parameter(Mandatory)] [string]$Path ) if (-not (Test-Path -LiteralPath $Path)) { return @() } return @(Get-ChildItem -LiteralPath $Path -Recurse -File -Filter '*.ps1' | Sort-Object -Property FullName) } function New-RenderKitDirectory { [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions', '', Justification = '"This is not a public Function, that should be tested with -Whatif')] [CmdletBinding()] param( [Parameter(Mandatory)] [string]$Path ) if (Test-Path -LiteralPath $Path) { Remove-Item -LiteralPath $Path -Recurse -Force } New-Item -ItemType Directory -Path $Path -Force | Out-Null } function New-RenderKitBundledModule { [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions', '', Justification = '"This is not a public Function, that should be tested with -Whatif')] [CmdletBinding()] param( [Parameter(Mandatory)] [string]$RepositoryRoot, [Parameter(Mandatory)] [string]$DestinationPath, [Parameter(Mandatory)] [hashtable]$Manifest ) $builder = New-Object System.Text.StringBuilder $publicFunctionsLiteral = ConvertTo-RenderKitArrayLiteral -Value @($Manifest.FunctionsToExport) $publicAliasesLiteral = ConvertTo-RenderKitArrayLiteral -Value @($Manifest.AliasesToExport) $moduleVersionLiteral = ConvertTo-RenderKitStringLiteral -Value ([string]$Manifest.ModuleVersion) [void]$builder.AppendLine('$script:RenderKitModuleRoot = $PSScriptRoot') [void]$builder.AppendLine('$script:RenderKitModuleVersion = {0}' -f $moduleVersionLiteral) [void]$builder.AppendLine('$script:RenderKitPublicFunctions = {0}' -f $publicFunctionsLiteral) [void]$builder.AppendLine('$script:RenderKitPublicAliases = {0}' -f $publicAliasesLiteral) [void]$builder.AppendLine('') [void]$builder.AppendLine('$moduleInfo = $ExecutionContext.SessionState.Module') [void]$builder.AppendLine('if ($moduleInfo -and $moduleInfo.Version) {') [void]$builder.AppendLine(' $script:RenderKitModuleVersion = $moduleInfo.Version.ToString()') [void]$builder.AppendLine('}') [void]$builder.AppendLine('') [void]$builder.AppendLine('function Register-RenderKitFunction {') [void]$builder.AppendLine(' [CmdletBinding()]') [void]$builder.AppendLine(' param(') [void]$builder.AppendLine(' [Parameter(Mandatory)]') [void]$builder.AppendLine(' [string]$Name') [void]$builder.AppendLine(' )') [void]$builder.AppendLine('') [void]$builder.AppendLine(' if ($script:RenderKitPublicFunctions -notcontains $Name) {') [void]$builder.AppendLine(' return') [void]$builder.AppendLine(' }') [void]$builder.AppendLine('}') [void]$builder.AppendLine('') foreach ($relativeSourcePath in 'Classes', 'Private', 'Public') { $sourcePath = Join-Path -Path $RepositoryRoot -ChildPath ('src\{0}' -f $relativeSourcePath) foreach ($sourceFile in Get-RenderKitSourceFiles -Path $sourcePath) { $relativeFile = $sourceFile.FullName.Substring($RepositoryRoot.Length).TrimStart('\') [void]$builder.AppendLine('# region {0}' -f $relativeFile) [void]$builder.AppendLine((Get-Content -LiteralPath $sourceFile.FullName -Raw).TrimEnd()) [void]$builder.AppendLine('# endregion {0}' -f $relativeFile) [void]$builder.AppendLine('') } } [void]$builder.AppendLine("Set-Alias -Name 'projectroot' -Value 'Set-ProjectRoot' -Scope Script") [void]$builder.AppendLine("Set-Alias -Name 'setroot' -Value 'Set-ProjectRoot' -Scope Script") [void]$builder.AppendLine('') [void]$builder.AppendLine('Export-ModuleMember -Function $script:RenderKitPublicFunctions -Alias $script:RenderKitPublicAliases') Set-Content -LiteralPath $DestinationPath -Value $builder.ToString() -Encoding utf8 } function New-RenderKitNuspec { [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions', '', Justification = '"This is not a public Function, that should be tested with -Whatif')] [CmdletBinding()] param( [Parameter(Mandatory)] [hashtable]$Manifest, [Parameter(Mandatory)] [string]$DestinationPath ) $psData = $Manifest.PrivateData.PSData $tags = @('PSModule') + @($psData.Tags) $tagString = ($tags | Where-Object { -not [string]::IsNullOrWhiteSpace($_) } | Sort-Object -Unique) -join ' ' $nuspec = @" <?xml version="1.0" encoding="utf-8"?> <package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd"> <metadata> <id>$(ConvertTo-RenderKitXmlLiteral -Value 'RenderKit')</id> <version>$(ConvertTo-RenderKitXmlLiteral -Value ([string]$Manifest.ModuleVersion))</version> <authors>$(ConvertTo-RenderKitXmlLiteral -Value ([string]$Manifest.Author))</authors> <owners>$(ConvertTo-RenderKitXmlLiteral -Value ([string]$Manifest.CompanyName))</owners> <requireLicenseAcceptance>false</requireLicenseAcceptance> <license type="file">LICENSE</license> <projectUrl>$(ConvertTo-RenderKitXmlLiteral -Value ([string]$psData.ProjectUri))</projectUrl> <icon>images\RenderKit_Logo.png</icon> <readme>README.md</readme> <description>$(ConvertTo-RenderKitXmlLiteral -Value ([string]$Manifest.Description))</description> <releaseNotes>$(ConvertTo-RenderKitXmlLiteral -Value ([string]$psData.ReleaseNotes))</releaseNotes> <copyright>$(ConvertTo-RenderKitXmlLiteral -Value ([string]$Manifest.Copyright))</copyright> <tags>$(ConvertTo-RenderKitXmlLiteral -Value $tagString)</tags> <repository type="git" url="https://github.com/djtroi/RenderKit" branch="main" /> </metadata> <files> <file src="RenderKit.psd1" /> <file src="RenderKit.psm1" /> <file src="README.md" /> <file src="CHANGELOG.md" /> <file src="LICENSE" /> <file src="images\RenderKit_Logo.png" target="images" /> <file src="src\Resources\**\*.*" target="src\Resources" /> </files> </package> "@ Set-Content -LiteralPath $DestinationPath -Value $nuspec -Encoding utf8 } $RepositoryRoot = (Resolve-Path -LiteralPath $RepositoryRoot).ProviderPath $OutputRoot = [System.IO.Path]::GetFullPath($OutputRoot) $manifestPath = Join-Path -Path $RepositoryRoot -ChildPath 'RenderKit.psd1' $manifest = Import-PowerShellDataFile -LiteralPath $manifestPath $moduleName = 'RenderKit' $moduleVersion = [string]$manifest.ModuleVersion $stageRoot = Join-Path -Path $OutputRoot -ChildPath ('staging\{0}\{1}' -f $moduleName, $moduleVersion) $packageRoot = Join-Path -Path $OutputRoot -ChildPath 'packages' $tempPackRoot = Join-Path -Path $OutputRoot -ChildPath ('temp\{0}\{1}' -f $moduleName, $moduleVersion) $nupkgPath = Join-Path -Path $packageRoot -ChildPath ('{0}.{1}.nupkg' -f $moduleName, $moduleVersion) New-RenderKitDirectory -Path $stageRoot New-Item -ItemType Directory -Path $packageRoot -Force | Out-Null New-RenderKitDirectory -Path $tempPackRoot New-Item -ItemType Directory -Path (Join-Path -Path $stageRoot -ChildPath 'images') -Force | Out-Null New-Item -ItemType Directory -Path (Join-Path -Path $stageRoot -ChildPath 'src') -Force | Out-Null Copy-Item -LiteralPath (Join-Path -Path $RepositoryRoot -ChildPath 'RenderKit.psd1') -Destination (Join-Path -Path $stageRoot -ChildPath 'RenderKit.psd1') Copy-Item -LiteralPath (Join-Path -Path $RepositoryRoot -ChildPath 'README.md') -Destination (Join-Path -Path $stageRoot -ChildPath 'README.md') Copy-Item -LiteralPath (Join-Path -Path $RepositoryRoot -ChildPath 'CHANGELOG.md') -Destination (Join-Path -Path $stageRoot -ChildPath 'CHANGELOG.md') Copy-Item -LiteralPath (Join-Path -Path $RepositoryRoot -ChildPath 'LICENSE') -Destination (Join-Path -Path $stageRoot -ChildPath 'LICENSE') Copy-Item -LiteralPath (Join-Path -Path $RepositoryRoot -ChildPath 'src\assets\RenderKit_Logo.png') -Destination (Join-Path -Path $stageRoot -ChildPath 'images\RenderKit_Logo.png') Copy-Item -LiteralPath (Join-Path -Path $RepositoryRoot -ChildPath 'src\Resources') -Destination (Join-Path -Path $stageRoot -ChildPath 'src\Resources') -Recurse New-RenderKitBundledModule -RepositoryRoot $RepositoryRoot -DestinationPath (Join-Path -Path $stageRoot -ChildPath 'RenderKit.psm1') -Manifest $manifest New-RenderKitNuspec -Manifest $manifest -DestinationPath (Join-Path -Path $stageRoot -ChildPath 'RenderKit.nuspec') $csprojPath = Join-Path -Path $tempPackRoot -ChildPath 'RenderKit.Package.csproj' $csprojContent = @' <Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <TargetFramework>net8.0</TargetFramework> <IncludeBuildOutput>false</IncludeBuildOutput> </PropertyGroup> </Project> '@ Set-Content -LiteralPath $csprojPath -Value $csprojContent -Encoding utf8 Remove-Item -LiteralPath $nupkgPath -Force -ErrorAction SilentlyContinue if (-not $SkipPackage) { $env:DOTNET_CLI_UI_LANGUAGE = 'en-US' $env:DOTNET_SKIP_FIRST_TIME_EXPERIENCE = '1' $env:DOTNET_NOLOGO = '1' $env:DOTNET_ADD_GLOBAL_TOOLS_TO_PATH = '0' $env:DOTNET_CLI_HOME = $OutputRoot Push-Location -LiteralPath $stageRoot try { $packOutput = & 'C:\Program Files\dotnet\dotnet.exe' pack $csprojPath ("/p:NuspecFile={0}" -f (Join-Path -Path $stageRoot -ChildPath 'RenderKit.nuspec')) '--output' $packageRoot '--configuration' 'Release' 2>&1 foreach ($line in $packOutput) { Write-Output $line } if ($LASTEXITCODE -ne 0) { throw "dotnet pack failed with exit code $LASTEXITCODE." } } finally { Pop-Location } } Remove-Module RenderKit -Force -ErrorAction SilentlyContinue Import-Module (Join-Path -Path $stageRoot -ChildPath 'RenderKit.psd1') -Force -ErrorAction Stop | Out-Null [PSCustomObject]@{ ModuleName = $moduleName Version = $moduleVersion StagePath = $stageRoot PackagePath = $nupkgPath } |