diff --git a/StabilityMatrix.Core/Processes/ProcessArgs.cs b/StabilityMatrix.Core/Processes/ProcessArgs.cs new file mode 100644 index 00000000..25af2561 --- /dev/null +++ b/StabilityMatrix.Core/Processes/ProcessArgs.cs @@ -0,0 +1,29 @@ +using System.Text.RegularExpressions; +using OneOf; + +namespace StabilityMatrix.Core.Processes; + +public partial class ProcessArgs : OneOfBase +{ + /// + private ProcessArgs(OneOf input) + : base(input) { } + + // Implicit conversions + + public static implicit operator ProcessArgs(string input) => new(input); + + public static implicit operator ProcessArgs(string[] input) => new(input); + + public static implicit operator string(ProcessArgs input) => + input.Match(str => str, arr => string.Join(' ', arr.Select(ProcessRunner.Quote))); + + public static implicit operator string[](ProcessArgs input) => + input.Match( + str => ArgumentsRegex().Matches(str).Select(x => x.Value.Trim('"')).ToArray(), + arr => arr + ); + + [GeneratedRegex("""[\"].+?[\"]|[^ ]+""", RegexOptions.IgnoreCase)] + private static partial Regex ArgumentsRegex(); +} diff --git a/StabilityMatrix.Tests/Models/ProcessArgsTests.cs b/StabilityMatrix.Tests/Models/ProcessArgsTests.cs new file mode 100644 index 00000000..ae3281d9 --- /dev/null +++ b/StabilityMatrix.Tests/Models/ProcessArgsTests.cs @@ -0,0 +1,43 @@ +using StabilityMatrix.Core.Processes; + +namespace StabilityMatrix.Tests.Models; + +[TestClass] +public class ProcessArgsTests +{ + [DataTestMethod] + [DataRow("pip", new[] { "pip" })] + [DataRow("pip install torch", new[] { "pip", "install", "torch" })] + [DataRow( + "pip install -r \"file spaces/here\"", + new[] { "pip", "install", "-r", "file spaces/here" } + )] + [DataRow( + "pip install -r \"file spaces\\here\"", + new[] { "pip", "install", "-r", "file spaces\\here" } + )] + public void TestStringToArray(string input, string[] expected) + { + ProcessArgs args = input; + string[] result = args; + CollectionAssert.AreEqual(expected, result); + } + + [DataTestMethod] + [DataRow(new[] { "pip" }, "pip")] + [DataRow(new[] { "pip", "install", "torch" }, "pip install torch")] + [DataRow( + new[] { "pip", "install", "-r", "file spaces/here" }, + "pip install -r \"file spaces/here\"" + )] + [DataRow( + new[] { "pip", "install", "-r", "file spaces\\here" }, + "pip install -r \"file spaces\\here\"" + )] + public void TestArrayToString(string[] input, string expected) + { + ProcessArgs args = input; + string result = args; + Assert.AreEqual(expected, result); + } +}