From aea21a4cdcace456d93030a7c98d200f0f646ee5 Mon Sep 17 00:00:00 2001 From: Mateus Rodrigues de Morais Date: Thu, 10 Oct 2024 12:09:52 -0300 Subject: [PATCH] feat: add InvocationResult return type to Terminal class --- .../Services/Contracts/ISnapService.cs | 6 +-- .../Services/Contracts/ISystemdService.cs | 10 ++--- .../Services/Implementations/SnapService.cs | 16 ++++---- .../Implementations/SystemdService.cs | 27 ++++++------- .../Types/InvocationResult.cs | 8 ---- src/Dotnet.Installer.Core/Types/Terminal.cs | 38 +++++++++++++++++-- .../Models/ComponentTests.cs | 36 +++++++++--------- 7 files changed, 79 insertions(+), 62 deletions(-) delete mode 100644 src/Dotnet.Installer.Core/Types/InvocationResult.cs diff --git a/src/Dotnet.Installer.Core/Services/Contracts/ISnapService.cs b/src/Dotnet.Installer.Core/Services/Contracts/ISnapService.cs index ee4453c..4abb69e 100644 --- a/src/Dotnet.Installer.Core/Services/Contracts/ISnapService.cs +++ b/src/Dotnet.Installer.Core/Services/Contracts/ISnapService.cs @@ -5,6 +5,6 @@ namespace Dotnet.Installer.Core.Services.Contracts; public interface ISnapService { bool IsSnapInstalled(string name, CancellationToken cancellationToken = default); - Task Install(string name, CancellationToken cancellationToken = default); - Task Remove(string name, bool purge = false, CancellationToken cancellationToken = default); -} \ No newline at end of file + Task Install(string name, CancellationToken cancellationToken = default); + Task Remove(string name, bool purge = false, CancellationToken cancellationToken = default); +} diff --git a/src/Dotnet.Installer.Core/Services/Contracts/ISystemdService.cs b/src/Dotnet.Installer.Core/Services/Contracts/ISystemdService.cs index 59a6593..916ed99 100644 --- a/src/Dotnet.Installer.Core/Services/Contracts/ISystemdService.cs +++ b/src/Dotnet.Installer.Core/Services/Contracts/ISystemdService.cs @@ -4,9 +4,9 @@ namespace Dotnet.Installer.Core.Services.Contracts; public interface ISystemdService { - Task DaemonReload(); - Task EnableUnit(string unit); - Task DisableUnit(string unit); - Task StartUnit(string unit); - Task StopUnit(string unit); + Task DaemonReload(); + Task EnableUnit(string unit); + Task DisableUnit(string unit); + Task StartUnit(string unit); + Task StopUnit(string unit); } diff --git a/src/Dotnet.Installer.Core/Services/Implementations/SnapService.cs b/src/Dotnet.Installer.Core/Services/Implementations/SnapService.cs index 508408d..a5b585e 100644 --- a/src/Dotnet.Installer.Core/Services/Implementations/SnapService.cs +++ b/src/Dotnet.Installer.Core/Services/Implementations/SnapService.cs @@ -10,23 +10,21 @@ public bool IsSnapInstalled(string name, CancellationToken cancellationToken = d return Directory.Exists(Path.Combine("/", "snap", name)); } - public async Task Install(string name, CancellationToken cancellationToken = default) + public Task Install(string name, CancellationToken cancellationToken = default) { - var result = await Terminal.Invoke("snap", "install", name); - return new InvocationResult(result == 0, "", ""); + return Terminal.Invoke("snap", "install", name); } - public async Task Remove(string name, bool purge = false, CancellationToken cancellationToken = default) + public Task Remove(string name, bool purge = false, CancellationToken cancellationToken = default) { var arguments = new List { "remove" }; - + if (purge) arguments.Add("--purge"); arguments.Add(name); - - var result = await Terminal.Invoke("snap", arguments.ToArray()); - return new InvocationResult(result == 0, "", ""); + + return Terminal.Invoke("snap", arguments.ToArray()); } -} \ No newline at end of file +} diff --git a/src/Dotnet.Installer.Core/Services/Implementations/SystemdService.cs b/src/Dotnet.Installer.Core/Services/Implementations/SystemdService.cs index 4ca920c..c396684 100644 --- a/src/Dotnet.Installer.Core/Services/Implementations/SystemdService.cs +++ b/src/Dotnet.Installer.Core/Services/Implementations/SystemdService.cs @@ -10,34 +10,29 @@ public class SystemdService : ISystemdService RedirectStandardError = true, RedirectStandardOutput = true, }; - - public async Task DaemonReload() + + public Task DaemonReload() { - var result = await Terminal.Invoke("systemctl", _globalSystemdOptions, "daemon-reload"); - return new InvocationResult(result == 0, string.Empty, string.Empty); + return Terminal.Invoke("systemctl", _globalSystemdOptions, "daemon-reload"); } - public async Task EnableUnit(string unit) + public Task EnableUnit(string unit) { - var result = await Terminal.Invoke("systemctl", _globalSystemdOptions, "enable", unit); - return new InvocationResult(result == 0, string.Empty, string.Empty); + return Terminal.Invoke("systemctl", _globalSystemdOptions, "enable", unit); } - public async Task DisableUnit(string unit) + public Task DisableUnit(string unit) { - var result = await Terminal.Invoke("systemctl", _globalSystemdOptions, "disable", unit); - return new InvocationResult(result == 0, string.Empty, string.Empty); + return Terminal.Invoke("systemctl", _globalSystemdOptions, "disable", unit); } - public async Task StartUnit(string unit) + public Task StartUnit(string unit) { - var result = await Terminal.Invoke("systemctl", _globalSystemdOptions, "start", unit); - return new InvocationResult(result == 0, string.Empty, string.Empty); + return Terminal.Invoke("systemctl", _globalSystemdOptions, "start", unit); } - public async Task StopUnit(string unit) + public Task StopUnit(string unit) { - var result = await Terminal.Invoke("systemctl", _globalSystemdOptions, "stop", unit); - return new InvocationResult(result == 0, string.Empty, string.Empty); + return Terminal.Invoke("systemctl", _globalSystemdOptions, "stop", unit); } } diff --git a/src/Dotnet.Installer.Core/Types/InvocationResult.cs b/src/Dotnet.Installer.Core/Types/InvocationResult.cs deleted file mode 100644 index 93a2c2a..0000000 --- a/src/Dotnet.Installer.Core/Types/InvocationResult.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace Dotnet.Installer.Core.Types; - -public class InvocationResult(bool isSuccess, string standardOutput, string standardError) -{ - public bool IsSuccess { get; init; } = isSuccess; - public string StandardOutput { get; init; } = standardOutput; - public string StandardError { get; init; } = standardError; -} \ No newline at end of file diff --git a/src/Dotnet.Installer.Core/Types/Terminal.cs b/src/Dotnet.Installer.Core/Types/Terminal.cs index 25c6fac..28ec614 100644 --- a/src/Dotnet.Installer.Core/Types/Terminal.cs +++ b/src/Dotnet.Installer.Core/Types/Terminal.cs @@ -4,12 +4,12 @@ namespace Dotnet.Installer.Core.Types; public static class Terminal { - public static async Task Invoke(string program, params string[] arguments) + public static async Task Invoke(string program, params string[] arguments) { return await Invoke(program, options: null, arguments); } - public static async Task Invoke(string program, InvocationOptions? options = default, + public static async Task Invoke(string program, InvocationOptions? options = default, params string[] arguments) { options ??= InvocationOptions.Default; @@ -28,7 +28,16 @@ public static async Task Invoke(string program, InvocationOptions? options process.Start(); await process.WaitForExitAsync(); - return process.ExitCode; + return new InvocationResult + { + ExitCode = process.ExitCode, + RedirectedStandardError = options.RedirectStandardError, + RedirectedStandardOutput = options.RedirectStandardOutput, + StandardError = options.RedirectStandardError ? + await process.StandardError.ReadToEndAsync() : default, + StandardOutput = options.RedirectStandardOutput ? + await process.StandardOutput.ReadToEndAsync() : default + }; } public class InvocationOptions @@ -38,4 +47,27 @@ public class InvocationOptions public bool RedirectStandardOutput { get; set; } = false; public bool RedirectStandardError { get; set; } = false; } + + public class InvocationResult + { + public InvocationResult() + { } + + public InvocationResult(int exitCode, string standardOutput, string standardError) + { + ExitCode = exitCode; + StandardOutput = standardOutput; + StandardError = standardError; + + RedirectedStandardError = true; + RedirectedStandardOutput = true; + } + + public bool IsSuccess => ExitCode == 0; + public int ExitCode { get; init; } + public bool RedirectedStandardOutput { get; init; } + public bool RedirectedStandardError { get; init; } + public string? StandardOutput { get; init; } + public string? StandardError { get; init; } + } } diff --git a/tests/Dotnet.Installer.Core.Tests/Models/ComponentTests.cs b/tests/Dotnet.Installer.Core.Tests/Models/ComponentTests.cs index 1e18cd0..516f80e 100644 --- a/tests/Dotnet.Installer.Core.Tests/Models/ComponentTests.cs +++ b/tests/Dotnet.Installer.Core.Tests/Models/ComponentTests.cs @@ -29,15 +29,15 @@ public async Task Install_WithValidVersions_ShouldInvokeInstallationStartedEvent var systemDService = new Mock(); snapService.Setup(s => s.Install(It.IsAny(), CancellationToken.None)) - .ReturnsAsync(new InvocationResult( - isSuccess: true, standardOutput: string.Empty, standardError: string.Empty)); + .ReturnsAsync(new Terminal.InvocationResult( + exitCode: 0, standardOutput: string.Empty, standardError: string.Empty)); systemDService.Setup(s => s.DaemonReload()) - .ReturnsAsync(new InvocationResult(true, string.Empty, string.Empty)); + .ReturnsAsync(new Terminal.InvocationResult(0, string.Empty, string.Empty)); systemDService.Setup(s => s.EnableUnit(It.IsAny())) - .ReturnsAsync(new InvocationResult(true, string.Empty, string.Empty)); + .ReturnsAsync(new Terminal.InvocationResult(0, string.Empty, string.Empty)); systemDService.Setup(s => s.StartUnit(It.IsAny())) - .ReturnsAsync(new InvocationResult(true, string.Empty, string.Empty)); + .ReturnsAsync(new Terminal.InvocationResult(0, string.Empty, string.Empty)); // Act var evt = await Assert.RaisesAsync( @@ -73,15 +73,15 @@ public async Task Install_WithValidVersions_ShouldInvokeInstallationFinishedEven var systemDService = new Mock(); snapService.Setup(s => s.Install(It.IsAny(), CancellationToken.None)) - .ReturnsAsync(new InvocationResult( - isSuccess: true, standardOutput: string.Empty, standardError: string.Empty)); + .ReturnsAsync(new Terminal.InvocationResult( + exitCode: 0, standardOutput: string.Empty, standardError: string.Empty)); systemDService.Setup(s => s.DaemonReload()) - .ReturnsAsync(new InvocationResult(true, string.Empty, string.Empty)); + .ReturnsAsync(new Terminal.InvocationResult(0, string.Empty, string.Empty)); systemDService.Setup(s => s.EnableUnit(It.IsAny())) - .ReturnsAsync(new InvocationResult(true, string.Empty, string.Empty)); + .ReturnsAsync(new Terminal.InvocationResult(0, string.Empty, string.Empty)); systemDService.Setup(s => s.StartUnit(It.IsAny())) - .ReturnsAsync(new InvocationResult(true, string.Empty, string.Empty)); + .ReturnsAsync(new Terminal.InvocationResult(0, string.Empty, string.Empty)); // Act var evt = await Assert.RaisesAsync( @@ -146,15 +146,15 @@ public async Task Install_WithMultipleDependencies_ShouldTraverseAndInstallDepen }); snapService.Setup(s => s.Install(It.IsAny(), CancellationToken.None)) - .ReturnsAsync(new InvocationResult( - isSuccess: true, standardOutput: string.Empty, standardError: string.Empty)); + .ReturnsAsync(new Terminal.InvocationResult( + exitCode: 0, standardOutput: string.Empty, standardError: string.Empty)); systemDService.Setup(s => s.DaemonReload()) - .ReturnsAsync(new InvocationResult(true, string.Empty, string.Empty)); + .ReturnsAsync(new Terminal.InvocationResult(0, string.Empty, string.Empty)); systemDService.Setup(s => s.EnableUnit(It.IsAny())) - .ReturnsAsync(new InvocationResult(true, string.Empty, string.Empty)); + .ReturnsAsync(new Terminal.InvocationResult(0, string.Empty, string.Empty)); systemDService.Setup(s => s.StartUnit(It.IsAny())) - .ReturnsAsync(new InvocationResult(true, string.Empty, string.Empty)); + .ReturnsAsync(new Terminal.InvocationResult(0, string.Empty, string.Empty)); // Act await component1.Install(fileService.Object, manifestService.Object, snapService.Object, systemDService.Object, @@ -201,11 +201,11 @@ public async Task Uninstall_WithInstalledComponent_ShouldUninstall() }); systemDService.Setup(s => s.DaemonReload()) - .ReturnsAsync(new InvocationResult(true, string.Empty, string.Empty)); + .ReturnsAsync(new Terminal.InvocationResult(0, string.Empty, string.Empty)); systemDService.Setup(s => s.DisableUnit(It.IsAny())) - .ReturnsAsync(new InvocationResult(true, string.Empty, string.Empty)); + .ReturnsAsync(new Terminal.InvocationResult(0, string.Empty, string.Empty)); systemDService.Setup(s => s.StopUnit(It.IsAny())) - .ReturnsAsync(new InvocationResult(true, string.Empty, string.Empty)); + .ReturnsAsync(new Terminal.InvocationResult(0, string.Empty, string.Empty)); installedComponents.Add(component1);