Skip to content

Commit

Permalink
Merge pull request #557 from moh-hassan/HelpText
Browse files Browse the repository at this point in the history
Enhance HelpText customization using a new overload AutoBuild method.
  • Loading branch information
moh-hassan authored Dec 31, 2019
2 parents 58b4f0b + b8169cd commit 00c34e8
Show file tree
Hide file tree
Showing 3 changed files with 209 additions and 81 deletions.
19 changes: 10 additions & 9 deletions src/CommandLine/Text/CopyrightInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,11 @@ public class CopyrightInfo
/// <summary>
/// An empty object used for initialization.
/// </summary>
public static CopyrightInfo Empty
public static CopyrightInfo Empty
{
get
{
return new CopyrightInfo("author", 1);
return new CopyrightInfo("author", DateTime.Now.Year);
}
}

Expand Down Expand Up @@ -115,12 +115,13 @@ public static CopyrightInfo Default
case MaybeType.Just:
return new CopyrightInfo(copyrightAttr.FromJustOrFail());
default:
// if no copyright attribute exist but a company attribute does, use it as copyright holder
return new CopyrightInfo(
ReflectionHelper.GetAttribute<AssemblyCompanyAttribute>().FromJustOrFail(
new InvalidOperationException("CopyrightInfo::Default requires that you define AssemblyCopyrightAttribute or AssemblyCompanyAttribute.")
).Company,
DateTime.Now.Year);
var companyAttr = ReflectionHelper.GetAttribute<AssemblyCompanyAttribute>();
return companyAttr.IsNothing()
//if both copyrightAttr and companyAttr aren't available in Assembly,don't fire Exception
? Empty
// if no copyright attribute exist but a company attribute does, use it as copyright holder
: new CopyrightInfo(companyAttr.FromJust().Company, DateTime.Now.Year);

}
}
}
Expand Down Expand Up @@ -192,4 +193,4 @@ protected virtual string FormatYears(int[] years)
return yearsPart.ToString();
}
}
}
}
54 changes: 41 additions & 13 deletions src/CommandLine/Text/HelpText.cs
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,7 @@ public bool AdditionalNewLineAfterOption
/// </summary>
public bool AddNewLineBetweenHelpSections
{
get { return addNewLineBetweenHelpSections; }
get { return addNewLineBetweenHelpSections; }
set { addNewLineBetweenHelpSections = value; }
}

Expand Down Expand Up @@ -389,7 +389,7 @@ public static HelpText AutoBuild<T>(
}

