using System; using System.Collections.Generic; using System.ComponentModel; using System.IO; using System.Linq; using NDesk.Options; using Sep.Git.Tfs.Core; using Sep.Git.Tfs.Util; using StructureMap; using StructureMap.Pipeline; using StructureMap.Query; using IContainer = StructureMap.IContainer; namespace Sep.Git.Tfs.Commands { [Pluggable("help")] [Description("help [command-name]")] public class Help : GitTfsCommand { private readonly TextWriter output; private readonly GitTfsCommandFactory commandFactory; private readonly IContainer _container; public Help(TextWriter output, GitTfsCommandFactory commandFactory, IContainer container) { this.output = output; this.commandFactory = commandFactory; _container = container; } public OptionSet OptionSet { get { return new OptionSet(); } } /// /// Figures out whether it should show help for git-tfs or for /// a particular command, and then does that. /// public int Run(IList args) { foreach(var arg in args) { var command = commandFactory.GetCommand(arg); if(command != null) { return Run(command); } else { output.WriteLine("Invalid argument: " + arg); } } return Run(); } /// /// Shows help for git-tfs as a whole (i.e. a list of commands). /// public int Run() { output.WriteLine("Usage: git-tfs [command] [options]"); foreach(var pair in GetCommandMap()) { output.Write(" " + pair.Key); if (pair.Value.Any()) { output.WriteLine(" (" + string.Join(", ", pair.Value) + ")"); } else { output.WriteLine(); } } output.WriteLine(" (use 'git-tfs help [command]' for more information)"); return GitTfsExitCodes.Help; } /// /// Shows help for a specific command. /// public int Run(GitTfsCommand command) { if (command is Help) return Run(); output.WriteLine("Usage: git-tfs " + GetCommandUsage(command)); command.GetAllOptions(_container).WriteOptionDescriptions(output); return GitTfsExitCodes.Help; } private Dictionary> GetCommandMap() { return (from instance in GetCommandInstances() where instance.Name != null orderby instance.Name select instance.Name) .ToDictionary(s => s, s => commandFactory.GetAliasesForCommandName(s)); } private string GetCommandName(GitTfsCommand command) { return (from instance in GetCommandInstances() where instance.ConcreteType == command.GetType() select instance.Name).Single(); } private IEnumerable GetCommandInstances() { return _container.Model .PluginTypes .Single(p => p.PluginType == typeof (GitTfsCommand)) .Instances .Where(i => i != null); } private string GetCommandUsage(GitTfsCommand command) { var descriptionAttribute = command.GetType().GetCustomAttributes(typeof (DescriptionAttribute), false).FirstOrDefault() as DescriptionAttribute; var commandName = GetCommandName(command); return (descriptionAttribute != null) ? descriptionAttribute.Description : commandName + " [options]"; } } public interface IHelpHelper { int ShowHelp(GitTfsCommand command); int ShowHelpForInvalidArguments(GitTfsCommand command); } public class HelpHelper : IHelpHelper { private readonly IContainer _container; public HelpHelper(IContainer container) { _container = container; } public int ShowHelp(GitTfsCommand command) { return _container.GetInstance().Run(command); } public int ShowHelpForInvalidArguments(GitTfsCommand command) { ShowHelp(command); return GitTfsExitCodes.InvalidArguments; } } }