Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
919bfda
Add note on .Net Core support
nemec Jun 8, 2016
dbc6cc0
Defaults to current consoles width if available otherwise uses defaul…
CreepyGnome Jun 14, 2016
78848d0
Merge pull request #321 from CreepyGnome/Issue320
nemec Jun 15, 2016
4a47661
Implemented Hidden Verbs, Options and Values
CreepyGnome Jun 15, 2016
2912a6f
Allow spaces when tokenizing option-value
billbogaiv Jul 20, 2016
c98c643
Merge pull request #334 from billboga/allow-spaces-when-tokenizing-op…
nemec Jul 20, 2016
6acf8e6
Merge pull request #324 from CreepyGnome/Issue263
nemec Jul 27, 2016
d296589
Update README.md
alexanderfast Aug 6, 2016
27ad5b1
Merge branch 'dotnet-core'
nemec Aug 7, 2016
ecb9e64
Fix unit tests for new code merged before Core migration
nemec Aug 7, 2016
9ff3c90
Start VB.NET examples in README
nemec Aug 7, 2016
4e15d55
Get building.
anthonylangsworth Sep 30, 2016
9dd1adb
Add missing XML comments
anthonylangsworth Sep 30, 2016
a7fd065
Initial implementation
anthonylangsworth Sep 30, 2016
8b0c55c
Starting tests
anthonylangsworth Oct 1, 2016
31adc9e
Working on tests
anthonylangsworth Oct 1, 2016
211f073
Finish first draft of unit tests
anthonylangsworth Oct 1, 2016
7b82ada
Made new tests thread safe
anthonylangsworth Oct 1, 2016
55a3f35
Remove unneeded IEquatable<HelpText>
anthonylangsworth Oct 1, 2016
d10f367
Check on error called.
anthonylangsworth Oct 1, 2016
13d8b58
Revert csproj and project.json for CI
anthonylangsworth Oct 2, 2016
a0e9cb7
Merge pull request #356 from anthonylangsworth/missing_author_NullRef…
nemec Oct 4, 2016
47d717e
Update README.md
Misterhex Oct 4, 2016
ae88004
Merge pull request #357 from Misterhex/master
nemec Oct 7, 2016
d4e0b25
Revert "Get building."
anthonylangsworth Oct 7, 2016
4669688
Revert "Revert "Get building.""
anthonylangsworth Oct 7, 2016
a622376
Get building locally
anthonylangsworth Oct 7, 2016
2b63108
Fix invalid cast coverting bool to expected int
anthonylangsworth Oct 7, 2016
9146a74
Expand tests
anthonylangsworth Oct 7, 2016
977b754
Convert from yield return to object[][]
anthonylangsworth Oct 7, 2016
6ba656e
More tests
anthonylangsworth Oct 7, 2016
8b31892
Reverse local build changes for CI
anthonylangsworth Oct 7, 2016
4fa8ddf
Merge pull request #358 from anthonylangsworth/type_conversion
nemec Oct 7, 2016
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
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,7 @@ artifacts/*
.vs/*
*.xproj.user
*.nuget.targets
*.lock.json
*.lock.json
*.nuget.props
*.DotSettings.user

59 changes: 48 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ Compatibility:
---
- .NET Framework 4.0+
- Mono 2.1+ Profile
- .Net Core - Note: support for Core is currently limited to an [alternate branch](https://github.com/gsscoder/commandline/tree/dotnet-core) while we wait for release of 1.0. If you have suggestions or changes for support of .Net Core, please submit a pull request to that branch until it's merged into master.

Current Release:
---
Expand Down Expand Up @@ -90,17 +91,8 @@ class Options {
Consume them:
```csharp
static int Main(string[] args) {
var result = CommandLine.Parser.Default.ParseArguments<Options>(args);
var exitCode = result
.MapResult(
options = > {
if (options.Verbose) Console.WriteLine("Filenames: {0}", string.Join(",", options.InputFiles.ToArray()));
return 0; },
errors => {
LogHelper.Log(errors);
return 1; });
return exitCode;
}
var options = new Options();
var isValid = CommandLine.Parser.Default.ParseArgumentsStrict(args, options);
```
**F#:**
```fsharp
Expand All @@ -119,6 +111,32 @@ let main argv =
| :? Parsed<options> as parsed -> run parsed.Value
| :? NotParsed<options> as notParsed -> fail notParsed.Errors
```
**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, default --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
```
Consume them:
```VB.NET
TODO
```


For verbs:

Expand Down Expand Up @@ -175,6 +193,25 @@ let main args =
| :? CloneOptions as opts -> RunCloneAndReturnExitCode opts
| :? CommandLine.NotParsed<obj> -> 1
```
**VB.NET:**
```VB.NET
<CommandLine.Verb("add", HelpText:="Add file contents to the index.")>
Public Class AddOptions
'Normal options here
End Class
<CommandLine.Verb("commit", HelpText:="Record changes to the repository.")>
Public Class AddOptions
'Normal options here
End Class
<CommandLine.Verb("clone", HelpText:="Clone a repository into a new directory.")>
Public Class AddOptions
'Normal options here
End Class

Public Shared Sub Main()
'TODO
End Sub
```

Acknowledgements:
---
Expand Down
9 changes: 9 additions & 0 deletions src/CommandLine/BaseAttribute.cs
Original file line number Diff line number Diff line change
Expand Up @@ -123,5 +123,14 @@ public string MetaValue
metaValue = value;
}
}

/// <summary>
/// Gets or sets a value indicating whether a command line option is visible in the help text.
/// </summary>
public bool Hidden
{
get;
set;
}
}
}
11 changes: 6 additions & 5 deletions src/CommandLine/Core/OptionSpecification.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ sealed class OptionSpecification : Specification

public OptionSpecification(string shortName, string longName, bool required, string setName, Maybe<int> min, Maybe<int> max,
char separator, Maybe<object> defaultValue, string helpText, string metaValue, IEnumerable<string> enumValues,
Type conversionType, TargetType targetType)
: base(SpecificationType.Option, required, min, max, defaultValue, helpText, metaValue, enumValues, conversionType, targetType)
Type conversionType, TargetType targetType, bool hidden = false)
: base(SpecificationType.Option, required, min, max, defaultValue, helpText, metaValue, enumValues, conversionType, targetType, hidden)
{
this.shortName = shortName;
this.longName = longName;
Expand All @@ -40,13 +40,14 @@ public static OptionSpecification FromAttribute(OptionAttribute attribute, Type
attribute.MetaValue,
enumValues,
conversionType,
conversionType.ToTargetType());
conversionType.ToTargetType(),
attribute.Hidden);
}

public static OptionSpecification NewSwitch(string shortName, string longName, bool required, string helpText, string metaValue)
public static OptionSpecification NewSwitch(string shortName, string longName, bool required, string helpText, string metaValue, bool hidden = false)
{
return new OptionSpecification(shortName, longName, required, string.Empty, Maybe.Nothing<int>(), Maybe.Nothing<int>(),
'\0', Maybe.Nothing<object>(), helpText, metaValue, Enumerable.Empty<string>(), typeof(bool), TargetType.Switch);
'\0', Maybe.Nothing<object>(), helpText, metaValue, Enumerable.Empty<string>(), typeof(bool), TargetType.Switch, hidden);
}

public string ShortName
Expand Down
9 changes: 8 additions & 1 deletion src/CommandLine/Core/Specification.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ abstract class Specification
{
private readonly SpecificationType tag;
private readonly bool required;
private readonly bool hidden;
private readonly Maybe<int> min;
private readonly Maybe<int> max;
private readonly Maybe<object> defaultValue;
Expand All @@ -37,7 +38,7 @@ abstract class Specification

protected Specification(SpecificationType tag, bool required, Maybe<int> min, Maybe<int> max,
Maybe<object> defaultValue, string helpText, string metaValue, IEnumerable<string> enumValues,
Type conversionType, TargetType targetType)
Type conversionType, TargetType targetType, bool hidden = false)
{
this.tag = tag;
this.required = required;
Expand All @@ -49,6 +50,7 @@ protected Specification(SpecificationType tag, bool required, Maybe<int> min, Ma
this.helpText = helpText;
this.metaValue = metaValue;
this.enumValues = enumValues;
this.hidden = hidden;
}

public SpecificationType Tag
Expand Down Expand Up @@ -101,6 +103,11 @@ public TargetType TargetType
get { return targetType; }
}

public bool Hidden
{
get { return hidden; }
}

public static Specification FromProperty(PropertyInfo property)
{
var attrs = property.GetCustomAttributes(true);
Expand Down
3 changes: 2 additions & 1 deletion src/CommandLine/Core/SpecificationExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ public static OptionSpecification WithLongName(this OptionSpecification specific
specification.MetaValue,
specification.EnumValues,
specification.ConversionType,
specification.TargetType);
specification.TargetType,
specification.Hidden);
}

public static string UniqueName(this OptionSpecification specification)
Expand Down
17 changes: 14 additions & 3 deletions src/CommandLine/Core/Tokenizer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using CommandLine.Infrastructure;
using CSharpx;
using RailwaySharp.ErrorHandling;
using System.Text.RegularExpressions;

namespace CommandLine.Core
{
Expand Down Expand Up @@ -188,9 +189,19 @@ private static IEnumerable<Token> TokenizeLongName(
onError(new BadFormatTokenError(value));
yield break;
}
var parts = text.Split('=');
yield return Token.Name(parts[0]);
yield return Token.Value(parts[1], true);

var tokenMatch = Regex.Match(text, "^([^=]+)=([^ ].*)$");

if (tokenMatch.Success)
{
yield return Token.Name(tokenMatch.Groups[1].Value);
yield return Token.Value(tokenMatch.Groups[2].Value, true);
}
else
{
onError(new BadFormatTokenError(value));
yield break;
}
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/CommandLine/Core/TypeConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ private static Result<object, Exception> ChangeTypeScalarImpl(string value, Type
return (value == null) ? empty() : withValue();
};

return value.IsBooleanString()
return value.IsBooleanString() && conversionType == typeof(bool)
? value.ToBoolean() : conversionType.GetTypeInfo().IsEnum
? value.ToEnum(conversionType, ignoreValueCase) : safeChangeType();
};
Expand Down
7 changes: 4 additions & 3 deletions src/CommandLine/Core/ValueSpecification.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ sealed class ValueSpecification : Specification

public ValueSpecification(int index, string metaName, bool required, Maybe<int> min, Maybe<int> max, Maybe<object> defaultValue,
string helpText, string metaValue, IEnumerable<string> enumValues,
Type conversionType, TargetType targetType)
: base(SpecificationType.Value, required, min, max, defaultValue, helpText, metaValue, enumValues, conversionType, targetType)
Type conversionType, TargetType targetType, bool hidden = false)
: base(SpecificationType.Value, required, min, max, defaultValue, helpText, metaValue, enumValues, conversionType, targetType, hidden)
{
this.index = index;
this.metaName = metaName;
Expand All @@ -33,7 +33,8 @@ public static ValueSpecification FromAttribute(ValueAttribute attribute, Type co
attribute.MetaValue,
enumValues,
conversionType,
conversionType.ToTargetType());
conversionType.ToTargetType(),
attribute.Hidden);
}

public int Index
Expand Down
12 changes: 10 additions & 2 deletions src/CommandLine/Core/Verb.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,16 @@ sealed class Verb
{
private readonly string name;
private readonly string helpText;
private readonly bool hidden;

public Verb(string name, string helpText)
public Verb(string name, string helpText, bool hidden = false)
{
if (name == null) throw new ArgumentNullException("name");
if (helpText == null) throw new ArgumentNullException("helpText");

this.name = name;
this.helpText = helpText;
this.hidden = hidden;
}

public string Name
Expand All @@ -33,11 +35,17 @@ public string HelpText
get { return helpText; }
}

public bool Hidden
{
get { return hidden; }
}

public static Verb FromAttribute(VerbAttribute attribute)
{
return new Verb(
attribute.Name,
attribute.HelpText
attribute.HelpText,
attribute.Hidden
);
}

Expand Down
11 changes: 11 additions & 0 deletions src/CommandLine/Error.cs
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,11 @@ public abstract class TokenError : Error, IEquatable<TokenError>
{
private readonly string token;

/// <summary>
/// Initializes a new instance of the <see cref="CommandLine.TokenError"/> class.
/// </summary>
/// <param name="tag">Error type.</param>
/// <param name="token">Problematic token.</param>
protected internal TokenError(ErrorType tag, string token)
: base(tag)
{
Expand Down Expand Up @@ -232,6 +237,12 @@ public abstract class NamedError : Error, IEquatable<NamedError>
{
private readonly NameInfo nameInfo;

/// <summary>
/// Initializes a new instance of the <see cref="CommandLine.NamedError"/> class.
/// </summary>
/// <param name="tag">Error type.</param>
/// <param name="nameInfo">Problematic name.</param>

protected internal NamedError(ErrorType tag, NameInfo nameInfo)
: base(tag)
{
Expand Down
39 changes: 39 additions & 0 deletions src/CommandLine/Infrastructure/ReflectionHelper.cs
Original file line number Diff line number Diff line change
@@ -1,18 +1,57 @@
// Copyright 2005-2015 Giacomo Stelluti Scala & Contributors. All rights reserved. See License.md in the project root for license information.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Runtime.Remoting.Messaging;
using CommandLine.Core;
using CSharpx;

namespace CommandLine.Infrastructure
{
static class ReflectionHelper
{
/// <summary>
/// Per thread assembly attribute overrides for testing.
/// </summary>
[ThreadStatic] private static IDictionary<Type, Attribute> _overrides;

/// <summary>
/// Assembly attribute overrides for testing.
/// </summary>
/// <remarks>
/// The implementation will fail if two or more attributes of the same type
/// are included in <paramref name="overrides"/>.
/// </remarks>
/// <param name="overrides">
/// Attributes that replace the existing assembly attributes or null,
/// to clear any testing attributes.
/// </param>
public static void SetAttributeOverride(IEnumerable<Attribute> overrides)
{
if (overrides != null)
{
_overrides = overrides.ToDictionary(attr => attr.GetType(), attr => attr);
}
else
{
_overrides = null;
}
}

public static Maybe<TAttribute> GetAttribute<TAttribute>()
where TAttribute : Attribute
{
// Test support
if (_overrides != null)
{
return
_overrides.ContainsKey(typeof(TAttribute)) ?
Maybe.Just((TAttribute)_overrides[typeof(TAttribute)]) :
Maybe.Nothing< TAttribute>();
}

var assembly = GetExecutingOrEntryAssembly();

#if NET40
Expand Down
7 changes: 4 additions & 3 deletions src/CommandLine/Parser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -187,15 +187,16 @@ private static ParserResult<T> MakeParserResult<T>(ParserResult<T> parserResult,
{
return DisplayHelp(
parserResult,
settings.HelpWriter);
settings.HelpWriter,
settings.MaximumDisplayWidth);
}

private static ParserResult<T> DisplayHelp<T>(ParserResult<T> parserResult, TextWriter helpWriter)
private static ParserResult<T> DisplayHelp<T>(ParserResult<T> parserResult, TextWriter helpWriter, int maxDisplayWidth)
{
parserResult.WithNotParsed(
errors =>
Maybe.Merge(errors.ToMaybe(), helpWriter.ToMaybe())
.Do((_, writer) => writer.Write(HelpText.AutoBuild(parserResult)))
.Do((_, writer) => writer.Write(HelpText.AutoBuild(parserResult, maxDisplayWidth)))
);

return parserResult;
Expand Down
Loading