diff --git a/src/CommandLine/Parser.cs b/src/CommandLine/Parser.cs index 6a6a0e45..40edd3c7 100644 --- a/src/CommandLine/Parser.cs +++ b/src/CommandLine/Parser.cs @@ -8,6 +8,7 @@ using CommandLine.Text; using CSharpx; using RailwaySharp.ErrorHandling; +using CommandLine.Infrastructure; namespace CommandLine { @@ -159,6 +160,28 @@ public ParserResult ParseArguments(IEnumerable args, params Type settings); } + public ParserResult ParseArguments(IEnumerable args, IEnumerable types, bool useWinStyleOptions = true) + { + return ParseArguments(ParserExtensions.ConvertWindowsStyleOptions(args), types.ToArray()); + } + + /// + /// + /// Parses a string array of command line arguments constructing values in an instance of type . + /// Grammar rules are defined decorating public properties with appropriate attributes. + /// + /// Type of the target instance built with parsed value. + /// A array of command line arguments, normally supplied by application entry point. + /// Allows using '/' instead of '--' for option long names + /// A containing an instance of type with parsed values + /// and a sequence of . + /// Thrown if one or more arguments are null. + public ParserResult ParseArguments(IEnumerable args, bool useWinStyleOptions = true) + { + if (args == null) throw new ArgumentNullException("args"); + return ParseArguments(ParserExtensions.ConvertWindowsStyleOptions(args)); + } + /// /// Frees resources owned by the instance. /// diff --git a/src/CommandLine/ParserExtensions.cs b/src/CommandLine/ParserExtensions.cs index 1c78ce9d..2bdef404 100644 --- a/src/CommandLine/ParserExtensions.cs +++ b/src/CommandLine/ParserExtensions.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; +using System.Linq; namespace CommandLine { @@ -422,5 +423,20 @@ public static ParserResult ParseArguments ConvertWindowsStyleOptions(IEnumerable args) + { + var longNameStock = "--"; + var longNameWin = "/"; + + return args.Any() ? + args.Select(a => + a.StartsWith(longNameWin) + ? a.Replace(longNameWin, longNameStock) + : a) : args; + } + + } } \ No newline at end of file diff --git a/tests/CommandLine.Tests/Unit/ParserTests.cs b/tests/CommandLine.Tests/Unit/ParserTests.cs index 5d14b1e2..7b82369f 100644 --- a/tests/CommandLine.Tests/Unit/ParserTests.cs +++ b/tests/CommandLine.Tests/Unit/ParserTests.cs @@ -1,12 +1,11 @@ // Copyright 2005-2015 Giacomo Stelluti Scala & Contributors. All rights reserved. See License.md in the project root for license information. +using CommandLine.Tests.Fakes; +using FluentAssertions; using System; using System.Collections.Generic; -using System.Diagnostics; using System.IO; using System.Linq; -using CommandLine.Tests.Fakes; -using FluentAssertions; using Xunit; namespace CommandLine.Tests.Unit @@ -132,6 +131,105 @@ public void Parse_options_with_double_dash() // Teardown } + [Fact] + [Trait("windows-style-options", "stock long and short names only")] + public void Parse_options_with_win_style_enabled() + { + // Fixture setup + var expectedOptions = new Simple_Options_With_Values + { + StringValue = "astring", + LongValue = 20L, + StringSequence = new[] { "--aaa", "-b", "--ccc" }, + IntValue = 30 + }; + + var sut = new Parser(with => with.EnableDashDash = true); + + // Exercize system + var result = + sut.ParseArguments( + new[] { "--stringvalue", "astring", "--", "20", "--aaa", "-b", "--ccc", "30" }, true); + + // Verify outcome + ((Parsed)result).Value.ShouldBeEquivalentTo(expectedOptions); + // Teardown + } + + [Fact] + [Trait("windows-style-options", "windows long names and stock short names")] + public void Parse_options_with_win_style_enabled_2() + { + // Fixture setup + var expectedOptions = new Simple_Options_With_Values + { + StringValue = "astring", + LongValue = 20L, + StringSequence = new[] { "--aaa", "-b", "--ccc" }, + IntValue = 30 + }; + + var sut = new Parser(with => with.EnableDashDash = true); + + // Exercize system + var result = + sut.ParseArguments( + new[] { "/stringvalue", "astring", "/", "20", "/aaa", "-b", "/ccc", "30" }, true); + + // Verify outcome + ((Parsed)result).Value.ShouldBeEquivalentTo(expectedOptions); + // Teardown + } + + [Fact] + [Trait("windows-style-options", "mixed long names and stock short names")] + public void Parse_options_with_mixed_option_longName_styles() + { + // Fixture setup + var expectedOptions = new Simple_Options_With_Values + { + StringValue = "astring", + LongValue = 20L, + StringSequence = new[] { "--aaa", "-b", "--ccc" }, + IntValue = 30 + }; + + var sut = new Parser(with => with.EnableDashDash = true); + + // Exercize system + var result = + sut.ParseArguments( + new[] { "--stringvalue", "astring", "/", "20", "--aaa", "-b", "/ccc", "30" }, true); + + // Verify outcome + ((Parsed)result).Value.ShouldBeEquivalentTo(expectedOptions); + // Teardown + } + + [Fact] + [Trait("windows-style-options", "single verb without options")] + public void Parse_options_with_win_style_in_verbs_scenario() + { + // Fixture setup + var expectedOptions = new Add_Verb { Patch = true, FileName = "--strange-fn" }; + var sut = new Parser(with => with.EnableDashDash = true); + + // Exercize system + var result = sut.ParseArguments( + new[] { "add", "-p", "/", "/strange-fn" }, + new List + { + typeof(Add_Verb), + typeof(Commit_Verb), + typeof(Clone_Verb) + }, useWinStyleOptions: true); + + // Verify outcome + Assert.IsType(((Parsed)result).Value); + ((Parsed)result).Value.ShouldBeEquivalentTo(expectedOptions, o => o.RespectingRuntimeTypes()); + // Teardown + } + [Fact] public void Parse_options_with_double_dash_in_verbs_scenario() { @@ -262,6 +360,23 @@ public void Parse_to_immutable_instance() // Teardown } + [Fact] + [Trait("windows-style-options", "parse to immutable instance")] + public void Parse_to_immutable_instance_winstyle_option() + { + // Fixture setup + var expectedOptions = new Immutable_Simple_Options("strvalue", new[] { 1, 2, 3 }, default(bool), default(long)); + var sut = new Parser(); + + // Exercize system + var result = sut.ParseArguments(new[] { "/stringvalue=strvalue", "-i1", "2", "3" } + , useWinStyleOptions: true); + + // Verify outcome + ((Parsed)result).Value.ShouldBeEquivalentTo(expectedOptions); + // Teardown + } + [Fact] public void Explicit_help_request_with_immutable_instance_generates_help_requested_error() { @@ -526,9 +641,9 @@ public static IEnumerable IgnoreUnknownArgumentsForVerbsData { get { - yield return new object[] { new[] { "commit", "-up" }, new Commit_Verb { Patch = true } }; + yield return new object[] { new[] { "commit", "-up" }, new Commit_Verb { Patch = true } }; yield return new object[] { new[] { "commit", "--amend", "--unknown", "valid" }, new Commit_Verb { Amend = true } }; } } } -} +} \ No newline at end of file