Skip to content

Extract Installer.Core shared library and refactor CLI (#755)#761

Merged
erikdarlingdata merged 3 commits intodevfrom
feature/755-installer-core
Mar 30, 2026
Merged

Extract Installer.Core shared library and refactor CLI (#755)#761
erikdarlingdata merged 3 commits intodevfrom
feature/755-installer-core

Conversation

@erikdarlingdata
Copy link
Copy Markdown
Owner

Summary

  • New Installer.Core class library — shared installation logic extracted from InstallerGui/Services/InstallationService.cs into a standalone net8.0 library with no WPF dependency
  • CLI Installer refactoredProgram.cs reduced from 2,122 to 1,172 lines (45%), now a thin console wrapper over Installer.Core
  • SQL scripts embedded as assembly resourcesScriptProvider abstraction supports filesystem (CLI/GUI) and embedded resources (future Dashboard integration in Phase 2)
  • InstallerGui and Installer.Tests retargeted to consume Installer.Core

This is Phase 1 of #755. Phase 2 (Dashboard Add Server integration) and Phase 3 (retire InstallerGui) will follow.

What's in Installer.Core

File Purpose
InstallationService.cs All static methods: connect, install, upgrade, validate, uninstall, history logging, report generation
DependencyInstaller.cs Community dependency downloads (sp_WhoIsActive, DarlingData, First Responder Kit)
ScriptProvider.cs Abstract base + FileSystemScriptProvider + EmbeddedResourceScriptProvider
Patterns.cs Shared [GeneratedRegex] patterns (GO splitter, SQL file pattern, SQLCMD directive)
Models/ InstallationProgress, ServerInfo, InstallationResult, UpgradeInfo, InstallationResultCode (enum mapping CLI exit codes 0-8)

Test plan

  • 19/19 unit tests pass (FileFiltering, UpgradeOrdering)
  • CLI --help shows all flags and exit codes 0-8
  • Fresh install: SQL2016, SQL2017, SQL2019, SQL2022, SQL2025 — 54/54 scripts, 3/3 deps, 45 collectors each
  • Upgrade path: faked 2.0.0 → 2.4.1 on SQL2022 — 4 upgrades (11 scripts), then 54 install scripts
  • Uninstall: clean removal of jobs, XE sessions, database on SQL2022
  • Installation history: UPGRADE record written correctly with version tracking
  • GUI Installer: builds and runs against Installer.Core
  • Dashboard: builds and launches normally on this branch

🤖 Generated with Claude Code

erikdarlingdata and others added 3 commits March 29, 2026 10:54
…755)

Phase 1 extraction of shared installation logic into Installer.Core class
library. InstallerGui and Installer.Tests now consume the shared library
instead of duplicating code. CLI Installer refactor is next.

New files:
- Installer.Core/InstallationService.cs — all static install/upgrade methods
- Installer.Core/DependencyInstaller.cs — community dependency downloads
- Installer.Core/ScriptProvider.cs — filesystem + embedded resource abstraction
- Installer.Core/Patterns.cs — shared regex patterns ([GeneratedRegex])
- Installer.Core/Models/ — InstallationProgress, ServerInfo, InstallationResult,
  UpgradeInfo, InstallationResultCode (enum mapping CLI exit codes 0-8)

Key changes:
- SQL scripts embedded as assembly resources for future Dashboard integration
- ScriptProvider.FromDirectory() for CLI/GUI, FromEmbeddedResources() for Dashboard
- AutoDiscover() searches filesystem then falls back to embedded
- Comprehensive [DEBUG] logging throughout all methods for GUI diagnostics
- upgrade.txt missing warning (was silently skipped, now logged)
- GenerateSummaryReport gains optional outputDirectory parameter

Retargeted:
- InstallerGui references Installer.Core, old InstallationService.cs deleted
- Installer.Tests targets net8.0 (was net8.0-windows), no WPF dependency
- Tests use ScriptProvider.FromDirectory() instead of raw file paths

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Program.cs rewritten from 2,122 lines to 1,172 lines (45% reduction).
All duplicated logic removed — CLI now delegates to Installer.Core for:

- Connection string building (InstallationService.BuildConnectionString)
- Connection testing (InstallationService.TestConnectionAsync)
- Script discovery (ScriptProvider.FromDirectory)
- SQL file execution (InstallationService.ExecuteInstallationAsync)
- Upgrade detection and execution (ExecuteAllUpgradesAsync)
- Uninstall (InstallationService.ExecuteUninstallAsync)
- Version detection (InstallationService.GetInstalledVersionAsync)
- Community dependencies (DependencyInstaller)
- Validation (InstallationService.RunValidationAsync)
- Installation history (InstallationService.LogInstallationHistoryAsync)
- Summary reports (InstallationService.GenerateSummaryReport)

What stays in Program.cs (console-specific):
- Argument parsing, interactive prompts, retry loop
- Console output helpers (WriteSuccess/WriteError/WriteWarning)
- ReadPassword, WaitForExit, CheckForInstallerUpdateAsync
- Error log generation (WriteErrorLog)

Fixes during review:
- Added missing exit code 8 (UpgradesFailed) to --help text
- Fixed encryption default label in error message (was "optional", is "mandatory")

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ollection_table (#756)

When calculate_deltas was called inside a collector's transaction and failed,
the CATCH block tried to INSERT into collection_log while the transaction was
doomed (XACT_STATE = -1), swallowing the real error with "The current transaction
cannot be committed." Same pattern in ensure_collection_table where INSERT
happened before ROLLBACK.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@erikdarlingdata erikdarlingdata merged commit 8d682ee into dev Mar 30, 2026
7 checks passed
@erikdarlingdata erikdarlingdata deleted the feature/755-installer-core branch March 30, 2026 12:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant