Skip to content

Commit 00c34e8

Browse files
authored
Merge pull request #557 from moh-hassan/HelpText
Enhance HelpText customization using a new overload AutoBuild method.
2 parents 58b4f0b + b8169cd commit 00c34e8

File tree

3 files changed

+209
-81
lines changed

3 files changed

+209
-81
lines changed

src/CommandLine/Text/CopyrightInfo.cs

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,11 @@ public class CopyrightInfo
2727
/// <summary>
2828
/// An empty object used for initialization.
2929
/// </summary>
30-
public static CopyrightInfo Empty
30+
public static CopyrightInfo Empty
3131
{
3232
get
3333
{
34-
return new CopyrightInfo("author", 1);
34+
return new CopyrightInfo("author", DateTime.Now.Year);
3535
}
3636
}
3737

@@ -115,12 +115,13 @@ public static CopyrightInfo Default
115115
case MaybeType.Just:
116116
return new CopyrightInfo(copyrightAttr.FromJustOrFail());
117117
default:
118-
// if no copyright attribute exist but a company attribute does, use it as copyright holder
119-
return new CopyrightInfo(
120-
ReflectionHelper.GetAttribute<AssemblyCompanyAttribute>().FromJustOrFail(
121-
new InvalidOperationException("CopyrightInfo::Default requires that you define AssemblyCopyrightAttribute or AssemblyCompanyAttribute.")
122-
).Company,
123-
DateTime.Now.Year);
118+
var companyAttr = ReflectionHelper.GetAttribute<AssemblyCompanyAttribute>();
119+
return companyAttr.IsNothing()
120+
//if both copyrightAttr and companyAttr aren't available in Assembly,don't fire Exception
121+
? Empty
122+
// if no copyright attribute exist but a company attribute does, use it as copyright holder
123+
: new CopyrightInfo(companyAttr.FromJust().Company, DateTime.Now.Year);
124+
124125
}
125126
}
126127
}
@@ -192,4 +193,4 @@ protected virtual string FormatYears(int[] years)
192193
return yearsPart.ToString();
193194
}
194195
}
195-
}
196+
}

src/CommandLine/Text/HelpText.cs

Lines changed: 41 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -266,7 +266,7 @@ public bool AdditionalNewLineAfterOption
266266
/// </summary>
267267
public bool AddNewLineBetweenHelpSections
268268
{
269-
get { return addNewLineBetweenHelpSections; }
269+
get { return addNewLineBetweenHelpSections; }
270270
set { addNewLineBetweenHelpSections = value; }
271271
}
272272

@@ -389,7 +389,7 @@ public static HelpText AutoBuild<T>(
389389
}
390390

