Skip to content

Commit 8725412

Browse files
committed
Merge branch 'develop'
2 parents 24e2be2 + e6c670c commit 8725412

22 files changed

+735
-110
lines changed

CHANGELOG.md

+13
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,19 @@ All notable changes to this project will be documented in this file.
33

44
CommandLineParser project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
55

6+
## [2.9.0-preview1] - 2020-7-24
7+
8+
### Added
9+
- Add multi-instance option support by [@rmunn and @tydunkel, PR# 594](https://github.com/commandlineparser/commandline/pull/594).
10+
- Fix unparsing FileInfo and DirectoryInfo by[@kapsiR, PR# 627](https://github.com/commandlineparser/commandline/pull/627).
11+
- Move Errors and Value up to the abstract class definition, fixes #543 , #165 by [@johnjaylward, PR# 634](https://github.com/commandlineparser/commandline/pull/634).
12+
- Add support for flags enums, fixes #247, #599 and #582 by [@shaosss, PR# 623](https://github.com/commandlineparser/commandline/pull/623).
13+
- Implement verb aliases, fixes #6, #517 by[@johnjaylward, PR# 636](https://github.com/commandlineparser/commandline/pull/636).
14+
- Add a new method FormatCommandLineArgs to unparse commandline to array of string, Fix #375 and #628 .
15+
- Also, add SplitArgs method to split commandline, fix #665 by[@moh-hassan, PR# 662](https://github.com/commandlineparser/commandline/pull/662) and [commit cccae2db](https://github.com/commandlineparser/commandline/commit/cccae2db749c2ebf25125bfd18e05427be0adbcf).
16+
- Allow single dash as a value, fix #300 and #574 by [@moh-hassan, PR# 669](https://github.com/commandlineparser/commandline/pull/669).
17+
18+
619
## [2.8.0] - 2020-5-1
720
## [2.8.0-preview4] - 2020-4-30
821
## [2.8.0-preview1] - 2020-3-14

appveyor.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#version should be only changed with RELEASE eminent, see RELEASE.md
22

3-
version: 2.8.0-ci-{build}
3+
version: 2.9.0-ci-{build}
44

55
image: Visual Studio 2019
66

src/CommandLine/Core/InstanceChooser.cs

+26-18
Original file line numberDiff line numberDiff line change
@@ -25,18 +25,18 @@ public static ParserResult<object> Choose(
2525
{
2626
var verbs = Verb.SelectFromTypes(types);
2727
var defaultVerbs = verbs.Where(t => t.Item1.IsDefault);
28-
28+
2929
int defaultVerbCount = defaultVerbs.Count();
3030
if (defaultVerbCount > 1)
3131
return MakeNotParsed(types, new MultipleDefaultVerbsError());
3232

3333
var defaultVerb = defaultVerbCount == 1 ? defaultVerbs.First() : null;
3434

35-
Func<ParserResult<object>> choose = () =>
35+
ParserResult<object> choose()
3636
{
3737
var firstArg = arguments.First();
3838

39-
Func<string, bool> preprocCompare = command =>
39+
bool preprocCompare(string command) =>
4040
nameComparer.Equals(command, firstArg) ||
4141
nameComparer.Equals(string.Concat("--", command), firstArg);
4242

@@ -47,7 +47,7 @@ public static ParserResult<object> Choose(
4747
: (autoVersion && preprocCompare("version"))
4848
? MakeNotParsed(types, new VersionRequestedError())
4949
: MatchVerb(tokenizer, verbs, defaultVerb, arguments, nameComparer, ignoreValueCase, parsingCulture, autoHelp, autoVersion, nonFatalErrors);
50-
};
50+
}
5151

5252
return arguments.Any()
5353
? choose()
@@ -94,20 +94,28 @@ private static ParserResult<object> MatchVerb(
9494
bool autoVersion,
9595
IEnumerable<ErrorType> nonFatalErrors)
9696
{
97-
return verbs.Any(a => nameComparer.Equals(a.Item1.Name, arguments.First()))
98-
? InstanceBuilder.Build(
99-
Maybe.Just<Func<object>>(
100-
() =>
101-
verbs.Single(v => nameComparer.Equals(v.Item1.Name, arguments.First())).Item2.AutoDefault()),
102-
tokenizer,
103-
arguments.Skip(1),
104-
nameComparer,
105-
ignoreValueCase,
106-
parsingCulture,
107-
autoHelp,
108-
autoVersion,
109-
nonFatalErrors)
110-
: MatchDefaultVerb(tokenizer, verbs, defaultVerb, arguments, nameComparer, ignoreValueCase, parsingCulture, autoHelp, autoVersion, nonFatalErrors);
97+
string firstArg = arguments.First();
98+
99+
var verbUsed = verbs.FirstOrDefault(vt =>
100+
nameComparer.Equals(vt.Item1.Name, firstArg)
101+
|| vt.Item1.Aliases.Any(alias => nameComparer.Equals(alias, firstArg))
102+
);
103+
104+
if (verbUsed == default)
105+
{
106+
return MatchDefaultVerb(tokenizer, verbs, defaultVerb, arguments, nameComparer, ignoreValueCase, parsingCulture, autoHelp, autoVersion, nonFatalErrors);
107+
}
108+
return InstanceBuilder.Build(
109+
Maybe.Just<Func<object>>(
110+
() => verbUsed.Item2.AutoDefault()),
111+
tokenizer,
112+
arguments.Skip(1),
113+
nameComparer,
114+
ignoreValueCase,
115+
parsingCulture,
116+
autoHelp,
117+
autoVersion,
118+
nonFatalErrors);
111119
}
112120

113121
private static HelpVerbRequestedError MakeHelpVerbRequestedError(

src/CommandLine/Core/Sequence.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@ private static IEnumerable<Token> OfSequence(this IEnumerable<Token> tokens, Tok
3434
return info.NextValue.MapValueOrDefault(
3535
_ => info.MaxItems.MapValueOrDefault(
3636
n => tokens.Skip(nameIndex + 1).Take(n),
37-
tokens.Skip(nameIndex + 1).TakeWhile(v => v.IsValue())),
38-
tokens.Skip(nameIndex + 1).TakeWhile(v => v.IsValue()));
37+
tokens.Skip(nameIndex + 1).TakeWhile(v => v.IsValue() && !v.IsValueForced())),
38+
tokens.Skip(nameIndex + 1).TakeWhile(v => v.IsValue() && !v.IsValueForced()));
3939
}
4040
return new Token[] { };
4141
}

src/CommandLine/Core/Token.cs

+25-3
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,11 @@ public static Token Value(string text, bool explicitlyAssigned)
3232
return new Value(text, explicitlyAssigned);
3333
}
3434

35+
public static Token ValueForced(string text)
36+
{
37+
return new Value(text, false, true);
38+
}
39+
3540
public TokenType Tag
3641
{
3742
get { return tag; }
@@ -80,23 +85,35 @@ public bool Equals(Name other)
8085
class Value : Token, IEquatable<Value>
8186
{
8287
private readonly bool explicitlyAssigned;
88+
private readonly bool forced;
8389

8490
public Value(string text)
85-
: this(text, false)
91+
: this(text, false, false)
8692
{
8793
}
8894

8995
public Value(string text, bool explicitlyAssigned)
96+
: this(text, explicitlyAssigned, false)
97+
{
98+
}
99+
100+
public Value(string text, bool explicitlyAssigned, bool forced)
90101
: base(TokenType.Value, text)
91102
{
92103
this.explicitlyAssigned = explicitlyAssigned;
104+
this.forced = forced;
93105
}
94106

95107
public bool ExplicitlyAssigned
96108
{
97109
get { return explicitlyAssigned; }
98110
}
99111

112+
public bool Forced
113+
{
114+
get { return forced; }
115+
}
116+
100117
public override bool Equals(object obj)
101118
{
102119
var other = obj as Value;
@@ -120,7 +137,7 @@ public bool Equals(Value other)
120137
return false;
121138
}
122139

123-
return Tag.Equals(other.Tag) && Text.Equals(other.Text);
140+
return Tag.Equals(other.Tag) && Text.Equals(other.Text) && this.Forced == other.Forced;
124141
}
125142
}
126143

@@ -135,5 +152,10 @@ public static bool IsValue(this Token token)
135152
{
136153
return token.Tag == TokenType.Value;
137154
}
155+
156+
public static bool IsValueForced(this Token token)
157+
{
158+
return token.IsValue() && ((Value)token).Forced;
159+
}
138160
}
139-
}
161+
}

