Skip to content
This repository has been archived by the owner on Jan 2, 2021. It is now read-only.

Commit

Permalink
Merge pull request #55 from patriksvensson/feature/GH-54
Browse files Browse the repository at this point in the history
Removes value tuples due to problem consumers have
  • Loading branch information
patriksvensson committed Nov 3, 2018
2 parents 9d5926c + 28dca8c commit de3e352
Show file tree
Hide file tree
Showing 14 changed files with 231 additions and 126 deletions.
4 changes: 2 additions & 2 deletions src/Spectre.Cli.Tests/Unit/Internal/CommandTreeBinderTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -114,11 +114,11 @@ public static T Bind<T>(IEnumerable<string> args, Action<Configurator> action)

// Parse command tree.
var parser = new CommandTreeParser(CommandModelBuilder.Build(configurator));
var (tree, _) = parser.Parse(args);
var result = parser.Parse(args);

// Bind the settings to the tree.
CommandSettings settings = new T();
CommandBinder.Bind(tree, ref settings, new TypeResolverAdapter(null));
CommandBinder.Bind(result.Tree, ref settings, new TypeResolverAdapter(null));

// Return the settings.
return (T)settings;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
using Spectre.Cli.Tests.Data;
using Spectre.Cli.Tests.Data.Settings;
using Xunit;
using static Spectre.Cli.Internal.Parsing.CommandTreeParser;

