Skip to content

Commit 5f4dceb

Browse files
committed
Refactor: Match compiler-emitted stdout against error regex to detect errors in: compilation via compiler binary and compilation via compiler wrapper
1 parent b77e9cf commit 5f4dceb

1 file changed

Lines changed: 26 additions & 37 deletions

File tree

src/Compile-SourceScript/Public/Compile-SourceScript.ps1

Lines changed: 26 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,9 @@ function Compile-SourceScript {
6161

6262
# Initialize variables
6363
$MOD = @{
64+
# The sourcemod compiler returns exits code correctly.
65+
# The sourcemod compiler wrapper returns the exit code of the lastmost executed shell statement. This is particularly bad when the compiler exits with '0' from a successful finalmost shell statement, even when one or more prior shell statements exited with non-zero exit codes.
66+
# Hence, knowing that exit codes are not a reliable way to determine whether one or more compilation statements failed, we are going to use a regex on the stdout as a more reliable way to detect compilation errors, regardless of whether compilation was performed via the compiler binary or via the compiler wrapper.
6467
sourcemod = @{
6568
script_ext = '.sp'
6669
plugin_ext = '.smx'
@@ -70,13 +73,18 @@ function Compile-SourceScript {
7073
windows = @{
7174
wrapper = 'compile.exe'
7275
bin = 'spcomp.exe'
76+
error_regex = '^.*\.sp\(\d+\)\s*:\s*error (\d+)'
7377
}
7478
others = @{
7579
wrapper = 'compile.sh'
7680
bin = 'spcomp'
81+
error_regex = '^.*\.sp\(\d+\)\s*:\s*error (\d+)'
7782
}
7883
}
7984
}
85+
# The amxmodx compiler binary always exits with exit code 0.
86+
# The amxmodx compiler wrapper always exits with exit code 0.
87+
# Hence, knowing that exit codes are not a reliable way to determine whether one or more compilation statements failed, we are going to use a regex on the stdout as a more reliable way to detect compilation errors, regardless of whether compilation was performed via the compiler binary or via the compiler wrapper.
8088
amxmodx = @{
8189
script_ext = '.sma'
8290
plugin_ext = '.amxx'
@@ -86,21 +94,18 @@ function Compile-SourceScript {
8694
windows = @{
8795
wrapper = 'compile.exe'
8896
bin = 'amxxpc.exe'
97+
error_regex = '^.*\.sma\(\d+\)\s*:\s*error (\d+)'
8998
}
9099
others = @{
91100
wrapper = 'compile.sh'
92101
bin = 'amxxpc'
102+
error_regex = '^.*\.sma\(\d+\)\s*:\s*error (\d+)'
93103
}
94104
}
95105
}
96106
}
97-
$COMPILER_NAME = if ($env:OS -eq 'Windows_NT') {
98-
if ($PSBoundParameters['SkipWrapper']) { $MOD[$MOD_NAME]['compiler']['windows']['bin'] }
99-
else { $MOD[$MOD_NAME]['compiler']['windows']['wrapper'] }
100-
}else {
101-
if ($PSBoundParameters['SkipWrapper']) { $MOD[$MOD_NAME]['compiler']['others']['bin'] }
102-
else { $MOD[$MOD_NAME]['compiler']['others']['wrapper'] }
103-
}
107+
$OS = if ($env:OS -eq 'Windows_NT') { 'windows' } else { 'others' }
108+
$COMPILER_NAME = if ($PSBoundParameters['SkipWrapper']) { $MOD[$MOD_NAME]['compiler'][$OS]['bin'] } else { $MOD[$MOD_NAME]['compiler'][$OS]['wrapper'] }
104109
$SCRIPTING_DIR = $sourceFile.DirectoryName
105110
$COMPILED_DIR = Join-Path $SCRIPTING_DIR $MOD[$MOD_NAME]['compiled_dir_name']
106111
$COMPILER_PATH = Join-Path $SCRIPTING_DIR $COMPILER_NAME
@@ -156,42 +161,26 @@ function Compile-SourceScript {
156161
New-Item $tempDir -ItemType Directory -Force > $null
157162
New-Item -Path $COMPILED_DIR -ItemType Directory -Force | Out-Null
158163

159-
$returnExitCode = $false
160-
if ($MOD_NAME -eq 'sourcemod') {
161-
$pluginErrorRegexPattern = '^.*\.sp\(\d+\)\s*:\s*error (\d+)'
162-
if (!$PSBoundParameters['SkipWrapper'] -or $env:OS -ne 'Windows_NT') {
163-
$returnExitCode = $true
164-
}
165-
}elseif ($MOD_NAME -eq 'amxmodx') {
166-
$pluginErrorRegexPattern = '^.*\.sma\(\d+\)\s*:\s*error (\d+)'
167-
$returnExitCode = $true
168-
}
169-
170164
# Begin compilation
171165
"Compiling..." | Write-Host -ForegroundColor Cyan
172166
if ($PSBoundParameters['SkipWrapper']) { "Compiling $($sourceFile.Name)..." | Write-Host -ForegroundColor Yellow }
173167

174-
if ($returnExitCode) {
175-
# The amxmodx compiler always exits with exit code 0, so we have to use a regex on the stdout
176-
$global:LASTEXITCODE = 0
177-
178-
$p = Start-Process @processArgs
179-
$stdout = Get-Content $stdoutFile
180-
$stdout | Write-Host
181-
$stderr = Get-Content $stderrFile
182-
foreach ($line in $stdout) {
183-
if ($line -match $pluginErrorRegexPattern) {
184-
$global:LASTEXITCODE = 1
185-
break
186-
}
168+
# Compile
169+
$global:LASTEXITCODE = 0
170+
$p = Start-Process @processArgs
171+
$stdout = Get-Content $stdoutFile
172+
$stdout | Write-Host
173+
$stderr = Get-Content $stderrFile
174+
foreach ($line in $stdout) {
175+
if ($line -match $MOD[$MOD_NAME]['compiler'][$OS]['error_regex']) {
176+
$global:LASTEXITCODE = 1
177+
break
187178
}
188-
189-
# Cleanup
190-
Remove-Item $tempDir -Recurse -Force
191-
}else {
192-
$p = Start-Process @processArgs
193-
$global:LASTEXITCODE = $p.ExitCode
194179
}
180+
181+
# Cleanup
182+
Remove-Item $tempDir -Recurse -Force
183+
195184
if ($PSBoundParameters['SkipWrapper']) { "End of compilation." | Write-Host -ForegroundColor Yellow }
196185

197186
# Get all items in compiled directory after compilation by hash

0 commit comments

Comments
 (0)