Created
November 19, 2021 17:14
-
-
Save endowdly/97585502efe3bb2213e78f68a6d5e38b to your computer and use it in GitHub Desktop.
Basic Cmdlet Build Script (No External Tools Needed)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<#PSScriptInfo | |
.VERSION 1.0.0 | |
.GUID d6ffefc9-781f-4e1b-a46d-0238655151c7 | |
.AUTHOR endowdly | |
.COMPANYNAME endowdly | |
.COPYRIGHT 2019 | |
.TAGS | |
.LICENSEURI | |
.PROJECTURI | |
.ICONURI | |
.EXTERNALMODULEDEPENDENCIES | |
.REQUIREDSCRIPTS | |
.EXTERNALSCRIPTDEPENDENCIES | |
.RELEASENOTES | |
#> | |
<# | |
.DESCRIPTION | |
A simple build script that can compile PowerShell Cmdlets without external tooling or references. | |
Uses the native csharp compiler (csc.exe) located in the Framework directory. | |
Uses 64bit tooling if available and then the highest version of framework tooling available. | |
Does not use additional toolkits installed by Visual Studio or the user. | |
Uses the current session's PowerShell assembly. | |
#> | |
param () | |
# Setup | |
data Messages { | |
@{ | |
Warning = @{ | |
DotSourced = 'This script was dot sourced. This is verboten to prevent session pollution!' | |
CannotInit = 'You are missing core Windows components! Cannot initialize.' | |
} | |
Information = @{ | |
DotSourced = 'RECOMMENDATION: Invoke this script using this call operator (&).' | |
CannotClean = 'RECOMMENDATION: File is likely in use by another process. Close the process and try to build again.' | |
} | |
Initialize = 'Initializing...' | |
Initialized = 'Initialized' | |
Cleaning = 'Cleaning... ' | |
Cleaned = 'Cleaned' | |
Building = 'Building... ' | |
Built = 'Built' | |
Fail = 'Fail' | |
Nothing = 'Nothing to build!' | |
LinkingCompiler = 'Linking compiler...' | |
LinkedCompiler = 'Compiler linked' | |
Source = 'Source directory exists' | |
NewSource = 'Creating source directory...' | |
} | |
} | |
data Build { | |
@{ | |
FrameworkPaths = 'C:\Windows\Microsoft.NET\Framework*' | |
Framework64 = 'C:\Windows\Microsoft.NET\Framework64' | |
Framework = 'C:\Windows\Microsoft.NET\Framework64' | |
} | |
} | |
$ErrorActionPreference = 'Stop' | |
$WarningPreference = 'Continue' | |
$InformationPreference = 'Continue' | |
function Get-Indent ($s, $n) { $s.Insert(0, (' ' * 2 * $n)) } | |
function Write-ColorOutput { | |
param ( | |
$Object, | |
[System.ConsoleColor] $ForegroundColor | |
) | |
$isHostReady = | |
($null -ne $Host.UI) -and | |
($null -ne $Host.UI.RawUI) -and | |
($null -ne $Host.UI.RawUI.ForegroundColor) | |
if ($isHostReady -and ($null -ne $ForegroundColor)) { | |
$originalColor = $Host.UI.RawUI.ForegroundColor | |
$Host.UI.RawUI.ForegroundColor = $ForegroundColor | |
} | |
$Object | |
if ($null -ne $originalColor) { | |
$Host.UI.RawUI.ForegroundColor = $originalColor | |
} | |
} | |
# Do not allow sourcing | |
$IsDotSourced = $MyInvocation.InvocationName -eq '.' -or $MyInvocation.Line -eq '' | |
if ($IsDotSourced) { | |
Write-Warning $Messages.Warning.DotSourced | |
Write-Information $Messages.Information.DotSourced -Tags Recommendation | |
exit 1 | |
} | |
Push-Location $PSScriptRoot | |
Write-Output $Messages.Initialize | |
try { | |
Get-Command csc -CommandType Application | Out-Null | |
Write-Output (Indent $Messages.LinkedCompiler 1) | |
} | |
catch { | |
Write-Output (Indent $Messages.LinkingCompiler 1) | |
$IsFrameworkDir = Test-Path $Build.FrameworkPaths | |
$Is64bit = Test-Path $Build.Framework64 | |
if (!$IsFrameworkDir) { | |
Write-PrettyOutput (Indent $Messages.Fail 1) -ForegroundColor Red | |
Write-Host | |
Write-Warning (Indent $Messages.Warning.CannotInit 1) | |
exit 1 | |
} | |
$FrameworkDir = | |
if ($Is64bit) { | |
$Build.Framework64 | |
} | |
else { | |
$Build.Framework | |
} | |
Get-ChildItem $FrameworkDir -Directory | | |
Sort-Object Name | | |
Select-Object -Last 1 | | |
Get-ChildItem -Filter csc.exe | | |
Set-Variable csc | |
Set-Alias -Name csc -Value $csc.FullName | |
Write-Output (Indent $Messages.LinkedCompiler 1) | |
} | |
if (Test-Path src) { | |
Write-Output (Indent $Messages.Source 1) | |
} | |
else { | |
Write-Output (Indent $Messages.NewSource 1) | |
New-Item src -ItemType Directory | Out-Null | |
Write-Output (Indent $Messages.Source 1) | |
} | |
Write-ColorOutput (Indent $Messages.Initialized 1) -ForegroundColor Green | |
Write-Host | |
Write-Output $Messages.Cleaning | |
try { | |
Join-Path $PSScriptRoot out -OutVariable OutputDirectory | | |
Get-ChildItem -Recurse -File -OutVariable CleanedFiles | | |
ForEach-Object { | |
Write-Information (Indent $_.Name 1) | |
Remove-Item $_.FullName -Force | |
} | |
} | |
catch { | |
Write-ColorOutput (Indent $Messages.Fail 1) -ForegroundColor Red | |
Write-Host | |
Write-Information $Messages.Information.CannotClean | |
exit 1 | |
} | |
New-Item out -ItemType Directory -Force | Out-Null | |
Write-ColorOutput (Indent $Messages.Cleaned 1) -ForegroundColor Green | |
Write-Host | |
# Get every src file | |
Write-Information $Messages.Building | |
Get-ChildItem src -Filter *.cs -OutVariable SourceFiles | Foreach-Object { Write-Information (Indent $_.Name 1) } | |
if (!$SourceFiles) { | |
Write-ColorOutput (Indent $Messages.Nothing 1) -ForegroundColor Yellow | |
exit 0 | |
} | |
# Get Assembly Reference | |
$PSAssemblyPath = [psobject].Assembly.Location | |
$TargetName = Split-Path $PSScriptRoot -Leaf | |
$OutPath = Join-Path out "${TargetName}.dll" | |
# Compiler Options | |
$CscArguments = @( | |
"/reference:$PSAssemblyPath" | |
"/out:$OutPath" | |
'/target:library' | |
'/nologo' | |
) | |
$Result = & csc $CscArguments $SourceFiles.FullName 2>&1 | |
if (!$?) { | |
Write-ColorOutput (Indent $Messages.Fail 1) -ForegroundColor Red | |
Write-Host | |
$Result | Foreach-Object { Write-ColorOutput $_ -ForegroundColor Red } | |
exit 1 | |
} | |
else { | |
Write-ColorOutput (Indent $Messages.Built 1) -ForegroundColor Green | |
Write-Host | |
} | |
Pop-Location |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment