This commit is contained in:
Alexey Golub
2019-08-13 17:27:26 +03:00
parent 018320582b
commit f09caa876f
3 changed files with 79 additions and 60 deletions

View File

@@ -48,7 +48,7 @@ namespace CliFx
// Fail if there are no commands defined // Fail if there are no commands defined
if (!availableCommandSchemas.Any()) if (!availableCommandSchemas.Any())
{ {
_console.WithColor(ConsoleColor.Red, _console.WithForegroundColor(ConsoleColor.Red,
() => _console.Error.WriteLine("There are no commands defined in this application.")); () => _console.Error.WriteLine("There are no commands defined in this application."));
return -1; return -1;
@@ -64,7 +64,7 @@ namespace CliFx
{ {
isError = true; isError = true;
_console.WithColor(ConsoleColor.Red, _console.WithForegroundColor(ConsoleColor.Red,
() => _console.Error.WriteLine($"Specified command [{commandInput.CommandName}] is not defined.")); () => _console.Error.WriteLine($"Specified command [{commandInput.CommandName}] is not defined."));
} }
@@ -115,7 +115,7 @@ namespace CliFx
var message = ex is CliFxException ? ex.Message : ex.ToString(); var message = ex is CliFxException ? ex.Message : ex.ToString();
var exitCode = ex is CommandErrorException errorException ? errorException.ExitCode : -1; var exitCode = ex is CommandErrorException errorException ? errorException.ExitCode : -1;
_console.WithColor(ConsoleColor.Red, () => _console.Error.WriteLine(message)); _console.WithForegroundColor(ConsoleColor.Red, () => _console.Error.WriteLine(message));
return exitCode; return exitCode;
} }

View File

