small change to arg forwarding methods, test fixes

This commit is contained in:
Jon Sequeira 2017-03-09 09:14:55 -08:00
parent 0b94c979db
commit 4284c4e363
10 changed files with 91 additions and 64 deletions

View file

@ -7,11 +7,14 @@ namespace Microsoft.DotNet.Cli
{ {
public static class ArgumentForwardingExtensions public static class ArgumentForwardingExtensions
{ {
public static ArgumentsRule Forward(
this ArgumentsRule rule) =>
rule.MaterializeAs(o => new ForwardedArgument(o.Arguments.SingleOrDefault()));
public static ArgumentsRule ForwardAs( public static ArgumentsRule ForwardAs(
this ArgumentsRule rule, this ArgumentsRule rule,
string template) => string template) =>
rule.MaterializeAs(o => rule.MaterializeAs(o => new ForwardedArgument(template));
new ForwardedArgument(string.Format(template, o.Arguments.Single())));
public static ArgumentsRule ForwardAs( public static ArgumentsRule ForwardAs(
this ArgumentsRule rule, this ArgumentsRule rule,

View file

@ -1,4 +1,5 @@
using System.IO; using System.IO;
using System.Linq;
using Microsoft.DotNet.Cli.CommandLine; using Microsoft.DotNet.Cli.CommandLine;
using Microsoft.DotNet.Tools.Common; using Microsoft.DotNet.Tools.Common;
@ -22,7 +23,7 @@ namespace Microsoft.DotNet.Cli
"m", "minimal", "m", "minimal",
"n", "normal", "n", "normal",
"d", "detailed") "d", "detailed")
.ForwardAs("/verbosity:{0}")); .ForwardAs(o => $"/verbosity:{o.Arguments.Single()}"));
public static ArgumentsRule DefaultToCurrentDirectory(this ArgumentsRule rule) => public static ArgumentsRule DefaultToCurrentDirectory(this ArgumentsRule rule) =>
rule.With(defaultValue: () => PathUtility.EnsureTrailingSlash(Directory.GetCurrentDirectory())); rule.With(defaultValue: () => PathUtility.EnsureTrailingSlash(Directory.GetCurrentDirectory()));

View file

@ -1,6 +1,7 @@
// Copyright (c) .NET Foundation and contributors. All rights reserved. // Copyright (c) .NET Foundation and contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information. // Licensed under the MIT license. See LICENSE file in the project root for full license information.
using System.Linq;
using Microsoft.DotNet.Cli.CommandLine; using Microsoft.DotNet.Cli.CommandLine;
namespace Microsoft.DotNet.Cli namespace Microsoft.DotNet.Cli
@ -12,37 +13,37 @@ namespace Microsoft.DotNet.Cli
"build", "build",
".NET Builder", ".NET Builder",
Accept.ZeroOrOneArgument Accept.ZeroOrOneArgument
.ForwardAs("{0}"), .Forward(),
CommonOptions.HelpOption(), CommonOptions.HelpOption(),
Create.Option( Create.Option(
"-o|--output", "-o|--output",
"Output directory in which to place built artifacts.", "Output directory in which to place built artifacts.",
Accept.ExactlyOneArgument Accept.ExactlyOneArgument
.With(name: "OUTPUT_DIR") .With(name: "OUTPUT_DIR")
.ForwardAs("/p:OutputPath={0}")), .ForwardAs(o => $"/p:OutputPath={o.Arguments.Single()}")),
Create.Option( Create.Option(
"-f|--framework", "-f|--framework",
"Target framework to build for. The target framework has to be specified in the project file.", "Target framework to build for. The target framework has to be specified in the project file.",
Accept.AnyOneOf(Suggest.TargetFrameworksFromProjectFile) Accept.AnyOneOf(Suggest.TargetFrameworksFromProjectFile)
.ForwardAs("/p:TargetFramework={0}")), .ForwardAs(o => $"/p:TargetFramework={o.Arguments.Single()}")),
Create.Option( Create.Option(
"-r|--runtime", "-r|--runtime",
"Target runtime to build for. The default is to build a portable application.", "Target runtime to build for. The default is to build a portable application.",
Accept.AnyOneOf(Suggest.RunTimesFromProjectFile) Accept.AnyOneOf(Suggest.RunTimesFromProjectFile)
.ForwardAs("/p:RuntimeIdentifier={0}")), .ForwardAs(o => $"/p:RuntimeIdentifier={o.Arguments.Single()}")),
Create.Option( Create.Option(
"-c|--configuration", "-c|--configuration",
"Configuration to use for building the project. Default for most projects is \"Debug\".", "Configuration to use for building the project. Default for most projects is \"Debug\".",
Accept.ExactlyOneArgument Accept.ExactlyOneArgument
.With(name: "CONFIGURATION") .With(name: "CONFIGURATION")
.WithSuggestionsFrom("DEBUG", "RELEASE") .WithSuggestionsFrom("DEBUG", "RELEASE")
.ForwardAs("/p:Configuration={0}")), .ForwardAs(o => $"/p:Configuration={o.Arguments.Single()}")),
Create.Option( Create.Option(
"--version-suffix", "--version-suffix",
"Defines the value for the $(VersionSuffix) property in the project", "Defines the value for the $(VersionSuffix) property in the project",
Accept.ExactlyOneArgument Accept.ExactlyOneArgument
.With(name: "VERSION_SUFFIX") .With(name: "VERSION_SUFFIX")
.ForwardAs("/p:VersionSuffix={0}")), .ForwardAs(o => $"/p:VersionSuffix={o.Arguments.Single()}")),
Create.Option( Create.Option(
"--no-incremental", "--no-incremental",
"Disables incremental build."), "Disables incremental build."),

View file

@ -24,7 +24,7 @@ namespace Microsoft.DotNet.Cli
// parse the arguments // parse the arguments
var result = parser.ParseFrom("dotnet complete", args); var result = parser.ParseFrom("dotnet complete", args);
var complete = result["complete"]; var complete = result["dotnet"]["complete"];
var suggestions = Suggestions(complete); var suggestions = Suggestions(complete);

View file

@ -15,7 +15,6 @@ namespace Microsoft.DotNet.Cli
.With(name: "path"), .With(name: "path"),
Create.Option("--position", "", Create.Option("--position", "",
Accept.ExactlyOneArgument Accept.ExactlyOneArgument
.With(name: "command") .With(name: "command")));
.MaterializeAs(o => int.Parse(o.Arguments.Single()))));
} }
} }

