2020-12-21 20:42:55 -04:00
// Copyright Epic Games, Inc. All Rights Reserved.
using System ;
using System.Collections.Generic ;
using System.ComponentModel ;
using System.Linq ;
using System.Text ;
2022-03-24 16:35:00 -04:00
using Microsoft.Extensions.Logging ;
2020-12-21 20:42:55 -04:00
2020-12-21 23:07:37 -04:00
namespace EpicGames.Core
2020-12-21 20:42:55 -04:00
{
/// <summary>
/// Utility functions for showing help for objects
/// </summary>
public static class HelpUtils
{
/// <summary>
/// Gets the width of the window for formatting purposes
/// </summary>
2022-01-03 17:00:37 -05:00
public static int WindowWidth = > ConsoleUtils . WindowWidth ;
2020-12-21 20:42:55 -04:00
/// <summary>
/// Prints help for the given object type
/// </summary>
2022-03-24 16:35:00 -04:00
/// <param name="type">Type to print help for</param>
public static void PrintHelp ( string title , Type type )
2020-12-21 20:42:55 -04:00
{
2022-03-24 16:35:00 -04:00
PrintHelp ( title , GetDescription ( type ) , CommandLineArguments . GetParameters ( type ) ) ;
2020-12-21 20:42:55 -04:00
}
/// <summary>
/// Prints help for a command
/// </summary>
2022-03-24 16:35:00 -04:00
/// <param name="title">Title for the help text</param>
/// <param name="description">Description for the command</param>
/// <param name="parameters">List of parameters</param>
public static void PrintHelp ( string? title , string? description , List < KeyValuePair < string , string > > parameters )
2020-12-21 20:42:55 -04:00
{
bool bFirstLine = true ;
2022-03-24 16:35:00 -04:00
if ( ! String . IsNullOrEmpty ( title ) )
2020-12-21 20:42:55 -04:00
{
2022-03-24 16:35:00 -04:00
PrintParagraph ( title ) ;
2020-12-21 20:42:55 -04:00
bFirstLine = false ;
}
2022-03-24 16:35:00 -04:00
if ( ! String . IsNullOrEmpty ( description ) )
2020-12-21 20:42:55 -04:00
{
if ( ! bFirstLine )
{
2022-02-15 14:41:10 -05:00
Console . WriteLine ( "" ) ;
2020-12-21 20:42:55 -04:00
}
2022-03-24 16:35:00 -04:00
PrintParagraph ( description ) ;
2020-12-21 20:42:55 -04:00
bFirstLine = false ;
}
2022-03-24 16:35:00 -04:00
if ( parameters . Count > 0 )
2020-12-21 20:42:55 -04:00
{
if ( ! bFirstLine )
{
2022-02-15 14:41:10 -05:00
Console . WriteLine ( "" ) ;
2020-12-21 20:42:55 -04:00
}
2022-02-15 14:41:10 -05:00
Console . WriteLine ( "Parameters:" ) ;
2022-03-24 16:35:00 -04:00
PrintTable ( parameters , 4 , 24 ) ;
2020-12-21 20:42:55 -04:00
}
}
/// <summary>
/// Gets the description from a type
/// </summary>
2022-03-24 16:35:00 -04:00
/// <param name="type">The type to get a description for</param>
2020-12-21 20:42:55 -04:00
/// <returns>The description text</returns>
2022-03-24 16:35:00 -04:00
public static string GetDescription ( Type type )
2020-12-21 20:42:55 -04:00
{
2022-03-24 16:35:00 -04:00
StringBuilder descriptionText = new StringBuilder ( ) ;
foreach ( DescriptionAttribute attribute in type . GetCustomAttributes ( typeof ( DescriptionAttribute ) , false ) )
2020-12-21 20:42:55 -04:00
{
2022-03-24 16:35:00 -04:00
if ( descriptionText . Length > 0 )
2020-12-21 20:42:55 -04:00
{
2022-03-24 16:35:00 -04:00
descriptionText . AppendLine ( ) ;
2020-12-21 20:42:55 -04:00
}
2022-03-24 16:35:00 -04:00
descriptionText . AppendLine ( attribute . Description ) ;
2020-12-21 20:42:55 -04:00
}
2022-03-24 16:35:00 -04:00
return descriptionText . ToString ( ) ;
2020-12-21 20:42:55 -04:00
}
/// <summary>
/// Prints a paragraph of text using word wrapping
/// </summary>
2022-03-24 16:35:00 -04:00
/// <param name="text">Text to print</param>
2021-04-27 22:41:48 -04:00
/// <param name="Logger">Logger implementation to write to</param>
2022-03-24 16:35:00 -04:00
public static void PrintParagraph ( string text )
2020-12-21 20:42:55 -04:00
{
2022-03-24 16:35:00 -04:00
PrintParagraph ( text , WindowWidth - 1 ) ;
2020-12-21 20:42:55 -04:00
}
/// <summary>
/// Prints a paragraph of text using word wrapping
/// </summary>
2022-03-24 16:35:00 -04:00
/// <param name="text">Text to print</param>
/// <param name="maxWidth">Maximum width for each line</param>
public static void PrintParagraph ( string text , int maxWidth )
2020-12-21 20:42:55 -04:00
{
2022-03-24 16:35:00 -04:00
IEnumerable < string > lines = StringUtils . WordWrap ( text , maxWidth ) ;
foreach ( string line in lines )
2020-12-21 20:42:55 -04:00
{
2022-03-24 16:35:00 -04:00
Console . WriteLine ( line ) ;
2022-02-15 14:41:10 -05:00
}
}
/// <summary>
/// Prints an argument list to the console
/// </summary>
2022-03-24 16:35:00 -04:00
/// <param name="items">List of parameters arranged as "-ParamName Param Description"</param>
/// <param name="indent">Indent from the left hand side</param>
/// <param name="minFirstColumnWidth">The minimum padding from the start of the param name to the start of the description (resizes with larger param names)</param>
2022-02-15 14:41:10 -05:00
/// <returns></returns>
2022-03-24 16:35:00 -04:00
public static void PrintTable ( List < KeyValuePair < string , string > > items , int indent , int minFirstColumnWidth )
2022-02-15 14:41:10 -05:00
{
2022-03-24 16:35:00 -04:00
List < string > lines = new List < string > ( ) ;
FormatTable ( items , indent , minFirstColumnWidth , WindowWidth - 1 , lines ) ;
2022-02-15 14:41:10 -05:00
2022-03-24 16:35:00 -04:00
foreach ( string line in lines )
2022-02-15 14:41:10 -05:00
{
2022-03-24 16:35:00 -04:00
Console . WriteLine ( line ) ;
2022-02-15 14:41:10 -05:00
}
}
/// <summary>
/// Prints a table of items to a logging device
/// </summary>
2022-03-24 16:35:00 -04:00
/// <param name="items"></param>
/// <param name="indent"></param>
/// <param name="minFirstColumnWidth"></param>
/// <param name="maxWidth"></param>
/// <param name="logger"></param>
public static void PrintTable ( List < KeyValuePair < string , string > > items , int indent , int minFirstColumnWidth , int maxWidth , ILogger logger )
2022-02-15 14:41:10 -05:00
{
2022-03-24 16:35:00 -04:00
List < string > lines = new List < string > ( ) ;
FormatTable ( items , indent , minFirstColumnWidth , maxWidth , lines ) ;
2022-02-15 14:41:10 -05:00
2022-03-24 16:35:00 -04:00
foreach ( string line in lines )
2022-02-15 14:41:10 -05:00
{
2022-04-13 10:27:29 -04:00
logger . LogInformation ( "{Line}" , line ) ;
2020-12-21 20:42:55 -04:00
}
}
/// <summary>
/// Formats the given parameters as so:
/// -Param1 Param1 Description
///
/// -Param2 Param2 Description, this description is
/// longer and splits onto a separate line.
///
/// -Param3 Param3 Description continues as before.
/// </summary>
2022-03-24 16:35:00 -04:00
/// <param name="items">List of parameters arranged as "-ParamName Param Description"</param>
/// <param name="indent">Indent from the left hand side</param>
/// <param name="minFirstColumnWidth">The minimum padding from the start of the param name to the start of the description (resizes with larger param names)</param>
2022-02-15 14:41:10 -05:00
/// <returns>Sequence of formatted lines in the table</returns>
2022-03-24 16:35:00 -04:00
public static void FormatTable ( IReadOnlyList < KeyValuePair < string , string > > items , int indent , int minFirstColumnWidth , int maxWidth , List < string > lines )
2020-12-21 20:42:55 -04:00
{
2022-03-24 16:35:00 -04:00
if ( items . Count > 0 )
2020-12-21 20:42:55 -04:00
{
// string used to intent the param
2022-03-24 16:35:00 -04:00
string indentString = new string ( ' ' , indent ) ;
2020-12-21 20:42:55 -04:00
// default the padding value
2022-03-24 16:35:00 -04:00
int rightPadding = Math . Max ( minFirstColumnWidth , items . Max ( x = > x . Key . Length + 2 ) ) ;
2020-12-21 20:42:55 -04:00
// Build the formatted params
2022-03-24 16:35:00 -04:00
foreach ( KeyValuePair < string , string > item in items )
2020-12-21 20:42:55 -04:00
{
// build the param first, including intend and padding on the rights size
2022-03-24 16:35:00 -04:00
string paramString = indentString + item . Key . PadRight ( rightPadding ) ;
2020-12-21 20:42:55 -04:00
// Build the description line by line, adding the same amount of intending each time.
2022-03-24 16:35:00 -04:00
IEnumerable < string > descriptionLines = StringUtils . WordWrap ( item . Value , maxWidth - paramString . Length ) ;
2020-12-21 20:42:55 -04:00
2022-03-24 16:35:00 -04:00
foreach ( string descriptionLine in descriptionLines )
2020-12-21 20:42:55 -04:00
{
// Formatting as following:
// <Indent>-param<Right Padding>Description<New line>
2022-03-24 16:35:00 -04:00
lines . Add ( paramString + descriptionLine ) ;
2020-12-21 20:42:55 -04:00
// we replace the param string on subsequent lines with white space of the same length
2022-03-24 16:35:00 -04:00
paramString = string . Empty . PadRight ( indentString . Length + rightPadding ) ;
2020-12-21 20:42:55 -04:00
}
}
}
}
}
}