Skip to content

Commit 0112423

Browse files
committed
Respond to reviewer comments.
1 parent 4007bfc commit 0112423

3 files changed

Lines changed: 136 additions & 58 deletions

File tree

Build/Agent/Invoke-VsCodeDebugBuild.ps1

Lines changed: 89 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -15,41 +15,100 @@ $outputDir = Join-Path $repoRoot ("Output\{0}" -f $Configuration)
1515
$stampPath = Join-Path $outputDir 'BuildStamp.json'
1616
$runtimeExePath = Join-Path $outputDir 'FieldWorks.exe'
1717

18-
function Test-RelevantPathChanged {
18+
function Get-DebugRebuildCheckPathspecs {
1919
param(
20-
[Parameter(Mandatory = $true)][string]$Path,
21-
[Parameter(Mandatory = $true)][datetime]$SinceUtc
20+
[Parameter(Mandatory = $true)][ValidateSet('Package', 'Local')][string]$ResolvedLcmMode
2221
)
2322

24-
if (-not (Test-Path $Path)) {
25-
return $false
23+
$pathspecs = @(
24+
'build.ps1',
25+
'Directory.Build.props',
26+
'Directory.Build.targets',
27+
'Directory.Packages.props',
28+
'FieldWorks.proj',
29+
'Build',
30+
'Src',
31+
'Lib'
32+
)
33+
34+
if ($ResolvedLcmMode -eq 'Local') {
35+
$pathspecs += @('FieldWorks.LocalLcm.sln', 'Localizations/LCM')
36+
}
37+
else {
38+
$pathspecs += 'FieldWorks.sln'
2639
}
2740

28-
if ((Get-Item $Path).PSIsContainer) {
29-
$excludedSegments = @('\.git\', '\.vs\', '\Output\', '\Obj\', '\obj\', '\bin\', '\packages\', '\artifacts\')
30-
foreach ($item in Get-ChildItem -Path $Path -Recurse -Force -ErrorAction SilentlyContinue) {
31-
$fullPath = $item.FullName
32-
$skip = $false
33-
foreach ($segment in $excludedSegments) {
34-
if ($fullPath.Contains($segment)) {
35-
$skip = $true
36-
break
37-
}
38-
}
39-
40-
if ($skip) {
41-
continue
42-
}
43-
44-
if ($item.LastWriteTimeUtc -gt $SinceUtc) {
45-
return $true
46-
}
41+
return $pathspecs | ForEach-Object { $_ -replace '\\', '/' }
42+
}
43+
44+
function Invoke-Git {
45+
param(
46+
[Parameter(Mandatory = $true)][string[]]$Arguments
47+
)
48+
49+
$output = & git @Arguments
50+
if ($LASTEXITCODE -ne 0) {
51+
throw "Git command failed: git $($Arguments -join ' ')"
52+
}
53+
54+
return @($output | ForEach-Object { $_.TrimEnd() } | Where-Object { -not [string]::IsNullOrWhiteSpace($_) })
55+
}
56+
57+
function Get-GitStatusForDebugRebuildCheck {
58+
param(
59+
[Parameter(Mandatory = $true)][string[]]$Pathspecs
60+
)
61+
62+
return Invoke-Git -Arguments (@('status', '--porcelain=v1', '--untracked-files=all', '--') + $Pathspecs)
63+
}
64+
65+
function Test-GitStateRequiresDebugRebuild {
66+
param(
67+
[Parameter(Mandatory = $true)][psobject]$Stamp,
68+
[Parameter(Mandatory = $true)][string[]]$Pathspecs
69+
)
70+
71+
# We only skip the prelaunch build when we can prove the last successful debug build
72+
# still matches the source inputs for this debug session. The proof has three parts:
73+
# 1. the stamp recorded the same debug mode inputs we are asking for now,
74+
# 2. no relevant commits have landed since the stamped HEAD, and
75+
# 3. the current relevant worktree status still matches the stamped worktree status.
76+
# If any of those checks fail, we rebuild before launching so debugging does not start
77+
# against stale binaries or symbols.
78+
79+
if (-not ($Stamp.PSObject.Properties.Name -contains 'GitHead') -or [string]::IsNullOrWhiteSpace($Stamp.GitHead)) {
80+
Write-Host "Build stamp is missing Git head metadata. Rebuilding before launch..." -ForegroundColor Yellow
81+
return $true
82+
}
83+
84+
if (-not ($Stamp.PSObject.Properties.Name -contains 'RelevantDebugPathspecs') -or -not ($Stamp.PSObject.Properties.Name -contains 'RelevantDebugStatus')) {
85+
Write-Host "Build stamp is missing Git-based debug metadata. Rebuilding before launch..." -ForegroundColor Yellow
86+
return $true
87+
}
88+
89+
$stampPathspecs = @($Stamp.RelevantDebugPathspecs)
90+
if (($stampPathspecs.Count -ne $Pathspecs.Count) -or (@($stampPathspecs) -join "`n") -ne ($Pathspecs -join "`n")) {
91+
Write-Host "Build stamp inputs do not match the requested VS Code debug mode. Rebuilding..." -ForegroundColor Yellow
92+
return $true
93+
}
94+
95+
$currentHead = (Invoke-Git -Arguments @('rev-parse', 'HEAD'))[0]
96+
if ($currentHead -ne $Stamp.GitHead) {
97+
$committedChanges = Invoke-Git -Arguments (@('diff', '--name-only', "$($Stamp.GitHead)..$currentHead", '--') + $Pathspecs)
98+
if ($committedChanges.Count -gt 0) {
99+
Write-Host "Detected committed changes since the last successful $Configuration debug build. Rebuilding before launch..." -ForegroundColor Yellow
100+
return $true
47101
}
102+
}
48103

49-
return $false
104+
$currentStatus = Get-GitStatusForDebugRebuildCheck -Pathspecs $Pathspecs
105+
$stampStatus = @($Stamp.RelevantDebugStatus)
106+
if (($stampStatus.Count -ne $currentStatus.Count) -or (($stampStatus -join "`n") -ne ($currentStatus -join "`n"))) {
107+
Write-Host "Detected working tree changes since the last successful $Configuration debug build. Rebuilding before launch..." -ForegroundColor Yellow
108+
return $true
50109
}
51110

52-
return (Get-Item $Path).LastWriteTimeUtc -gt $SinceUtc
111+
return $false
53112
}
54113

55114
function Invoke-DebugBuild {
@@ -80,7 +139,6 @@ if (-not (Test-Path $stampPath) -or -not (Test-Path $runtimeExePath)) {
80139
}
81140

82141
$stamp = Get-Content -LiteralPath $stampPath -Raw | ConvertFrom-Json
83-
$stampTimeUtc = [DateTime]::Parse($stamp.TimestampUtc).ToUniversalTime()
84142
$resolvedLcmMode = if ($LcmMode -eq 'Local') { 'Local' } else { 'Package' }
85143

86144
$modeMatches = ($stamp.PSObject.Properties.Name -contains 'ResolvedLcmMode') -and ($stamp.ResolvedLcmMode -eq $resolvedLcmMode)
@@ -92,33 +150,10 @@ if (-not $modeMatches -or -not $debugTypeMatches) {
92150
exit 0
93151
}
94152

95-
$pathsToCheck = @(
96-
(Join-Path $repoRoot 'build.ps1'),
97-
(Join-Path $repoRoot 'Directory.Build.props'),
98-
(Join-Path $repoRoot 'Directory.Build.targets'),
99-
(Join-Path $repoRoot 'Directory.Packages.props'),
100-
(Join-Path $repoRoot 'FieldWorks.proj'),
101-
(Join-Path $repoRoot 'Build'),
102-
(Join-Path $repoRoot 'Src'),
103-
(Join-Path $repoRoot 'Lib')
104-
)
105-
106-
if ($resolvedLcmMode -eq 'Local') {
107-
$pathsToCheck += @(
108-
(Join-Path $repoRoot 'FieldWorks.LocalLcm.sln'),
109-
(Join-Path $repoRoot 'Localizations\LCM')
110-
)
111-
}
112-
else {
113-
$pathsToCheck += (Join-Path $repoRoot 'FieldWorks.sln')
114-
}
115-
116-
foreach ($pathToCheck in $pathsToCheck) {
117-
if (Test-RelevantPathChanged -Path $pathToCheck -SinceUtc $stampTimeUtc) {
118-
Write-Host "Detected changes since the last successful $Configuration debug build. Rebuilding before launch..." -ForegroundColor Yellow
119-
Invoke-DebugBuild
120-
exit 0
121-
}
153+
$pathspecsToCheck = Get-DebugRebuildCheckPathspecs -ResolvedLcmMode $resolvedLcmMode
154+
if (Test-GitStateRequiresDebugRebuild -Stamp $stamp -Pathspecs $pathspecsToCheck) {
155+
Invoke-DebugBuild
156+
exit 0
122157
}
123158

124159
Write-Host "[OK] No relevant changes since the last successful $Configuration debug build. Skipping prelaunch build." -ForegroundColor Green

Directory.Packages.props

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<Project>
22
<PropertyGroup>
3-
<_IsNestedLcmProject Condition="$([System.String]::Copy('$(MSBuildProjectFullPath)').Contains('\\Localizations\\LCM\\'))">true</_IsNestedLcmProject>
3+
<_IsNestedLcmProject Condition="$([System.String]::Copy('$(MSBuildProjectFullPath)').ToUpperInvariant().Contains('\\LOCALIZATIONS\\LCM\\'))">true</_IsNestedLcmProject>
44
<ManagePackageVersionsCentrally Condition="'$(_IsNestedLcmProject)'=='true'">false</ManagePackageVersionsCentrally>
55
<ManagePackageVersionsCentrally Condition="'$(_IsNestedLcmProject)'!='true'">true</ManagePackageVersionsCentrally>
66
<!--

build.ps1

Lines changed: 46 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,46 @@ function Get-RepoStamp {
302302
}
303303
}
304304

305+
function Get-DebugRebuildCheckPathspecs {
306+
param(
307+
[Parameter(Mandatory = $true)][ValidateSet('Package', 'Local')][string]$ResolvedLcmMode
308+
)
309+
310+
$pathspecs = @(
311+
'build.ps1',
312+
'Directory.Build.props',
313+
'Directory.Build.targets',
314+
'Directory.Packages.props',
315+
'FieldWorks.proj',
316+
'Build',
317+
'Src',
318+
'Lib'
319+
)
320+
321+
if ($ResolvedLcmMode -eq 'Local') {
322+
$pathspecs += @('FieldWorks.LocalLcm.sln', 'Localizations/LCM')
323+
}
324+
else {
325+
$pathspecs += 'FieldWorks.sln'
326+
}
327+
328+
return $pathspecs | ForEach-Object { $_ -replace '\\', '/' }
329+
}
330+
331+
function Get-GitStatusForDebugRebuildCheck {
332+
param(
333+
[Parameter(Mandatory = $true)][string[]]$Pathspecs
334+
)
335+
336+
$gitArgs = @('status', '--porcelain=v1', '--untracked-files=all', '--') + $Pathspecs
337+
$statusOutput = & git @gitArgs
338+
if ($LASTEXITCODE -ne 0) {
339+
throw "Failed to determine git status snapshot for build stamp."
340+
}
341+
342+
return @($statusOutput | ForEach-Object { $_.TrimEnd() } | Where-Object { -not [string]::IsNullOrWhiteSpace($_) })
343+
}
344+
305345
function Get-BuildStampPath {
306346
param(
307347
[Parameter(Mandatory = $true)][string]$RepoRoot,
@@ -339,8 +379,7 @@ function Get-LocalLcmState {
339379
function Resolve-LcmMode {
340380
param(
341381
[Parameter(Mandatory = $true)][ValidateSet('Auto', 'Package', 'Local')][string]$RequestedMode,
342-
[Parameter(Mandatory = $true)][string]$ProjectArgument,
343-
[Parameter(Mandatory = $true)][psobject]$LocalLcmState
382+
[Parameter(Mandatory = $true)][string]$ProjectArgument
344383
)
345384

346385
if ($RequestedMode -eq 'Local') {
@@ -471,7 +510,7 @@ try {
471510
$installerMsBuildArgs += $MsBuildArgs
472511

473512
$localLcmState = Get-LocalLcmState -RepoRoot $PSScriptRoot -ConfigurationName $Configuration
474-
$resolvedLcmMode = Resolve-LcmMode -RequestedMode $LcmMode -ProjectArgument $Project -LocalLcmState $localLcmState
513+
$resolvedLcmMode = Resolve-LcmMode -RequestedMode $LcmMode -ProjectArgument $Project
475514
$useLocalLcmSource = ($resolvedLcmMode -eq 'Local')
476515
$restoreSolution = if ($useLocalLcmSource) { $localLcmState.LocalSolutionPath } else { Join-Path $PSScriptRoot 'FieldWorks.sln' }
477516

@@ -603,6 +642,8 @@ try {
603642
}
604643

605644
$repoStamp = Get-RepoStamp
645+
$relevantDebugPathspecs = Get-DebugRebuildCheckPathspecs -ResolvedLcmMode $resolvedLcmMode
646+
$relevantDebugStatus = Get-GitStatusForDebugRebuildCheck -Pathspecs $relevantDebugPathspecs
606647
$stampObject = [pscustomobject]@{
607648
Configuration = $Configuration
608649
Platform = $platform
@@ -613,6 +654,8 @@ try {
613654
GitHead = $repoStamp.GitHead
614655
IsDirty = $repoStamp.IsDirty
615656
IsDirtyOutsideInstaller = $repoStamp.IsDirtyOutsideInstaller
657+
RelevantDebugPathspecs = $relevantDebugPathspecs
658+
RelevantDebugStatus = $relevantDebugStatus
616659
TimestampUtc = (Get-Date).ToUniversalTime().ToString('o')
617660
}
618661

0 commit comments

Comments
 (0)