Skip to content

Commit

Permalink
Merge pull request #289 from PerthHackers/develop
Browse files Browse the repository at this point in the history
Remerge 274 directly into master
  • Loading branch information
ericnewton76 authored Aug 13, 2018
2 parents 68d46c7 + 6ce423d commit d16d24c
Show file tree
Hide file tree
Showing 8 changed files with 151 additions and 22 deletions.
77 changes: 61 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,43 @@ You can utilize the parser library in several ways:
1. Create a class to define valid options, and to receive the parsed options.
2. Call ParseArguments with the args string array.

C# Quick Start:

```csharp
using System;
using CommandLine;

namespace QuickStart
{
class Program
{
public class Options
{
[Option('v', "verbose", Required = false, HelpText = "Set output to verbose messages.")]
public bool Verbose { get; set; }
}

static void Main(string[] args)
{
Parser.Default.ParseArguments<Options>(args)
.WithParsed<Options>(o =>
{
if (o.Verbose)
{
Console.WriteLine($"Verbose output enabled. Current Arguments: -v {o.Verbose}");
Console.WriteLine("Quick Start Example! App is in Verbose mode!");
}
else
{
Console.WriteLine($"Current Arguments: -v {o.Verbose}");
Console.WriteLine("Quick Start Example!");
}
});
}
}
}
```

C# Examples:

```csharp
Expand All @@ -55,10 +92,14 @@ class Options
public IEnumerable<string> InputFiles { get; set; }

// Omitting long name, defaults to name of property, ie "--verbose"
[Option(Default = false, HelpText = "Prints all messages to standard output.")]
[Option(
Default = false,
HelpText = "Prints all messages to standard output.")]
public bool Verbose { get; set; }

[Option("stdin", Default = false, HelpText = "Read from stdin")]

[Option("stdin",
Default = false
HelpText = "Read from stdin")]
public bool stdin { get; set; }

[Value(0, MetaName = "offset", HelpText = "File offset.")]
Expand All @@ -79,7 +120,7 @@ F# Examples:
type options = {
[<Option('r', "read", Required = true, HelpText = "Input files.")>] files : seq<string>;
[<Option(HelpText = "Prints all messages to standard output.")>] verbose : bool;
[<Option(DefaultValue = "русский", HelpText = "Content language.")>] language : string;
[<Option(Default = "русский", HelpText = "Content language.")>] language : string;
[<Value(0, MetaName="offset", HelpText = "File offset.")>] offset : int64 option;
}
Expand All @@ -94,18 +135,22 @@ VB.Net:

```VB.NET
Class Options
<CommandLine.Option("r", "read", Required:=True, HelpText:="Input files to be processed.")>
Public Property InputFiles As IEnumerable(Of String)

' Omitting long name, defaults to name of property, ie "--verbose"
<CommandLine.Option(HelpText:="Prints all messages to standard output.")>
Public Property Verbose As Boolean

<CommandLine.Option([Default]:="中文", HelpText:="Content language.")>
Public Property Language As String

<CommandLine.Value(0, MetaName:="offset", HelpText:="File offset.")>
Public Property Offset As Long?
<CommandLine.Option('r', "read", Required := true,
HelpText:="Input files to be processed.")>
Public Property InputFiles As IEnumerable(Of String)

' Omitting long name, defaults to name of property, ie "--verbose"
<CommandLine.Option(
HelpText:="Prints all messages to standard output.")>
Public Property Verbose As Boolean

<CommandLine.Option(Default:="中文",
HelpText:="Content language.")>
Public Property Language As String

<CommandLine.Value(0, MetaName:="offset",
HelpText:="File offset.")>
Public Property Offset As Long?
End Class

Sub Main(ByVal args As String())
Expand Down
18 changes: 15 additions & 3 deletions src/CommandLine/Core/TypeConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,19 @@ private static Maybe<object> ChangeTypeScalar(string value, Type conversionType,
return result.ToMaybe();
}

private static object ConvertString(string value, Type type, CultureInfo conversionCulture)
{
try
{
return Convert.ChangeType(value, type, conversionCulture);
}
catch (InvalidCastException)
{
// Required for converting from string to TimeSpan because Convert.ChangeType can't
return System.ComponentModel.TypeDescriptor.GetConverter(type).ConvertFrom(null, conversionCulture, value);
}
}