namespace Spectre.Cli.Tests.Unit.Internal.Parsing
{
Expand All @@ -18,17 +19,17 @@ public sealed class CommandTreeParserTests
public void Should_Capture_Remaining_Arguments()
{
// Given, When
var (tree, remaining) = new Fixture().Parse(new[] { "dog", "--", "--foo", "-bar", "\"baz\"", "qux" }, config =>
var result = new Fixture().Parse(new[] { "dog", "--", "--foo", "-bar", "\"baz\"", "qux" }, config =>
{
config.AddCommand<DogCommand>("dog");
});

// Then
remaining.Raw.Count.ShouldBe(4);
remaining.Raw[0].ShouldBe("--foo");
remaining.Raw[1].ShouldBe("-bar");
remaining.Raw[2].ShouldBe("\"baz\"");
remaining.Raw[3].ShouldBe("qux");
result.Remaining.Raw.Count.ShouldBe(4);
result.Remaining.Raw[0].ShouldBe("--foo");
result.Remaining.Raw[1].ShouldBe("-bar");
result.Remaining.Raw[2].ShouldBe("\"baz\"");
result.Remaining.Raw[3].ShouldBe("qux");
}

/// <summary>
Expand Down Expand Up @@ -145,16 +146,16 @@ public void Should_Use_Default_Command_If_No_Command_Was_Specified(string expect
public void Should_Not_Use_Default_Command_If_Command_Was_Specified()
{
// Given, When
var (tree, _) = new Fixture()
var result = new Fixture()
.WithDefaultCommand<DogCommand>()
.Parse(new[] { "cat" }, config =>
{
config.AddCommand<CatCommand>("cat");
});

// Then
tree.Command.CommandType.ShouldBe<CatCommand>();
tree.Command.SettingsType.ShouldBe<CatSettings>();
result.Tree.Command.CommandType.ShouldBe<CatCommand>();
result.Tree.Command.SettingsType.ShouldBe<CatSettings>();
}

private sealed class Fixture
Expand All @@ -173,7 +174,7 @@ public Fixture WithDefaultCommand<TCommand>()
return this;
}

public (CommandTree, IRemainingArguments remaining) Parse(IEnumerable<string> args, Action<Configurator> func)
public CommandTreeParserResult Parse(IEnumerable<string> args, Action<Configurator> func)
{
func(_configurator);

Expand All @@ -183,7 +184,7 @@ public Fixture WithDefaultCommand<TCommand>()

public string Serialize(IEnumerable<string> args, Action<Configurator> func)
{
var (tree, _) = Parse(args, func);
var result = Parse(args, func);

var settings = new XmlWriterSettings
{
Expand All @@ -196,7 +197,7 @@ public string Serialize(IEnumerable<string> args, Action<Configurator> func)
using (var buffer = new StringWriter())
using (var xmlWriter = XmlWriter.Create(buffer, settings))
{
CommandTreeSerializer.Serialize(tree).WriteTo(xmlWriter);
CommandTreeSerializer.Serialize(result.Tree).WriteTo(xmlWriter);
xmlWriter.Flush();
return buffer.GetStringBuilder().ToString().NormalizeLineEndings();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System;
using System.Collections.Generic;
using System.Xml;
using Spectre.Cli.Internal.Modelling;
Expand Down Expand Up @@ -57,22 +58,22 @@ private static XmlNode Serialize(XmlDocument doc, CommandTree tree)
return node;
}

private static IEnumerable<XmlNode> CreateMappedParameterNodes(XmlDocument document, List<(CommandParameter param, string value)> parameters)
private static IEnumerable<XmlNode> CreateMappedParameterNodes(XmlDocument document, List<MappedCommandParameter> parameters)
{
foreach (var (param, value) in parameters)
foreach (var parameter in parameters)
{
if (param is CommandOption option)
if (parameter.Parameter is CommandOption option)
{
var node = document.CreateElement("option");
node.SetNullableAttribute("name", option.GetOptionName());
node.SetNullableAttribute("assigned", value);
node.SetNullableAttribute("assigned", parameter.Value);
yield return node;
}
else if (param is CommandArgument argument)
else if (parameter.Parameter is CommandArgument argument)
{
var node = document.CreateElement("argument");
node.SetNullableAttribute("name", argument.Value);
node.SetNullableAttribute("assigned", value);
node.SetNullableAttribute("assigned", parameter.Value);
yield return node;
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using Shouldly;
using Shouldly;
using Spectre.Cli.Internal.Parsing;
using Xunit;

Expand All @@ -11,25 +11,25 @@ public sealed class CommandTreeTokenizerTests
public void Should_Parse_String_Correctly(params string[] args)
{
// Given, When
var (result, remaining) = CommandTreeTokenizer.Tokenize(args);
var result = CommandTreeTokenizer.Tokenize(args);

// Then
result.Count.ShouldBe(1);
result[0].TokenKind.ShouldBe(CommandTreeToken.Kind.String);
result[0].Value.ShouldBe("foo");
result.Tokens.Count.ShouldBe(1);
result.Tokens[0].TokenKind.ShouldBe(CommandTreeToken.Kind.String);
result.Tokens[0].Value.ShouldBe("foo");
}

[Theory]
[InlineData("\"foo\"")]
public void Should_Parse_Quoted_String_Correctly(params string[] args)
{
// Given, When
var (result, remaining) = CommandTreeTokenizer.Tokenize(args);
var result = CommandTreeTokenizer.Tokenize(args);

// Then
result.Count.ShouldBe(1);
result[0].TokenKind.ShouldBe(CommandTreeToken.Kind.String);
result[0].Value.ShouldBe("foo");
result.Tokens.Count.ShouldBe(1);
result.Tokens[0].TokenKind.ShouldBe(CommandTreeToken.Kind.String);
result.Tokens[0].Value.ShouldBe("foo");
}

[Theory]
Expand All @@ -41,14 +41,14 @@ public void Should_Parse_Quoted_String_Correctly(params string[] args)
public void Should_Parse_Short_Option_Correctly(params string[] args)
{
// Given, When
var (result, remaining) = CommandTreeTokenizer.Tokenize(args);
var result = CommandTreeTokenizer.Tokenize(args);

// Then
result.Count.ShouldBe(2);
result[0].TokenKind.ShouldBe(CommandTreeToken.Kind.ShortOption);
result[0].Value.ShouldBe("f");
result[1].TokenKind.ShouldBe(CommandTreeToken.Kind.String);
result[1].Value.ShouldBe("bar");
result.Tokens.Count.ShouldBe(2);
result.Tokens[0].TokenKind.ShouldBe(CommandTreeToken.Kind.ShortOption);
result.Tokens[0].Value.ShouldBe("f");
result.Tokens[1].TokenKind.ShouldBe(CommandTreeToken.Kind.String);
result.Tokens[1].Value.ShouldBe("bar");
}

[Theory]
Expand All @@ -60,47 +60,48 @@ public void Should_Parse_Short_Option_Correctly(params string[] args)
public void Should_Parse_Long_Option_Correctly(params string[] args)
{
// Given, When
var (result, remaining) = CommandTreeTokenizer.Tokenize(args);
var result = CommandTreeTokenizer.Tokenize(args);

// Then
result.Count.ShouldBe(2);
result[0].TokenKind.ShouldBe(CommandTreeToken.Kind.LongOption);
result[0].Value.ShouldBe("foo");
result[1].TokenKind.ShouldBe(CommandTreeToken.Kind.String);
result[1].Value.ShouldBe("bar");
result.Tokens.Count.ShouldBe(2);
result.Tokens[0].TokenKind.ShouldBe(CommandTreeToken.Kind.LongOption);
result.Tokens[0].Value.ShouldBe("foo");
result.Tokens[1].TokenKind.ShouldBe(CommandTreeToken.Kind.String);
result.Tokens[1].Value.ShouldBe("bar");
}

[Fact]
public void Should_Parse_Remaining_Parameters()
{
// Given, When
var (result, remaining) = CommandTreeTokenizer.Tokenize(new[] { "--foo", "--", "--bar", "-qux", "\"lol\"", "w00t" });
var result = CommandTreeTokenizer.Tokenize(
new[] { "--foo", "--", "--bar", "-qux", "\"lol\"", "w00t" });

// Then
result.Count.ShouldBe(8);
result.Tokens.Count.ShouldBe(8);

remaining.Count.ShouldBe(4);
remaining[0].ShouldBe("--bar");
remaining[1].ShouldBe("-qux");
remaining[2].ShouldBe("\"lol\"");
remaining[3].ShouldBe("w00t");
result.Remaining.Count.ShouldBe(4);
result.Remaining[0].ShouldBe("--bar");
result.Remaining[1].ShouldBe("-qux");
result.Remaining[2].ShouldBe("\"lol\"");
result.Remaining[3].ShouldBe("w00t");

result[0].TokenKind.ShouldBe(CommandTreeToken.Kind.LongOption);
result[0].Value.ShouldBe("foo");
result[1].TokenKind.ShouldBe(CommandTreeToken.Kind.Remaining);
result[1].Value.ShouldBe("--");
result[2].TokenKind.ShouldBe(CommandTreeToken.Kind.LongOption);
result[2].Value.ShouldBe("bar");
result[3].TokenKind.ShouldBe(CommandTreeToken.Kind.ShortOption);
result[3].Value.ShouldBe("q");
result[4].TokenKind.ShouldBe(CommandTreeToken.Kind.ShortOption);
result[4].Value.ShouldBe("u");
result[5].TokenKind.ShouldBe(CommandTreeToken.Kind.ShortOption);
result[5].Value.ShouldBe("x");
result[6].TokenKind.ShouldBe(CommandTreeToken.Kind.String);
result[6].Value.ShouldBe("lol");
result[7].TokenKind.ShouldBe(CommandTreeToken.Kind.String);
result[7].Value.ShouldBe("w00t");
result.Tokens[0].TokenKind.ShouldBe(CommandTreeToken.Kind.LongOption);
result.Tokens[0].Value.ShouldBe("foo");
result.Tokens[1].TokenKind.ShouldBe(CommandTreeToken.Kind.Remaining);
result.Tokens[1].Value.ShouldBe("--");
result.Tokens[2].TokenKind.ShouldBe(CommandTreeToken.Kind.LongOption);
result.Tokens[2].Value.ShouldBe("bar");
result.Tokens[3].TokenKind.ShouldBe(CommandTreeToken.Kind.ShortOption);
result.Tokens[3].Value.ShouldBe("q");
result.Tokens[4].TokenKind.ShouldBe(CommandTreeToken.Kind.ShortOption);
result.Tokens[4].Value.ShouldBe("u");
result.Tokens[5].TokenKind.ShouldBe(CommandTreeToken.Kind.ShortOption);
result.Tokens[5].Value.ShouldBe("x");
result.Tokens[6].TokenKind.ShouldBe(CommandTreeToken.Kind.String);
result.Tokens[6].Value.ShouldBe("lol");
result.Tokens[7].TokenKind.ShouldBe(CommandTreeToken.Kind.String);
result.Tokens[7].Value.ShouldBe("w00t");
}
}
}
8 changes: 4 additions & 4 deletions src/Spectre.Cli/Internal/CommandBinder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,11 @@ TypeConverter GetConverter(CommandParameter parameter)
while (tree != null)
{
// Process mapped parameters.
foreach (var (parameter, value) in tree.Mapped)
foreach (var mapped in tree.Mapped)
{
var converter = GetConverter(parameter);
parameter.Assign(settings, converter.ConvertFromInvariantString(value));
ValidateParameter(parameter, settings);
var converter = GetConverter(mapped.Parameter);
mapped.Parameter.Assign(settings, converter.ConvertFromInvariantString(mapped.Value));
ValidateParameter(mapped.Parameter, settings);
}

// Process unmapped parameters.
Expand Down
12 changes: 6 additions & 6 deletions src/Spectre.Cli/Internal/CommandExecutor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,18 +30,18 @@ public Task<int> Execute(IConfiguration configuration, IEnumerable<string> args)

// Parse and map the model against the arguments.
var parser = new CommandTreeParser(model);
var (tree, remaining) = parser.Parse(args);
var parsedResult = parser.Parse(args);

// Currently the root?
if (tree == null)
if (parsedResult.Tree == null)
{
// Display help.
ConsoleRenderer.Render(HelpWriter.Write(model));
return Task.FromResult(0);
}

// Get the command to execute.
var leaf = tree.GetLeafCommand();
var leaf = parsedResult.Tree.GetLeafCommand();
if (leaf.Command.IsBranch || leaf.ShowHelp)
{
// Branches can't be executed. Show help.
Expand All @@ -50,14 +50,14 @@ public Task<int> Execute(IConfiguration configuration, IEnumerable<string> args)
}

// Register the arguments with the container.
_registrar?.RegisterInstance(typeof(IRemainingArguments), remaining);
_registrar?.RegisterInstance(typeof(IRemainingArguments), parsedResult.Remaining);

// Create the resolver and the context.
var resolver = new TypeResolverAdapter(_registrar?.Build());
var context = new CommandContext(remaining);
var context = new CommandContext(parsedResult.Remaining);

// Execute the command tree.
return Execute(leaf, tree, context, resolver);
return Execute(leaf, parsedResult.Tree, context, resolver);
}

private static Task<int> Execute(
Expand Down
Loading

0 comments on commit de3e352

Please sign in to comment.