View file

@ -1,6 +1,7 @@
// Copyright (c) .NET Foundation and contributors. All rights reserved. // Copyright (c) .NET Foundation and contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information. // Licensed under the MIT license. See LICENSE file in the project root for full license information.
using System.Linq;
using Microsoft.DotNet.Cli.CommandLine; using Microsoft.DotNet.Cli.CommandLine;
namespace Microsoft.DotNet.Cli namespace Microsoft.DotNet.Cli
@ -8,38 +9,39 @@ namespace Microsoft.DotNet.Cli
internal static class PublishCommandParser internal static class PublishCommandParser
{ {
public static Command Publish() => public static Command Publish() =>
Create.Command("publish", Create.Command(
".NET Publisher", "publish",
Accept.ZeroOrMoreArguments, ".NET Publisher",
CommonOptions.HelpOption(), Accept.ZeroOrMoreArguments,
Create.Option("-f|--framework", CommonOptions.HelpOption(),
"Target framework to publish for. The target framework has to be specified in the project file.", Create.Option("-f|--framework",
Accept.WithSuggestionsFrom(_ => Suggest.TargetFrameworksFromProjectFile()) "Target framework to publish for. The target framework has to be specified in the project file.",
.With(name: "FRAMEWORK") Accept.WithSuggestionsFrom(_ => Suggest.TargetFrameworksFromProjectFile())
.ForwardAs("/p:TargetFramework={0}")), .With(name: "FRAMEWORK")
Create.Option("-r|--runtime", .ForwardAs(o => $"/p:TargetFramework={o.Arguments.Single()}")),
"Publish the project for a given runtime. This is used when creating self-contained deployment. Default is to publish a framework-dependent app.", Create.Option("-r|--runtime",
Accept.WithSuggestionsFrom(_ => Suggest.RunTimesFromProjectFile()) "Publish the project for a given runtime. This is used when creating self-contained deployment. Default is to publish a framework-dependent app.",
.With(name: "RUNTIME_IDENTIFIER") Accept.WithSuggestionsFrom(_ => Suggest.RunTimesFromProjectFile())
.ForwardAs("/p:RuntimeIdentifier={0}")), .With(name: "RUNTIME_IDENTIFIER")
Create.Option("-o|--output", .ForwardAs(o => $"/p:RuntimeIdentifier={o.Arguments.Single()}")),
"Output directory in which to place the published artifacts.", Create.Option("-o|--output",
Accept.ExactlyOneArgument "Output directory in which to place the published artifacts.",
.With(name: "OUTPUT_DIR") Accept.ExactlyOneArgument
.ForwardAs("/p:PublishDir={0}")), .With(name: "OUTPUT_DIR")
Create.Option("-c|--configuration", "Configuration to use for building the project. Default for most projects is \"Debug\".", .ForwardAs(o => $"/p:PublishDir={o.Arguments.Single()}")),
Accept.ExactlyOneArgument Create.Option("-c|--configuration", "Configuration to use for building the project. Default for most projects is \"Debug\".",
.With(name: "CONFIGURATION") Accept.ExactlyOneArgument
.WithSuggestionsFrom("DEBUG", "RELEASE") .With(name: "CONFIGURATION")
.ForwardAs("/p:Configuration={0}")), .WithSuggestionsFrom("DEBUG", "RELEASE")
Create.Option("--version-suffix", "Defines the value for the $(VersionSuffix) property in the project.", .ForwardAs(o => $"/p:Configuration={o.Arguments.Single()}")),
Accept.ExactlyOneArgument Create.Option("--version-suffix", "Defines the value for the $(VersionSuffix) property in the project.",
.With(name: "VERSION_SUFFIX") Accept.ExactlyOneArgument
.ForwardAs("/p:VersionSuffix={0}")), .With(name: "VERSION_SUFFIX")
Create.Option("--filter", "The XML file that contains the list of packages to be excluded from publish step.", .ForwardAs(o => $"/p:VersionSuffix={o.Arguments.Single()}")),
Accept.ExactlyOneArgument Create.Option("--filter", "The XML file that contains the list of packages to be excluded from publish step.",
.With(name: "PROFILE_XML") Accept.ExactlyOneArgument
.ForwardAs("/p:FilterProjectFiles={0}")), .With(name: "PROFILE_XML")
CommonOptions.VerbosityOption()); .ForwardAs(o => $"/p:FilterProjectFiles={o.Arguments.Single()}")),
CommonOptions.VerbosityOption());
} }
} }

