Skip to content

Commit

Permalink
could do some more work on the formatting, but features are complete now
Browse files Browse the repository at this point in the history
  • Loading branch information
mookid8000 committed Oct 5, 2015
1 parent bf31e1b commit 5f7edb4
Show file tree
Hide file tree
Showing 6 changed files with 95 additions and 18 deletions.
2 changes: 1 addition & 1 deletion GoCommando/DescriptionAttribute.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ namespace GoCommando
/// Apply this attribute to a property of a command class (which is also decorated with <see cref="ParameterAttribute"/>) in
/// order to provide a description of the parameter
/// </summary>
[AttributeUsage(AttributeTargets.Property)]
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class)]
public class DescriptionAttribute : Attribute
{
public string DescriptionText { get; }
Expand Down
37 changes: 20 additions & 17 deletions GoCommando/Go.cs
Original file line number Diff line number Diff line change
Expand Up @@ -81,13 +81,16 @@ static void InnerRun()
{
if (command.Parameters.Any())
{
Console.WriteLine(@"Type
Console.WriteLine(@"{0}
Type
{0} {1} <args>
{1} {2} <args>
where <args> can consist of the following parameters:
{2}",
{3}",
command.Description,
exe,
command.Command,
string.Join(Environment.NewLine, command.Parameters.Select(parameter => FormatParameter(parameter, settings))));
Expand All @@ -102,13 +105,11 @@ static void InnerRun()
}
return;
}
else
{
Console.WriteLine("Unknown command '{0}'", helpSwitch.Value);
}

throw new GoCommandoException($"Unknown command: '{helpSwitch.Value}'");
}

var availableCommands = string.Join(Environment.NewLine, commandTypes.Select(c => " " + c.Command));
var availableCommands = string.Join(Environment.NewLine, commandTypes.Select(c => $" {c.Command} - {c.Description}"));

Console.WriteLine($@"The following commands are available:
Expand Down Expand Up @@ -157,30 +158,32 @@ static string FormatParameter(Parameter parameter, Settings settings)
additionalProperties.Add("optional");
}

var additionalPropertiesText = additionalProperties.Any() ? $" ({string.Join("/", additionalProperties)})" : "";
var additionalPropertiesText = additionalProperties.Any()
? $" ({string.Join("/", additionalProperties)})"
: "";

var helpText = parameter.DescriptionText ?? "";
var helpText = " " + (parameter.DescriptionText ?? "(no help text available)");

var examplesText = !parameter.ExampleValues.Any()
? ""
: FormatExamples(parameter, settings);

return $@" {settings.SwitchPrefix}{parameter.Name}{shorthand}{additionalPropertiesText}
var switchText = $"{settings.SwitchPrefix}{parameter.Name}{shorthand}{additionalPropertiesText}";

return $@" {switchText}
{helpText}
{examplesText}
";
{examplesText}";
}

static string FormatExamples(Parameter parameter, Settings settings)
{
var examples = string.Join(Environment.NewLine, parameter.ExampleValues
.Select(e => $" {settings.SwitchPrefix}{parameter.Name} {e}"));
.Select(e => $" {settings.SwitchPrefix}{parameter.Name} {e}"));

return $@"
Examples:
{examples}";
Examples:
{examples}
";
}

internal static List<CommandInvoker> GetCommands(Settings settings)
Expand Down
1 change: 1 addition & 0 deletions GoCommando/GoCommando.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
<Compile Include="GoCommandoException.cs" />
<Compile Include="Internals\Command.cs" />
<Compile Include="Internals\Parameter.cs" />
<Compile Include="Internals\StringExtensions.cs" />
<Compile Include="ParameterAttribute.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Internals\Settings.cs" />
Expand Down
4 changes: 4 additions & 0 deletions GoCommando/Internals/Command.cs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,10 @@ static TAttribute GetSingleAttributeOrNull<TAttribute>(PropertyInfo p) where TAt
public Type Type { get; }
public IEnumerable<Parameter> Parameters { get; }

public string Description => Type.GetCustomAttribute<DescriptionAttribute>()?.DescriptionText ??
"(no help text for this command)";


public void Invoke(IEnumerable<Switch> switches)
{
var commandInstance = (ICommand)Activator.CreateInstance(Type);
Expand Down
68 changes: 68 additions & 0 deletions GoCommando/Internals/StringExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
using System;
using System.Linq;
using System.Text;

namespace GoCommando.Internals
{
static class StringExtensions
{
public static string WrappedAt(this string str, int width)
{
var twoLineBreaks = Environment.NewLine + Environment.NewLine;

var sections = str.Split(new[] { twoLineBreaks },
StringSplitOptions.RemoveEmptyEntries);

return string.Join(twoLineBreaks, sections.Select(section => WrapSection(section, width)));
}

static string WrapSection(string section, int width)
{
var oneLongString = string.Join(" ",
section.Split(new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries));

var words = oneLongString.Split(new[] { " " }, StringSplitOptions.RemoveEmptyEntries);

var builder = new StringBuilder();

var currentLineLength = 0;

for (var index = 0; index < words.Length; index++)
{
var word = words[index];
builder.Append(word);
currentLineLength += word.Length;

if (index < words.Length - 1)
{
var nextWord = words[index];

var spaceLeftOnCurrentLine = width - currentLineLength - 1; // -1 to leave room for space...
var nextWordIsTooLong = nextWord.Length > spaceLeftOnCurrentLine;

if (nextWordIsTooLong)
{
builder.AppendLine();
currentLineLength = 0;
}
else
{
builder.Append(" ");
currentLineLength++;
}
}
}

return builder.ToString();
}

public static string Indented(this string str, int indent)
{
var indentedLines = str
.Split(new[] { Environment.NewLine }, StringSplitOptions.None)
.Select(line => string.Concat(new string(' ', indent), line));

return string.Join(Environment.NewLine, indentedLines);
}
}
}
1 change: 1 addition & 0 deletions TestApp/Commands/RunCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
namespace TestApp.Commands
{
[Command("run")]
[Description("Runs the program")]
public class RunCommand : ICommand
{
[Description("Specifies the path with which stuff is to be done")]
Expand Down

0 comments on commit 5f7edb4

Please sign in to comment.