Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added Windows Style LongName ("/") to Options along with the required… #224

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions src/CommandLine/Parser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
using CommandLine.Text;
using CSharpx;
using RailwaySharp.ErrorHandling;
using CommandLine.Infrastructure;

namespace CommandLine
{
Expand Down Expand Up @@ -159,6 +160,28 @@ public ParserResult<object> ParseArguments(IEnumerable<string> args, params Type
settings);
}

public ParserResult<object> ParseArguments(IEnumerable<string> args, IEnumerable<Type> types, bool useWinStyleOptions = true)
{
return ParseArguments(ParserExtensions.ConvertWindowsStyleOptions(args), types.ToArray());
}

///
/// <summary>
/// Parses a string array of command line arguments constructing values in an instance of type <typeparamref name="T"/>.
/// Grammar rules are defined decorating public properties with appropriate attributes.
/// </summary>
/// <typeparam name="T">Type of the target instance built with parsed value.</typeparam>
/// <param name="args">A <see cref="System.String"/> array of command line arguments, normally supplied by application entry point.</param>
/// <param name="useWinStyleOptions">Allows using '/' instead of '--' for option long names</param>
/// <returns>A <see cref="CommandLine.ParserResult{T}"/> containing an instance of type <typeparamref name="T"/> with parsed values
/// and a sequence of <see cref="CommandLine.Error"/>.</returns>
/// <exception cref="System.ArgumentNullException">Thrown if one or more arguments are null.</exception>
public ParserResult<T> ParseArguments<T>(IEnumerable<string> args, bool useWinStyleOptions = true)
{
if (args == null) throw new ArgumentNullException("args");
return ParseArguments<T>(ParserExtensions.ConvertWindowsStyleOptions(args));
}

/// <summary>
/// Frees resources owned by the instance.
/// </summary>
Expand Down
16 changes: 16 additions & 0 deletions src/CommandLine/ParserExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

using System;
using System.Collections.Generic;
using System.Linq;

namespace CommandLine
{
Expand Down Expand Up @@ -422,5 +423,20 @@ public static ParserResult<object> ParseArguments<T1, T2, T3, T4, T5, T6, T7, T8
return parser.ParseArguments(args, new[] { typeof(T1), typeof(T2), typeof(T3), typeof(T4), typeof(T5), typeof(T6), typeof(T7), typeof(T8),
typeof(T9), typeof(T10), typeof(T11), typeof(T12), typeof(T13), typeof(T14), typeof(T15), typeof(T16) });
}


internal static IEnumerable<string> ConvertWindowsStyleOptions(IEnumerable<string> args)
{
var longNameStock = "--";
var longNameWin = "/";

return args.Any() ?
args.Select(a =>
a.StartsWith(longNameWin)
? a.Replace(longNameWin, longNameStock)
: a) : args;
}


}
}
125 changes: 120 additions & 5 deletions tests/CommandLine.Tests/Unit/ParserTests.cs
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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<Simple_Options_With_Values>(
new[] { "--stringvalue", "astring", "--", "20", "--aaa", "-b", "--ccc", "30" }, true);

// Verify outcome
((Parsed<Simple_Options_With_Values>)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<Simple_Options_With_Values>(
new[] { "/stringvalue", "astring", "/", "20", "/aaa", "-b", "/ccc", "30" }, true);

// Verify outcome
((Parsed<Simple_Options_With_Values>)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<Simple_Options_With_Values>(
new[] { "--stringvalue", "astring", "/", "20", "--aaa", "-b", "/ccc", "30" }, true);

// Verify outcome
((Parsed<Simple_Options_With_Values>)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<Type>
{
typeof(Add_Verb),
typeof(Commit_Verb),
typeof(Clone_Verb)
}, useWinStyleOptions: true);

// Verify outcome
Assert.IsType<Add_Verb>(((Parsed<object>)result).Value);
((Parsed<object>)result).Value.ShouldBeEquivalentTo(expectedOptions, o => o.RespectingRuntimeTypes());
// Teardown
}

[Fact]
public void Parse_options_with_double_dash_in_verbs_scenario()
{
Expand Down Expand Up @@ -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<Immutable_Simple_Options>(new[] { "/stringvalue=strvalue", "-i1", "2", "3" }
, useWinStyleOptions: true);

// Verify outcome
((Parsed<Immutable_Simple_Options>)result).Value.ShouldBeEquivalentTo(expectedOptions);
// Teardown
}

[Fact]
public void Explicit_help_request_with_immutable_instance_generates_help_requested_error()
{
Expand Down Expand Up @@ -526,9 +641,9 @@ public static IEnumerable<object> 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 } };
}
}
}
}
}