From 182c695275bcd79dbbe3d4c8c33a3fa0d8b154db Mon Sep 17 00:00:00 2001 From: jonsequitur Date: Fri, 3 Feb 2017 10:57:57 -0800 Subject: [PATCH] throw CommandParsingException rather than crash on missing single value --- .../CommandLine/CommandLineApplication.cs | 21 ++++++++++++--- src/dotnet/CommandLine/LocalizableStrings.cs | 2 ++ .../CommandLineApplicationTests.cs | 26 +++++++++++++++++++ 3 files changed, 45 insertions(+), 4 deletions(-) create mode 100644 test/dotnet.Tests/CommandLineApplicationTests.cs diff --git a/src/dotnet/CommandLine/CommandLineApplication.cs b/src/dotnet/CommandLine/CommandLineApplication.cs index 81ad516b0..087d89dda 100644 --- a/src/dotnet/CommandLine/CommandLineApplication.cs +++ b/src/dotnet/CommandLine/CommandLineApplication.cs @@ -156,7 +156,10 @@ namespace Microsoft.DotNet.Cli.CommandLine else if (isLongOption || arg.StartsWith("-")) { CommandOption option; + var result = ParseOption(isLongOption, command, args, ref index, out option); + + if (result == ParseOptionResult.ShowHelp) { command.ShowHelp(); @@ -285,14 +288,24 @@ namespace Microsoft.DotNet.Cli.CommandLine else { index++; - arg = args[index]; - if (!option.TryParse(arg)) + + if (index < args.Length) + { + arg = args[index]; + if (!option.TryParse(arg)) + { + command.ShowHint(); + throw new CommandParsingException( + command, + String.Format(LocalizableStrings.UnexpectedValueForOptionError, arg, optionName)); + } + } + else { command.ShowHint(); throw new CommandParsingException( command, - String.Format(LocalizableStrings.UnexpectedValueForOptionError, arg, optionName)); - + String.Format(LocalizableStrings.OptionRequiresSingleValueWhichIsMissing, arg, optionName)); } } } diff --git a/src/dotnet/CommandLine/LocalizableStrings.cs b/src/dotnet/CommandLine/LocalizableStrings.cs index 117be72fc..5458291a6 100644 --- a/src/dotnet/CommandLine/LocalizableStrings.cs +++ b/src/dotnet/CommandLine/LocalizableStrings.cs @@ -4,6 +4,8 @@ namespace Microsoft.DotNet.Cli.CommandLine { public const string LastArgumentMultiValueError = "The last argument '{0}' accepts multiple values. No more argument can be added."; + public const string OptionRequiresSingleValueWhichIsMissing = "Required value for option '{0}' was not provided."; + public const string UnexpectedValueForOptionError = "Unexpected value '{0}' for option '{1}'"; public const string UnexpectedArgumentError = "Unrecognized {0} '{1}'"; diff --git a/test/dotnet.Tests/CommandLineApplicationTests.cs b/test/dotnet.Tests/CommandLineApplicationTests.cs new file mode 100644 index 000000000..8a7237dd3 --- /dev/null +++ b/test/dotnet.Tests/CommandLineApplicationTests.cs @@ -0,0 +1,26 @@ +using System; +using FluentAssertions; +using Microsoft.DotNet.Cli.CommandLine; +using Xunit; + +namespace Microsoft.DotNet.Tests +{ + public class CommandLineApplicationTests + { + [Fact] + public void WhenAnOptionRequiresASingleValueThatIsNotSuppliedItThrowsCommandParsingException() + { + var app = new CommandLineApplication(); + + app.Option("-v|--verbosity", "be verbose", CommandOptionType.SingleValue); + + Action execute = () => app.Execute("-v"); + + execute.ShouldThrow() + .Which + .Message + .Should() + .Be("Required value for option '-v' was not provided."); + } + } +}