Skip to content

Commit

Permalink
better help
Browse files Browse the repository at this point in the history
  • Loading branch information
adrianaisemberg committed Mar 13, 2012
1 parent c86d279 commit 5a56e02
Show file tree
Hide file tree
Showing 5 changed files with 185 additions and 41 deletions.
168 changes: 146 additions & 22 deletions CLAP/HelpGenerator.cs
@@ -1,4 +1,5 @@
using System.Collections.Generic;
using System.Text;

#if !FW2
using System.Linq;
Expand Down Expand Up @@ -33,7 +34,130 @@ internal static string GetHelp(IEnumerable<ParserRunner> parsers)

private static string GetHelpString(HelpInfo helpInfo)
{
return "";
const string verbsLead = " ";
const string parametersLead = " ";
const string validationsLead = " ";

var sb = new StringBuilder();

var count = helpInfo.Parsers.Count;
var multi = count > 1;

for (int i = 0; i < count; i++)
{
var parser = helpInfo.Parsers[i];

foreach (var verb in parser.Verbs.OrderBy(v => v.Names.First()))
{
sb.AppendLine();
sb.Append(verbsLead);

if (multi)
{
sb.AppendFormat("{0}.", parser.Type.Name.ToLowerInvariant());
}

sb.AppendLine(verb.Names.StringJoin("|").ToLowerInvariant());

if (verb.Parameters.Any())
{
var longestParameter = verb.Parameters.Max(p => p.Names.StringJoin("|").Length);
var longestType = verb.Parameters.Max(p => p.Type.GetGenericTypeName().Length);

foreach (var p in verb.Parameters.OrderBy(p => p.Names.First()))
{
sb.Append(parametersLead);
sb.AppendFormat("/{0} : ",
p.Names.StringJoin("|").ToLowerInvariant().PadRight(longestParameter, ' '));

sb.AppendFormat("<{0}> ", p.Type.GetGenericTypeName());

if (!string.IsNullOrEmpty(p.Description))
{
sb.AppendFormat("{0} ", p.Description);
}

if (p.Required)
{
sb.Append("(Required) ");
}

if (p.Default != null)
{
sb.AppendFormat("(Default = {0}) ", p.Default);
}

if (p.Validations.Any())
{
sb.AppendFormat("({0}) ", p.Validations.StringJoin(", "));
}

sb.AppendLine();
} // foreach (var p in verb.Parameters
}

if (verb.Validations.Any())
{
sb.AppendLine();
sb.Append(parametersLead);
sb.AppendLine("Validation:");

foreach (var v in verb.Validations)
{
sb.Append(validationsLead);
sb.AppendLine(v);
}
}

} // foreach (var verb in parser.Verbs

if (parser.Globals.Any())
{
sb.AppendLine();

var longestGlobal = parser.Globals.Max(p => p.Names.StringJoin("|").Length);

foreach (var g in parser.Globals.OrderBy(g => g.Names.First()))
{
sb.Append(verbsLead);
sb.AppendFormat("/{0} : ",
g.Names.StringJoin("|").ToLowerInvariant().PadRight(longestGlobal, ' '));

sb.AppendFormat("<{0}> ", g.Type.GetGenericTypeName());

if (!string.IsNullOrEmpty(g.Description))
{
sb.AppendFormat("{0} ", g.Description);
}

if (g.Required)
{
sb.Append("(Required) ");
}

if (g.Default != null)
{
sb.AppendFormat("(Default = {0}) ", g.Default);
}

if (g.Validations.Any())
{
sb.AppendFormat("({0}) ", g.Validations.StringJoin(", "));
}

sb.AppendLine();
} // foreach (var g in parser.Globals
}

if (multi && i < count - 1)
{
sb.AppendLine();
sb.Append(verbsLead);
sb.AppendLine(string.Empty.PadRight(80, '-'));
}
}

return sb.ToString();
}

