Permalink
Find file Copy path
139 lines (113 sloc) 3.99 KB
// Copyright (c) Nate McMaster.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using System.Reflection;
using McMaster.Extensions.CommandLineUtils;
namespace SubcommandSample
{
/// <summary>
/// In this example, each sub command type inherits from <see cref="GitCommandBase"/>,
/// which provides shared functionality between all the commands.
/// This example also shows you how the subcommands can be linked to their parent types.
/// </summary>
[Command("fake-git")]
[VersionOptionFromMember("--version", MemberName = nameof(GetVersion))]
[Subcommand(
typeof(AddCommand),
typeof(CommitCommand))]
class Git : GitCommandBase
{
public static void Main(string[] args) => CommandLineApplication.Execute<Git>(args);
[Option("-C <path>")]
[FileExists]
public string ConfigFile { get; set; }
[Option("-c <name>=<value>")]
public string[] ConfigSetting { get; set; }
[Option("--exec-path[:<path>]")]
public (bool hasValue, string value) ExecPath { get; set; }
[Option("--bare")]
public bool Bare { get; }
[Option("--git-dir=<path>")]
[DirectoryExists]
public string GitDir { get; set; }
protected override int OnExecute(CommandLineApplication app)
{
// this shows help even if the --help option isn't specified
app.ShowHelp();
return 1;
}
public override List<string> CreateArgs()
{
var args = new List<string>();
if (GitDir != null)
{
args.Add("--git-dir=" + GitDir);
}
return args;
}
private static string GetVersion()
=> typeof(Git).Assembly.GetCustomAttribute<AssemblyInformationalVersionAttribute>().InformationalVersion;
}
[Command(Description = "Add file contents to the index")]
class AddCommand : GitCommandBase
{
[Argument(0)]
[LegalFilePath]
public string[] Files { get; set; }
// You can use this pattern when the parent command may have options or methods you want to
// use from sub-commands.
// This will automatically be set before OnExecute is invoked
private Git Parent { get; set; }
protected override int OnExecute(CommandLineApplication app)
{
app.ShowHelp();
return base.OnExecute(app);
}
public override List<string> CreateArgs()
{
var args = Parent.CreateArgs();
args.Add("add");
if (Files != null)
{
args.AddRange(Files);
}
return args;
}
}
[Command(Description = "Record changes to the repository")]
class CommitCommand : GitCommandBase
{
[Option("-m")]
public string Message { get; set; }
// This will automatically be set before OnExecute is invoked.
private Git Parent { get; set; }
public override List<string> CreateArgs()
{
var args = Parent.CreateArgs();
args.Add("commit");
if (Message != null)
{
args.Add("-m");
args.Add(Message);
}
return args;
}
}
/// <summary>
/// This base type provides shared functionality.
/// Also, declaring <see cref="HelpOptionAttribute"/> on this type means all types that inherit from it
/// will automatically support '--help'
/// </summary>
[HelpOption("--help")]
abstract class GitCommandBase
{
public abstract List<string> CreateArgs();
protected virtual int OnExecute(CommandLineApplication app)
{
var args = CreateArgs();
Console.WriteLine("Result = git " + ArgumentEscaper.EscapeAndConcatenate(args));
return 0;
}
}
}