private static Result<object, Exception> ChangeTypeScalarImpl(string value, Type conversionType, CultureInfo conversionCulture, bool ignoreValueCase)
{
Func<object> changeType = () =>
Expand All @@ -71,10 +84,9 @@ private static Result<object, Exception> ChangeTypeScalarImpl(string value, Type
() =>
#if !SKIP_FSHARP
isFsOption
? FSharpOptionHelper.Some(type, Convert.ChangeType(value, type, conversionCulture)) :
? FSharpOptionHelper.Some(type, ConvertString(value, type, conversionCulture)) :
#endif
Convert.ChangeType(value, type, conversionCulture);

ConvertString(value, type, conversionCulture);
#if !SKIP_FSHARP
Func<object> empty = () => isFsOption ? FSharpOptionHelper.None(type) : null;
#else
Expand Down
17 changes: 14 additions & 3 deletions src/CommandLine/UnParserExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ public class UnParserSettings
private bool preferShortName;
private bool groupSwitches;
private bool useEqualToken;
private bool showHidden;

/// <summary>
/// Gets or sets a value indicating whether unparsing process shall prefer short or long names.
Expand Down Expand Up @@ -46,6 +47,14 @@ public bool UseEqualToken
set { PopsicleSetter.Set(Consumed, ref useEqualToken, value); }
}

/// <summary>
/// Gets or sets a value indicating whether unparsing process shall expose hidden options.
/// </summary>
public bool ShowHidden
{
get { return showHidden; }
set { PopsicleSetter.Set(Consumed, ref showHidden, value); }
}
/// <summary>
/// Factory method that creates an instance of <see cref="CommandLine.UnParserSettings"/> with GroupSwitches set to true.
/// </summary>
Expand Down Expand Up @@ -119,6 +128,7 @@ public static string FormatCommandLine<T>(this Parser parser, T options, Action<
var allOptSpecs = from info in specs.Where(i => i.Specification.Tag == SpecificationType.Option)
let o = (OptionSpecification)info.Specification
where o.TargetType != TargetType.Switch || (o.TargetType == TargetType.Switch && ((bool)info.Value))
where !o.Hidden || settings.ShowHidden
orderby o.UniqueName()
select info;

Expand Down Expand Up @@ -206,9 +216,10 @@ private static string FormatOption(OptionSpecification spec, object value, UnPar

private static string FormatName(this OptionSpecification optionSpec, UnParserSettings settings)
{
var longName =
optionSpec.LongName.Length > 0
&& !settings.PreferShortName;
// Have a long name and short name not preferred? Go with long!
// No short name? Has to be long!
var longName = (optionSpec.LongName.Length > 0 && !settings.PreferShortName)
|| optionSpec.ShortName.Length == 0;

return
new StringBuilder(longName
Expand Down
2 changes: 2 additions & 0 deletions tests/CommandLine.Tests/CommandLine.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
<Link>Properties\SharedAssemblyInfo.cs</Link>
</Compile>
<Compile Include="CultureInfoExtensions.cs" />
<Compile Include="Fakes\Hidden_Option.cs" />
<Compile Include="Fakes\Options_With_Default_Set_To_Sequence.cs" />
<Compile Include="Fakes\Options_With_Guid.cs" />
<Compile Include="Fakes\Options_With_Option_And_Value_Of_String_Type.cs" />
Expand Down Expand Up @@ -95,6 +96,7 @@
<Compile Include="Fakes\Options_With_Two_Options_Having_Required_Set_To_True.cs" />
<Compile Include="Fakes\Options_With_Required_Set_To_True.cs" />
<Compile Include="Fakes\Options_With_Required_Set_To_True_Within_Same_Set.cs" />
<Compile Include="Fakes\Options_With_TimeSpan.cs" />
<Compile Include="Fakes\Help_Fakes.cs" />
<Compile Include="Fakes\IInterface_With_Two_Scalar_Options.cs" />
<Compile Include="Fakes\Immutable_Verb_Fakes.cs" />
Expand Down
14 changes: 14 additions & 0 deletions tests/CommandLine.Tests/Fakes/Hidden_Option.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CommandLine.Tests.Fakes
{
public class Hidden_Option
{
[Option('h', "hiddenOption", Default="hidden", Hidden = true)]
public string HiddenOption { get; set; }
}
}
12 changes: 12 additions & 0 deletions tests/CommandLine.Tests/Fakes/Options_With_TimeSpan.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// Copyright 2005-2015 Giacomo Stelluti Scala & Contributors. All rights reserved. See License.md in the project root for license information.

using System;

namespace CommandLine.Tests.Fakes
{
public class Options_With_TimeSpan
{
[Option('d', "duration")]
public TimeSpan Duration { get; set; }
}
}
16 changes: 16 additions & 0 deletions tests/CommandLine.Tests/Unit/Core/InstanceBuilderTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1023,6 +1023,22 @@ public void Parse_Guid(string[] arguments, Options_With_Guid expected)
// Teardown
}

[Fact]
public void Parse_TimeSpan()
{
// Fixture setup
var expectedResult = new Options_With_TimeSpan { Duration = TimeSpan.FromMinutes(42) };

// Exercize system
var result = InvokeBuild<Options_With_TimeSpan>(
new[] { "--duration=00:42:00" });

// Verify outcome
expectedResult.ShouldBeEquivalentTo(((Parsed<Options_With_TimeSpan>)result).Value);

// Teardown
}

public static IEnumerable<object> RequiredValueStringData
{
get
Expand Down
17 changes: 17 additions & 0 deletions tests/CommandLine.Tests/Unit/UnParserExtensionsTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,15 @@ public static void UnParsing_immutable_instance_returns_command_line(Immutable_S
.ShouldBeEquivalentTo(result);
}

[Theory]
[MemberData("UnParseDataHidden")]
public static void Unparsing_hidden_option_returns_command_line(Hidden_Option options, bool showHidden, string result)
{
new Parser()
.FormatCommandLine(options, config => config.ShowHidden = showHidden)
.ShouldBeEquivalentTo(result);
}

#if !SKIP_FSHARP
[Theory]
[MemberData("UnParseDataFSharpOption")]
Expand Down Expand Up @@ -141,6 +150,14 @@ public static IEnumerable<object> UnParseDataImmutable
}
}

public static IEnumerable<object> UnParseDataHidden
{
get
{
yield return new object[] { new Hidden_Option { HiddenOption = "hidden" }, true, "--hiddenOption hidden" };
yield return new object[] { new Hidden_Option { HiddenOption = "hidden" }, false, ""};
}
}
#if !SKIP_FSHARP
public static IEnumerable<object> UnParseDataFSharpOption
{
Expand Down

0 comments on commit d16d24c

Please sign in to comment.