@@ -10,6 +10,7 @@ namespace CliFx.Services
{ {
private readonly IConsole _console; private readonly IConsole _console;
private bool _isEmpty = true;
private int _position; private int _position;
public CommandHelpTextRenderer(IConsole console) public CommandHelpTextRenderer(IConsole console)
@@ -20,44 +21,87 @@ namespace CliFx.Services
private void Render(string text) private void Render(string text)
{ {
_console.Output.Write(text); _console.Output.Write(text);
_isEmpty = false;
_position += text.Length; _position += text.Length;
} }
private void RenderNewLine() private void RenderNewLine()
{ {
_console.Output.WriteLine(); _console.Output.WriteLine();
_isEmpty = false;
_position = 0; _position = 0;
} }
private void RenderIndent(int spaces = 2) => Render(' '.Repeat(spaces)); private void RenderIndent(int spaces = 2) => Render(' '.Repeat(spaces));
private void Render(string text, ConsoleColor foregroundColor, ConsoleColor backgroundColor = ConsoleColor.Black) => private void RenderColumnIndent(int spaces = 20, int margin = 2)
_console.WithColor(foregroundColor, backgroundColor, () => Render(text)); {
if (_position + margin >= spaces)
{
RenderNewLine();
RenderIndent(spaces);
}
else
{
RenderIndent(spaces - _position);
}
}
private void Render(string text, ConsoleColor foregroundColor) =>
_console.WithForegroundColor(foregroundColor, () => Render(text));
private void Render(string text, ConsoleColor foregroundColor, ConsoleColor backgroundColor) =>
_console.WithColors(foregroundColor, backgroundColor, () => Render(text));
private void RenderHeader(string text)
{
Render(text, ConsoleColor.Black, ConsoleColor.DarkGray);
RenderNewLine();
}
private void RenderApplicationInfo(ApplicationMetadata applicationMetadata, CommandSchema commandSchema)
{
if (!commandSchema.IsDefault())
return;
// Margin
if (!_isEmpty)
RenderNewLine();
// Title and version
Render($"{applicationMetadata.Title} v{applicationMetadata.VersionText}", ConsoleColor.Yellow);
RenderNewLine();
}
private void RenderDescription(CommandSchema commandSchema) private void RenderDescription(CommandSchema commandSchema)
{ {
if (commandSchema.Description.IsNullOrWhiteSpace()) if (commandSchema.Description.IsNullOrWhiteSpace())
return; return;
// Margin
if (!_isEmpty)
RenderNewLine();
// Header // Header
Render("Description", ConsoleColor.Black, ConsoleColor.DarkGray); RenderHeader("Description");
RenderNewLine();
// Description // Description
RenderIndent(); RenderIndent();
Render(commandSchema.Description); Render(commandSchema.Description);
RenderNewLine(); RenderNewLine();
// Margin
RenderNewLine();
} }
private void RenderUsage(ApplicationMetadata applicationMetadata, CommandSchema commandSchema, private void RenderUsage(ApplicationMetadata applicationMetadata, CommandSchema commandSchema,
IReadOnlyList<CommandSchema> childCommandSchemas) IReadOnlyList<CommandSchema> childCommandSchemas)
{ {
// Margin
if (!_isEmpty)
RenderNewLine();
// Header // Header
Render("Usage", ConsoleColor.Black, ConsoleColor.DarkGray); RenderHeader("Usage");
RenderNewLine();
// Exe name // Exe name
RenderIndent(); RenderIndent();
@@ -81,9 +125,6 @@ namespace CliFx.Services
Render(" "); Render(" ");
Render("[options]", ConsoleColor.White); Render("[options]", ConsoleColor.White);
RenderNewLine(); RenderNewLine();
// Margin
RenderNewLine();
} }
private void RenderOptions(CommandSchema commandSchema) private void RenderOptions(CommandSchema commandSchema)
@@ -96,9 +137,12 @@ namespace CliFx.Services
if (commandSchema.IsDefault()) if (commandSchema.IsDefault())
options.Add(new CommandOptionSchema(null, "version", null, null, false, "Shows application version.")); options.Add(new CommandOptionSchema(null, "version", null, null, false, "Shows application version."));
// Margin
if (!_isEmpty)
RenderNewLine();
// Header // Header
Render("Options", ConsoleColor.Black, ConsoleColor.DarkGray); RenderHeader("Options");
RenderNewLine();
// Options // Options
foreach (var option in options) foreach (var option in options)
@@ -126,25 +170,12 @@ namespace CliFx.Services
// Description // Description
if (!option.Description.IsNullOrWhiteSpace()) if (!option.Description.IsNullOrWhiteSpace())
{ {
const int threshold = 20; RenderColumnIndent();
if (_position >= threshold)
{
RenderNewLine();
RenderIndent(threshold);
}
else
{
RenderIndent(threshold - _position);
}
Render(option.Description); Render(option.Description);
} }
RenderNewLine(); RenderNewLine();
} }
RenderNewLine();
} }
private void RenderChildCommands(ApplicationMetadata applicationMetadata, CommandSchema commandSchema, private void RenderChildCommands(ApplicationMetadata applicationMetadata, CommandSchema commandSchema,
@@ -153,9 +184,12 @@ namespace CliFx.Services
if (!childCommandSchemas.Any()) if (!childCommandSchemas.Any())
return; return;
// Margin
if (!_isEmpty)
RenderNewLine();
// Header // Header
Render("Commands", ConsoleColor.Black, ConsoleColor.DarkGray); RenderHeader("Commands");
RenderNewLine();
// Child commands // Child commands
foreach (var childCommandSchema in childCommandSchemas) foreach (var childCommandSchema in childCommandSchemas)
@@ -169,18 +203,7 @@ namespace CliFx.Services
// Description // Description
if (!childCommandSchema.Description.IsNullOrWhiteSpace()) if (!childCommandSchema.Description.IsNullOrWhiteSpace())
{ {
const int threshold = 20; RenderColumnIndent();
if (_position >= threshold)
{
RenderNewLine();
RenderIndent(threshold);
}
else
{
RenderIndent(threshold - _position);
}
Render(childCommandSchema.Description); Render(childCommandSchema.Description);
} }
@@ -218,14 +241,7 @@ namespace CliFx.Services
.Where(c => availableCommandSchemas.FindParent(c.Name) == matchingCommandSchema) .Where(c => availableCommandSchemas.FindParent(c.Name) == matchingCommandSchema)
.ToArray(); .ToArray();
// Render application info RenderApplicationInfo(applicationMetadata, matchingCommandSchema);
if (matchingCommandSchema.IsDefault())
{
Render($"{applicationMetadata.Title} v{applicationMetadata.VersionText}", ConsoleColor.Yellow);
RenderNewLine();
RenderNewLine();
}
RenderDescription(matchingCommandSchema); RenderDescription(matchingCommandSchema);
RenderUsage(applicationMetadata, matchingCommandSchema, childCommandSchemas); RenderUsage(applicationMetadata, matchingCommandSchema, childCommandSchemas);
RenderOptions(matchingCommandSchema); RenderOptions(matchingCommandSchema);

View File

@@ -11,24 +11,27 @@ namespace CliFx.Services
IReadOnlyList<Type> commandTypes) => IReadOnlyList<Type> commandTypes) =>
commandTypes.Select(resolver.GetCommandSchema).ToArray(); commandTypes.Select(resolver.GetCommandSchema).ToArray();
public static void WithColor(this IConsole console, ConsoleColor foregroundColor, Action action) public static void WithForegroundColor(this IConsole console, ConsoleColor foregroundColor, Action action)
{ {
var lastForegroundColor = console.ForegroundColor; var lastColor = console.ForegroundColor;
console.ForegroundColor = foregroundColor; console.ForegroundColor = foregroundColor;
action(); action();
console.ForegroundColor = lastForegroundColor; console.ForegroundColor = lastColor;
} }
public static void WithColor(this IConsole console, ConsoleColor foregroundColor, ConsoleColor backgroundColor, Action action) public static void WithBackgroundColor(this IConsole console, ConsoleColor backgroundColor, Action action)
{ {
var lastBackgroundColor = console.BackgroundColor; var lastColor = console.BackgroundColor;
console.BackgroundColor = backgroundColor; console.BackgroundColor = backgroundColor;
console.WithColor(foregroundColor, action); action();
console.BackgroundColor = lastBackgroundColor; console.BackgroundColor = lastColor;
} }
public static void WithColors(this IConsole console, ConsoleColor foregroundColor, ConsoleColor backgroundColor, Action action) =>
console.WithForegroundColor(foregroundColor, () => console.WithBackgroundColor(backgroundColor, action));
} }
} }