Remove obsolete test projects and associated test files for StellaOps.Replay.Core and StellaOps.Gateway.WebService. This includes the deletion of various test classes, project files, and related resources to streamline the codebase and improve maintainability.
This commit is contained in:
100
devops/scripts/fix-duplicate-packages.ps1
Normal file
100
devops/scripts/fix-duplicate-packages.ps1
Normal file
@@ -0,0 +1,100 @@
|
||||
#!/usr/bin/env pwsh
|
||||
# fix-duplicate-packages.ps1 - Remove duplicate PackageReference items from test projects
|
||||
# These are already provided by Directory.Build.props
|
||||
|
||||
param([switch]$DryRun)
|
||||
|
||||
$packagesToRemove = @(
|
||||
"coverlet.collector",
|
||||
"Microsoft.NET.Test.Sdk",
|
||||
"Microsoft.AspNetCore.Mvc.Testing",
|
||||
"xunit",
|
||||
"xunit.runner.visualstudio",
|
||||
"Microsoft.Extensions.TimeProvider.Testing"
|
||||
)
|
||||
|
||||
$sharpCompressPackage = "SharpCompress"
|
||||
|
||||
# Find all test project files
|
||||
$testProjects = Get-ChildItem -Path "src" -Filter "*.Tests.csproj" -Recurse
|
||||
$corpusProjects = Get-ChildItem -Path "src" -Filter "*.Corpus.*.csproj" -Recurse
|
||||
|
||||
Write-Host "=== Fix Duplicate Package References ===" -ForegroundColor Cyan
|
||||
Write-Host "Found $($testProjects.Count) test projects" -ForegroundColor Yellow
|
||||
Write-Host "Found $($corpusProjects.Count) corpus projects (SharpCompress)" -ForegroundColor Yellow
|
||||
|
||||
$fixedCount = 0
|
||||
|
||||
foreach ($proj in $testProjects) {
|
||||
$content = Get-Content $proj.FullName -Raw
|
||||
$modified = $false
|
||||
|
||||
# Skip projects that opt out of common test infrastructure
|
||||
if ($content -match "<UseConcelierTestInfra>\s*false\s*</UseConcelierTestInfra>") {
|
||||
Write-Host " Skipped (UseConcelierTestInfra=false): $($proj.Name)" -ForegroundColor DarkGray
|
||||
continue
|
||||
}
|
||||
|
||||
foreach ($pkg in $packagesToRemove) {
|
||||
# Match PackageReference for this package (various formats)
|
||||
$patterns = @(
|
||||
"(?s)\s*<PackageReference\s+Include=`"$pkg`"\s+Version=`"[^`"]+`"\s*/>\r?\n?",
|
||||
"(?s)\s*<PackageReference\s+Include=`"$pkg`"\s+Version=`"[^`"]+`"\s*>\s*</PackageReference>\r?\n?"
|
||||
)
|
||||
|
||||
foreach ($pattern in $patterns) {
|
||||
if ($content -match $pattern) {
|
||||
$content = $content -replace $pattern, ""
|
||||
$modified = $true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Clean up empty ItemGroups
|
||||
$content = $content -replace "(?s)\s*<ItemGroup>\s*</ItemGroup>", ""
|
||||
# Clean up ItemGroups with only whitespace/comments
|
||||
$content = $content -replace "(?s)<ItemGroup>\s*<!--[^-]*-->\s*</ItemGroup>", ""
|
||||
|
||||
if ($modified) {
|
||||
$fixedCount++
|
||||
Write-Host " Fixed: $($proj.Name)" -ForegroundColor Green
|
||||
if (-not $DryRun) {
|
||||
$content | Set-Content $proj.FullName -NoNewline
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Fix SharpCompress in corpus projects
|
||||
foreach ($proj in $corpusProjects) {
|
||||
$content = Get-Content $proj.FullName -Raw
|
||||
$modified = $false
|
||||
|
||||
$patterns = @(
|
||||
"(?s)\s*<PackageReference\s+Include=`"$sharpCompressPackage`"\s+Version=`"[^`"]+`"\s*/>\r?\n?",
|
||||
"(?s)\s*<PackageReference\s+Include=`"$sharpCompressPackage`"\s+Version=`"[^`"]+`"\s*>\s*</PackageReference>\r?\n?"
|
||||
)
|
||||
|
||||
foreach ($pattern in $patterns) {
|
||||
if ($content -match $pattern) {
|
||||
$content = $content -replace $pattern, ""
|
||||
$modified = $true
|
||||
}
|
||||
}
|
||||
|
||||
# Clean up empty ItemGroups
|
||||
$content = $content -replace "(?s)\s*<ItemGroup>\s*</ItemGroup>", ""
|
||||
|
||||
if ($modified) {
|
||||
$fixedCount++
|
||||
Write-Host " Fixed: $($proj.Name)" -ForegroundColor Green
|
||||
if (-not $DryRun) {
|
||||
$content | Set-Content $proj.FullName -NoNewline
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Write-Host ""
|
||||
Write-Host "Fixed $fixedCount projects" -ForegroundColor Cyan
|
||||
if ($DryRun) {
|
||||
Write-Host "(Dry run - no changes made)" -ForegroundColor Yellow
|
||||
}
|
||||
55
devops/scripts/fix-duplicate-using-testkit.ps1
Normal file
55
devops/scripts/fix-duplicate-using-testkit.ps1
Normal file
@@ -0,0 +1,55 @@
|
||||
# Fix duplicate "using StellaOps.TestKit;" statements in C# files
|
||||
# The pattern shows files have this statement both at top (correct) and in middle (wrong)
|
||||
# This script removes all occurrences AFTER the first one
|
||||
|
||||
$ErrorActionPreference = "Stop"
|
||||
|
||||
$srcPath = Join-Path $PSScriptRoot "..\..\src"
|
||||
$pattern = "using StellaOps.TestKit;"
|
||||
|
||||
# Find all .cs files containing the pattern
|
||||
$files = Get-ChildItem -Path $srcPath -Recurse -Filter "*.cs" |
|
||||
Where-Object { (Get-Content $_.FullName -Raw) -match [regex]::Escape($pattern) }
|
||||
|
||||
Write-Host "Found $($files.Count) files with 'using StellaOps.TestKit;'" -ForegroundColor Cyan
|
||||
|
||||
$fixedCount = 0
|
||||
$errorCount = 0
|
||||
|
||||
foreach ($file in $files) {
|
||||
try {
|
||||
$lines = Get-Content $file.FullName
|
||||
$newLines = @()
|
||||
$foundFirst = $false
|
||||
$removedAny = $false
|
||||
|
||||
foreach ($line in $lines) {
|
||||
if ($line.Trim() -eq $pattern) {
|
||||
if (-not $foundFirst) {
|
||||
# Keep the first occurrence
|
||||
$newLines += $line
|
||||
$foundFirst = $true
|
||||
} else {
|
||||
# Skip subsequent occurrences
|
||||
$removedAny = $true
|
||||
}
|
||||
} else {
|
||||
$newLines += $line
|
||||
}
|
||||
}
|
||||
|
||||
if ($removedAny) {
|
||||
$newLines | Set-Content -Path $file.FullName -Encoding UTF8
|
||||
Write-Host "Fixed: $($file.Name)" -ForegroundColor Green
|
||||
$fixedCount++
|
||||
}
|
||||
} catch {
|
||||
Write-Host "Error processing $($file.FullName): $_" -ForegroundColor Red
|
||||
$errorCount++
|
||||
}
|
||||
}
|
||||
|
||||
Write-Host ""
|
||||
Write-Host "Summary:" -ForegroundColor Cyan
|
||||
Write-Host " Files fixed: $fixedCount" -ForegroundColor Green
|
||||
Write-Host " Errors: $errorCount" -ForegroundColor $(if ($errorCount -gt 0) { "Red" } else { "Green" })
|
||||
68
devops/scripts/fix-sln-duplicates.ps1
Normal file
68
devops/scripts/fix-sln-duplicates.ps1
Normal file
@@ -0,0 +1,68 @@
|
||||
#!/usr/bin/env pwsh
|
||||
# fix-sln-duplicates.ps1 - Remove duplicate project entries from solution file
|
||||
|
||||
param(
|
||||
[string]$SlnPath = "src/StellaOps.sln"
|
||||
)
|
||||
|
||||
$ErrorActionPreference = "Stop"
|
||||
|
||||
Write-Host "=== Solution Duplicate Cleanup ===" -ForegroundColor Cyan
|
||||
Write-Host "Solution: $SlnPath"
|
||||
|
||||
$content = Get-Content $SlnPath -Raw
|
||||
$lines = $content -split "`r?`n"
|
||||
|
||||
# Track seen project names
|
||||
$seenProjects = @{}
|
||||
$duplicateGuids = @()
|
||||
$newLines = @()
|
||||
$skipNext = $false
|
||||
|
||||
for ($i = 0; $i -lt $lines.Count; $i++) {
|
||||
$line = $lines[$i]
|
||||
|
||||
if ($skipNext) {
|
||||
$skipNext = $false
|
||||
continue
|
||||
}
|
||||
|
||||
# Check for project declaration
|
||||
if ($line -match 'Project\(.+\) = "([^"]+)",.*\{([A-F0-9-]+)\}"?$') {
|
||||
$name = $Matches[1]
|
||||
$guid = $Matches[2]
|
||||
|
||||
if ($seenProjects.ContainsKey($name)) {
|
||||
Write-Host "Removing duplicate: $name ($guid)" -ForegroundColor Yellow
|
||||
$duplicateGuids += $guid
|
||||
# Skip this line and the next EndProject line
|
||||
$skipNext = $true
|
||||
continue
|
||||
} else {
|
||||
$seenProjects[$name] = $true
|
||||
}
|
||||
}
|
||||
|
||||
$newLines += $line
|
||||
}
|
||||
|
||||
# Remove GlobalSection references to duplicate GUIDs
|
||||
$finalLines = @()
|
||||
foreach ($line in $newLines) {
|
||||
$skip = $false
|
||||
foreach ($guid in $duplicateGuids) {
|
||||
if ($line -match $guid) {
|
||||
$skip = $true
|
||||
break
|
||||
}
|
||||
}
|
||||
if (-not $skip) {
|
||||
$finalLines += $line
|
||||
}
|
||||
}
|
||||
|
||||
# Write back
|
||||
$finalLines -join "`r`n" | Set-Content $SlnPath -Encoding UTF8 -NoNewline
|
||||
|
||||
Write-Host ""
|
||||
Write-Host "Removed $($duplicateGuids.Count) duplicate projects" -ForegroundColor Green
|
||||
190
devops/scripts/migrations-reset-pre-1.0.sql
Normal file
190
devops/scripts/migrations-reset-pre-1.0.sql
Normal file
@@ -0,0 +1,190 @@
|
||||
-- ============================================================================
|
||||
-- StellaOps Migration Reset Script for Pre-1.0 Deployments
|
||||
-- ============================================================================
|
||||
-- This script updates schema_migrations tables to recognize the 1.0.0 compacted
|
||||
-- migrations for deployments that upgraded from pre-1.0 versions.
|
||||
--
|
||||
-- Run via: psql -f migrations-reset-pre-1.0.sql
|
||||
-- Or with connection: psql -h <host> -U <user> -d <db> -f migrations-reset-pre-1.0.sql
|
||||
-- ============================================================================
|
||||
|
||||
BEGIN;
|
||||
|
||||
-- ============================================================================
|
||||
-- Authority Module Reset
|
||||
-- ============================================================================
|
||||
-- Original: 001_initial_schema, 002_mongo_store_equivalents, 003_enable_rls,
|
||||
-- 004_offline_kit_audit, 005_verdict_manifests
|
||||
-- New: 001_initial_schema (compacted)
|
||||
|
||||
DELETE FROM authority.schema_migrations
|
||||
WHERE migration_name IN (
|
||||
'001_initial_schema.sql',
|
||||
'002_mongo_store_equivalents.sql',
|
||||
'003_enable_rls.sql',
|
||||
'004_offline_kit_audit.sql',
|
||||
'005_verdict_manifests.sql'
|
||||
);
|
||||
|
||||
INSERT INTO authority.schema_migrations (migration_name, category, checksum, applied_at)
|
||||
VALUES ('001_initial_schema.sql', 'startup', 'compacted_1.0.0', NOW())
|
||||
ON CONFLICT (migration_name) DO NOTHING;
|
||||
|
||||
-- ============================================================================
|
||||
-- Scheduler Module Reset
|
||||
-- ============================================================================
|
||||
-- Original: 001_initial_schema, 002_graph_jobs, 003_runs_policy,
|
||||
-- 010_generated_columns_runs, 011_enable_rls, 012_partition_audit,
|
||||
-- 012b_migrate_audit_data
|
||||
-- New: 001_initial_schema (compacted)
|
||||
|
||||
DELETE FROM scheduler.schema_migrations
|
||||
WHERE migration_name IN (
|
||||
'001_initial_schema.sql',
|
||||
'002_graph_jobs.sql',
|
||||
'003_runs_policy.sql',
|
||||
'010_generated_columns_runs.sql',
|
||||
'011_enable_rls.sql',
|
||||
'012_partition_audit.sql',
|
||||
'012b_migrate_audit_data.sql'
|
||||
);
|
||||
|
||||
INSERT INTO scheduler.schema_migrations (migration_name, category, checksum, applied_at)
|
||||
VALUES ('001_initial_schema.sql', 'startup', 'compacted_1.0.0', NOW())
|
||||
ON CONFLICT (migration_name) DO NOTHING;
|
||||
|
||||
-- ============================================================================
|
||||
-- Scanner Module Reset
|
||||
-- ============================================================================
|
||||
-- Original: 001-034 plus various numbered files (27 total)
|
||||
-- New: 001_initial_schema (compacted)
|
||||
|
||||
DELETE FROM scanner.schema_migrations
|
||||
WHERE migration_name IN (
|
||||
'001_create_tables.sql',
|
||||
'002_proof_spine_tables.sql',
|
||||
'003_classification_history.sql',
|
||||
'004_scan_metrics.sql',
|
||||
'005_smart_diff_tables.sql',
|
||||
'006_score_replay_tables.sql',
|
||||
'007_unknowns_ranking_containment.sql',
|
||||
'008_epss_integration.sql',
|
||||
'0059_scans_table.sql',
|
||||
'0065_unknowns_table.sql',
|
||||
'0075_scan_findings_table.sql',
|
||||
'020_call_graph_tables.sql',
|
||||
'021_smart_diff_tables_search_path.sql',
|
||||
'022_reachability_drift_tables.sql',
|
||||
'023_scanner_api_ingestion.sql',
|
||||
'024_smart_diff_priority_score_widen.sql',
|
||||
'025_epss_raw_layer.sql',
|
||||
'026_epss_signal_layer.sql',
|
||||
'027_witness_storage.sql',
|
||||
'028_epss_triage_columns.sql',
|
||||
'029_vuln_surfaces.sql',
|
||||
'030_vuln_surface_triggers_update.sql',
|
||||
'031_reach_cache.sql',
|
||||
'032_idempotency_keys.sql',
|
||||
'033_binary_evidence.sql',
|
||||
'034_func_proof_tables.sql',
|
||||
'DM001_rename_scanner_migrations.sql'
|
||||
);
|
||||
|
||||
INSERT INTO scanner.schema_migrations (migration_name, category, checksum, applied_at)
|
||||
VALUES ('001_initial_schema.sql', 'startup', 'compacted_1.0.0', NOW())
|
||||
ON CONFLICT (migration_name) DO NOTHING;
|
||||
|
||||
-- ============================================================================
|
||||
-- Policy Module Reset
|
||||
-- ============================================================================
|
||||
-- Original: 001-013 (14 files, includes duplicate 010 prefix)
|
||||
-- New: 001_initial_schema (compacted)
|
||||
|
||||
DELETE FROM policy.schema_migrations
|
||||
WHERE migration_name IN (
|
||||
'001_initial_schema.sql',
|
||||
'002_cvss_receipts.sql',
|
||||
'003_snapshots_violations.sql',
|
||||
'004_epss_risk_scores.sql',
|
||||
'005_cvss_multiversion.sql',
|
||||
'006_enable_rls.sql',
|
||||
'007_unknowns_registry.sql',
|
||||
'008_exception_objects.sql',
|
||||
'009_exception_applications.sql',
|
||||
'010_recheck_evidence.sql',
|
||||
'010_unknowns_blast_radius_containment.sql',
|
||||
'011_unknowns_reason_codes.sql',
|
||||
'012_budget_ledger.sql',
|
||||
'013_exception_approval.sql'
|
||||
);
|
||||
|
||||
INSERT INTO policy.schema_migrations (migration_name, category, checksum, applied_at)
|
||||
VALUES ('001_initial_schema.sql', 'startup', 'compacted_1.0.0', NOW())
|
||||
ON CONFLICT (migration_name) DO NOTHING;
|
||||
|
||||
-- ============================================================================
|
||||
-- Notify Module Reset
|
||||
-- ============================================================================
|
||||
-- Original: 001_initial_schema, 010_enable_rls, 011_partition_deliveries,
|
||||
-- 011b_migrate_deliveries_data
|
||||
-- New: 001_initial_schema (compacted)
|
||||
|
||||
DELETE FROM notify.schema_migrations
|
||||
WHERE migration_name IN (
|
||||
'001_initial_schema.sql',
|
||||
'010_enable_rls.sql',
|
||||
'011_partition_deliveries.sql',
|
||||
'011b_migrate_deliveries_data.sql'
|
||||
);
|
||||
|
||||
INSERT INTO notify.schema_migrations (migration_name, category, checksum, applied_at)
|
||||
VALUES ('001_initial_schema.sql', 'startup', 'compacted_1.0.0', NOW())
|
||||
ON CONFLICT (migration_name) DO NOTHING;
|
||||
|
||||
-- ============================================================================
|
||||
-- Concelier Module Reset
|
||||
-- ============================================================================
|
||||
-- Original: 17 migration files
|
||||
-- New: 001_initial_schema (compacted)
|
||||
|
||||
DELETE FROM concelier.schema_migrations
|
||||
WHERE migration_name ~ '^[0-9]{3}_.*\.sql$';
|
||||
|
||||
INSERT INTO concelier.schema_migrations (migration_name, category, checksum, applied_at)
|
||||
VALUES ('001_initial_schema.sql', 'startup', 'compacted_1.0.0', NOW())
|
||||
ON CONFLICT (migration_name) DO NOTHING;
|
||||
|
||||
-- ============================================================================
|
||||
-- Verification
|
||||
-- ============================================================================
|
||||
-- Display current migration status per module
|
||||
|
||||
DO $$
|
||||
DECLARE
|
||||
v_module TEXT;
|
||||
v_count INT;
|
||||
BEGIN
|
||||
FOR v_module IN SELECT unnest(ARRAY['authority', 'scheduler', 'scanner', 'policy', 'notify', 'concelier']) LOOP
|
||||
EXECUTE format('SELECT COUNT(*) FROM %I.schema_migrations', v_module) INTO v_count;
|
||||
RAISE NOTICE '% module: % migrations registered', v_module, v_count;
|
||||
END LOOP;
|
||||
END $$;
|
||||
|
||||
COMMIT;
|
||||
|
||||
-- ============================================================================
|
||||
-- Post-Reset Notes
|
||||
-- ============================================================================
|
||||
-- After running this script:
|
||||
-- 1. All modules should show exactly 1 migration registered
|
||||
-- 2. The schema structure should be identical to a fresh 1.0.0 deployment
|
||||
-- 3. Future migrations (002+) will apply normally
|
||||
--
|
||||
-- To verify manually:
|
||||
-- SELECT * FROM authority.schema_migrations;
|
||||
-- SELECT * FROM scheduler.schema_migrations;
|
||||
-- SELECT * FROM scanner.schema_migrations;
|
||||
-- SELECT * FROM policy.schema_migrations;
|
||||
-- SELECT * FROM notify.schema_migrations;
|
||||
-- SELECT * FROM concelier.schema_migrations;
|
||||
-- ============================================================================
|
||||
169
devops/scripts/regenerate-solution.ps1
Normal file
169
devops/scripts/regenerate-solution.ps1
Normal file
@@ -0,0 +1,169 @@
|
||||
#!/usr/bin/env pwsh
|
||||
# regenerate-solution.ps1 - Regenerate StellaOps.sln without duplicate projects
|
||||
#
|
||||
# This script:
|
||||
# 1. Backs up the existing solution
|
||||
# 2. Creates a new solution
|
||||
# 3. Adds all .csproj files, skipping duplicates
|
||||
# 4. Preserves solution folders where possible
|
||||
|
||||
param(
|
||||
[string]$SolutionPath = "src/StellaOps.sln",
|
||||
[switch]$DryRun
|
||||
)
|
||||
|
||||
$ErrorActionPreference = "Stop"
|
||||
|
||||
# Canonical locations for test projects (in priority order)
|
||||
# Later entries win when there are duplicates
|
||||
$canonicalPatterns = @(
|
||||
# Module-local tests (highest priority)
|
||||
"src/*/__Tests/*/*.csproj",
|
||||
"src/*/__Libraries/__Tests/*/*.csproj",
|
||||
"src/__Libraries/__Tests/*/*.csproj",
|
||||
# Cross-module integration tests
|
||||
"src/__Tests/Integration/*/*.csproj",
|
||||
"src/__Tests/__Libraries/*/*.csproj",
|
||||
# Category-based cross-module tests
|
||||
"src/__Tests/chaos/*/*.csproj",
|
||||
"src/__Tests/security/*/*.csproj",
|
||||
"src/__Tests/interop/*/*.csproj",
|
||||
"src/__Tests/parity/*/*.csproj",
|
||||
"src/__Tests/reachability/*/*.csproj",
|
||||
# Single global tests
|
||||
"src/__Tests/*/*.csproj"
|
||||
)
|
||||
|
||||
Write-Host "=== Solution Regeneration Script ===" -ForegroundColor Cyan
|
||||
Write-Host "Solution: $SolutionPath"
|
||||
Write-Host "Dry Run: $DryRun"
|
||||
Write-Host ""
|
||||
|
||||
# Find all .csproj files
|
||||
Write-Host "Finding all project files..." -ForegroundColor Yellow
|
||||
$allProjects = Get-ChildItem -Path "src" -Filter "*.csproj" -Recurse |
|
||||
Where-Object { $_.FullName -notmatch "\\obj\\" -and $_.FullName -notmatch "\\bin\\" }
|
||||
|
||||
Write-Host "Found $($allProjects.Count) project files"
|
||||
|
||||
# Build a map of project name -> list of paths
|
||||
$projectMap = @{}
|
||||
foreach ($proj in $allProjects) {
|
||||
$name = $proj.BaseName
|
||||
if (-not $projectMap.ContainsKey($name)) {
|
||||
$projectMap[$name] = @()
|
||||
}
|
||||
$projectMap[$name] += $proj.FullName
|
||||
}
|
||||
|
||||
# Find duplicates
|
||||
$duplicates = $projectMap.GetEnumerator() | Where-Object { $_.Value.Count -gt 1 }
|
||||
Write-Host ""
|
||||
Write-Host "Found $($duplicates.Count) projects with duplicate names:" -ForegroundColor Yellow
|
||||
foreach ($dup in $duplicates) {
|
||||
Write-Host " $($dup.Key):" -ForegroundColor Red
|
||||
foreach ($path in $dup.Value) {
|
||||
Write-Host " - $path"
|
||||
}
|
||||
}
|
||||
|
||||
# Select canonical path for each project
|
||||
function Get-CanonicalPath {
|
||||
param([string[]]$Paths)
|
||||
|
||||
# Prefer module-local __Tests over global __Tests
|
||||
$moduleTests = $Paths | Where-Object { $_ -match "src\\[^_][^\\]+\\__Tests\\" }
|
||||
if ($moduleTests.Count -gt 0) { return $moduleTests[0] }
|
||||
|
||||
# Prefer __Libraries/__Tests
|
||||
$libTests = $Paths | Where-Object { $_ -match "__Libraries\\__Tests\\" }
|
||||
if ($libTests.Count -gt 0) { return $libTests[0] }
|
||||
|
||||
# Prefer __Tests over non-__Tests location in same parent
|
||||
$testsPath = $Paths | Where-Object { $_ -match "\\__Tests\\" }
|
||||
if ($testsPath.Count -gt 0) { return $testsPath[0] }
|
||||
|
||||
# Otherwise, take first
|
||||
return $Paths[0]
|
||||
}
|
||||
|
||||
# Build final project list
|
||||
$finalProjects = @()
|
||||
foreach ($entry in $projectMap.GetEnumerator()) {
|
||||
$canonical = Get-CanonicalPath -Paths $entry.Value
|
||||
$finalProjects += $canonical
|
||||
}
|
||||
|
||||
Write-Host ""
|
||||
Write-Host "Final project count: $($finalProjects.Count)" -ForegroundColor Green
|
||||
|
||||
if ($DryRun) {
|
||||
Write-Host ""
|
||||
Write-Host "=== DRY RUN - No changes made ===" -ForegroundColor Magenta
|
||||
Write-Host "Would add the following projects to solution:"
|
||||
$finalProjects | ForEach-Object { Write-Host " $_" }
|
||||
exit 0
|
||||
}
|
||||
|
||||
# Backup existing solution
|
||||
$backupPath = "$SolutionPath.bak"
|
||||
if (Test-Path $SolutionPath) {
|
||||
Copy-Item $SolutionPath $backupPath -Force
|
||||
Write-Host "Backed up existing solution to $backupPath" -ForegroundColor Gray
|
||||
}
|
||||
|
||||
# Create new solution
|
||||
Write-Host ""
|
||||
Write-Host "Creating new solution..." -ForegroundColor Yellow
|
||||
$slnDir = Split-Path $SolutionPath -Parent
|
||||
$slnName = [System.IO.Path]::GetFileNameWithoutExtension($SolutionPath)
|
||||
|
||||
# Remove old solution
|
||||
if (Test-Path $SolutionPath) {
|
||||
Remove-Item $SolutionPath -Force
|
||||
}
|
||||
|
||||
# Create fresh solution
|
||||
Push-Location $slnDir
|
||||
dotnet new sln -n $slnName --force 2>$null
|
||||
Pop-Location
|
||||
|
||||
# Add projects in batches (dotnet sln add can handle multiple)
|
||||
Write-Host "Adding projects to solution..." -ForegroundColor Yellow
|
||||
$added = 0
|
||||
$failed = 0
|
||||
|
||||
foreach ($proj in $finalProjects) {
|
||||
try {
|
||||
$result = dotnet sln $SolutionPath add $proj 2>&1
|
||||
if ($LASTEXITCODE -eq 0) {
|
||||
$added++
|
||||
if ($added % 50 -eq 0) {
|
||||
Write-Host " Added $added projects..." -ForegroundColor Gray
|
||||
}
|
||||
} else {
|
||||
Write-Host " Failed to add: $proj" -ForegroundColor Red
|
||||
$failed++
|
||||
}
|
||||
} catch {
|
||||
Write-Host " Error adding: $proj - $_" -ForegroundColor Red
|
||||
$failed++
|
||||
}
|
||||
}
|
||||
|
||||
Write-Host ""
|
||||
Write-Host "=== Summary ===" -ForegroundColor Cyan
|
||||
Write-Host "Projects added: $added" -ForegroundColor Green
|
||||
Write-Host "Projects failed: $failed" -ForegroundColor $(if ($failed -gt 0) { "Red" } else { "Green" })
|
||||
Write-Host ""
|
||||
Write-Host "Solution regenerated at: $SolutionPath"
|
||||
|
||||
# Verify
|
||||
Write-Host ""
|
||||
Write-Host "Verifying solution..." -ForegroundColor Yellow
|
||||
$verifyResult = dotnet build $SolutionPath --no-restore -t:ValidateSolutionConfiguration 2>&1
|
||||
if ($LASTEXITCODE -eq 0) {
|
||||
Write-Host "Solution validation passed!" -ForegroundColor Green
|
||||
} else {
|
||||
Write-Host "Solution validation had issues - check manually" -ForegroundColor Yellow
|
||||
}
|
||||
70
devops/scripts/remove-stale-refs.ps1
Normal file
70
devops/scripts/remove-stale-refs.ps1
Normal file
@@ -0,0 +1,70 @@
|
||||
#!/usr/bin/env pwsh
|
||||
# remove-stale-refs.ps1 - Remove stale project references that don't exist
|
||||
|
||||
param([string]$SlnPath = "src/StellaOps.sln")
|
||||
|
||||
$content = Get-Content $SlnPath -Raw
|
||||
$lines = $content -split "`r?`n"
|
||||
|
||||
# Stale project paths (relative from solution location)
|
||||
$staleProjects = @(
|
||||
"__Tests\AirGap\StellaOps.AirGap.Controller.Tests",
|
||||
"__Tests\AirGap\StellaOps.AirGap.Importer.Tests",
|
||||
"__Tests\AirGap\StellaOps.AirGap.Time.Tests",
|
||||
"__Tests\StellaOps.Gateway.WebService.Tests",
|
||||
"__Tests\Graph\StellaOps.Graph.Indexer.Tests",
|
||||
"Scanner\StellaOps.Scanner.Analyzers.Native",
|
||||
"__Libraries\__Tests\StellaOps.Signals.Tests",
|
||||
"__Tests\StellaOps.Audit.ReplayToken.Tests",
|
||||
"__Tests\StellaOps.Router.Gateway.Tests",
|
||||
"__Libraries\StellaOps.Cryptography"
|
||||
)
|
||||
|
||||
$staleGuids = @()
|
||||
$newLines = @()
|
||||
$skipNext = $false
|
||||
|
||||
for ($i = 0; $i -lt $lines.Count; $i++) {
|
||||
$line = $lines[$i]
|
||||
|
||||
if ($skipNext) {
|
||||
$skipNext = $false
|
||||
continue
|
||||
}
|
||||
|
||||
$isStale = $false
|
||||
foreach ($stalePath in $staleProjects) {
|
||||
if ($line -like "*$stalePath*") {
|
||||
# Extract GUID
|
||||
if ($line -match '\{([A-F0-9-]+)\}"?$') {
|
||||
$staleGuids += $Matches[1]
|
||||
}
|
||||
Write-Host "Removing stale: $stalePath"
|
||||
$isStale = $true
|
||||
$skipNext = $true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if (-not $isStale) {
|
||||
$newLines += $line
|
||||
}
|
||||
}
|
||||
|
||||
# Remove GlobalSection references to stale GUIDs
|
||||
$finalLines = @()
|
||||
foreach ($line in $newLines) {
|
||||
$skip = $false
|
||||
foreach ($guid in $staleGuids) {
|
||||
if ($line -match $guid) {
|
||||
$skip = $true
|
||||
break
|
||||
}
|
||||
}
|
||||
if (-not $skip) {
|
||||
$finalLines += $line
|
||||
}
|
||||
}
|
||||
|
||||
$finalLines -join "`r`n" | Set-Content $SlnPath -Encoding UTF8 -NoNewline
|
||||
Write-Host "Removed $($staleGuids.Count) stale project references"
|
||||
Reference in New Issue
Block a user