Refactor DevTool constructors and include WebGateway in solution
This commit is contained in:
parent
29e027b918
commit
3789492de3
@ -5,7 +5,7 @@ using Spectre.Console;
|
|||||||
// ── Workspace + project discovery ────────────────────────────────────────────
|
// ── Workspace + project discovery ────────────────────────────────────────────
|
||||||
|
|
||||||
var workspaceResult = WorkspaceLoader.FindAndLoad();
|
var workspaceResult = WorkspaceLoader.FindAndLoad();
|
||||||
var projectResult = ConfigLoader.FindAndLoad();
|
var projectResult = ConfigLoader.FindAndLoad();
|
||||||
|
|
||||||
if (projectResult is null)
|
if (projectResult is null)
|
||||||
{
|
{
|
||||||
@ -17,7 +17,7 @@ if (projectResult is null)
|
|||||||
// ── Main run loop (handles workspace project switching) ───────────────────────
|
// ── Main run loop (handles workspace project switching) ───────────────────────
|
||||||
|
|
||||||
var (currentConfig, currentRoot) = projectResult.Value;
|
var (currentConfig, currentRoot) = projectResult.Value;
|
||||||
var (workspace, workspaceRoot) = workspaceResult.HasValue
|
var (workspace, workspaceRoot) = workspaceResult.HasValue
|
||||||
? (workspaceResult.Value.Config, workspaceResult.Value.WorkspaceRoot)
|
? (workspaceResult.Value.Config, workspaceResult.Value.WorkspaceRoot)
|
||||||
: ((WorkspaceConfig?)null, (string?)null);
|
: ((WorkspaceConfig?)null, (string?)null);
|
||||||
|
|
||||||
@ -25,7 +25,7 @@ try
|
|||||||
{
|
{
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
var app = new App(currentConfig, currentRoot, workspace, workspaceRoot);
|
var app = new App(currentConfig, currentRoot, workspace, workspaceRoot);
|
||||||
var result = await app.RunAsync();
|
var result = await app.RunAsync();
|
||||||
|
|
||||||
if (result.Reason == AppExitReason.Quit)
|
if (result.Reason == AppExitReason.Quit)
|
||||||
|
|||||||
@ -10,28 +10,20 @@ internal sealed record MenuItem(string Display, string Value);
|
|||||||
public enum AppExitReason { Quit, SwitchProject }
|
public enum AppExitReason { Quit, SwitchProject }
|
||||||
public sealed record AppResult(AppExitReason Reason, string? NewProjectRoot = null);
|
public sealed record AppResult(AppExitReason Reason, string? NewProjectRoot = null);
|
||||||
|
|
||||||
public sealed class App
|
public sealed class App(
|
||||||
|
DevToolConfig config,
|
||||||
|
string projectRoot,
|
||||||
|
WorkspaceConfig? workspace = null,
|
||||||
|
string? workspaceRoot = null)
|
||||||
{
|
{
|
||||||
private DevToolConfig _config;
|
private DevToolConfig _config = config;
|
||||||
private string _projectRoot;
|
private string _projectRoot = projectRoot;
|
||||||
private readonly WorkspaceConfig? _workspace;
|
private readonly WorkspaceConfig? _workspace = workspace;
|
||||||
private readonly string? _workspaceRoot;
|
private readonly string? _workspaceRoot = workspaceRoot;
|
||||||
|
|
||||||
private IReadOnlyDictionary<string, BuildTarget> TargetMap =>
|
private IReadOnlyDictionary<string, BuildTarget> TargetMap =>
|
||||||
_config.Targets.ToDictionary(t => t.Id, StringComparer.OrdinalIgnoreCase);
|
_config.Targets.ToDictionary(t => t.Id, StringComparer.OrdinalIgnoreCase);
|
||||||
|
|
||||||
public App(
|
|
||||||
DevToolConfig config,
|
|
||||||
string projectRoot,
|
|
||||||
WorkspaceConfig? workspace = null,
|
|
||||||
string? workspaceRoot = null)
|
|
||||||
{
|
|
||||||
_config = config;
|
|
||||||
_projectRoot = projectRoot;
|
|
||||||
_workspace = workspace;
|
|
||||||
_workspaceRoot = workspaceRoot;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<AppResult> RunAsync()
|
public async Task<AppResult> RunAsync()
|
||||||
{
|
{
|
||||||
while (true)
|
while (true)
|
||||||
|
|||||||
@ -10,34 +10,34 @@ namespace Sdt.Tui;
|
|||||||
internal static class Theme
|
internal static class Theme
|
||||||
{
|
{
|
||||||
// ── Hex colour constants (use in Spectre markup strings) ─────────────────
|
// ── Hex colour constants (use in Spectre markup strings) ─────────────────
|
||||||
public const string Green = "#00ff41"; // primary phosphor — all normal text
|
public const string Green = "#00ff41"; // primary phosphor — all normal text
|
||||||
public const string GreenDim = "#005c1b"; // muted — borders, secondary info
|
public const string GreenDim = "#005c1b"; // muted — borders, secondary info
|
||||||
public const string GreenBold = "#a8ff90"; // bright — selections, emphasis
|
public const string GreenBold = "#a8ff90"; // bright — selections, emphasis
|
||||||
public const string Amber = "#ffb300"; // warnings / group titles
|
public const string Amber = "#ffb300"; // warnings / group titles
|
||||||
public const string Red = "#ff4040"; // errors
|
public const string Red = "#ff4040"; // errors
|
||||||
public const string Ghost = "#003d12"; // near-invisible — decorative scanlines
|
public const string Ghost = "#003d12"; // near-invisible — decorative scanlines
|
||||||
|
|
||||||
// ── Spectre Color instances (for FigletText, Rule styles, etc.) ──────────
|
// ── Spectre Color instances (for FigletText, Rule styles, etc.) ──────────
|
||||||
public static readonly Color GreenColor = new(0, 255, 65);
|
public static readonly Color GreenColor = new(0, 255, 65);
|
||||||
public static readonly Color GreenDimColor = new(0, 92, 27);
|
public static readonly Color GreenDimColor = new(0, 92, 27);
|
||||||
public static readonly Color GreenBoldColor = new(168, 255, 144);
|
public static readonly Color GreenBoldColor = new(168, 255, 144);
|
||||||
public static readonly Color AmberColor = new(255, 179, 0);
|
public static readonly Color AmberColor = new(255, 179, 0);
|
||||||
public static readonly Color RedColor = new(255, 64, 64);
|
public static readonly Color RedColor = new(255, 64, 64);
|
||||||
|
|
||||||
// ── Pre-built Style objects ───────────────────────────────────────────────
|
// ── Pre-built Style objects ───────────────────────────────────────────────
|
||||||
public static readonly Style PrimaryStyle = new(GreenColor);
|
public static readonly Style PrimaryStyle = new(GreenColor);
|
||||||
public static readonly Style DimStyle = new(GreenDimColor);
|
public static readonly Style DimStyle = new(GreenDimColor);
|
||||||
public static readonly Style BrightStyle = new(GreenBoldColor, decoration: Decoration.Bold);
|
public static readonly Style BrightStyle = new(GreenBoldColor, decoration: Decoration.Bold);
|
||||||
public static readonly Style AmberStyle = new(AmberColor);
|
public static readonly Style AmberStyle = new(AmberColor);
|
||||||
public static readonly Style RedStyle = new(RedColor, decoration: Decoration.Bold);
|
public static readonly Style RedStyle = new(RedColor, decoration: Decoration.Bold);
|
||||||
|
|
||||||
// ── Markup helper methods (auto-escape user content) ─────────────────────
|
// ── Markup helper methods (auto-escape user content) ─────────────────────
|
||||||
public static string G(string t) => $"[{Green}]{Markup.Escape(t)}[/]";
|
public static string G(string t) => $"[{Green}]{Markup.Escape(t)}[/]";
|
||||||
public static string Faint(string t) => $"[{GreenDim}]{Markup.Escape(t)}[/]";
|
public static string Faint(string t) => $"[{GreenDim}]{Markup.Escape(t)}[/]";
|
||||||
public static string Bold(string t) => $"[bold {GreenBold}]{Markup.Escape(t)}[/]";
|
public static string Bold(string t) => $"[bold {GreenBold}]{Markup.Escape(t)}[/]";
|
||||||
public static string Warn(string t) => $"[{Amber}]{Markup.Escape(t)}[/]";
|
public static string Warn(string t) => $"[{Amber}]{Markup.Escape(t)}[/]";
|
||||||
public static string Err(string t) => $"[bold {Red}]{Markup.Escape(t)}[/]";
|
public static string Err(string t) => $"[bold {Red}]{Markup.Escape(t)}[/]";
|
||||||
public static string Ok(string t) => $"[bold {Green}]✓ {Markup.Escape(t)}[/]";
|
public static string Ok(string t) => $"[bold {Green}]✓ {Markup.Escape(t)}[/]";
|
||||||
public static string Fail(string t) => $"[bold {Red}]✗ {Markup.Escape(t)}[/]";
|
public static string Fail(string t) => $"[bold {Red}]✗ {Markup.Escape(t)}[/]";
|
||||||
|
|
||||||
// ── Shared UI components ──────────────────────────────────────────────────
|
// ── Shared UI components ──────────────────────────────────────────────────
|
||||||
|
|||||||
@ -5,16 +5,10 @@ using Spectre.Console;
|
|||||||
|
|
||||||
namespace Sdt.Tui;
|
namespace Sdt.Tui;
|
||||||
|
|
||||||
public sealed class ToolchainScreen
|
public sealed class ToolchainScreen(DevToolConfig config, string projectRoot)
|
||||||
{
|
{
|
||||||
private readonly DevToolConfig _config;
|
private readonly DevToolConfig _config = config;
|
||||||
private readonly string _projectRoot;
|
private readonly string _projectRoot = projectRoot;
|
||||||
|
|
||||||
public ToolchainScreen(DevToolConfig config, string projectRoot)
|
|
||||||
{
|
|
||||||
_config = config;
|
|
||||||
_projectRoot = projectRoot;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task RunAsync()
|
public async Task RunAsync()
|
||||||
{
|
{
|
||||||
@ -83,8 +77,8 @@ public sealed class ToolchainScreen
|
|||||||
{
|
{
|
||||||
switch (action)
|
switch (action)
|
||||||
{
|
{
|
||||||
case "py:check": await CheckPythonAsync(tc.Python!); break;
|
case "py:check": await CheckPythonAsync(tc.Python!); break;
|
||||||
case "py:venv": await CreateVenvAsync(tc.Python!); break;
|
case "py:venv": await CreateVenvAsync(tc.Python!); break;
|
||||||
case "py:install": await InstallProfileAsync(tc.Python!); break;
|
case "py:install": await InstallProfileAsync(tc.Python!); break;
|
||||||
case "py:upgradepip": await UpgradePipAsync(tc.Python!); break;
|
case "py:upgradepip": await UpgradePipAsync(tc.Python!); break;
|
||||||
case "node:check": await CheckNodeAsync(tc.Node!); break;
|
case "node:check": await CheckNodeAsync(tc.Node!); break;
|
||||||
@ -208,7 +202,7 @@ public sealed class ToolchainScreen
|
|||||||
AnsiConsole.MarkupLine(Theme.Faint($"Post-install: {cmd}"));
|
AnsiConsole.MarkupLine(Theme.Faint($"Post-install: {cmd}"));
|
||||||
var parts = cmd.Split(' ', 2);
|
var parts = cmd.Split(' ', 2);
|
||||||
var postArgs = parts.Length > 1 ? parts[1].Split(' ') : Array.Empty<string>();
|
var postArgs = parts.Length > 1 ? parts[1].Split(' ') : Array.Empty<string>();
|
||||||
await RunLiveAsync(venvPy, ["-m", ..postArgs], _projectRoot);
|
await RunLiveAsync(venvPy, ["-m", .. postArgs], _projectRoot);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -263,7 +257,7 @@ public sealed class ToolchainScreen
|
|||||||
|
|
||||||
// ── Helpers ───────────────────────────────────────────────────────────────
|
// ── Helpers ───────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
private string ResolvePythonExe(PythonToolchain py)
|
private static string ResolvePythonExe(PythonToolchain py)
|
||||||
{
|
{
|
||||||
if (OperatingSystem.IsWindows() && !string.IsNullOrWhiteSpace(py.WindowsExecutable))
|
if (OperatingSystem.IsWindows() && !string.IsNullOrWhiteSpace(py.WindowsExecutable))
|
||||||
return py.WindowsExecutable;
|
return py.WindowsExecutable;
|
||||||
|
|||||||
@ -3,18 +3,11 @@ using Spectre.Console;
|
|||||||
|
|
||||||
namespace Sdt.Tui;
|
namespace Sdt.Tui;
|
||||||
|
|
||||||
public sealed class WorkspaceScreen
|
public sealed class WorkspaceScreen(WorkspaceConfig workspace, string workspaceRoot, string currentProjectRoot)
|
||||||
{
|
{
|
||||||
private readonly WorkspaceConfig _workspace;
|
private readonly WorkspaceConfig _workspace = workspace;
|
||||||
private readonly string _workspaceRoot;
|
private readonly string _workspaceRoot = workspaceRoot;
|
||||||
private readonly string _currentProjectRoot;
|
private readonly string _currentProjectRoot = currentProjectRoot;
|
||||||
|
|
||||||
public WorkspaceScreen(WorkspaceConfig workspace, string workspaceRoot, string currentProjectRoot)
|
|
||||||
{
|
|
||||||
_workspace = workspace;
|
|
||||||
_workspaceRoot = workspaceRoot;
|
|
||||||
_currentProjectRoot = currentProjectRoot;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Shows the project switcher. Returns the absolute path to the selected project root,
|
/// Shows the project switcher. Returns the absolute path to the selected project root,
|
||||||
|
|||||||
@ -3,4 +3,5 @@
|
|||||||
<Project Path="Journal.Sidecar/Journal.Sidecar.csproj" />
|
<Project Path="Journal.Sidecar/Journal.Sidecar.csproj" />
|
||||||
<Project Path="Journal.SmokeTests/Journal.SmokeTests.csproj" />
|
<Project Path="Journal.SmokeTests/Journal.SmokeTests.csproj" />
|
||||||
<Project Path="Journal.DevTool/Journal.DevTool.csproj" />
|
<Project Path="Journal.DevTool/Journal.DevTool.csproj" />
|
||||||
|
<Project Path="Journal.WebGateway/Journal.WebGateway.csproj" />
|
||||||
</Solution>
|
</Solution>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user