391391
/// <summary>
392-
/// Creates a new instance of the <see cref="CommandLine.Text.HelpText"/> class,
392+
/// Creates a default instance of the <see cref="CommandLine.Text.HelpText"/> class,
393393
/// automatically handling verbs or options scenario.
394394
/// </summary>
395395
/// <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>
@@ -400,6 +400,23 @@ public static HelpText AutoBuild<T>(
400400
/// <remarks>This feature is meant to be invoked automatically by the parser, setting the HelpWriter property
401401
/// of <see cref="CommandLine.ParserSettings"/>.</remarks>
402402
public static HelpText AutoBuild<T>(ParserResult<T> parserResult, int maxDisplayWidth = DefaultMaximumLength)
403+
{
404+
return AutoBuild<T>(parserResult, h => h, maxDisplayWidth);
405+
}
406+
407+
/// <summary>
408+
/// Creates a custom instance of the <see cref="CommandLine.Text.HelpText"/> class,
409+
/// automatically handling verbs or options scenario.
410+
/// </summary>
411+
/// <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>
412+
/// <param name='onError'>A delegate used to customize the text block of reporting parsing errors text block.</param>
413+
/// <param name="maxDisplayWidth">The maximum width of the display.</param>
414+
/// <returns>
415+
/// An instance of <see cref="CommandLine.Text.HelpText"/> class.
416+
/// </returns>
417+
/// <remarks>This feature is meant to be invoked automatically by the parser, setting the HelpWriter property
418+
/// of <see cref="CommandLine.ParserSettings"/>.</remarks>
419+
public static HelpText AutoBuild<T>(ParserResult<T> parserResult, Func<HelpText, HelpText> onError, int maxDisplayWidth = DefaultMaximumLength)
403420
{
404421
if (parserResult.Tag != ParserResultType.NotParsed)
405422
throw new ArgumentException("Excepting NotParsed<T> type.", "parserResult");
@@ -410,13 +427,25 @@ public static HelpText AutoBuild<T>(ParserResult<T> parserResult, int maxDisplay
410427
return new HelpText($"{HeadingInfo.Default}{Environment.NewLine}") { MaximumDisplayWidth = maxDisplayWidth }.AddPreOptionsLine(Environment.NewLine);
411428

412429
if (!errors.Any(e => e.Tag == ErrorType.HelpVerbRequestedError))
413-
return AutoBuild(parserResult, current => DefaultParsingErrorsHandler(parserResult, current), e => e, maxDisplayWidth: maxDisplayWidth);
430+
return AutoBuild(parserResult, current =>
431+
{
432+
onError?.Invoke(current);
433+
return DefaultParsingErrorsHandler(parserResult, current);
434+
}, e => e, maxDisplayWidth: maxDisplayWidth);
414435

415436
var err = errors.OfType<HelpVerbRequestedError>().Single();
416-
var pr = new NotParsed<object>(TypeInfo.Create(err.Type), Enumerable.Empty<Error>());
437+
var pr = new NotParsed<object>(TypeInfo.Create(err.Type), new Error[] { err });
417438
return err.Matched
418-
? AutoBuild(pr, current => DefaultParsingErrorsHandler(pr, current), e => e, maxDisplayWidth: maxDisplayWidth)
419-
: AutoBuild(parserResult, current => DefaultParsingErrorsHandler(parserResult, current), e => e, true, maxDisplayWidth);
439+
? AutoBuild(pr, current =>
440+
{
441+
onError?.Invoke(current);
442+
return DefaultParsingErrorsHandler(pr, current);
443+
}, e => e, maxDisplayWidth: maxDisplayWidth)
444+
: AutoBuild(parserResult, current =>
445+
{
446+
onError?.Invoke(current);
447+
return DefaultParsingErrorsHandler(parserResult, current);
448+
}, e => e, true, maxDisplayWidth);
420449
}
421450

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

432461
if (((NotParsed<T>)parserResult).Errors.OnlyMeaningfulOnes().Empty())
433462
return current;
434-
435463
var errors = RenderParsingErrorsTextAsLines(parserResult,
436464
current.SentenceBuilder.FormatError,
437465
current.SentenceBuilder.FormatMutuallyExclusiveSetErrors,
@@ -732,8 +760,8 @@ public override string ToString()
732760
var result = new StringBuilder(sbLength);
733761

734762
result.Append(heading)
735-
.AppendWhen(!string.IsNullOrEmpty(copyright),
736-
Environment.NewLine,
763+
.AppendWhen(!string.IsNullOrEmpty(copyright),
764+
Environment.NewLine,
737765
copyright)
738766
.AppendWhen(preOptionsHelp.SafeLength() > 0,
739767
NewLineIfNeededBefore(preOptionsHelp),
@@ -743,15 +771,15 @@ public override string ToString()
743771
Environment.NewLine,
744772
Environment.NewLine,
745773
optionsHelp.SafeToString())
746-
.AppendWhen(postOptionsHelp.SafeLength() > 0,
774+
.AppendWhen(postOptionsHelp.SafeLength() > 0,
747775
NewLineIfNeededBefore(postOptionsHelp),
748776
Environment.NewLine,
749777
postOptionsHelp.ToString());
750778

751779
string NewLineIfNeededBefore(StringBuilder sb)
752780
{
753-
if (AddNewLineBetweenHelpSections
754-
&& result.Length > 0
781+
if (AddNewLineBetweenHelpSections
782+
&& result.Length > 0
755783
&& !result.SafeEndsWith(Environment.NewLine)
756784
&& !sb.SafeStartsWith(Environment.NewLine))
757785
return Environment.NewLine;
@@ -952,7 +980,7 @@ specification is OptionSpecification optionSpecification &&
952980

953981
if (optionGroupSpecification != null)
954982
{
955-
optionHelpText = "({0}: {1}) ".FormatInvariant(optionGroupWord, optionGroupSpecification.Group) + optionHelpText;
983+
optionHelpText = "({0}: {1}) ".FormatInvariant(optionGroupWord, optionGroupSpecification.Group) + optionHelpText;
956984
}
957985

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

0 commit comments

Comments
 (0)