Files
NixOS_WindowsWrapper/src/NixWslWrapper.Cli/CliController.cs
T
2026-07-01 02:10:35 +02:00

204 lines
9.0 KiB
C#

using System;
using System.Diagnostics;
using System.Linq;
using NixWslWrapper.Core.Domain;
using NixWslWrapper.Core.Interfaces;
using Spectre.Console;
namespace NixWslWrapper.Cli
{
public class CliController
{
private readonly ICommandExecutor _commandExecutor;
public CliController(ICommandExecutor commandExecutor)
{
_commandExecutor = commandExecutor ?? throw new ArgumentNullException(nameof(commandExecutor));
}
public int Run(string[] args)
{
// Intercept special configuration/status options
if (args.Contains("--wsl-status", StringComparer.OrdinalIgnoreCase))
{
RenderStatusDashboard();
return 0;
}
if (args.Contains("--wsl-help", StringComparer.OrdinalIgnoreCase))
{
RenderHelp();
return 0;
}
// Get configuration from environment variables or use defaults
string distro = Environment.GetEnvironmentVariable("NIX_WSL_DISTRO") ?? "Debian";
string user = Environment.GetEnvironmentVariable("NIX_WSL_USER") ?? "root";
string profile = Environment.GetEnvironmentVariable("NIX_WSL_PROFILE") ?? "/nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh";
try
{
PrerequisiteManager.EnsurePrerequisites(distro, user, profile);
}
catch (Exception ex)
{
AnsiConsole.MarkupLine($"[bold red]Prerequisite Check Failed:[/] {ex.Message}");
return 1;
}
WslTarget target;
try
{
target = new WslTarget(distro, user, profile);
}
catch (Exception ex)
{
AnsiConsole.MarkupLine($"[red]Configuration Error:[/] {ex.Message}");
return 1;
}
var nixArgs = new NixArguments(args);
var result = _commandExecutor.Execute(nixArgs, target);
if (!result.IsSuccess)
{
if (result.ErrorMessage != null)
{
AnsiConsole.MarkupLine($"[bold red]Execution Error:[/] {result.ErrorMessage}");
}
return result.ExitCode;
}
return result.ExitCode;
}
private static void RenderStatusDashboard()
{
AnsiConsole.Write(
new FigletText("Nix WSL Wrapper")
.Color(Color.DeepSkyBlue1));
var panel = new Panel(
new Markup(
"[bold]Nix WSL Wrapper Diagnostic Dashboard[/]\n" +
"Wraps native Windows MCP / CLI tool inputs and redirects them into Nix running inside WSL.\n\n" +
$"[grey]Generated at: {DateTime.Now:yyyy-MM-dd HH:mm:ss}[/]"
))
{
Border = BoxBorder.Rounded,
Padding = new Padding(1, 1, 1, 1),
Header = new PanelHeader("System Info")
};
AnsiConsole.Write(panel);
// Fetch Environment details
string distro = Environment.GetEnvironmentVariable("NIX_WSL_DISTRO") ?? "Debian (Default)";
string user = Environment.GetEnvironmentVariable("NIX_WSL_USER") ?? "root (Default)";
string profile = Environment.GetEnvironmentVariable("NIX_WSL_PROFILE") ?? "/nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh (Default)";
var table = new Table()
.Border(TableBorder.Rounded)
.BorderColor(Color.Grey)
.AddColumn("[bold]Setting[/]")
.AddColumn("[bold]Value[/]")
.AddColumn("[bold]Source[/]");
table.AddRow("WSL Target Distro", distro, Environment.GetEnvironmentVariable("NIX_WSL_DISTRO") != null ? "[green]Env Var[/]" : "[yellow]Fallback[/]");
table.AddRow("WSL Execution User", user, Environment.GetEnvironmentVariable("NIX_WSL_USER") != null ? "[green]Env Var[/]" : "[yellow]Fallback[/]");
table.AddRow("Nix Profile Path", profile, Environment.GetEnvironmentVariable("NIX_WSL_PROFILE") != null ? "[green]Env Var[/]" : "[yellow]Fallback[/]");
AnsiConsole.Write(new Rule("[yellow]Configured Parameters[/]") { Justification = Justify.Left });
AnsiConsole.Write(table);
// Run WSL check
AnsiConsole.Write(new Rule("[yellow]WSL Integration Status[/]") { Justification = Justify.Left });
AnsiConsole.Status()
.Spinner(Spinner.Known.Dots)
.Start("Verifying WSL and Nix installation...", ctx =>
{
bool wslOk = false;
string wslVersion = "Unknown";
try
{
var psi = new ProcessStartInfo("wsl.exe", "--status")
{
RedirectStandardOutput = true,
UseShellExecute = false,
CreateNoWindow = true
};
using var p = Process.Start(psi);
p?.WaitForExit(3000);
wslOk = p?.ExitCode == 0;
wslVersion = wslOk ? "WSL Active" : "WSL Error";
}
catch
{
wslVersion = "wsl.exe not found in PATH";
}
ctx.Status("Checking Nix inside WSL Distro...");
bool nixOk = false;
string nixVersion = "Not Found";
if (wslOk)
{
try
{
string targetDistro = Environment.GetEnvironmentVariable("NIX_WSL_DISTRO") ?? "Debian";
string targetUser = Environment.GetEnvironmentVariable("NIX_WSL_USER") ?? "root";
string targetProfile = Environment.GetEnvironmentVariable("NIX_WSL_PROFILE") ?? "/nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh";
var psi = new ProcessStartInfo("wsl.exe", $"-d {targetDistro} -u {targetUser} -- sh -c \". {targetProfile} && nix --version\"")
{
RedirectStandardOutput = true,
RedirectStandardError = true,
UseShellExecute = false,
CreateNoWindow = true
};
using var p = Process.Start(psi);
p?.WaitForExit(5000);
if (p?.ExitCode == 0)
{
nixOk = true;
nixVersion = p.StandardOutput.ReadToEnd().Trim();
}
else
{
nixVersion = "Nix execution failed inside WSL";
}
}
catch (Exception ex)
{
nixVersion = $"Error querying: {ex.Message}";
}
}
// Render Checks
var grid = new Grid().AddColumn().AddColumn();
grid.AddRow(new Markup("wsl.exe Executable Status:"), wslOk ? new Markup("[green]✔ OK[/]") : new Markup($"[red]✘ FAILED ({wslVersion})[/]"));
grid.AddRow(new Markup("Nix Engine in WSL Distro:"), nixOk ? new Markup($"[green]✔ OK ({nixVersion})[/]") : new Markup($"[red]✘ FAILED ({nixVersion})[/]"));
AnsiConsole.Write(new Panel(grid) { Border = BoxBorder.None });
});
}
private static void RenderHelp()
{
AnsiConsole.Write(
new FigletText("Nix WSL Wrapper")
.Color(Color.DeepSkyBlue1));
AnsiConsole.MarkupLine("[bold]Usage:[/] nix.exe [[nix-arguments-to-forward]]");
AnsiConsole.MarkupLine("[bold]Alternative flags (Wrapper specific):[/]");
AnsiConsole.MarkupLine(" [yellow]--wsl-status[/] Displays diagnostic status of WSL and Nix integration.");
AnsiConsole.MarkupLine(" [yellow]--wsl-help[/] Displays this help menu.");
AnsiConsole.WriteLine();
AnsiConsole.MarkupLine("[bold]Configuration Environment Variables:[/]");
AnsiConsole.MarkupLine(" [green]NIX_WSL_DISTRO[/] The target WSL distribution name (default: [grey]Debian[/]).");
AnsiConsole.MarkupLine(" [green]NIX_WSL_USER[/] The user to execute commands under (default: [grey]root[/]).");
AnsiConsole.MarkupLine(" [green]NIX_WSL_PROFILE[/] The path to the nix-daemon profile script (default: [grey]/nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh[/]).");
}
}
}