Skip to content

Instantly share code, notes, and snippets.

@tintoy
Last active April 17, 2019 13:24
Show Gist options
  • Save tintoy/8e22ac81d6b206fd6489f5d07428a7c5 to your computer and use it in GitHub Desktop.
Save tintoy/8e22ac81d6b206fd6489f5d07428a7c5 to your computer and use it in GitHub Desktop.
Sub-verbs command line parser
using CommandLine;
using CommandLine.Text;
using System;
using System.Collections.Generic;
using System.Linq;
namespace SubVerbs
{
class Program
{
static void Main(string[] args)
{
Command currentCommand = null;
ParserResult<object> result = Parser.Default
.ParseArguments(args,
typeof(Verb1Command),
typeof(Verb2Command)
)
.WithParsed(
command => currentCommand = (Command)command
);
while (currentCommand != null)
{
switch (currentCommand)
{
case CompoundVerbCommand compoundVerb:
{
if (currentCommand != null)
Console.WriteLine($"CompoundVerbCommand: {currentCommand}");
IEnumerable<string> remainingArgs = compoundVerb.RemainingArgs ?? Enumerable.Empty<string>();
Parser.Default
.ParseArguments(remainingArgs.DefaultIfEmpty("help"),
compoundVerb.SubVerbTypes.ToArray()
)
.WithParsed(
command => currentCommand = (Command)command
)
.WithNotParsed( _ => currentCommand = null );
break;
}
case Command command:
{
Console.WriteLine( $"Command: {currentCommand}" );
goto done;
}
}
}
done:
if (currentCommand != null)
Console.WriteLine( $"Final: {currentCommand}" );
}
}
public abstract class Command
{
}
public abstract class CompoundVerbCommand
: Command
{
public abstract IEnumerable<Type> SubVerbTypes { get; }
[Value(0)]
public IEnumerable<string> RemainingArgs { get; set; }
}
[Verb("verb1", HelpText = "Verb 1")]
public sealed class Verb1Command
: CompoundVerbCommand
{
[Option("ho")]
public bool Ho { get; set; }
[Option("pip")]
public int Pip { get; set; }
public override string ToString() => $"Verb1(Ho={Ho}, Pip={Pip})";
public override IEnumerable<Type> SubVerbTypes
{
get
{
yield return typeof(Verb1FooCommand);
yield return typeof(Verb1BarCommand);
}
}
}
[Verb("foo", HelpText = "Verb 1 Foo")]
public sealed class Verb1FooCommand
: Command
{
public override string ToString() => "Verb1Foo()";
}
[Verb("bar", HelpText = "Verb 1 Bar")]
public sealed class Verb1BarCommand
: CompoundVerbCommand
{
public override string ToString() => "Verb1Bar()";
public override IEnumerable<Type> SubVerbTypes
{
get
{
yield return typeof(Verb1BarDiddlyCommand);
yield return typeof(Verb1BarBoCommand);
}
}
}
[Verb("diddly", HelpText = "Verb 1 Bar Diddly")]
public sealed class Verb1BarDiddlyCommand
: Command
{
public override string ToString() => "Verb1BarDiddly()";
}
[Verb("bo", HelpText = "Verb 1 Bar Bo")]
public sealed class Verb1BarBoCommand
: Command
{
public override string ToString() => "Verb1BarBo()";
}
[Verb("verb2", HelpText = "Verb 2")]
public sealed class Verb2Command
: CompoundVerbCommand
{
public override string ToString() => "Verb2()";
public override IEnumerable<Type> SubVerbTypes
{
get
{
yield return typeof(Verb2BazCommand);
yield return typeof(Verb2BonkCommand);
}
}
}
[Verb("baz", HelpText = "Verb 2 Baz")]
public sealed class Verb2BazCommand
: Command
{
public override string ToString() => "Verb2Baz()";
}
[Verb("bonk", HelpText = "Verb 2 Bonk")]
public sealed class Verb2BonkCommand
: Command
{
public override string ToString() => "Verb2Bonk()";
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment