74 lines
1.9 KiB
C#
74 lines
1.9 KiB
C#
|
|
// Copyright (c) The Geekeey Authors
|
||
|
|
// SPDX-License-Identifier: EUPL-1.2
|
||
|
|
|
||
|
|
using System.Diagnostics;
|
||
|
|
|
||
|
|
namespace Geekeey.Arcade.NET.Tests.Shared;
|
||
|
|
|
||
|
|
internal sealed record Command(string WorkingDirectory, IEnumerable<KeyValuePair<string, string>> Environment)
|
||
|
|
{
|
||
|
|
public bool ThrowOnExit { get; init; }
|
||
|
|
|
||
|
|
public static Command WithWorkingDirectory(string path)
|
||
|
|
{
|
||
|
|
return new Command(path, []);
|
||
|
|
}
|
||
|
|
|
||
|
|
public Command WithEnvironment(string name, string value)
|
||
|
|
{
|
||
|
|
return WithEnvironment([new KeyValuePair<string, string>(name, value)]);
|
||
|
|
}
|
||
|
|
|
||
|
|
public Command WithEnvironment(IEnumerable<KeyValuePair<string, string>> environment)
|
||
|
|
{
|
||
|
|
var env = new Dictionary<string, string>(Environment);
|
||
|
|
|
||
|
|
foreach (var pair in environment)
|
||
|
|
{
|
||
|
|
env[pair.Key] = pair.Value;
|
||
|
|
}
|
||
|
|
|
||
|
|
return this with { Environment = env };
|
||
|
|
}
|
||
|
|
|
||
|
|
public Command WithThrowOnExit()
|
||
|
|
{
|
||
|
|
return this with { ThrowOnExit = true };
|
||
|
|
}
|
||
|
|
|
||
|
|
public async Task<CommandOutput> RunAsync(string exe, params IReadOnlyList<string> args)
|
||
|
|
{
|
||
|
|
ArgumentNullException.ThrowIfNull(args);
|
||
|
|
|
||
|
|
var startInfo = new ProcessStartInfo(exe)
|
||
|
|
{
|
||
|
|
WorkingDirectory = WorkingDirectory,
|
||
|
|
RedirectStandardOutput = true,
|
||
|
|
RedirectStandardError = true,
|
||
|
|
UseShellExecute = false,
|
||
|
|
CreateNoWindow = true
|
||
|
|
};
|
||
|
|
|
||
|
|
foreach (var argument in args)
|
||
|
|
{
|
||
|
|
startInfo.ArgumentList.Add(argument);
|
||
|
|
}
|
||
|
|
|
||
|
|
foreach (var pair in Environment)
|
||
|
|
{
|
||
|
|
startInfo.Environment[pair.Key] = pair.Value;
|
||
|
|
}
|
||
|
|
|
||
|
|
var process = Process.Start(startInfo) ?? throw new InvalidOperationException("Could not start dotnet.");
|
||
|
|
var output = await process.StandardOutput.ReadToEndAsync();
|
||
|
|
var error = await process.StandardError.ReadToEndAsync();
|
||
|
|
|
||
|
|
await process.WaitForExitAsync();
|
||
|
|
|
||
|
|
_ = ThrowOnExit && process.ExitCode is not 0
|
||
|
|
? throw new InvalidOperationException($"'{exe}' exited with code {process.ExitCode}.{System.Environment.NewLine}{error}{output}")
|
||
|
|
: 0;
|
||
|
|
|
||
|
|
return new CommandOutput(output, error, process.ExitCode);
|
||
|
|
}
|
||
|
|
}
|