Browse files

new help format

  • Loading branch information...
1 parent 2920911 commit dbfa809674718e2fa287bb6fd60b1db584b5ab0f @adrianaisemberg adrianaisemberg committed Nov 1, 2011
Showing with 395 additions and 42 deletions.
  1. +317 −0 CLAP/HelpGenerator.cs
  2. +10 −21 CLAP/ParserRegistration.cs
  3. +9 −12 CLAP/ParserRunner.cs
  4. +18 −0 CLAP/Utils.cs
  5. +27 −6 ConsoleTest/Program.cs
  6. +11 −1 Tests/Samples.cs
  7. +3 −2 Tests/Tests.cs
View
317 CLAP/HelpGenerator.cs
@@ -0,0 +1,317 @@
+using System;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+using System.Diagnostics;
+using System.Collections;
+
+namespace CLAP
+{
+ internal static class HelpGenerator
+ {
+ internal static string GetHelp(MultiParser parser)
+ {
+ var sb = new StringBuilder();
+
+ foreach (var type in parser.Types)
+ {
+ var pr = new ParserRunner(type, parser.Register);
+
+ sb.AppendLine(type.Name);
+ sb.AppendLine("".PadLeft(30, '-'));
+
+ sb.AppendLine(GetHelp(pr));
+
+ sb.AppendLine();
+ }
+
+ return sb.ToString();
+ }
+
+ internal static string GetHelp(ParserRunner parser)
+ {
+ var verbs = parser.GetVerbs();
+
+ if (verbs.None())
+ {
+ return string.Empty;
+ }
+
+ var sb = new StringBuilder();
+
+ foreach (var verb in verbs)
+ {
+ sb.AppendLine();
+
+ // verb name (title)
+ //
+ var name = verb.IsDefault ? verb.MethodInfo.Name + " [DEFAULT]" : verb.MethodInfo.Name;
+
+ sb.AppendLine(name);
+ sb.AppendLine(string.Empty.PadLeft(name.Length, '~'));
+
+ // description
+ //
+ if (!string.IsNullOrEmpty(verb.Description))
+ {
+ sb.AppendLine(verb.Description);
+
+ sb.AppendLine();
+ }
+
+ // all names
+ //
+ sb.Append(
+ verb.Names.
+ OrderBy(n => n.Length).
+ Select(n => n.ToUpperInvariant()).
+ StringJoin("|")).Append(" ");
+
+ // parameters
+ //
+ var parameters = ParserRunner.GetParameters(verb.MethodInfo);
+
+ foreach (var p in parameters)
+ {
+ if (!p.Required)
+ {
+ sb.Append("[");
+ }
+
+ sb.AppendFormat("/{0}", GetParameterNameAndType(p));
+
+ if (!p.Required)
+ {
+ sb.Append("]");
+ }
+
+ sb.Append(" ");
+ }
+
+ sb.AppendLine();
+
+ // parameters options
+ //
+ if (parameters.Any())
+ {
+ sb.AppendLine();
+ }
+
+ foreach (var p in parameters)
+ {
+ sb.Append(" /");
+ sb.Append(GetParameterNameAndType(p));
+ sb.AppendLine(GetParameterOption(p));
+ }
+
+ // verb validation
+ //
+ var validators = verb.MethodInfo.GetInterfaceAttributes<ICollectionValidation>();
+
+ if (validators.Any())
+ {
+ sb.AppendLine();
+ sb.AppendLine("Validation:");
+ sb.AppendLine("-----------");
+
+ foreach (var validator in validators)
+ {
+ sb.AppendLine(" - {0}".FormatWith(validator.Description));
+ }
+ }
+
+ sb.AppendLine();
+ sb.AppendLine(string.Empty.PadLeft(80, '='));
+ }
+
+ // globals
+ //
+ var definedGlobals = parser.GetDefinedGlobals();
+
+ if (parser.Register.RegisteredGlobalHandlers.Any() || definedGlobals.Any())
+ {
+ sb.AppendLine();
+ sb.AppendLine("Global Parameters:");
+ sb.AppendLine("------------------");
+ sb.AppendLine();
+
+ foreach (var handler in parser.Register.RegisteredGlobalHandlers.Values)
+ {
+ sb.AppendLine(" /{0}=<{1}>".FormatWith(
+ handler.Names.
+ OrderBy(n => n.Length).
+ Select(n => n.ToUpperInvariant()).
+ StringJoin("|"),
+ handler.Type.GetGenericTypeName()));
+
+ if (!string.IsNullOrEmpty(handler.Desription))
+ {
+ sb.AppendLine(" {0}".FormatWith(handler.Desription));
+ sb.AppendLine();
+ }
+ }
+
+ foreach (var handler in definedGlobals)
+ {
+ sb.AppendLine(" /{0}".FormatWith(GetDefinedGlobalHelpString(handler)));
+ }
+ }
+
+ return sb.ToString();
+ }
+
+ private static string GetDefinedGlobalHelpString(MethodInfo method)
+ {
+ var sb = new StringBuilder();
+
+ var globalAtt = method.GetAttribute<GlobalAttribute>();
+
+ // name
+ //
+ var name = globalAtt.Name ?? method.Name;
+
+ var names = globalAtt.Aliases.CommaSplit().
+ Union(new[] { name }).
+ OrderBy(n => n.Length).
+ Select(n => n.ToUpperInvariant()).
+ StringJoin("|");
+
+ sb.Append(names);
+
+ // type
+ //
+ var parameters = ParserRunner.GetParameters(method);
+ if (parameters.Any())
+ {
+ // can't be more than one parameter
+ //
+ var p = parameters.First();
+
+ sb.Append("=<{0}>".FormatWith(p.ParameterInfo.ParameterType.GetGenericTypeName()));
+
+ sb.Append(GetParameterOption(p));
+ }
+ else // bool switch
+ {
+
+ }
+
+ var lineAdded = false;
+
+ // description
+ //
+ if (!string.IsNullOrEmpty(globalAtt.Description))
+ {
+ sb.AppendLine();
+ sb.AppendLine(" {0}".FormatWith(globalAtt.Description));
+
+ lineAdded = true;
+ }
+
+ // validations
+ //
+ var validators = method.GetInterfaceAttributes<ICollectionValidation>();
+
+ if (validators.Any() && !lineAdded)
+ {
+ sb.AppendLine();
+ }
+
+ foreach (var validator in validators)
+ {
+ sb.AppendLine(" {0}".FormatWith(validator.Description));
+ }
+
+ return sb.ToString();
+ }
+
+ private static string GetParameterNameAndType(Parameter p)
+ {
+ var sb = new StringBuilder();
+
+ sb.Append(p.Names.
+ OrderBy(n => n.Length).
+ Select(n => n.ToUpperInvariant()).
+ StringJoin("|"));
+
+ // not a switch - print the type
+ //
+ if (p.ParameterInfo.ParameterType != typeof(bool))
+ {
+ sb.AppendFormat("=<{0}>", p.ParameterInfo.ParameterType.GetGenericTypeName());
+ }
+
+ // if it is a required switch
+ //
+ else if (p.Required)
+ {
+ sb.Append("[=<true|false>]");
+ }
+
+ return sb.ToString();
+ }
+
+ private static string GetParameterOption(Parameter p)
+ {
+ var sb = new StringBuilder();
+
+ // required
+ //
+ if (p.Required)
+ {
+ sb.Append(", Required");
+ }
+
+ // default value
+ //
+ if (p.Default != null)
+ {
+ sb.AppendFormat(", Default = {0}", p.Default);
+ }
+
+ // enum values
+ //
+ if (p.ParameterInfo.ParameterType.IsEnum)
+ {
+ sb.AppendLine();
+ sb.AppendLine(" Options:");
+ sb.AppendLine(" --------");
+
+ var values = Enum.GetNames(p.ParameterInfo.ParameterType);
+
+ foreach (var v in values)
+ {
+ sb.AppendLine(" {0}".FormatWith(v));
+ }
+ }
+
+ var lineAdded = false;
+
+ // description
+ //
+ if (!string.IsNullOrEmpty(p.Description))
+ {
+ sb.AppendLine();
+ sb.AppendLine(" {0}".FormatWith(p.Description));
+
+ lineAdded = true;
+ }
+
+ // validations
+ //
+ var validationAttributes = p.ParameterInfo.GetAttributes<ValidationAttribute>();
+
+ if (validationAttributes.Any() && !lineAdded)
+ {
+ sb.AppendLine();
+ }
+
+ foreach (var validationAttribute in validationAttributes)
+ {
+ sb.AppendLine(" {0}".FormatWith(validationAttribute.Description));
+ }
+
+ return sb.ToString();
+ }
+ }
+}
View
31 CLAP/ParserRegistration.cs
@@ -185,14 +185,6 @@ public void ParameterHandler<TParameter>(string names, Action<TParameter> action
private void RegisterParameterHandlerInternal<TParameter>(string names, Action<TParameter> action, string description)
{
- RegisterParameterHandlerInternal(
- names.CommaSplit(),
- action,
- description);
- }
-
- private void RegisterParameterHandlerInternal<TParameter>(IEnumerable<string> names, Action<TParameter> action, string description)
- {
var objectAction = new Action<string>(str =>
{
object v = null;
@@ -209,18 +201,15 @@ private void RegisterParameterHandlerInternal<TParameter>(IEnumerable<string> na
action((TParameter)v);
});
- foreach (var name in names)
- {
- RegisteredGlobalHandlers.Add(
- name,
- new GlobalParameterHandler
- {
- Name = name,
- Handler = objectAction,
- Desription = description,
- Type = typeof(TParameter),
- });
- }
+ RegisteredGlobalHandlers.Add(
+ names,
+ new GlobalParameterHandler
+ {
+ Names = names.CommaSplit(),
+ Handler = objectAction,
+ Desription = description,
+ Type = typeof(TParameter),
+ });
}
private void RegisterHelpHandlerInternal(string names, Action<string> helpHandler)
@@ -250,7 +239,7 @@ private void RegisterHelpHandlerInternal(IEnumerable<string> names, Action<strin
internal class GlobalParameterHandler
{
- internal string Name { get; set; }
+ internal IEnumerable<string> Names { get; set; }
internal Action<string> Handler { get; set; }
internal string Desription { get; set; }
internal Type Type { get; set; }
View
21 CLAP/ParserRunner.cs
@@ -411,7 +411,7 @@ private static void ValidateDefinedEmptyHandlers(Type type)
}
}
- private Action<string> GetHelpHandler(string input)
+ private Action<string> GetRegisteredHelpHandler(string input)
{
Debug.Assert(!string.IsNullOrEmpty(input));
@@ -530,11 +530,15 @@ private void HandleRegisteredGlobals(Dictionary<string, string> args)
foreach (var kvp in args)
{
- GlobalParameterHandler handler = null;
+ var key = m_registration.RegisteredGlobalHandlers.Keys.FirstOrDefault(
+ k => k.CommaSplit().Contains(kvp.Key));
- if (m_registration.RegisteredGlobalHandlers.TryGetValue(kvp.Key, out handler))
+ if (key != null)
{
+ var handler = m_registration.RegisteredGlobalHandlers[key];
+
handler.Handler(kvp.Value);
+
handled.Add(kvp.Key);
}
}
@@ -648,16 +652,14 @@ private bool HandleHelp(string firstArg, object target)
arg = firstArg.Substring(1);
}
- Action<string> helpHandler = GetHelpHandler(arg);
+ Action<string> helpHandler = GetRegisteredHelpHandler(arg);
- string help = null;
+ var help = HelpGenerator.GetHelp(this);
var helpHandled = false;
if (helpHandler != null)
{
- help = HelpGenerator.GetHelp(this);
-
helpHandler(help);
helpHandled = true;
@@ -680,11 +682,6 @@ private bool HandleHelp(string firstArg, object target)
var obj = method.IsStatic ? null : target;
- if (help == null)
- {
- help = HelpGenerator.GetHelp(this);
- }
-
MethodInvoker.Invoke(method, obj, new[] { help });
helpHandled = true;
View
18 CLAP/Utils.cs
@@ -140,5 +140,23 @@ public static bool Contains(this string str, IEnumerable<string> values)
{
return values.Any(v => str.Contains(v));
}
+
+ public static string GetGenericTypeName(this Type type)
+ {
+ if (!type.IsGenericType)
+ {
+ return type.Name;
+ }
+
+ var genericTypeName = type.GetGenericTypeDefinition().Name;
+
+ genericTypeName = genericTypeName.Remove(genericTypeName.IndexOf('`'));
+
+ var genericArgs = type.GetGenericArguments().
+ Select(a => GetGenericTypeName(a)).
+ StringJoin(",");
+
+ return "{0}<{1}>".FormatWith(genericTypeName, genericArgs);
+ }
}
}
View
33 ConsoleTest/Program.cs
@@ -5,14 +5,20 @@
using System.Threading;
using CLAP;
using CLAP.Validation;
+using System.Reflection;
namespace ConsoleTest
{
class Program
{
static void Main(string[] args)
{
- Parser.Run<ClapApp>(args);
+ var p = new Parser<ClapApp>();
+
+ p.Register.ParameterHandler<List<string>>("blonda,blnd", list => { });
+ p.Register.ParameterHandler<List<string>>("kramer,krmr,k", list => { }, "a sample description");
+
+ p.RunStatic(args);
}
}
@@ -24,19 +30,29 @@ public static void Foo(string bar, int count)
for (int i = 0; i < count; i++) Console.WriteLine("This parser {0}", bar);
}
- [Verb]
+ [Verb(Description = "bar somthing", Aliases = "b,barbar")]
[SameLength]
- public static void Bar(int[] numbers, string[] names)
+ public static void Bar(int[] numbers, [Parameter(Aliases = "n,nms", Required = true, Description = "some names")]string[] names)
{
for (int i = 0; i < numbers.Length; i++)
{
Console.WriteLine("{0}:{1}", numbers[i], names[i]);
}
}
- [Verb]
+ [Verb(IsDefault = true)]
[Validate("num1 + num2 >= num3")]
- public static void Zoo(int num1, int num2, int num3)
+ public static void Zoo(
+ int num1,
+ [MoreThan(10)] int num2,
+ [LessOrEqualTo(100)]
+ [Parameter(Default = 55, Description = "a number")] int num3,
+ BindingFlags bf,
+
+ [Parameter(Required = true)]
+ bool rsw,
+ bool sw,
+ ClapApp clap)
{
}
@@ -47,12 +63,17 @@ public static void Help(string h)
}
[Global]
+ public static void Cat([CLAP.Validation.RegexMatches("adasdadoiy3829834723xb378423c")]string x)
+ {
+ }
+
+ [Global(Description = "pong pong pong.")]
[Validate("num > 100")]
public static void Pong(int num)
{
}
- [Global(Aliases = "d")]
+ [Global(Aliases = "d", Description = "attach a debugger")]
public static void Debug()
{
Debugger.Launch();
View
12 Tests/Samples.cs
@@ -301,7 +301,7 @@ public void Print()
[Verb]
[Validate("str like 'foo*'")]
- public void Print2([Parameter(Required = true)]string str)
+ public void Print2([Parameter(Required = true, Description = "string!")]string str)
{
}
@@ -337,6 +337,16 @@ public void ShowHelp(string help)
{
Printer.Print("help");
}
+
+ [Global(Description = "cat!")]
+ public void Cat(Dictionary<string, Sample_10> x)
+ {
+ }
+
+ [Verb]
+ public void WithARequiredSwitch(string str, [Parameter(Required = true)] bool sw)
+ {
+ }
}
public class Sample_11 : BaseSample
View
5 Tests/Tests.cs
@@ -479,16 +479,17 @@ public void RegisterParameterHandler_CallsTheHandler_IgnoreTheValue()
// with and without description for coverage
//
- p.Register.ParameterHandler("dec", delegate { x--; });
+ p.Register.ParameterHandler("dec,d", delegate { x--; });
p.Register.ParameterHandler("inc", delegate { x++; }, "description");
p.Run("print /c=5 /msg=test /prefix=hello_ /inc".Split(' '), sample);
Assert.AreEqual(1, x);
p.Run("print /c=5 /msg=test /prefix=hello_ /dec".Split(' '), sample);
+ p.Run("print /c=5 /msg=test /prefix=hello_ /d".Split(' '), sample);
- Assert.AreEqual(0, x);
+ Assert.AreEqual(-1, x);
}
[Test]

0 comments on commit dbfa809

Please sign in to comment.