/// <summary>
/// Creates a new instance of the <see cref="CommandLine.Text.HelpText"/> class,
/// Creates a default instance of the <see cref="CommandLine.Text.HelpText"/> class,
/// automatically handling verbs or options scenario.
/// </summary>
/// <param name='parserResult'>The <see cref="CommandLine.ParserResult{T}"/> containing the instance that collected command line arguments parsed with <see cref="CommandLine.Parser"/> class.</param>
Expand All @@ -400,6 +400,23 @@ public static HelpText AutoBuild<T>(
/// <remarks>This feature is meant to be invoked automatically by the parser, setting the HelpWriter property
/// of <see cref="CommandLine.ParserSettings"/>.</remarks>
public static HelpText AutoBuild<T>(ParserResult<T> parserResult, int maxDisplayWidth = DefaultMaximumLength)
{
return AutoBuild<T>(parserResult, h => h, maxDisplayWidth);
}

/// <summary>
/// Creates a custom instance of the <see cref="CommandLine.Text.HelpText"/> class,
/// automatically handling verbs or options scenario.
/// </summary>
/// <param name='parserResult'>The <see cref="CommandLine.ParserResult{T}"/> containing the instance that collected command line arguments parsed with <see cref="CommandLine.Parser"/> class.</param>
/// <param name='onError'>A delegate used to customize the text block of reporting parsing errors text block.</param>
/// <param name="maxDisplayWidth">The maximum width of the display.</param>
/// <returns>
/// An instance of <see cref="CommandLine.Text.HelpText"/> class.
/// </returns>
/// <remarks>This feature is meant to be invoked automatically by the parser, setting the HelpWriter property
/// of <see cref="CommandLine.ParserSettings"/>.</remarks>
public static HelpText AutoBuild<T>(ParserResult<T> parserResult, Func<HelpText, HelpText> onError, int maxDisplayWidth = DefaultMaximumLength)
{
if (parserResult.Tag != ParserResultType.NotParsed)
throw new ArgumentException("Excepting NotParsed<T> type.", "parserResult");
Expand All @@ -410,13 +427,25 @@ public static HelpText AutoBuild<T>(ParserResult<T> parserResult, int maxDisplay
return new HelpText($"{HeadingInfo.Default}{Environment.NewLine}") { MaximumDisplayWidth = maxDisplayWidth }.AddPreOptionsLine(Environment.NewLine);

if (!errors.Any(e => e.Tag == ErrorType.HelpVerbRequestedError))
return AutoBuild(parserResult, current => DefaultParsingErrorsHandler(parserResult, current), e => e, maxDisplayWidth: maxDisplayWidth);
return AutoBuild(parserResult, current =>
{
onError?.Invoke(current);
return DefaultParsingErrorsHandler(parserResult, current);
}, e => e, maxDisplayWidth: maxDisplayWidth);

var err = errors.OfType<HelpVerbRequestedError>().Single();
var pr = new NotParsed<object>(TypeInfo.Create(err.Type), Enumerable.Empty<Error>());
var pr = new NotParsed<object>(TypeInfo.Create(err.Type), new Error[] { err });
return err.Matched
? AutoBuild(pr, current => DefaultParsingErrorsHandler(pr, current), e => e, maxDisplayWidth: maxDisplayWidth)
: AutoBuild(parserResult, current => DefaultParsingErrorsHandler(parserResult, current), e => e, true, maxDisplayWidth);
? AutoBuild(pr, current =>
{
onError?.Invoke(current);
return DefaultParsingErrorsHandler(pr, current);
}, e => e, maxDisplayWidth: maxDisplayWidth)
: AutoBuild(parserResult, current =>
{
onError?.Invoke(current);
return DefaultParsingErrorsHandler(parserResult, current);
}, e => e, true, maxDisplayWidth);
}

/// <summary>
Expand All @@ -431,7 +460,6 @@ public static HelpText DefaultParsingErrorsHandler<T>(ParserResult<T> parserResu

if (((NotParsed<T>)parserResult).Errors.OnlyMeaningfulOnes().Empty())
return current;

var errors = RenderParsingErrorsTextAsLines(parserResult,
current.SentenceBuilder.FormatError,
current.SentenceBuilder.FormatMutuallyExclusiveSetErrors,
Expand Down Expand Up @@ -732,8 +760,8 @@ public override string ToString()
var result = new StringBuilder(sbLength);

result.Append(heading)
.AppendWhen(!string.IsNullOrEmpty(copyright),
Environment.NewLine,
.AppendWhen(!string.IsNullOrEmpty(copyright),
Environment.NewLine,
copyright)
.AppendWhen(preOptionsHelp.SafeLength() > 0,
NewLineIfNeededBefore(preOptionsHelp),
Expand All @@ -743,15 +771,15 @@ public override string ToString()
Environment.NewLine,
Environment.NewLine,
optionsHelp.SafeToString())
.AppendWhen(postOptionsHelp.SafeLength() > 0,
.AppendWhen(postOptionsHelp.SafeLength() > 0,
NewLineIfNeededBefore(postOptionsHelp),
Environment.NewLine,
postOptionsHelp.ToString());

string NewLineIfNeededBefore(StringBuilder sb)
{
if (AddNewLineBetweenHelpSections
&& result.Length > 0
if (AddNewLineBetweenHelpSections
&& result.Length > 0
&& !result.SafeEndsWith(Environment.NewLine)
&& !sb.SafeStartsWith(Environment.NewLine))
return Environment.NewLine;
Expand Down Expand Up @@ -952,7 +980,7 @@ specification is OptionSpecification optionSpecification &&

if (optionGroupSpecification != null)
{
optionHelpText = "({0}: {1}) ".FormatInvariant(optionGroupWord, optionGroupSpecification.Group) + optionHelpText;
optionHelpText = "({0}: {1}) ".FormatInvariant(optionGroupWord, optionGroupSpecification.Group) + optionHelpText;
}

//note that we need to indent trim the start of the string because it's going to be
Expand Down
Loading

0 comments on commit 00c34e8

Please sign in to comment.