Skip to content

Commit fcab992

Browse files
committed
task: harden build scripts
1 parent be43dcb commit fcab992

6 files changed

Lines changed: 391 additions & 4 deletions
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
<#
2+
.SYNOPSIS
3+
Exports the FixedMathSharp Unity package variants in batch mode.
4+
5+
.DESCRIPTION
6+
Launches Unity without opening the editor UI and executes
7+
FixedMathSharpUnityPackageExporter.ExportUnityPackagesBatchMode. The exporter
8+
runs package sync before writing .unitypackage archives.
9+
10+
.PARAMETER UnityPath
11+
Path to the Unity executable. When omitted, UNITY_EDITOR is used first, then
12+
Unity/Unity.exe on PATH, then the newest Unity Hub editor on Windows.
13+
14+
.PARAMETER ProjectPath
15+
Path to the Unity project root. Relative paths are resolved from the package
16+
repository root.
17+
18+
.PARAMETER OutputPath
19+
Output directory passed to the Unity exporter. Relative paths are resolved by the
20+
exporter from the Unity project root. Defaults to UnityPackageExports~.
21+
22+
.PARAMETER LogFile
23+
Unity log destination. Defaults to '-' so Unity writes to stdout.
24+
25+
.PARAMETER WhatIf
26+
Prints the Unity command without launching Unity.
27+
#>
28+
[CmdletBinding()]
29+
param(
30+
[string]$UnityPath,
31+
[string]$ProjectPath,
32+
[string]$OutputPath = "UnityPackageExports~",
33+
[string]$LogFile = "-",
34+
[switch]$WhatIf
35+
)
36+
37+
Set-StrictMode -Version Latest
38+
$ErrorActionPreference = "Stop"
39+
40+
. (Join-Path $PSScriptRoot "fixedmathsharp-unity-batch.ps1")
41+
42+
$additionalArguments = @(
43+
"-FixedMathSharpUnityPackageOutputPath",
44+
$OutputPath
45+
)
46+
47+
Invoke-FixedMathSharpUnityBatchMethod `
48+
-ExecuteMethod "FixedMathSharp.Build.Editor.FixedMathSharpUnityPackageExporter.ExportUnityPackagesBatchMode" `
49+
-UnityPath $UnityPath `
50+
-ProjectPath $ProjectPath `
51+
-LogFile $LogFile `
52+
-AdditionalArguments $additionalArguments `
53+
-PathArgumentNames @("-FixedMathSharpUnityPackageOutputPath") `
54+
-WhatIf:$WhatIf
Lines changed: 267 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,267 @@
1+
[CmdletBinding()]
2+
param()
3+
4+
Set-StrictMode -Version Latest
5+
$ErrorActionPreference = "Stop"
6+
7+
function Get-FixedMathSharpPackagesRoot {
8+
$assetsRoot = Split-Path -Parent $PSScriptRoot
9+
return [System.IO.Path]::GetFullPath((Split-Path -Parent $assetsRoot))
10+
}
11+
12+
function Resolve-FixedMathSharpPath {
13+
param(
14+
[Parameter(Mandatory = $true)]
15+
[string]$Path,
16+
17+
[Parameter(Mandatory = $true)]
18+
[string]$BasePath
19+
)
20+
21+
if ([System.IO.Path]::IsPathRooted($Path)) {
22+
return [System.IO.Path]::GetFullPath($Path)
23+
}
24+
25+
return [System.IO.Path]::GetFullPath((Join-Path $BasePath $Path))
26+
}
27+
28+
function Resolve-FixedMathSharpUnityProjectPath {
29+
param([string]$ProjectPath)
30+
31+
$packagesRoot = Get-FixedMathSharpPackagesRoot
32+
33+
if (-not [string]::IsNullOrWhiteSpace($ProjectPath)) {
34+
$resolvedProjectPath = Resolve-FixedMathSharpPath -Path $ProjectPath -BasePath $packagesRoot
35+
}
36+
else {
37+
$resolvedProjectPath = [System.IO.Path]::GetFullPath((Join-Path $packagesRoot "../.."))
38+
}
39+
40+
$assetsPath = Join-Path $resolvedProjectPath "Assets"
41+
$projectSettingsPath = Join-Path $resolvedProjectPath "ProjectSettings"
42+
43+
if (-not (Test-Path -LiteralPath $assetsPath -PathType Container)) {
44+
throw "Unity project Assets folder was not found: $assetsPath"
45+
}
46+
47+
if (-not (Test-Path -LiteralPath $projectSettingsPath -PathType Container)) {
48+
throw "Unity project ProjectSettings folder was not found: $projectSettingsPath"
49+
}
50+
51+
return $resolvedProjectPath
52+
}
53+
54+
function Resolve-FixedMathSharpUnityEditorPath {
55+
param([string]$UnityPath)
56+
57+
if (-not [string]::IsNullOrWhiteSpace($UnityPath)) {
58+
return $UnityPath
59+
}
60+
61+
$environmentPath = [Environment]::GetEnvironmentVariable("UNITY_EDITOR")
62+
if (-not [string]::IsNullOrWhiteSpace($environmentPath)) {
63+
return $environmentPath
64+
}
65+
66+
$unityCommand = Get-Command "Unity" -ErrorAction SilentlyContinue
67+
if ($null -ne $unityCommand) {
68+
return $unityCommand.Source
69+
}
70+
71+
$unityExeCommand = Get-Command "Unity.exe" -ErrorAction SilentlyContinue
72+
if ($null -ne $unityExeCommand) {
73+
return $unityExeCommand.Source
74+
}
75+
76+
if ([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform([System.Runtime.InteropServices.OSPlatform]::Windows)) {
77+
$programFiles = [Environment]::GetEnvironmentVariable("ProgramFiles")
78+
if ([string]::IsNullOrWhiteSpace($programFiles)) {
79+
throw "Could not find Unity. Pass -UnityPath or set the UNITY_EDITOR environment variable."
80+
}
81+
82+
$hubRoot = Join-Path $programFiles "Unity/Hub/Editor"
83+
if (Test-Path -LiteralPath $hubRoot -PathType Container) {
84+
$editors = Get-ChildItem -LiteralPath $hubRoot -Directory |
85+
Sort-Object -Property @{ Expression = { Get-FixedMathSharpUnityVersionSortKey -VersionName $_.Name } } -Descending
86+
87+
foreach ($editor in $editors) {
88+
$candidate = Join-Path $editor.FullName "Editor/Unity.exe"
89+
if (Test-Path -LiteralPath $candidate -PathType Leaf) {
90+
return $candidate
91+
}
92+
}
93+
}
94+
}
95+
96+
throw "Could not find Unity. Pass -UnityPath or set the UNITY_EDITOR environment variable."
97+
}
98+
99+
function Get-FixedMathSharpUnityVersionSortKey {
100+
param([string]$VersionName)
101+
102+
if ($VersionName -match '^(?<major>\d+)\.(?<minor>\d+)\.(?<patch>\d+)(?<channel>[abfp])(?<build>\d+)') {
103+
$channelRank = switch ($Matches.channel) {
104+
"a" { 0 }
105+
"b" { 1 }
106+
"f" { 2 }
107+
"p" { 3 }
108+
default { 0 }
109+
}
110+
111+
return "{0:D6}.{1:D6}.{2:D6}.{3:D2}.{4:D6}" -f `
112+
[int]$Matches.major,
113+
[int]$Matches.minor,
114+
[int]$Matches.patch,
115+
$channelRank,
116+
[int]$Matches.build
117+
}
118+
119+
return "000000.000000.000000.00.000000.$VersionName"
120+
}
121+
122+
function Format-FixedMathSharpCommandArgument {
123+
param([string]$Argument)
124+
125+
if ($Argument -notmatch '\s|["]') {
126+
return $Argument
127+
}
128+
129+
return '"' + $Argument.Replace('"', '\"') + '"'
130+
}
131+
132+
function Test-FixedMathSharpWindowsUnityFromUnix {
133+
param([string]$UnityPath)
134+
135+
if ([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform([System.Runtime.InteropServices.OSPlatform]::Windows)) {
136+
return $false
137+
}
138+
139+
return $UnityPath.EndsWith(".exe", [System.StringComparison]::OrdinalIgnoreCase)
140+
}
141+
142+
function Convert-FixedMathSharpPathForUnity {
143+
param(
144+
[string]$Path,
145+
[string]$UnityPath
146+
)
147+
148+
if ([string]::IsNullOrWhiteSpace($Path) -or $Path -eq "-") {
149+
return $Path
150+
}
151+
152+
if (-not [System.IO.Path]::IsPathRooted($Path)) {
153+
return $Path
154+
}
155+
156+
if (-not (Test-FixedMathSharpWindowsUnityFromUnix -UnityPath $UnityPath)) {
157+
return $Path
158+
}
159+
160+
$wslPathCommand = Get-Command "wslpath" -ErrorAction SilentlyContinue
161+
if ($null -eq $wslPathCommand) {
162+
throw "Cannot convert '$Path' for Windows Unity because wslpath was not found."
163+
}
164+
165+
return (& $wslPathCommand.Source -w $Path).Trim()
166+
}
167+
168+
function Invoke-FixedMathSharpProcess {
169+
param(
170+
[Parameter(Mandatory = $true)]
171+
[string]$FilePath,
172+
173+
[string[]]$Arguments = @()
174+
)
175+
176+
$startInfo = [System.Diagnostics.ProcessStartInfo]::new()
177+
$startInfo.FileName = $FilePath
178+
$startInfo.UseShellExecute = $false
179+
180+
foreach ($argument in $Arguments) {
181+
[void]$startInfo.ArgumentList.Add($argument)
182+
}
183+
184+
$process = [System.Diagnostics.Process]::new()
185+
$process.StartInfo = $startInfo
186+
187+
try {
188+
if (-not $process.Start()) {
189+
throw "Failed to start process: $FilePath"
190+
}
191+
192+
$process.WaitForExit()
193+
return $process.ExitCode
194+
}
195+
finally {
196+
$process.Dispose()
197+
}
198+
}
199+
200+
function Invoke-FixedMathSharpUnityBatchMethod {
201+
param(
202+
[Parameter(Mandatory = $true)]
203+
[string]$ExecuteMethod,
204+
205+
[string]$UnityPath,
206+
207+
[string]$ProjectPath,
208+
209+
[string]$LogFile = "-",
210+
211+
[string[]]$AdditionalArguments = @(),
212+
213+
[string[]]$PathArgumentNames = @(),
214+
215+
[switch]$WhatIf
216+
)
217+
218+
$resolvedUnityPath = Resolve-FixedMathSharpUnityEditorPath -UnityPath $UnityPath
219+
$resolvedProjectPath = Resolve-FixedMathSharpUnityProjectPath -ProjectPath $ProjectPath
220+
$unityProjectPath = Convert-FixedMathSharpPathForUnity -Path $resolvedProjectPath -UnityPath $resolvedUnityPath
221+
$unityLogFile = Convert-FixedMathSharpPathForUnity -Path $LogFile -UnityPath $resolvedUnityPath
222+
$unityAdditionalArguments = @($AdditionalArguments)
223+
224+
for ($i = 0; $i -lt $unityAdditionalArguments.Count - 1; $i++) {
225+
if ($PathArgumentNames -contains $unityAdditionalArguments[$i]) {
226+
$unityAdditionalArguments[$i + 1] = Convert-FixedMathSharpPathForUnity `
227+
-Path $unityAdditionalArguments[$i + 1] `
228+
-UnityPath $resolvedUnityPath
229+
}
230+
}
231+
232+
$arguments = @(
233+
"-batchmode",
234+
"-quit",
235+
"-projectPath",
236+
$unityProjectPath,
237+
"-executeMethod",
238+
$ExecuteMethod,
239+
"-logFile",
240+
$unityLogFile
241+
) + $unityAdditionalArguments
242+
243+
Write-Output "Unity: $resolvedUnityPath"
244+
Write-Output "Project: $resolvedProjectPath"
245+
Write-Output "ExecuteMethod: $ExecuteMethod"
246+
247+
if ($unityProjectPath -ne $resolvedProjectPath) {
248+
Write-Output "Unity project argument: $unityProjectPath"
249+
}
250+
251+
if ($unityAdditionalArguments.Count -gt 0) {
252+
Write-Output "Additional arguments: $($unityAdditionalArguments -join ' ')"
253+
}
254+
255+
if ($WhatIf) {
256+
Write-Output "WhatIf: skipping Unity launch."
257+
$displayArguments = @($arguments | ForEach-Object { Format-FixedMathSharpCommandArgument -Argument $_ })
258+
Write-Output "Command: $(Format-FixedMathSharpCommandArgument -Argument $resolvedUnityPath) $($displayArguments -join ' ')"
259+
return
260+
}
261+
262+
$exitCode = Invoke-FixedMathSharpProcess -FilePath $resolvedUnityPath -Arguments $arguments
263+
264+
if ($exitCode -ne 0) {
265+
throw "Unity batch method '$ExecuteMethod' failed with exit code $exitCode."
266+
}
267+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
<#
2+
.SYNOPSIS
3+
Runs the FixedMathSharp package sync Unity editor method in batch mode.
4+
5+
.DESCRIPTION
6+
Launches Unity without opening the editor UI and executes
7+
FixedMathSharpPackageSync.SyncPackagesBatchMode. By default the script finds the
8+
Unity project two directories above this package repository and uses UNITY_EDITOR
9+
or Unity on PATH. Pass -UnityPath or -ProjectPath to override those defaults.
10+
11+
.PARAMETER UnityPath
12+
Path to the Unity executable. When omitted, UNITY_EDITOR is used first, then
13+
Unity/Unity.exe on PATH, then the newest Unity Hub editor on Windows.
14+
15+
.PARAMETER ProjectPath
16+
Path to the Unity project root. Relative paths are resolved from the package
17+
repository root.
18+
19+
.PARAMETER LogFile
20+
Unity log destination. Defaults to '-' so Unity writes to stdout.
21+
22+
.PARAMETER WhatIf
23+
Prints the Unity command without launching Unity.
24+
#>
25+
[CmdletBinding()]
26+
param(
27+
[string]$UnityPath,
28+
[string]$ProjectPath,
29+
[string]$LogFile = "-",
30+
[switch]$WhatIf
31+
)
32+
33+
Set-StrictMode -Version Latest
34+
$ErrorActionPreference = "Stop"
35+
36+
. (Join-Path $PSScriptRoot "fixedmathsharp-unity-batch.ps1")
37+
38+
Invoke-FixedMathSharpUnityBatchMethod `
39+
-ExecuteMethod "FixedMathSharp.Build.Editor.FixedMathSharpPackageSync.SyncPackagesBatchMode" `
40+
-UnityPath $UnityPath `
41+
-ProjectPath $ProjectPath `
42+
-LogFile $LogFile `
43+
-WhatIf:$WhatIf

.assets/scripts/update-unity-package-versions.ps1

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,25 @@
1+
<#
2+
.SYNOPSIS
3+
Synchronizes Unity package manifest and dependency versions from config.
4+
5+
.DESCRIPTION
6+
Reads unity-package-versions.json and compares the configured package version
7+
and dependency versions against the package manifests and installer scripts.
8+
By default the script runs in dry-run mode and reports pending changes. Pass
9+
-Apply to update files or -ValidateOnly to fail when configured versions are out
10+
of sync.
11+
12+
.PARAMETER ConfigPath
13+
Path to the JSON version configuration file. Defaults to
14+
.assets/unity-package-versions.json.
15+
16+
.PARAMETER Apply
17+
Writes any required package manifest and installer dependency version changes.
18+
19+
.PARAMETER ValidateOnly
20+
Reports version drift as errors and exits with a failure instead of writing
21+
changes.
22+
#>
123
[CmdletBinding()]
224
param(
325
[string]$ConfigPath = (Join-Path (Split-Path -Parent $PSScriptRoot) "unity-package-versions.json"),

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
UnityPackageExports~/

0 commit comments

Comments
 (0)