src/CommandLine/Core/Tokenizer.cs

+7-1
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ public static Result<IEnumerable<Token>, Error> PreprocessDashDash(
5050
if (arguments.Any(arg => arg.EqualsOrdinal("--")))
5151
{
5252
var tokenizerResult = tokenizer(arguments.TakeWhile(arg => !arg.EqualsOrdinal("--")));
53-
var values = arguments.SkipWhile(arg => !arg.EqualsOrdinal("--")).Skip(1).Select(Token.Value);
53+
var values = arguments.SkipWhile(arg => !arg.EqualsOrdinal("--")).Skip(1).Select(Token.ValueForced);
5454
return tokenizerResult.Map(tokens => tokens.Concat(values));
5555
}
5656
return tokenizer(arguments);
@@ -135,6 +135,12 @@ private static IEnumerable<Token> TokenizeShortName(
135135
string value,
136136
Func<string, NameLookupResult> nameLookup)
137137
{
138+
//Allow single dash as a value
139+
if (value.Length == 1 && value[0] == '-')
140+
{
141+
yield return Token.Value(value);
142+
yield break;
143+
}
138144
if (value.Length > 1 && value[0] == '-' && value[1] != '-')
139145
{
140146
var text = value.Substring(1);

src/CommandLine/Core/TypeConverter.cs

+10-1
Original file line numberDiff line numberDiff line change
@@ -129,11 +129,20 @@ private static object ToEnum(this string value, Type conversionType, bool ignore
129129
{
130130
throw new FormatException();
131131
}
132-
if (Enum.IsDefined(conversionType, parsedValue))
132+
if (IsDefinedEx(parsedValue))
133133
{
134134
return parsedValue;
135135
}
136136
throw new FormatException();
137137
}
138+
139+
private static bool IsDefinedEx(object enumValue)
140+
{
141+
char firstChar = enumValue.ToString()[0];
142+
if (Char.IsDigit(firstChar) || firstChar == '-')
143+
return false;
144+
145+
return true;
146+
}
138147
}
139148
}

src/CommandLine/Core/Verb.cs

+15-28
Original file line numberDiff line numberDiff line change
@@ -9,49 +9,36 @@ namespace CommandLine.Core
99
{
1010
sealed class Verb
1111
{
12-
private readonly string name;
13-
private readonly string helpText;
14-
private readonly bool hidden;
15-
private readonly bool isDefault;
16-
17-
public Verb(string name, string helpText, bool hidden = false, bool isDefault = false)
12+
public Verb(string name, string helpText, bool hidden, bool isDefault, string[] aliases)
1813
{
19-
if ( string.IsNullOrWhiteSpace(name))
14+
if (string.IsNullOrWhiteSpace(name))
2015
throw new ArgumentNullException(nameof(name));
21-
this.name = name;
16+
Name = name;
2217

23-
this.helpText = helpText ?? throw new ArgumentNullException(nameof(helpText));
24-
this.hidden = hidden;
25-
this.isDefault = isDefault;
18+
HelpText = helpText ?? throw new ArgumentNullException(nameof(helpText));
19+
Hidden = hidden;
20+
IsDefault = isDefault;
21+
Aliases = aliases ?? new string[0];
2622
}
2723

28-
public string Name
29-
{
30-
get { return name; }
31-
}
24+
public string Name { get; private set; }
3225

33-
public string HelpText
34-
{
35-
get { return helpText; }
36-
}
26+
public string HelpText { get; private set; }
3727

38-
public bool Hidden
39-
{
40-
get { return hidden; }
41-
}
28+
public bool Hidden { get; private set; }
4229

43-
public bool IsDefault
44-
{
45-
get => isDefault;
46-
}
30+
public bool IsDefault { get; private set; }
31+
32+
public string[] Aliases { get; private set; }
4733

4834
public static Verb FromAttribute(VerbAttribute attribute)
4935
{
5036
return new Verb(
5137
attribute.Name,
5238
attribute.HelpText,
5339
attribute.Hidden,
54-
attribute.IsDefault
40+
attribute.IsDefault,
41+
attribute.Aliases
5542
);
5643
}
5744

0 commit comments

Comments
 (0)