Upgrade projects to .NET 10 and implement automatic prerequisites check/installation and PATH registration
Build and Test / build (push) Failing after 41s
Build and Test / build (push) Failing after 41s
This commit is contained in:
@@ -10,7 +10,7 @@ jobs:
|
|||||||
build:
|
build:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
container:
|
container:
|
||||||
image: mcr.microsoft.com/dotnet/sdk:8.0
|
image: mcr.microsoft.com/dotnet/sdk:10.0
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v3
|
||||||
|
|||||||
@@ -36,6 +36,16 @@ namespace NixWslWrapper.Cli
|
|||||||
string user = Environment.GetEnvironmentVariable("NIX_WSL_USER") ?? "root";
|
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";
|
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;
|
WslTarget target;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<OutputType>Exe</OutputType>
|
<OutputType>Exe</OutputType>
|
||||||
<TargetFramework>net8.0</TargetFramework>
|
<TargetFramework>net10.0</TargetFramework>
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
<AssemblyName>nix</AssemblyName>
|
<AssemblyName>nix</AssemblyName>
|
||||||
|
|||||||
@@ -0,0 +1,210 @@
|
|||||||
|
using System;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using Spectre.Console;
|
||||||
|
|
||||||
|
namespace NixWslWrapper.Cli
|
||||||
|
{
|
||||||
|
public class PrerequisiteManager
|
||||||
|
{
|
||||||
|
public static void EnsurePrerequisites(string distro, string user, string profilePath)
|
||||||
|
{
|
||||||
|
EnsurePathRegistered();
|
||||||
|
EnsureWslAndDistro(distro);
|
||||||
|
EnsureNix(distro, user, profilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void EnsurePathRegistered()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
string currentExeDir = Path.GetDirectoryName(Process.GetCurrentProcess().MainModule?.FileName) ?? AppContext.BaseDirectory;
|
||||||
|
currentExeDir = Path.GetFullPath(currentExeDir).TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar);
|
||||||
|
|
||||||
|
string? userPath = Environment.GetEnvironmentVariable("PATH", EnvironmentVariableTarget.User);
|
||||||
|
var paths = (userPath ?? "")
|
||||||
|
.Split(';', StringSplitOptions.RemoveEmptyEntries)
|
||||||
|
.Select(p => Path.GetFullPath(p.Trim()).TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar))
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
if (!paths.Any(p => string.Equals(p, currentExeDir, StringComparison.OrdinalIgnoreCase)))
|
||||||
|
{
|
||||||
|
string newPath = string.IsNullOrWhiteSpace(userPath)
|
||||||
|
? currentExeDir
|
||||||
|
: userPath.TrimEnd(';') + ";" + currentExeDir;
|
||||||
|
|
||||||
|
Environment.SetEnvironmentVariable("PATH", newPath, EnvironmentVariableTarget.User);
|
||||||
|
|
||||||
|
var pathPanel = new Panel(new Markup(
|
||||||
|
$"[bold yellow]PATH Updated:[/] Added [green]\"{currentExeDir}\"[/] to your Windows User PATH.\n" +
|
||||||
|
"Please [bold]restart your terminal, MCP servers, or IDE[/] for changes to take effect."
|
||||||
|
))
|
||||||
|
{
|
||||||
|
Border = BoxBorder.Rounded,
|
||||||
|
Padding = new Padding(1, 1, 1, 1),
|
||||||
|
Header = new PanelHeader("PATH Auto-Registration")
|
||||||
|
};
|
||||||
|
AnsiConsole.Write(pathPanel.BorderColor(Color.Yellow));
|
||||||
|
AnsiConsole.WriteLine();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
AnsiConsole.MarkupLine($"[yellow]Warning: Could not automatically register directory to PATH: {ex.Message}[/]");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void EnsureWslAndDistro(string distro)
|
||||||
|
{
|
||||||
|
// 1. Check if wsl.exe exists
|
||||||
|
bool wslExists = false;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var checkWsl = new ProcessStartInfo("wsl.exe", "--status")
|
||||||
|
{
|
||||||
|
UseShellExecute = false,
|
||||||
|
RedirectStandardOutput = true,
|
||||||
|
CreateNoWindow = true
|
||||||
|
};
|
||||||
|
using var p = Process.Start(checkWsl);
|
||||||
|
p?.WaitForExit(3000);
|
||||||
|
wslExists = p != null;
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
wslExists = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!wslExists)
|
||||||
|
{
|
||||||
|
var wslPanel = new Panel(new Markup(
|
||||||
|
$"[bold red]WSL Not Found:[/] WSL (Windows Subsystem for Linux) is not installed.\n" +
|
||||||
|
$"Triggering automatic installation of WSL and the [green]{distro}[/] distribution.\n\n" +
|
||||||
|
"[bold yellow]Please approve the administrator UAC prompt that appears.[/]"
|
||||||
|
))
|
||||||
|
{
|
||||||
|
Border = BoxBorder.Double,
|
||||||
|
Header = new PanelHeader("WSL Auto-Installation")
|
||||||
|
};
|
||||||
|
AnsiConsole.Write(wslPanel.BorderColor(Color.Red));
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var installPsi = new ProcessStartInfo("wsl.exe", $"--install -d {distro}")
|
||||||
|
{
|
||||||
|
UseShellExecute = true,
|
||||||
|
Verb = "runas" // Elevates to Administrator
|
||||||
|
};
|
||||||
|
using var p = Process.Start(installPsi);
|
||||||
|
p?.WaitForExit();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
AnsiConsole.MarkupLine($"[bold red]Failed to start WSL installation:[/] {ex.Message}");
|
||||||
|
throw new InvalidOperationException("WSL is required to run this wrapper.", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. Check if the specific distro is installed
|
||||||
|
bool distroInstalled = false;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var checkDistro = new ProcessStartInfo("wsl.exe", $"-d {distro} -u root -- echo check")
|
||||||
|
{
|
||||||
|
UseShellExecute = false,
|
||||||
|
RedirectStandardOutput = true,
|
||||||
|
RedirectStandardError = true,
|
||||||
|
CreateNoWindow = true
|
||||||
|
};
|
||||||
|
using var p = Process.Start(checkDistro);
|
||||||
|
p?.WaitForExit(4000);
|
||||||
|
distroInstalled = p?.ExitCode == 0;
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
distroInstalled = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!distroInstalled)
|
||||||
|
{
|
||||||
|
AnsiConsole.MarkupLine($"[yellow]WSL Distro [green]'{distro}'[/] is not registered. Installing it now...[/]");
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var distroPsi = new ProcessStartInfo("wsl.exe", $"--install -d {distro}")
|
||||||
|
{
|
||||||
|
UseShellExecute = true,
|
||||||
|
Verb = "runas"
|
||||||
|
};
|
||||||
|
using var p = Process.Start(distroPsi);
|
||||||
|
p?.WaitForExit();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException($"Failed to automatically install WSL distribution '{distro}': {ex.Message}", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void EnsureNix(string distro, string user, string profilePath)
|
||||||
|
{
|
||||||
|
bool nixInstalled = false;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var checkNix = new ProcessStartInfo("wsl.exe", $"-d {distro} -u {user} -- sh -c \"command -v nix\"")
|
||||||
|
{
|
||||||
|
UseShellExecute = false,
|
||||||
|
RedirectStandardOutput = true,
|
||||||
|
RedirectStandardError = true,
|
||||||
|
CreateNoWindow = true
|
||||||
|
};
|
||||||
|
using var p = Process.Start(checkNix);
|
||||||
|
p?.WaitForExit(4000);
|
||||||
|
nixInstalled = p?.ExitCode == 0;
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
nixInstalled = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!nixInstalled)
|
||||||
|
{
|
||||||
|
var nixPanel = new Panel(new Markup(
|
||||||
|
$"[bold yellow]Nix Engine Not Found:[/] Nix is not installed inside the [green]'{distro}'[/] distribution.\n" +
|
||||||
|
"Triggering automatic installation using the official Determinate Nix installer.\n\n" +
|
||||||
|
"[grey]This may take a few minutes. Please wait...[/]"
|
||||||
|
))
|
||||||
|
{
|
||||||
|
Border = BoxBorder.Rounded,
|
||||||
|
Header = new PanelHeader("Nix Auto-Installation")
|
||||||
|
};
|
||||||
|
AnsiConsole.Write(nixPanel.BorderColor(Color.Yellow));
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
string installCmd = "curl --proto '=https' --tlsv1.2 -sSf -L https://install.determinate.systems/nix | sh -s -- install --no-confirm";
|
||||||
|
var nixPsi = new ProcessStartInfo("wsl.exe", $"-d {distro} -u root -- sh -c \"{installCmd}\"")
|
||||||
|
{
|
||||||
|
UseShellExecute = false,
|
||||||
|
RedirectStandardOutput = false,
|
||||||
|
RedirectStandardError = false,
|
||||||
|
CreateNoWindow = false
|
||||||
|
};
|
||||||
|
using var p = Process.Start(nixPsi);
|
||||||
|
p?.WaitForExit();
|
||||||
|
|
||||||
|
if (p?.ExitCode != 0)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException($"Nix installer exited with non-zero code: {p?.ExitCode}");
|
||||||
|
}
|
||||||
|
|
||||||
|
AnsiConsole.MarkupLine("[green]✔ Nix installed successfully inside WSL![/]");
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException($"Failed to automatically install Nix inside WSL distro: {ex.Message}", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net8.0</TargetFramework>
|
<TargetFramework>net10.0</TargetFramework>
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\NixWslWrapper.Core\NixWslWrapper.Core.csproj" />
|
<ProjectReference Include="..\NixWslWrapper.Core\NixWslWrapper.Core.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net8.0</TargetFramework>
|
<TargetFramework>net10.0</TargetFramework>
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net8.0</TargetFramework>
|
<TargetFramework>net10.0</TargetFramework>
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user