<# .SYNOPSIS Creates a new engine project from _Template/. .DESCRIPTION Copies _Template/ to /OpenNest.Engine./ and replaces the __NAME__ placeholder in file names and contents. The new engine builds against OpenNest via Directory.Build.props, which must sit in or a parent folder. With -IncludeBuildFiles, Directory.Build.props/.targets are copied into too, so the engine can live outside this repo, e.g. in an Engines/ folder inside an OpenNest checkout (the props detect that layout on their own). .EXAMPLE ./New-Engine.ps1 -Name Nova ./New-Engine.ps1 -Name Nova -Destination C:/bench/run1/OpenNest/Engines -IncludeBuildFiles #> param( [Parameter(Mandatory)] [ValidatePattern('^[A-Z][A-Za-z0-9]*$')] [string]$Name, [string]$Destination = $PSScriptRoot, [switch]$IncludeBuildFiles ) $ErrorActionPreference = 'Stop' $template = Join-Path $PSScriptRoot '_Template' $target = Join-Path $Destination "OpenNest.Engine.$Name" if (Test-Path $target) { throw "'$target' already exists." } New-Item -ItemType Directory -Force $Destination | Out-Null Copy-Item $template $target -Recurse Get-ChildItem $target -Recurse -File | ForEach-Object { $text = [IO.File]::ReadAllText($_.FullName) [IO.File]::WriteAllText($_.FullName, $text.Replace('__NAME__', $Name)) } # Deepest paths first so renaming a folder never invalidates a pending child path. Get-ChildItem $target -Recurse | Where-Object Name -like '*__NAME__*' | Sort-Object { $_.FullName.Length } -Descending | ForEach-Object { Rename-Item $_.FullName $_.Name.Replace('__NAME__', $Name) } if ($IncludeBuildFiles) { foreach ($file in 'Directory.Build.props', 'Directory.Build.targets') { Copy-Item (Join-Path $PSScriptRoot $file) $Destination -Force } } Write-Host "Created $target"