private static ParserHelpInfo GetParserHelp(ParserRunner parser)
Expand All @@ -43,42 +167,42 @@ private static ParserHelpInfo GetParserHelp(ParserRunner parser)
Type = parser.Type,
Verbs = parser.GetVerbs().Select(verb => new VerbHelpInfo
{
Names = verb.Names.Union(new[] { verb.MethodInfo.Name }).ToList(),
Names = verb.Names.OrderBy(n => n.Length).ToList(),
Description = verb.Description,
IsDefault = verb.IsDefault,
Validations = verb.MethodInfo.GetInterfaceAttributes<ICollectionValidation>().Select(v => v.Description).ToList(),
Parameters = ParserRunner.GetParameters(verb.MethodInfo).
Select(p => new ParameterHelpInfo
{
Required = p.Required,
Names = p.Names,
Names = p.Names.OrderBy(n => n.Length).ToList(),
Type = p.ParameterInfo.ParameterType,
Default = p.DefaultProvider != null ? p.DefaultProvider.Description : p.Default,
Description = p.Description,
Validations = p.ParameterInfo.GetAttributes<ValidationAttribute>().Select(v => v.Description).ToList(),
}).ToList(),
}).ToList(),
Globals = parser.GetDefinedGlobals().
Select(g =>
{
var att = g.GetAttribute<GlobalAttribute>();
var parameter = ParserRunner.GetParameters(g).FirstOrDefault();
Globals = parser.GetDefinedGlobals().Select(g =>
{
var att = g.GetAttribute<GlobalAttribute>();
var parameter = ParserRunner.GetParameters(g).FirstOrDefault();
return new ParameterHelpInfo
{
IsGlobal = true,
Names = att.Aliases.CommaSplit().Union(new[] { att.Name ?? g.Name }).ToList(),
Type = parameter != null ? parameter.ParameterInfo.ParameterType : typeof(bool),
Description = att.Description,
Validations = g.GetInterfaceAttributes<ICollectionValidation>().Select(v => v.Description).ToList(),
};
})
.Union(parser.Register.RegisteredGlobalHandlers.Values.Select(handler => new ParameterHelpInfo
return new ParameterHelpInfo
{
Names = handler.Names.ToList(),
Type = handler.Type,
Description = handler.Desription,
})).ToList(),
IsGlobal = true,
Names = att.Aliases.CommaSplit().Union(new[] { att.Name ?? g.Name }).OrderBy(n => n.Length).ToList(),
Type = parameter != null ? parameter.ParameterInfo.ParameterType : typeof(bool),
Description = att.Description,
Validations = g.GetInterfaceAttributes<ICollectionValidation>().Select(v => v.Description).ToList(),
};
}).Union(parser.Register.RegisteredGlobalHandlers.Values.Select(handler => new ParameterHelpInfo
{
IsGlobal = true,
Names = handler.Names.OrderBy(n => n.Length).ToList(),
Type = handler.Type,
Description = handler.Desription,
Validations = new List<string>(),
})).ToList(),
};
}
}
Expand Down
3 changes: 1 addition & 2 deletions CLAP/Method.cs
Expand Up @@ -56,8 +56,7 @@ internal Method(MethodInfo method)

if (verbAttribute.Aliases != null)
{
Names.AddRange(
verbAttribute.Aliases.ToLowerInvariant().CommaSplit());
Names.AddRange(verbAttribute.Aliases.ToLowerInvariant().CommaSplit());
}
}

Expand Down
4 changes: 2 additions & 2 deletions CLAP/ParserRegistration.cs
Expand Up @@ -73,10 +73,10 @@ public void EmptyHelpHandler(Action<string> handler)
throw new ArgumentNullException("handler");
}

var help = HelpGetter();

EmptyHandler(delegate
{
var help = HelpGetter();

handler(help);
});
}
Expand Down
18 changes: 7 additions & 11 deletions CLAP/ParserRunner.cs
Expand Up @@ -382,8 +382,8 @@ private static void ValidateParameterDefaults(IEnumerable<Method> verbs)

// make sure all default providers are DefaultProvider
//
bad = dict.Where(kvp =>
kvp.Key.DefaultProvider != null &&
bad = dict.Where(kvp =>
kvp.Key.DefaultProvider != null &&
!typeof(DefaultProvider).IsAssignableFrom(kvp.Key.DefaultProvider));

if (bad.Any())
Expand Down Expand Up @@ -676,15 +676,11 @@ private bool HandleHelp(string firstArg, object target)

Action<string> helpHandler = GetRegisteredHelpHandler(arg);

var help = HelpGenerator.GetHelp(this);

var helpHandled = false;

if (helpHandler != null)
{
helpHandler(help);
helpHandler(HelpGenerator.GetHelp(this));

helpHandled = true;
return true;
}

var definedHelpMethods = Type.GetMethodsWith<HelpAttribute>();
Expand All @@ -704,9 +700,9 @@ private bool HandleHelp(string firstArg, object target)

var obj = method.IsStatic ? null : target;

MethodInvoker.Invoke(method, obj, new[] { help });
MethodInvoker.Invoke(method, obj, new[] { HelpGenerator.GetHelp(this) });

helpHandled = true;
return true;
}
catch (TargetParameterCountException ex)
{
Expand All @@ -719,7 +715,7 @@ private bool HandleHelp(string firstArg, object target)
}
}

return helpHandled;
return false;
}

internal void HandleEmptyArguments(object target)
Expand Down
33 changes: 29 additions & 4 deletions ConsoleTest/Program.cs
Expand Up @@ -13,7 +13,7 @@ class Program
{
static void Main(string[] args)
{
Parser.RunConsole<DefaultApp>(args);
Parser.RunConsole<ClapApp, SomeApp, TheApp>(args);
}
}

Expand Down Expand Up @@ -90,11 +90,36 @@ public static void Bar(int[] numbers, [Parameter(Aliases = "n,nms", Required = t

[Parameter(Required = true)]
bool rsw,
bool sw,
[Parameter(DefaultProvider = typeof(MyDefaultProvider1))] bool sw1,
[Parameter(DefaultProvider = typeof(MyDefaultProvider2))] bool sw2,
ClapApp clap)
{
}

public class MyDefaultProvider1 : DefaultProvider
{
public override object GetDefault(VerbExecutionContext context)
{
return "foo";
}
}

public class MyDefaultProvider2 : DefaultProvider
{
public override object GetDefault(VerbExecutionContext context)
{
return "foo";
}

public override string Description
{
get
{
return "A Default Provider";
}
}
}

[Help, Empty]
public static void Help(string h)
{
Expand Down Expand Up @@ -132,10 +157,10 @@ public static void SavePersons(IEnumerable<Person> p)
class BaseApp
{
[Error]
public static void Error(Exception ex)
public static void Error(ExceptionContext ex)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine(ex.Message);
Console.WriteLine(ex.Exception.Message);
Console.ResetColor();
}

Expand Down

0 comments on commit 5a56e02

Please sign in to comment.