View file

@ -1,6 +1,7 @@
// Copyright (c) .NET Foundation and contributors. All rights reserved. // Copyright (c) .NET Foundation and contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information. // Licensed under the MIT license. See LICENSE file in the project root for full license information.
using System.Linq;
using Microsoft.DotNet.Cli.CommandLine; using Microsoft.DotNet.Cli.CommandLine;
namespace Microsoft.DotNet.Cli namespace Microsoft.DotNet.Cli
@ -31,7 +32,7 @@ namespace Microsoft.DotNet.Cli
"Directory to install packages in.", "Directory to install packages in.",
Accept.ExactlyOneArgument Accept.ExactlyOneArgument
.With(name: "PACKAGES_DIRECTORY") .With(name: "PACKAGES_DIRECTORY")
.ForwardAs("/p:RestorePackagesPath={0}")), .ForwardAs(o => $"/p:RestorePackagesPath={o.Arguments.Single()}")),
Create.Option( Create.Option(
"--disable-parallel", "--disable-parallel",
"Disables restoring multiple projects in parallel.", "Disables restoring multiple projects in parallel.",
@ -42,7 +43,7 @@ namespace Microsoft.DotNet.Cli
"The NuGet configuration file to use.", "The NuGet configuration file to use.",
Accept.ExactlyOneArgument Accept.ExactlyOneArgument
.With(name: "FILE") .With(name: "FILE")
.ForwardAs("/p:RestoreConfigFile={0}")), .ForwardAs(o => $"/p:RestoreConfigFile={o.Arguments.Single()}")),
Create.Option( Create.Option(
"--no-cache", "--no-cache",
"Do not cache packages and http requests.", "Do not cache packages and http requests.",

View file

@ -26,8 +26,8 @@ namespace Microsoft.DotNet.Cli.MSBuild.Tests
[InlineData(new string[] { "--no-cache" }, "/p:RestoreNoCache=true")] [InlineData(new string[] { "--no-cache" }, "/p:RestoreNoCache=true")]
[InlineData(new string[] { "--ignore-failed-sources" }, "/p:RestoreIgnoreFailedSources=true")] [InlineData(new string[] { "--ignore-failed-sources" }, "/p:RestoreIgnoreFailedSources=true")]
[InlineData(new string[] { "--no-dependencies" }, "/p:RestoreRecursive=false")] [InlineData(new string[] { "--no-dependencies" }, "/p:RestoreRecursive=false")]
[InlineData(new string[] { "-v", "<verbosity>" }, @"/verbosity:<verbosity>")] [InlineData(new string[] { "-v", "minimal" }, @"/verbosity:minimal")]
[InlineData(new string[] { "--verbosity", "<verbosity>" }, @"/verbosity:<verbosity>")] [InlineData(new string[] { "--verbosity", "minimal" }, @"/verbosity:minimal")]
public void MsbuildInvocationIsCorrect(string[] args, string expectedAdditionalArgs) public void MsbuildInvocationIsCorrect(string[] args, string expectedAdditionalArgs)
{ {
expectedAdditionalArgs = (string.IsNullOrEmpty(expectedAdditionalArgs) ? "" : $" {expectedAdditionalArgs}"); expectedAdditionalArgs = (string.IsNullOrEmpty(expectedAdditionalArgs) ? "" : $" {expectedAdditionalArgs}");

View file

@ -2,6 +2,7 @@
// Licensed under the MIT license. See LICENSE file in the project root for full license information. // Licensed under the MIT license. See LICENSE file in the project root for full license information.
using FluentAssertions; using FluentAssertions;
using System.Linq;
using Microsoft.DotNet.Cli; using Microsoft.DotNet.Cli;
using Microsoft.DotNet.Cli.CommandLine; using Microsoft.DotNet.Cli.CommandLine;
using Xunit; using Xunit;
@ -13,28 +14,31 @@ namespace Microsoft.DotNet.Tests.ParserTests
public class ArgumentForwardingExtensionsTests public class ArgumentForwardingExtensionsTests
{ {
[Fact] [Fact]
public void An_outgoing_command_line_can_be_generated_based_on_a_parse_result() public void AnOutgoingCommandLineCanBeGeneratedBasedOnAParseResult()
{ {
var command = Command("the-command", "", var command = Command("the-command", "",
Option("-o|--one", "", Option("-o|--one", "",
ZeroOrOneArgument.ForwardAs("/i:{0}")), ZeroOrOneArgument
Option("-t|--two", "", .ForwardAs(o => $"/i:{o.Arguments.Single()}")),
ZeroOrOneArgument.ForwardAs("/s:{0}"))); Option("-t|--two", "",
NoArguments
.ForwardAs("/s:true")));
var result = command.Parse("the-command -t argument-two-value -o 123"); var result = command.Parse("the-command -t -o 123");
result["the-command"] result["the-command"]
.OptionValuesToBeForwarded() .OptionValuesToBeForwarded()
.Should() .Should()
.BeEquivalentTo("/i:123", "/s:argument-two-value"); .BeEquivalentTo("/i:123", "/s:true");
} }
[Fact] [Fact]
public void MultipleArgumentsCanBeJoinedWhenForwarding() public void MultipleArgumentsCanBeJoinedWhenForwarding()
{ {
var command = Command("the-command", "", var command = Command("the-command", "",
Option("-x", "", Option("-x", "",
ZeroOrMoreArguments.ForwardAs(o => $"/x:{string.Join("&", o.Arguments)}"))); ZeroOrMoreArguments
.ForwardAs(o => $"/x:{string.Join("&", o.Arguments)}")));
var result = command.Parse("the-command -x one -x two"); var result = command.Parse("the-command -x one -x two");
@ -43,5 +47,21 @@ namespace Microsoft.DotNet.Tests.ParserTests
.Should() .Should()
.BeEquivalentTo("/x:one&two"); .BeEquivalentTo("/x:one&two");
} }
[Fact]
public void AnArgumentCanBeForwardedAsIs()
{
var command = Command("the-command", "",
Option("-x", "",
ZeroOrMoreArguments
.Forward()));
var result = command.Parse("the-command -x one");
result["the-command"]
.OptionValuesToBeForwarded()
.Should()
.BeEquivalentTo("one");
}
} }
} }

View file

@ -22,13 +22,13 @@ namespace Microsoft.DotNet.Tests.ParserTests
[Fact] [Fact]
public void RestoreCapturesArgumentsToForwardToMSBuildWhenTargetIsSpecified() public void RestoreCapturesArgumentsToForwardToMSBuildWhenTargetIsSpecified()
{ {
var parser = Parser.Instance["dotnet"]["restore"]; var parser = Parser.Instance;
var result = parser.Parse(@".\some.csproj --packages c:\.nuget\packages /p:SkipInvalidConfigurations=true"); var result = parser.Parse(@"dotnet restore .\some.csproj --packages c:\.nuget\packages /p:SkipInvalidConfigurations=true");
output.WriteLine(result.Diagram()); output.WriteLine(result.Diagram());
result["restore"] result["dotnet"]["restore"]
.Arguments .Arguments
.Should() .Should()
.BeEquivalentTo(@".\some.csproj", @"/p:SkipInvalidConfigurations=true"); .BeEquivalentTo(@".\some.csproj", @"/p:SkipInvalidConfigurations=true");
@ -37,13 +37,13 @@ namespace Microsoft.DotNet.Tests.ParserTests
[Fact] [Fact]
public void RestoreCapturesArgumentsToForwardToMSBuildWhenTargetIsNotSpecified() public void RestoreCapturesArgumentsToForwardToMSBuildWhenTargetIsNotSpecified()
{ {
var parser = Parser.Instance["dotnet"]["restore"]; var parser = Parser.Instance;
var result = parser.Parse(@"--packages c:\.nuget\packages /p:SkipInvalidConfigurations=true"); var result = parser.Parse(@"dotnet restore --packages c:\.nuget\packages /p:SkipInvalidConfigurations=true");
output.WriteLine(result.Diagram()); output.WriteLine(result.Diagram());
result["restore"] result["dotnet"]["restore"]
.Arguments .Arguments
.Should() .Should()
.BeEquivalentTo(@"/p:SkipInvalidConfigurations=true"); .BeEquivalentTo(@"/p:SkipInvalidConfigurations=true");