SOLID refactoring: Abstract prerequisite checks into IPrerequisiteVerifier to bypass physical OS checks and fix Gitea CI/CD test run
Build and Test / build (push) Successful in 1m14s
Build and Test / build (push) Successful in 1m14s
This commit is contained in:
+1
-1
@@ -14,7 +14,7 @@ All future modifications to the `NixWslWrapper` solution must adhere to the foll
|
|||||||
* **SOLID Principles**:
|
* **SOLID Principles**:
|
||||||
* *Single Responsibility (SRP)*: Keep execution strategies, builders, stream copiers, and CLI formatting separated.
|
* *Single Responsibility (SRP)*: Keep execution strategies, builders, stream copiers, and CLI formatting separated.
|
||||||
* *Open/Closed (OCP)*: If we need execution methods other than WSL (e.g. SSH, Local), implement a new strategy implementing `ICommandExecutor` rather than modifying `WslCommandExecutor`.
|
* *Open/Closed (OCP)*: If we need execution methods other than WSL (e.g. SSH, Local), implement a new strategy implementing `ICommandExecutor` rather than modifying `WslCommandExecutor`.
|
||||||
* *Dependency Inversion (DIP)*: Inject interfaces (`ICommandExecutor`, `IStreamCopier`) and stream abstractions (`Stream`) to facilitate seamless unit testing and mock assertions.
|
* *Dependency Inversion (DIP)*: Inject interfaces (`ICommandExecutor`, `IStreamCopier`, `IPrerequisiteVerifier`) and stream abstractions (`Stream`) to facilitate seamless unit testing and mock assertions without hitting physical OS or environmental components.
|
||||||
* **Visual UI/UX Check**:
|
* **Visual UI/UX Check**:
|
||||||
* For CLI diagnostics, use `Spectre.Console` markup (`[color]...[/]`) to color-code output. Always escape literal brackets by doubling them (`[[literal-text]]`) to prevent parser errors.
|
* For CLI diagnostics, use `Spectre.Console` markup (`[color]...[/]`) to color-code output. Always escape literal brackets by doubling them (`[[literal-text]]`) to prevent parser errors.
|
||||||
* Render a rich dashboard with `FigletText` and `Table` grids when administrative diagnostics are run (e.g. `--wsl-status`).
|
* Render a rich dashboard with `FigletText` and `Table` grids when administrative diagnostics are run (e.g. `--wsl-status`).
|
||||||
|
|||||||
@@ -10,10 +10,12 @@ namespace NixWslWrapper.Cli
|
|||||||
public class CliController
|
public class CliController
|
||||||
{
|
{
|
||||||
private readonly ICommandExecutor _commandExecutor;
|
private readonly ICommandExecutor _commandExecutor;
|
||||||
|
private readonly IPrerequisiteVerifier _prerequisiteVerifier;
|
||||||
|
|
||||||
public CliController(ICommandExecutor commandExecutor)
|
public CliController(ICommandExecutor commandExecutor, IPrerequisiteVerifier prerequisiteVerifier)
|
||||||
{
|
{
|
||||||
_commandExecutor = commandExecutor ?? throw new ArgumentNullException(nameof(commandExecutor));
|
_commandExecutor = commandExecutor ?? throw new ArgumentNullException(nameof(commandExecutor));
|
||||||
|
_prerequisiteVerifier = prerequisiteVerifier ?? throw new ArgumentNullException(nameof(prerequisiteVerifier));
|
||||||
}
|
}
|
||||||
|
|
||||||
public int Run(string[] args)
|
public int Run(string[] args)
|
||||||
@@ -38,7 +40,7 @@ namespace NixWslWrapper.Cli
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
PrerequisiteManager.EnsurePrerequisites(distro, user, profile);
|
_prerequisiteVerifier.EnsurePrerequisites(distro, user, profile);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ using Microsoft.Extensions.DependencyInjection;
|
|||||||
using NixWslWrapper.Core.Interfaces;
|
using NixWslWrapper.Core.Interfaces;
|
||||||
using NixWslWrapper.Infrastructure.IO;
|
using NixWslWrapper.Infrastructure.IO;
|
||||||
using NixWslWrapper.Infrastructure.Executors;
|
using NixWslWrapper.Infrastructure.Executors;
|
||||||
|
using NixWslWrapper.Infrastructure.Services;
|
||||||
|
|
||||||
namespace NixWslWrapper.Cli
|
namespace NixWslWrapper.Cli
|
||||||
{
|
{
|
||||||
@@ -20,6 +21,7 @@ namespace NixWslWrapper.Cli
|
|||||||
return new ServiceCollection()
|
return new ServiceCollection()
|
||||||
.AddSingleton<IStreamCopier, ThreadedStreamCopier>()
|
.AddSingleton<IStreamCopier, ThreadedStreamCopier>()
|
||||||
.AddSingleton<ICommandExecutor, WslCommandExecutor>()
|
.AddSingleton<ICommandExecutor, WslCommandExecutor>()
|
||||||
|
.AddSingleton<IPrerequisiteVerifier, WslPrerequisiteVerifier>()
|
||||||
.AddSingleton<CliController>()
|
.AddSingleton<CliController>()
|
||||||
.BuildServiceProvider();
|
.BuildServiceProvider();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
namespace NixWslWrapper.Core.Interfaces
|
||||||
|
{
|
||||||
|
public interface IPrerequisiteVerifier
|
||||||
|
{
|
||||||
|
void EnsurePrerequisites(string distro, string user, string profilePath);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,6 +4,10 @@
|
|||||||
<ProjectReference Include="..\NixWslWrapper.Core\NixWslWrapper.Core.csproj" />
|
<ProjectReference Include="..\NixWslWrapper.Core\NixWslWrapper.Core.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Spectre.Console" Version="0.57.1" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net10.0</TargetFramework>
|
<TargetFramework>net10.0</TargetFramework>
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
|||||||
+7
-6
@@ -2,20 +2,21 @@ using System;
|
|||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using NixWslWrapper.Core.Interfaces;
|
||||||
using Spectre.Console;
|
using Spectre.Console;
|
||||||
|
|
||||||
namespace NixWslWrapper.Cli
|
namespace NixWslWrapper.Infrastructure.Services
|
||||||
{
|
{
|
||||||
public class PrerequisiteManager
|
public class WslPrerequisiteVerifier : IPrerequisiteVerifier
|
||||||
{
|
{
|
||||||
public static void EnsurePrerequisites(string distro, string user, string profilePath)
|
public void EnsurePrerequisites(string distro, string user, string profilePath)
|
||||||
{
|
{
|
||||||
EnsurePathRegistered();
|
EnsurePathRegistered();
|
||||||
EnsureWslAndDistro(distro);
|
EnsureWslAndDistro(distro);
|
||||||
EnsureNix(distro, user, profilePath);
|
EnsureNix(distro, user, profilePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void EnsurePathRegistered()
|
private void EnsurePathRegistered()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -55,7 +56,7 @@ namespace NixWslWrapper.Cli
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void EnsureWslAndDistro(string distro)
|
private void EnsureWslAndDistro(string distro)
|
||||||
{
|
{
|
||||||
// 1. Check if wsl.exe exists
|
// 1. Check if wsl.exe exists
|
||||||
bool wslExists = false;
|
bool wslExists = false;
|
||||||
@@ -146,7 +147,7 @@ namespace NixWslWrapper.Cli
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void EnsureNix(string distro, string user, string profilePath)
|
private void EnsureNix(string distro, string user, string profilePath)
|
||||||
{
|
{
|
||||||
bool nixInstalled = false;
|
bool nixInstalled = false;
|
||||||
try
|
try
|
||||||
@@ -13,12 +13,13 @@ namespace NixWslWrapper.Tests
|
|||||||
public void CliController_ForwardArguments_ShouldReturnExecutorExitCode()
|
public void CliController_ForwardArguments_ShouldReturnExecutorExitCode()
|
||||||
{
|
{
|
||||||
var mockExecutor = new Mock<ICommandExecutor>();
|
var mockExecutor = new Mock<ICommandExecutor>();
|
||||||
|
var mockVerifier = new Mock<IPrerequisiteVerifier>();
|
||||||
var expectedResult = new ExecutionResult(42);
|
var expectedResult = new ExecutionResult(42);
|
||||||
mockExecutor
|
mockExecutor
|
||||||
.Setup(m => m.Execute(It.IsAny<NixArguments>(), It.IsAny<WslTarget>()))
|
.Setup(m => m.Execute(It.IsAny<NixArguments>(), It.IsAny<WslTarget>()))
|
||||||
.Returns(expectedResult);
|
.Returns(expectedResult);
|
||||||
|
|
||||||
var controller = new CliController(mockExecutor.Object);
|
var controller = new CliController(mockExecutor.Object, mockVerifier.Object);
|
||||||
string[] cliArgs = new[] { "run", "nixpkgs#hello" };
|
string[] cliArgs = new[] { "run", "nixpkgs#hello" };
|
||||||
|
|
||||||
int exitCode = controller.Run(cliArgs);
|
int exitCode = controller.Run(cliArgs);
|
||||||
@@ -34,7 +35,8 @@ namespace NixWslWrapper.Tests
|
|||||||
public void CliController_HelpMenuFlag_ShouldReturnZeroImmediately()
|
public void CliController_HelpMenuFlag_ShouldReturnZeroImmediately()
|
||||||
{
|
{
|
||||||
var mockExecutor = new Mock<ICommandExecutor>();
|
var mockExecutor = new Mock<ICommandExecutor>();
|
||||||
var controller = new CliController(mockExecutor.Object);
|
var mockVerifier = new Mock<IPrerequisiteVerifier>();
|
||||||
|
var controller = new CliController(mockExecutor.Object, mockVerifier.Object);
|
||||||
string[] cliArgs = new[] { "--wsl-help" };
|
string[] cliArgs = new[] { "--wsl-help" };
|
||||||
|
|
||||||
int exitCode = controller.Run(cliArgs);
|
int exitCode = controller.Run(cliArgs);
|
||||||
|
|||||||
Reference in New Issue
Block a user