From 9d90f16e160a9fc0328f2bad2648d9e4f4fa7d62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?= Date: Fri, 7 May 2021 02:15:45 +0300 Subject: [PATCH] abp batch command should handle spaces and quotes in arguments. --- .../Abp/Cli/Args/CommandLineArgumentParser.cs | 47 +++++++++++++++++++ .../Cli/Args/ICommandLineArgumentParser.cs | 2 + .../Volo/Abp/Cli/CliService.cs | 6 ++- .../Cli/CommandLineArgumentParser_Tests.cs | 21 +++++++++ 4 files changed, 74 insertions(+), 2 deletions(-) diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Args/CommandLineArgumentParser.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Args/CommandLineArgumentParser.cs index 1dd29e5df7..b7cd95a3e0 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Args/CommandLineArgumentParser.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Args/CommandLineArgumentParser.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Text; using Volo.Abp.DependencyInjection; namespace Volo.Abp.Cli.Args @@ -71,6 +72,11 @@ namespace Volo.Abp.Cli.Args return commandLineArgs; } + public CommandLineArgs Parse(string lineText) + { + return Parse(GetArgsArrayFromLine(lineText)); + } + private static bool IsOptionName(string argument) { return argument.StartsWith("-") || argument.StartsWith("--"); @@ -100,5 +106,46 @@ namespace Volo.Abp.Cli.Args throw new ArgumentException("Option names should start with '-' or '--'."); } + + private static string[] GetArgsArrayFromLine(string lineText) + { + var args = new List(); + var currentArgBuilder = new StringBuilder(); + string currentArg = null; + bool isInQuotes = false; + for (int i = 0; i < lineText.Length; i++) + { + var c = lineText[i]; + if (c == ' ' && !isInQuotes) + { + currentArg = currentArgBuilder.ToString(); + if (!currentArg.IsNullOrWhiteSpace()) + { + args.Add(currentArg); + } + + currentArgBuilder = new StringBuilder(); + } + else + { + if (c == '\"') + { + isInQuotes = !isInQuotes; + } + else + { + currentArgBuilder.Append(c); + } + } + } + + currentArg = currentArgBuilder.ToString(); + if (!currentArg.IsNullOrWhiteSpace()) + { + args.Add(currentArg); + } + + return args.ToArray(); + } } } \ No newline at end of file diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Args/ICommandLineArgumentParser.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Args/ICommandLineArgumentParser.cs index c467541210..4e8ee7cd77 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Args/ICommandLineArgumentParser.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Args/ICommandLineArgumentParser.cs @@ -3,5 +3,7 @@ public interface ICommandLineArgumentParser { CommandLineArgs Parse(string[] args); + + CommandLineArgs Parse(string lineText); } } \ No newline at end of file diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/CliService.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/CliService.cs index a847881d60..cfae12c76e 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/CliService.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/CliService.cs @@ -3,9 +3,11 @@ using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Abstractions; using NuGet.Versioning; using System; +using System.Collections.Generic; using System.IO; using System.Linq; using System.Reflection; +using System.Text; using System.Threading.Tasks; using Volo.Abp.Cli.Args; using Volo.Abp.Cli.Commands; @@ -98,11 +100,11 @@ namespace Volo.Abp.Cli lineText = lineText.Substring(0, lineText.IndexOf('#')); } - var args = CommandLineArgumentParser.Parse(lineText.Split(' ')); + var args = CommandLineArgumentParser.Parse(lineText); await RunInternalAsync(args); } } - + private async Task RunInternalAsync(CommandLineArgs commandLineArgs) { var commandType = CommandSelector.Select(commandLineArgs); diff --git a/framework/test/Volo.Abp.Cli.Core.Tests/Volo/Abp/Cli/CommandLineArgumentParser_Tests.cs b/framework/test/Volo.Abp.Cli.Core.Tests/Volo/Abp/Cli/CommandLineArgumentParser_Tests.cs index c8d31990cf..36174f1004 100644 --- a/framework/test/Volo.Abp.Cli.Core.Tests/Volo/Abp/Cli/CommandLineArgumentParser_Tests.cs +++ b/framework/test/Volo.Abp.Cli.Core.Tests/Volo/Abp/Cli/CommandLineArgumentParser_Tests.cs @@ -64,5 +64,26 @@ namespace Volo.Abp.Cli commandLineArgs.Options.ShouldContainKey("optionC"); commandLineArgs.Options["optionC"].ShouldBe("value2"); } + + [Fact] + public void Should_Parse_From_Line_Text() + { + var commandLineArgs = _commandLineArgumentParser.Parse( + "mycommand mytarget -a value1 -b \"value with space\" --optionC" + ); + + commandLineArgs.Command.ShouldBe("mycommand"); + commandLineArgs.Target.ShouldBe("mytarget"); + commandLineArgs.Options.Any().ShouldBeTrue(); + + commandLineArgs.Options.ShouldContainKey("a"); + commandLineArgs.Options["a"].ShouldBe("value1"); + + commandLineArgs.Options.ShouldContainKey("b"); + commandLineArgs.Options["b"].ShouldBe("value with space"); + + commandLineArgs.Options.ShouldContainKey("optionC"); + commandLineArgs.Options["optionC"].ShouldBeNull(); + } } }