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

Verb aliases #636

Merged
merged 5 commits into from
Jun 15, 2020
Merged
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
46 changes: 27 additions & 19 deletions src/CommandLine/Core/InstanceChooser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,18 +50,18 @@ public static ParserResult<object> Choose(
{
var verbs = Verb.SelectFromTypes(types);
var defaultVerbs = verbs.Where(t => t.Item1.IsDefault);

int defaultVerbCount = defaultVerbs.Count();
if (defaultVerbCount > 1)
return MakeNotParsed(types, new MultipleDefaultVerbsError());

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

Func<ParserResult<object>> choose = () =>
ParserResult<object> choose()
{
var firstArg = arguments.First();

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

Expand All @@ -72,7 +72,7 @@ public static ParserResult<object> Choose(
: (autoVersion && preprocCompare("version"))
? MakeNotParsed(types, new VersionRequestedError())
: MatchVerb(tokenizer, verbs, defaultVerb, arguments, nameComparer, ignoreValueCase, parsingCulture, autoHelp, autoVersion, allowMultiInstance, nonFatalErrors);
};
}

return arguments.Any()
? choose()
Expand Down Expand Up @@ -120,21 +120,29 @@ private static ParserResult<object> MatchVerb(
bool allowMultiInstance,
IEnumerable<ErrorType> nonFatalErrors)
{
return verbs.Any(a => nameComparer.Equals(a.Item1.Name, arguments.First()))
? InstanceBuilder.Build(
Maybe.Just<Func<object>>(
() =>
verbs.Single(v => nameComparer.Equals(v.Item1.Name, arguments.First())).Item2.AutoDefault()),
tokenizer,
arguments.Skip(1),
nameComparer,
ignoreValueCase,
parsingCulture,
autoHelp,
autoVersion,
allowMultiInstance,
nonFatalErrors)
: MatchDefaultVerb(tokenizer, verbs, defaultVerb, arguments, nameComparer, ignoreValueCase, parsingCulture, autoHelp, autoVersion, nonFatalErrors);
string firstArg = arguments.First();

var verbUsed = verbs.FirstOrDefault(vt =>
nameComparer.Equals(vt.Item1.Name, firstArg)
|| vt.Item1.Aliases.Any(alias => nameComparer.Equals(alias, firstArg))
);

if (verbUsed == default)
{
return MatchDefaultVerb(tokenizer, verbs, defaultVerb, arguments, nameComparer, ignoreValueCase, parsingCulture, autoHelp, autoVersion, nonFatalErrors);
}
return InstanceBuilder.Build(
Maybe.Just<Func<object>>(
() => verbUsed.Item2.AutoDefault()),
tokenizer,
arguments.Skip(1),
nameComparer,
ignoreValueCase,
parsingCulture,
autoHelp,
autoVersion,
allowMultiInstance,
nonFatalErrors);
}

private static HelpVerbRequestedError MakeHelpVerbRequestedError(
Expand Down
43 changes: 15 additions & 28 deletions src/CommandLine/Core/Verb.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,49 +9,36 @@ namespace CommandLine.Core
{
sealed class Verb
{
private readonly string name;
private readonly string helpText;
private readonly bool hidden;
private readonly bool isDefault;

public Verb(string name, string helpText, bool hidden = false, bool isDefault = false)
public Verb(string name, string helpText, bool hidden, bool isDefault, string[] aliases)
{
if ( string.IsNullOrWhiteSpace(name))
if (string.IsNullOrWhiteSpace(name))
throw new ArgumentNullException(nameof(name));
this.name = name;
Name = name;

this.helpText = helpText ?? throw new ArgumentNullException(nameof(helpText));
this.hidden = hidden;
this.isDefault = isDefault;
HelpText = helpText ?? throw new ArgumentNullException(nameof(helpText));
Hidden = hidden;
IsDefault = isDefault;
Aliases = aliases ?? new string[0];
}

public string Name
{
get { return name; }
}
public string Name { get; private set; }

public string HelpText
{
get { return helpText; }
}
public string HelpText { get; private set; }

public bool Hidden
{
get { return hidden; }
}
public bool Hidden { get; private set; }

public bool IsDefault
{
get => isDefault;
}
public bool IsDefault { get; private set; }

public string[] Aliases { get; private set; }

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

Expand Down
4 changes: 2 additions & 2 deletions src/CommandLine/Text/HelpText.cs
Original file line number Diff line number Diff line change
Expand Up @@ -851,10 +851,10 @@ private IEnumerable<Specification> AdaptVerbsToSpecifications(IEnumerable<Type>
var optionSpecs = from verbTuple in Verb.SelectFromTypes(types)
select
OptionSpecification.NewSwitch(
string.Empty,
verbTuple.Item1.Name,
verbTuple.Item1.Aliases.ToDelimitedString(", "),
false,
verbTuple.Item1.IsDefault? "(Default Verb) "+verbTuple.Item1.HelpText: verbTuple.Item1.HelpText, //Default verb
verbTuple.Item1.IsDefault ? "(Default Verb) " + verbTuple.Item1.HelpText : verbTuple.Item1.HelpText, //Default verb
string.Empty,
verbTuple.Item1.Hidden);
if (autoHelp)
Expand Down
34 changes: 17 additions & 17 deletions src/CommandLine/VerbAttribute.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// 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;

namespace CommandLine
{
Expand All @@ -9,36 +10,33 @@ namespace CommandLine
/// </summary>
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, AllowMultiple = false, Inherited = true)]
//public sealed class VerbAttribute : Attribute
public class VerbAttribute : Attribute
public class VerbAttribute : Attribute
{
private readonly string name;
private readonly bool isDefault;
private Infrastructure.LocalizableAttributeProperty helpText;
private readonly Infrastructure.LocalizableAttributeProperty helpText;
private Type resourceType;

/// <summary>
/// Initializes a new instance of the <see cref="CommandLine.VerbAttribute"/> class.
/// </summary>
/// <param name="name">The long name of the verb command.</param>
/// <param name="isDefault">Whether the verb is the default verb.</param>
/// <param name="aliases">aliases for this verb. i.e. "move" and "mv"</param>
/// <exception cref="System.ArgumentException">Thrown if <paramref name="name"/> is null, empty or whitespace and <paramref name="isDefault"/> is false.</exception>
public VerbAttribute(string name, bool isDefault = false)
public VerbAttribute(string name, bool isDefault = false, string[] aliases = null)
{
if (string.IsNullOrWhiteSpace(name)) throw new ArgumentException("name");

this.name = name ;
this.isDefault = isDefault;
Name = name;
IsDefault = isDefault;
helpText = new Infrastructure.LocalizableAttributeProperty(nameof(HelpText));
resourceType = null;
Aliases = aliases ?? new string[0];
}

/// <summary>
/// Gets the verb name.
/// </summary>
public string Name
{
get { return name; }
}
public string Name { get; private set; }

/// <summary>
/// Gets or sets a value indicating whether a command line verb is visible in the help text.
Expand All @@ -54,7 +52,7 @@ public bool Hidden
/// </summary>
public string HelpText
{
get => helpText.Value??string.Empty;
get => helpText.Value ?? string.Empty;
set => helpText.Value = value ?? throw new ArgumentNullException("value");
}
/// <summary>
Expand All @@ -63,15 +61,17 @@ public string HelpText
public Type ResourceType
{
get => resourceType;
set => resourceType =helpText.ResourceType = value;
set => resourceType = helpText.ResourceType = value;
}

/// <summary>
/// Gets whether this verb is the default verb.
/// </summary>
public bool IsDefault
{
get => isDefault;
}
public bool IsDefault { get; private set; }

/// <summary>
/// Gets or sets the aliases
/// </summary>
public string[] Aliases { get; private set; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

namespace CommandLine.Tests.Unit
{
public class Issue591ests
public class Issue591Tests
{
[Fact]
public void Parse_option_with_only_explicit_interface_implementation()
Expand Down
Loading