Platform/Tools/PowerShell/JetCmdlet/Load-JetCmdlet.ps1 (73 lines of code) (raw):
# Loads the JetCmdlet module with our cmdlets
# TODO: bootstrap by compiling the module on-demand
<#ScriptPrologue#> Set-StrictMode -Version Latest; $ErrorActionPreference = [System.Management.Automation.ActionPreference]::Stop
$DllRelpath = "bin/Debug/JetCmdlet.dll"
# Rootdir of the cmdlet project — one with the current script
function GetCmdletRootDir() { Split-Path $MyInvocation.ScriptName -Parent }
function IsModuleLoaded()
{
Get-Module -Name JetCmdlet
}
function DoLoadModule($CmdletRootDir)
{
Write-Host "Loading JetCmdlet module"
Join-Path $CmdletRootDir $DllRelpath | Import-Module -Force
}
# Emulates a bit of the MSBuild inputs/outputs tracking magic to avoid spawning MSBuild.exe on every module load — instead, quickly checks if the output DLL is up-to-date with all the folder's sources.
function IsDllUpToDate($CmdletRootDir)
{
# Collect the most recent date of all the source files
$inputs = ($CmdletRootDir + "/*") | Get-ChildItem -Recurse -Include ("*.cs", "*.csproj") | sort LastWriteTimeUtc | select -Last 1
if(-not $inputs)
{ throw "The source files of the cmdlet could not be found." }
$lastwrite = $inputs.LastWriteTimeUtc
# Output exists?
[System.IO.FileInfo]$dllfile = Join-Path $CmdletRootDir $DllRelpath
if(-not (Test-Path $dllfile -PathType Leaf)) # does not exist, definitely build
{
Write-Host "The JetCmdlet module DLL is not found, a build is required."
return $false
}
# Compare time
$isDirty = $lastwrite -gt $dllfile.LastWriteTimeUtc
# Log
if($isDirty)
{
Write-Host "The JetCmdlet module DLL is out of date, a build is required."
return $false
}
$true
}
#Invokes a build to compile a new copy of the CMD
function CompileNewDll($CmdletRootDir)
{
$dllfile = Join-Path $CmdletRootDir $DllRelpath
# make sure the old item is not in the way
DeleteAsideSimple $dllfile
DeleteAsideSimple ([System.IO.Path]::ChangeExtension($dllfile, ".pdb"))
DeleteAsideSimple ([System.IO.Path]::ChangeExtension($dllfile, ".xml"))
###############
# Spawn MSBuild
$dirNetfx = $([System.Runtime.InteropServices.RuntimeEnvironment]::GetRuntimeDirectory())
$fileMsbuild = Join-Path $dirNetfx "msbuild.exe"
$csproj = ($CmdletRootDir | Get-ChildItem -Filter "*.csproj").FullName
$cmdargs = ("/t:build", "/v:m", "/nologo", $csproj)
& $fileMsbuild $cmdargs
if($LASTEXITCODE) { throw "MSBuild failed to build the tool (exit code $LASTEXITCODE)." }
}
function DeleteAsideSimple([Parameter(Mandatory=$true)]$file)
{
Remove-Item $file -ErrorAction Ignore -Force #simple remove
if(Test-Path $file) #still there? move away!
{
$aside = Join-Path (Split-Path $file -Parent) ([guid]::NewGuid().ToString("B").ToUpperInvariant() + ".tmp.user")
Move-Item -Path $file -Destination $aside -Force -ErrorAction Stop
}
}
$CmdletRootDir = GetCmdletRootDir
# Skip if module already loaded
if(IsModuleLoaded $CmdletRootDir) { return }
# Check if we have to bootstrap-build it
if(-not (IsDllUpToDate $CmdletRootDir)) { CompileNewDll $CmdletRootDir }
# Load
DoLoadModule ($CmdletRootDir)