Merge branch 'tab-completion' of https://github.com/jonsequitur/cli into tab-completion

This commit is contained in:
jonsequitur 2017-03-11 09:45:19 -08:00
commit ae01694167
43 changed files with 657 additions and 1097 deletions

View file

@ -11,6 +11,7 @@
<!-- Publish DotNet -->
<DotNetPublish ToolPath="$(Stage0Directory)"
Verbosity="normal"
Configuration="$(Configuration)"
ProjectPath="$(RootProject)" />
</Target>

View file

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<CLI_SharedFrameworkVersion>2.0.0-beta-001697-00</CLI_SharedFrameworkVersion>
<CLI_SharedFrameworkVersion>2.0.0-beta-001728-00</CLI_SharedFrameworkVersion>
<CLI_MSBuild_Version>15.2.0-preview-000047-02</CLI_MSBuild_Version>
<CLI_Roslyn_Version>2.0.0-rc4-61325-08</CLI_Roslyn_Version>
<CLI_NETSDK_Version>1.1.0-alpha-20170306-2</CLI_NETSDK_Version>

View file

@ -13,7 +13,6 @@
</PropertyGroup>
<ItemGroup>
<TestTaskEnvironmentVariables Include="PATH=$(ExecPath)" />
<TestTaskEnvironmentVariables Include="TEST_ARTIFACTS=$(TestArtifactsDir)" />
</ItemGroup>

View file

@ -9,14 +9,16 @@ namespace Microsoft.DotNet.Cli.Build
{
public abstract class DotNetMSBuildTool : DotNetTool
{
public int MaxCpuCount {get; set;} = 0;
public int MaxCpuCount { get; set; } = 0;
protected override string Args
{
public string Verbosity { get; set; }
protected override string Args
{
get
{
return $"{GetMaxCpuCountArg()}";
}
return $"{GetVerbosityArg()} {GetMaxCpuCountArg()}";
}
}
private string GetMaxCpuCountArg()
@ -28,5 +30,15 @@ namespace Microsoft.DotNet.Cli.Build
return null;
}
private string GetVerbosityArg()
{
if (!string.IsNullOrEmpty(Verbosity))
{
return $"--verbosity:{Verbosity}";
}
return null;
}
}
}

View file

@ -37,7 +37,7 @@ namespace Microsoft.DotNet.Cli.Build
{
if (!string.IsNullOrEmpty(Logger))
{
return $"--logger:{Logger}";
return $"--logger {Logger}";
}
return null;

View file

@ -12,41 +12,10 @@ namespace Microsoft.DotNet.Cli.Utils
public static readonly string ProjectFileName = "project.json";
public static readonly string ExeSuffix = CurrentPlatform == Platform.Windows ? ".exe" : string.Empty;
public static readonly string ConfigSuffix = ".config";
// Priority order of runnable suffixes to look for and run
public static readonly string[] RunnableSuffixes = CurrentPlatform == Platform.Windows
? new string[] { ".exe", ".cmd", ".bat" }
: new string[] { string.Empty };
public static readonly string BinDirectoryName = "bin";
public static readonly string ObjDirectoryName = "obj";
public static readonly string DynamicLibSuffix = CurrentPlatform == Platform.Windows ? ".dll" :
CurrentPlatform == Platform.Darwin ? ".dylib" : ".so";
public static readonly string LibCoreClrFileName = (CurrentPlatform == Platform.Windows ? "coreclr" : "libcoreclr");
public static readonly string LibCoreClrName = LibCoreClrFileName + DynamicLibSuffix;
public static readonly string StaticLibSuffix = CurrentPlatform == Platform.Windows ? ".lib" : ".a";
public static readonly string ResponseFileSuffix = ".rsp";
public static readonly string PublishedHostExecutableName = "dotnet";
public static readonly string HostExecutableName = "corehost" + ExeSuffix;
public static readonly string[] HostBinaryNames = new string[] {
HostExecutableName,
(CurrentPlatform == Platform.Windows ? "hostpolicy" : "libhostpolicy") + DynamicLibSuffix,
(CurrentPlatform == Platform.Windows ? "hostfxr" : "libhostfxr") + DynamicLibSuffix
};
public static readonly string[] LibCoreClrBinaryNames = new string[]
{
"coreclr.dll",
"libcoreclr.so",
"libcoreclr.dylib"
};
public static readonly string MSBUILD_EXE_PATH = "MSBUILD_EXE_PATH";
public static readonly string MSBuildExtensionsPath = "MSBuildExtensionsPath";

View file

@ -24,6 +24,6 @@
<ItemGroup>
<PackageReference Include="Microsoft.Build" Version="$(CLI_MSBuild_Version)" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="1.3.0" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="$(CLI_Roslyn_Version)" />
</ItemGroup>
</Project>

View file

@ -0,0 +1,30 @@
// 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.
using System;
using System.Linq;
using Microsoft.DotNet.Cli.CommandLine;
namespace Microsoft.DotNet.Cli
{
public static class AppliedOptionExtensions
{
public static T ValueOrDefault<T>(this AppliedOption parseResult, string alias)
{
return parseResult
.AppliedOptions
.Where(o => o.HasAlias(alias))
.Select(o => o.Value<T>())
.SingleOrDefault();
}
public static string SingleArgumentOrDefault(this AppliedOption parseResult, string alias)
{
return parseResult
.AppliedOptions
.Where(o => o.HasAlias(alias))
.Select(o => o.Arguments.Single())
.SingleOrDefault();
}
}
}

View file

@ -38,7 +38,12 @@ namespace Microsoft.DotNet.Cli
_value = value;
}
public override string ToString() => _value;
public override string ToString() => _value;
public static explicit operator string(ForwardedArgument argument)
{
return argument.ToString();
}
}
}
}
}

View file

@ -17,7 +17,7 @@ namespace Microsoft.DotNet.Cli
public static Option VerbosityOption() =>
Create.Option(
"-v|--verbosity",
"Set the verbosity level of the command. Allowed values are q[uiet], m[inimal], n[ormal], d[etailed], and diag[nostic]",
"Set the verbosity level of the command. Allowed values are q[uiet],<EFBFBD>m[inimal],<2C>n[ormal],<2C>d[etailed], and<6E>diag[nostic]",
Accept.AnyOneOf(
"q", "quiet",
"m", "minimal",
@ -25,6 +25,41 @@ namespace Microsoft.DotNet.Cli
"d", "detailed",
"diag", "diagnostic")
.ForwardAs(o => $"/verbosity:{o.Arguments.Single()}"));
public static Option FrameworkOption() =>
Create.Option(
"-f|--framework",
"Target framework to publish for. The target framework has to be specified in the project file.",
Accept.ExactlyOneArgument()
.WithSuggestionsFrom(_ => Suggest.TargetFrameworksFromProjectFile())
.With(name: "FRAMEWORK")
.ForwardAs(o => $"/p:TargetFramework={o.Arguments.Single()}"));
public static Option RuntimeOption() =>
Create.Option(
"-r|--runtime",
"Publish the project for a given runtime. This is used when creating self-contained deployment. Default is to publish a framework-dependent app.",
Accept.ExactlyOneArgument()
.WithSuggestionsFrom(_ => Suggest.RunTimesFromProjectFile())
.With(name: "RUNTIME_IDENTIFIER")
.ForwardAs(o => $"/p:RuntimeIdentifier={o.Arguments.Single()}"));
public static Option ConfigurationOption() =>
Create.Option(
"-c|--configuration",
"Configuration to use for building the project. Default for most projects is \"Debug\".",
Accept.ExactlyOneArgument()
.With(name: "CONFIGURATION")
.WithSuggestionsFrom("DEBUG", "RELEASE")
.ForwardAs(o => $"/p:Configuration={o.Arguments.Single()}"));
public static Option VersionSuffixOption() =>
Create.Option(
"--version-suffix",
"Defines the value for the $(VersionSuffix) property in the project.",
Accept.ExactlyOneArgument()
.With(name: "VERSION_SUFFIX")
.ForwardAs(o => $"/p:VersionSuffix={o.Arguments.Single()}"));
public static ArgumentsRule DefaultToCurrentDirectory(this ArgumentsRule rule) =>
rule.With(defaultValue: () => PathUtility.EnsureTrailingSlash(Directory.GetCurrentDirectory()));

View file

@ -27,6 +27,7 @@ namespace Microsoft.DotNet.Cli
RemoveCommandParser.Remove(),
ListCommandParser.List(),
NuGetCommandParser.NuGet(),
CacheCommandParser.Cache(),
Create.Command("msbuild", ""),
Create.Command("vstest", ""),
CompleteCommandParser.Complete(),

View file

@ -0,0 +1,70 @@
// 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.
using System.Collections.Generic;
using Microsoft.DotNet.Cli.CommandLine;
using Microsoft.DotNet.Cli.Utils;
using Microsoft.DotNet.Tools.MSBuild;
using Microsoft.DotNet.Cli;
using Parser = Microsoft.DotNet.Cli.Parser;
namespace Microsoft.DotNet.Tools.Build
{
public class BuildCommand : MSBuildForwardingApp
{
public BuildCommand(IEnumerable<string> msbuildArgs, string msbuildPath = null)
: base(msbuildArgs, msbuildPath)
{
}
public static BuildCommand FromArgs(string[] args, string msbuildPath = null)
{
var msbuildArgs = new List<string>();
var parser = Parser.Instance;
var result = parser.ParseFrom("dotnet build", args);
Reporter.Output.WriteLine(result.Diagram());
result.ShowHelpIfRequested();
var appliedBuildOptions = result["dotnet"]["build"];
if (appliedBuildOptions.HasOption("--no-incremental"))
{
msbuildArgs.Add("/t:Rebuild");
}
else
{
msbuildArgs.Add("/t:Build");
}
msbuildArgs.AddRange(appliedBuildOptions.OptionValuesToBeForwarded());
msbuildArgs.AddRange(appliedBuildOptions.Arguments);
msbuildArgs.Add($"/clp:Summary");
return new BuildCommand(msbuildArgs, msbuildPath);
}
public static int Run(string[] args)
{
DebugHelper.HandleDebugSwitch(ref args);
BuildCommand cmd;
try
{
cmd = FromArgs(args);
}
catch (CommandCreationException e)
{
return e.ExitCode;
}
return cmd.Execute();
}
}
}

View file

@ -3,6 +3,7 @@
using System.Linq;
using Microsoft.DotNet.Cli.CommandLine;
using LocalizableStrings = Microsoft.DotNet.Tools.Build.LocalizableStrings;
namespace Microsoft.DotNet.Cli
{
@ -11,45 +12,25 @@ namespace Microsoft.DotNet.Cli
public static Command Build() =>
Create.Command(
"build",
".NET Builder",
Accept.ZeroOrOneArgument()
.Forward(),
LocalizableStrings.AppFullName,
Accept.ZeroOrMoreArguments(),
CommonOptions.HelpOption(),
Create.Option(
"-o|--output",
"Output directory in which to place built artifacts.",
LocalizableStrings.OutputOptionDescription,
Accept.ExactlyOneArgument()
.With(name: "OUTPUT_DIR")
.With(name: LocalizableStrings.OutputOptionName)
.ForwardAs(o => $"/p:OutputPath={o.Arguments.Single()}")),
Create.Option(
"-f|--framework",
"Target framework to build for. The target framework has to be specified in the project file.",
Accept.AnyOneOf(Suggest.TargetFrameworksFromProjectFile)
.ForwardAs(o => $"/p:TargetFramework={o.Arguments.Single()}")),
Create.Option(
"-r|--runtime",
"Target runtime to build for. The default is to build a portable application.",
Accept.AnyOneOf(Suggest.RunTimesFromProjectFile)
.ForwardAs(o => $"/p:RuntimeIdentifier={o.Arguments.Single()}")),
Create.Option(
"-c|--configuration",
"Configuration to use for building the project. Default for most projects is \"Debug\".",
Accept.ExactlyOneArgument()
.With(name: "CONFIGURATION")
.WithSuggestionsFrom("DEBUG", "RELEASE")
.ForwardAs(o => $"/p:Configuration={o.Arguments.Single()}")),
Create.Option(
"--version-suffix",
"Defines the value for the $(VersionSuffix) property in the project",
Accept.ExactlyOneArgument()
.With(name: "VERSION_SUFFIX")
.ForwardAs(o => $"/p:VersionSuffix={o.Arguments.Single()}")),
CommonOptions.FrameworkOption(),
CommonOptions.RuntimeOption(),
CommonOptions.ConfigurationOption(),
CommonOptions.VersionSuffixOption(),
Create.Option(
"--no-incremental",
"Disables incremental build."),
LocalizableStrings.NoIncrementialOptionDescription),
Create.Option(
"--no-dependencies",
"Set this flag to ignore project-to-project references and only build the root project",
LocalizableStrings.NoDependenciesOptionDescription,
Accept.NoArguments()
.ForwardAs("/p:BuildProjectReferences=false")),
CommonOptions.VerbosityOption());

View file

@ -9,14 +9,6 @@ namespace Microsoft.DotNet.Tools.Build
public const string AppFullName = ".NET Builder";
public const string ConfigurationOptionDescription = "Configuration to use for building the project. Default for most projects is \"Debug\".";
public const string ConfigurationOptionName = "CONFIGURATION";
public const string FrameworkOptionDescription = "Target framework to build for. The target framework has to be specified in the project file.";
public const string FrameworkOptionName = "FRAMEWORK";
public const string NoDependenciesOptionDescription = "Set this flag to ignore project-to-project references and only build the root project";
public const string NoIncrementialOptionDescription = "Disables incremental build.";
@ -24,18 +16,5 @@ namespace Microsoft.DotNet.Tools.Build
public const string OutputOptionDescription = "Output directory in which to place built artifacts.";
public const string OutputOptionName = "OUTPUT_DIR";
public const string ProjectArgumentDescription = "The MSBuild project file to build. If a project file is not specified, MSBuild searches the current working directory for a file that has a file extension that ends in `proj` and uses that file.";
public const string ProjectArgumentValueName = "PROJECT";
public const string RuntimeOptionDescription = "Target runtime to build for. The default is to build a portable application.";
public const string RuntimeOptionName = "RUNTIME_IDENTIFIER";
public const string VersionSuffixOptionDescription = "Defines the value for the $(VersionSuffix) property in the project";
public const string VersionSuffixOptionName = "VERSION_SUFFIX";
}
}

View file

@ -1,134 +0,0 @@
// 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.
using System.Collections.Generic;
using Microsoft.DotNet.Cli.CommandLine;
using Microsoft.DotNet.Cli.Utils;
using Microsoft.DotNet.Tools.MSBuild;
using System.Diagnostics;
using System;
using Microsoft.DotNet.Cli;
namespace Microsoft.DotNet.Tools.Build
{
public class BuildCommand : MSBuildForwardingApp
{
public BuildCommand(IEnumerable<string> msbuildArgs, string msbuildPath = null)
: base(msbuildArgs, msbuildPath)
{
}
public static BuildCommand FromArgs(string[] args, string msbuildPath = null)
{
CommandLineApplication app = new CommandLineApplication(throwOnUnexpectedArg: false);
app.Name = "dotnet build";
app.FullName = LocalizableStrings.AppFullName;
app.Description = LocalizableStrings.AppDescription;
app.ArgumentSeparatorHelpText = HelpMessageStrings.MSBuildAdditionalArgsHelpText;
app.HandleRemainingArguments = true;
app.HelpOption("-h|--help");
CommandArgument projectArgument = app.Argument($"<{LocalizableStrings.ProjectArgumentValueName}>", LocalizableStrings.ProjectArgumentDescription);
CommandOption outputOption = app.Option($"-o|--output <{LocalizableStrings.OutputOptionName}>", LocalizableStrings.OutputOptionDescription, CommandOptionType.SingleValue);
CommandOption frameworkOption = app.Option($"-f|--framework <{LocalizableStrings.FrameworkOptionName}>", LocalizableStrings.FrameworkOptionDescription, CommandOptionType.SingleValue);
CommandOption runtimeOption = app.Option(
$"-r|--runtime <{LocalizableStrings.RuntimeOptionName}>", LocalizableStrings.RuntimeOptionDescription,
CommandOptionType.SingleValue);
CommandOption configurationOption = app.Option($"-c|--configuration <{LocalizableStrings.ConfigurationOptionName}>", LocalizableStrings.ConfigurationOptionDescription, CommandOptionType.SingleValue);
CommandOption versionSuffixOption = app.Option($"--version-suffix <{LocalizableStrings.VersionSuffixOptionName}>", LocalizableStrings.VersionSuffixOptionDescription, CommandOptionType.SingleValue);
CommandOption noIncrementalOption = app.Option("--no-incremental", LocalizableStrings.NoIncrementialOptionDescription, CommandOptionType.NoValue);
CommandOption noDependenciesOption = app.Option("--no-dependencies", LocalizableStrings.NoDependenciesOptionDescription, CommandOptionType.NoValue);
CommandOption verbosityOption = MSBuildForwardingApp.AddVerbosityOption(app);
List<string> msbuildArgs = null;
app.OnExecute(() =>
{
// this delayed initialization is here intentionally
// this code will not get run in some cases (i.e. --help)
msbuildArgs = new List<string>();
if (!string.IsNullOrEmpty(projectArgument.Value))
{
msbuildArgs.Add(projectArgument.Value);
}
if (noIncrementalOption.HasValue())
{
msbuildArgs.Add("/t:Rebuild");
}
else
{
msbuildArgs.Add("/t:Build");
}
if (outputOption.HasValue())
{
msbuildArgs.Add($"/p:OutputPath={outputOption.Value()}");
}
if (frameworkOption.HasValue())
{
msbuildArgs.Add($"/p:TargetFramework={frameworkOption.Value()}");
}
if (runtimeOption.HasValue())
{
msbuildArgs.Add($"/p:RuntimeIdentifier={runtimeOption.Value()}");
}
if (configurationOption.HasValue())
{
msbuildArgs.Add($"/p:Configuration={configurationOption.Value()}");
}
if (versionSuffixOption.HasValue())
{
msbuildArgs.Add($"/p:VersionSuffix={versionSuffixOption.Value()}");
}
if (noDependenciesOption.HasValue())
{
msbuildArgs.Add("/p:BuildProjectReferences=false");
}
if (verbosityOption.HasValue())
{
msbuildArgs.Add($"/verbosity:{verbosityOption.Value()}");
}
msbuildArgs.Add($"/clp:Summary");
msbuildArgs.AddRange(app.RemainingArguments);
return 0;
});
int exitCode = app.Execute(args);
if (msbuildArgs == null)
{
throw new CommandCreationException(exitCode);
}
return new BuildCommand(msbuildArgs, msbuildPath);
}
public static int Run(string[] args)
{
DebugHelper.HandleDebugSwitch(ref args);
BuildCommand cmd;
try
{
cmd = FromArgs(args);
}
catch (CommandCreationException e)
{
return e.ExitCode;
}
return cmd.Execute();
}
}
}

View file

@ -0,0 +1,66 @@
// 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.
using System.Linq;
using Microsoft.DotNet.Cli.CommandLine;
using LocalizableStrings = Microsoft.DotNet.Tools.Cache.LocalizableStrings;
namespace Microsoft.DotNet.Cli
{
internal static class CacheCommandParser
{
public static Command Cache() =>
Create.Command(
"cache",
LocalizableStrings.AppDescription,
Accept.ZeroOrMoreArguments(),
CommonOptions.HelpOption(),
Create.Option(
"-e|--entries",
LocalizableStrings.ProjectEntryDescription,
Accept.OneOrMoreArguments()
.With(name: LocalizableStrings.ProjectEntries)
.ForwardAs(o =>
{
var materializedString = $"{o.Arguments.First()}";
if (o.Arguments.Count() == 1) return materializedString;
var additionalProjects = string.Join("%3B", o.Arguments.Skip(1));
return $"{materializedString} /p:AdditionalProjects={additionalProjects}";
})),
CommonOptions.FrameworkOption(),
Create.Option(
"--framework-version",
LocalizableStrings.FrameworkVersionOptionDescription,
Accept.ExactlyOneArgument()
.With(name: LocalizableStrings.FrameworkVersionOption)
.ForwardAs(o => $"/p:FX_Version={o.Arguments.Single()}")),
CommonOptions.RuntimeOption(),
CommonOptions.ConfigurationOption(),
Create.Option(
"-o|--output",
LocalizableStrings.OutputOptionDescription,
Accept.ExactlyOneArgument()
.With(name: LocalizableStrings.OutputOption)
.ForwardAs(o => $"/p:ComposeDir={o.Arguments.Single()}")),
Create.Option(
"-w|--working-dir",
LocalizableStrings.IntermediateWorkingDirOptionDescription,
Accept.ExactlyOneArgument()
.With(name: LocalizableStrings.IntermediateWorkingDirOption)
.ForwardAs(o => $"/p:ComposeWorkingDir={o.Arguments.Single()}")),
Create.Option(
"--preserve-working-dir",
LocalizableStrings.PreserveIntermediateWorkingDirOptionDescription,
Accept.NoArguments()
.ForwardAs(o => $"/p:PreserveComposeWorkingDir=true")),
Create.Option(
"--skip-optimization",
LocalizableStrings.SkipOptimizationOptionDescription,
Accept.NoArguments()
.ForwardAs("/p:SkipOptimization=true")),
CommonOptions.VerbosityOption());
}
}

View file

@ -9,18 +9,10 @@ namespace Microsoft.DotNet.Tools.Cache
public const string AppDescription = "Caches the specified assemblies for the .NET Platform. By default, these will be optimized for the target runtime and framework.";
public const string ProjectEntries = "ProjectEntries";
public const string ProjectEntries = "PROJECT_ENTRIES";
public const string ProjectEntryDescription = "The XML file that contains the list of packages to be cached.";
public const string FrameworkOption = "FRAMEWORK";
public const string FrameworkOptionDescription = "Target framework for which to cache for.";
public const string RuntimeOption = "RUNTIME_IDENTIFIER";
public const string RuntimeOptionDescription = "Target runtime to cache for.";
public const string OutputOption = "OUTPUT_DIR";
public const string OutputOptionDescription = "Output directory in which to cache the given assemblies.";

View file

@ -10,6 +10,7 @@ using System.Diagnostics;
using System;
using System.IO;
using System.Linq;
using Parser = Microsoft.DotNet.Cli.Parser;
namespace Microsoft.DotNet.Tools.Cache
{
@ -22,121 +23,29 @@ namespace Microsoft.DotNet.Tools.Cache
public static CacheCommand FromArgs(string[] args, string msbuildPath = null)
{
DebugHelper.HandleDebugSwitch(ref args);
var msbuildArgs = new List<string>();
var app = new CommandLineApplication(throwOnUnexpectedArg: false);
app.Name = "dotnet cache";
app.FullName = LocalizableStrings.AppFullName;
app.Description = LocalizableStrings.AppDescription;
app.AllowArgumentSeparator = true;
app.ArgumentSeparatorHelpText = HelpMessageStrings.MSBuildAdditionalArgsHelpText;
app.HelpOption("-h|--help");
var parser = Parser.Instance;
CommandOption projectArguments = app.Option(
$"-e|--entries <{LocalizableStrings.ProjectEntries}>", LocalizableStrings.ProjectEntryDescription,
CommandOptionType.MultipleValue);
var result = parser.ParseFrom("dotnet cache", args);
CommandOption frameworkOption = app.Option(
$"-f|--framework <{LocalizableStrings.FrameworkOption}>", LocalizableStrings.FrameworkOptionDescription,
CommandOptionType.SingleValue);
Reporter.Output.WriteLine(result.Diagram());
CommandOption runtimeOption = app.Option(
$"-r|--runtime <{LocalizableStrings.RuntimeOption}>", LocalizableStrings.RuntimeOptionDescription,
CommandOptionType.SingleValue);
result.ShowHelpIfRequested();
CommandOption outputOption = app.Option(
$"-o|--output <{LocalizableStrings.OutputOption}>", LocalizableStrings.OutputOptionDescription,
CommandOptionType.SingleValue);
var appliedBuildOptions = result["dotnet"]["cache"];
CommandOption fxOption = app.Option(
$"--framework-version <{LocalizableStrings.FrameworkVersionOption}>", LocalizableStrings.FrameworkVersionOptionDescription,
CommandOptionType.SingleValue);
CommandOption skipOptimizationOption = app.Option(
$"--skip-optimization", LocalizableStrings.SkipOptimizationOptionDescription,
CommandOptionType.NoValue);
CommandOption workingDir = app.Option(
$"-w |--working-dir <{LocalizableStrings.IntermediateWorkingDirOption}>", LocalizableStrings.IntermediateWorkingDirOptionDescription,
CommandOptionType.SingleValue);
CommandOption preserveWorkingDir = app.Option(
$"--preserve-working-dir", LocalizableStrings.PreserveIntermediateWorkingDirOptionDescription,
CommandOptionType.NoValue);
CommandOption verbosityOption = MSBuildForwardingApp.AddVerbosityOption(app);
List<string> msbuildArgs = null;
app.OnExecute(() =>
if (!appliedBuildOptions.HasOption("-e"))
{
msbuildArgs = new List<string>();
if (!projectArguments.HasValue())
{
throw new InvalidOperationException(LocalizableStrings.SpecifyEntries).DisplayAsError();
}
msbuildArgs.Add("/t:ComposeCache");
msbuildArgs.Add(projectArguments.Values[0]);
var additionalProjectsargs = projectArguments.Values.Skip(1);
if (additionalProjectsargs.Count() > 0)
{
msbuildArgs.Add($"/p:AdditionalProjects={string.Join("%3B", additionalProjectsargs)}");
}
if (!string.IsNullOrEmpty(frameworkOption.Value()))
{
msbuildArgs.Add($"/p:TargetFramework={frameworkOption.Value()}");
}
if (!string.IsNullOrEmpty(runtimeOption.Value()))
{
msbuildArgs.Add($"/p:RuntimeIdentifier={runtimeOption.Value()}");
}
if (!string.IsNullOrEmpty(outputOption.Value()))
{
var outputPath = Path.GetFullPath(outputOption.Value());
msbuildArgs.Add($"/p:ComposeDir={outputPath}");
}
if (!string.IsNullOrEmpty(fxOption.Value()))
{
msbuildArgs.Add($"/p:FX_Version={fxOption.Value()}");
}
if (!string.IsNullOrEmpty(workingDir.Value()))
{
msbuildArgs.Add($"/p:ComposeWorkingDir={workingDir.Value()}");
}
if (skipOptimizationOption.HasValue())
{
msbuildArgs.Add($"/p:SkipOptimization=true");
}
if (preserveWorkingDir.HasValue())
{
msbuildArgs.Add($"/p:PreserveComposeWorkingDir=true");
}
if (!string.IsNullOrEmpty(verbosityOption.Value()))
{
msbuildArgs.Add($"/verbosity:{verbosityOption.Value()}");
}
msbuildArgs.AddRange(app.RemainingArguments);
return 0;
});
int exitCode = app.Execute(args);
if (msbuildArgs == null)
{
throw new CommandCreationException(exitCode);
throw new InvalidOperationException(LocalizableStrings.SpecifyEntries);
}
msbuildArgs.Add("/t:ComposeCache");
msbuildArgs.AddRange(appliedBuildOptions.OptionValuesToBeForwarded());
msbuildArgs.AddRange(appliedBuildOptions.Arguments);
return new CacheCommand(msbuildArgs, msbuildPath);
}

View file

@ -1,27 +1,27 @@
// 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.
using System.Linq;
using Microsoft.DotNet.Cli.CommandLine;
using LocalizableStrings = Microsoft.DotNet.Tools.Clean.LocalizableStrings;
namespace Microsoft.DotNet.Cli
{
internal static class CleanCommandParser
{
public static Command Clean() =>
Create.Command("clean",
".NET Clean Command",
CommonOptions.HelpOption(),
Create.Option("-o|--output", "Directory in which the build outputs have been placed.",
Create.Command(
"clean",
LocalizableStrings.AppFullName,
Accept.ZeroOrMoreArguments(),
CommonOptions.HelpOption(),
Create.Option("-o|--output",
LocalizableStrings.CmdOutputDirDescription,
Accept.ExactlyOneArgument()
.With(name: "OUTPUT_DIR")),
Create.Option("-f|--framework", "Clean a specific framework.",
Accept.ExactlyOneArgument()
.With(name: "FRAMEWORK")
.WithSuggestionsFrom(_ => Suggest.TargetFrameworksFromProjectFile())),
Create.Option("-c|--configuration",
"Clean a specific configuration.",
Accept.ExactlyOneArgument()
.With(name: "CONFIGURATION")
.WithSuggestionsFrom("DEBUG", "RELEASE")));
.With(name: LocalizableStrings.CmdOutputDir)
.ForwardAs(o => $"/p:OutputPath={o.Arguments.Single()}")),
CommonOptions.FrameworkOption(),
CommonOptions.ConfigurationOption(),
CommonOptions.VerbosityOption());
}
}

View file

@ -9,20 +9,8 @@ namespace Microsoft.DotNet.Tools.Clean
public const string AppDescription = "Command to clean previously generated build outputs.";
public const string CmdArgProject = "PROJECT";
public const string CmdArgProjDescription= "The MSBuild project file to build. If a project file is not specified, MSBuild searches the current working directory for a file that has a file extension that ends in `proj` and uses that file.";
public const string CmdOutputDir = "OUTPUT_DIR";
public const string CmdOutputDirDescription = "Directory in which the build outputs have been placed.";
public const string CmdFramework = "FRAMEWORK";
public const string CmdFrameworkDescription = "Clean a specific framework.";
public const string CmdConfiguration = "CONFIGURATION";
public const string CmdConfigurationDescription = "Clean a specific configuration.";
}
}

View file

@ -6,7 +6,7 @@ using Microsoft.DotNet.Cli.CommandLine;
using Microsoft.DotNet.Cli.Utils;
using Microsoft.DotNet.Tools.MSBuild;
using Microsoft.DotNet.Cli;
using System.Diagnostics;
using Parser = Microsoft.DotNet.Cli.Parser;
namespace Microsoft.DotNet.Tools.Clean
{
@ -19,78 +19,23 @@ namespace Microsoft.DotNet.Tools.Clean
public static CleanCommand FromArgs(string[] args, string msbuildPath = null)
{
DebugHelper.HandleDebugSwitch(ref args);
var msbuildArgs = new List<string>();
CommandLineApplication app = new CommandLineApplication(throwOnUnexpectedArg: false)
{
Name = "dotnet clean",
FullName = LocalizableStrings.AppFullName,
Description = LocalizableStrings.AppDescription,
HandleRemainingArguments = true,
ArgumentSeparatorHelpText = HelpMessageStrings.MSBuildAdditionalArgsHelpText
};
app.HelpOption("-h|--help");
var parser = Parser.Instance;
CommandArgument projectArgument = app.Argument(
$"<{LocalizableStrings.CmdArgProject}>",
LocalizableStrings.CmdArgProjDescription);
var result = parser.ParseFrom("dotnet clean", args);
CommandOption outputOption = app.Option(
$"-o|--output <{LocalizableStrings.CmdOutputDir}>",
LocalizableStrings.CmdOutputDirDescription,
CommandOptionType.SingleValue);
CommandOption frameworkOption = app.Option(
$"-f|--framework <{LocalizableStrings.CmdFramework}>",
LocalizableStrings.CmdFrameworkDescription,
CommandOptionType.SingleValue);
CommandOption configurationOption = app.Option(
$"-c|--configuration <{LocalizableStrings.CmdConfiguration}>",
LocalizableStrings.CmdConfigurationDescription,
CommandOptionType.SingleValue);
CommandOption verbosityOption = AddVerbosityOption(app);
Reporter.Output.WriteLine(result.Diagram());
List<string> msbuildArgs = null;
app.OnExecute(() =>
{
msbuildArgs = new List<string>();
result.ShowHelpIfRequested();
if (!string.IsNullOrEmpty(projectArgument.Value))
{
msbuildArgs.Add(projectArgument.Value);
}
var parsedClean = result["dotnet"]["clean"];
msbuildArgs.Add("/t:Clean");
msbuildArgs.AddRange(parsedClean.Arguments);
msbuildArgs.Add("/t:Clean");
if (outputOption.HasValue())
{
msbuildArgs.Add($"/p:OutputPath={outputOption.Value()}");
}
if (frameworkOption.HasValue())
{
msbuildArgs.Add($"/p:TargetFramework={frameworkOption.Value()}");
}
if (configurationOption.HasValue())
{
msbuildArgs.Add($"/p:Configuration={configurationOption.Value()}");
}
if (verbosityOption.HasValue())
{
msbuildArgs.Add($"/verbosity:{verbosityOption.Value()}");
}
msbuildArgs.AddRange(app.RemainingArguments);
return 0;
});
int exitCode = app.Execute(args);
if (msbuildArgs == null)
{
throw new CommandCreationException(exitCode);
}
msbuildArgs.AddRange(parsedClean.OptionValuesToBeForwarded());
return new CleanCommand(msbuildArgs, msbuildPath);
}

View file

@ -1,29 +1,48 @@
// 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.
using System.Linq;
using Microsoft.DotNet.Cli.CommandLine;
using Microsoft.DotNet.Tools.Migrate;
using LocalizableStrings = Microsoft.DotNet.Tools.Migrate.LocalizableStrings;
namespace Microsoft.DotNet.Cli
{
internal static class MigrateCommandParser
{
public static Command Migrate() =>
Create.Command("migrate",
".NET Migrate Command",
CommonOptions.HelpOption(),
Create.Option("-t|--template-file",
"Base MSBuild template to use for migrated app. The default is the project included in dotnet new."),
Create.Option("-v|--sdk-package-version",
"The version of the SDK package that will be referenced in the migrated app. The default is the version of the SDK in dotnet new."),
Create.Option("-x|--xproj-file",
"The path to the xproj file to use. Required when there is more than one xproj in a project directory."),
Create.Option("-s|--skip-project-references",
"Skip migrating project references. By default, project references are migrated recursively."),
Create.Option("-r|--report-file",
"Output migration report to the given file in addition to the console."),
Create.Option("--format-report-file-json",
"Output migration report file as json rather than user messages."),
Create.Option("--skip-backup",
"Skip moving project.json, global.json, and *.xproj to a `backup` directory after successful migration."));
Create.Command(
"migrate",
".NET Migrate Command",
Accept.ZeroOrOneArgument()
.MaterializeAs(o =>
{
return new MigrateCommand(
o.ValueOrDefault<string>("--template-file"),
o.Arguments.FirstOrDefault(),
o.ValueOrDefault<string>("--sdk-package-version"),
o.ValueOrDefault<string>("--xproj-file"),
o.ValueOrDefault<string>("--report-file"),
o.ValueOrDefault<bool>("--skip-project-references"),
o.ValueOrDefault<bool>("--format-report-file-json"),
o.ValueOrDefault<bool>("--skip-backup"));
})
.With(name: LocalizableStrings.CmdProjectArgument,
description: LocalizableStrings.CmdProjectArgumentDescription),
CommonOptions.HelpOption(),
Create.Option("-t|--template-file",
LocalizableStrings.CmdTemplateDescription),
Create.Option("-v|--sdk-package-version",
LocalizableStrings.CmdVersionDescription),
Create.Option("-x|--xproj-file",
LocalizableStrings.CmdXprojFileDescription),
Create.Option("-s|--skip-project-references",
LocalizableStrings.CmdSkipProjectReferencesDescription),
Create.Option("-r|--report-file",
LocalizableStrings.CmdReportFileDescription),
Create.Option("--format-report-file-json",
LocalizableStrings.CmdReportOutputDescription),
Create.Option("--skip-backup",
LocalizableStrings.CmdSkipBackupDescription));
}
}

View file

@ -2,13 +2,32 @@
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
using System;
using System.Collections.Generic;
using Microsoft.DotNet.Cli;
using Microsoft.DotNet.Cli.CommandLine;
using Microsoft.DotNet.Cli.Utils;
using Parser = Microsoft.DotNet.Cli.Parser;
namespace Microsoft.DotNet.Tools.Migrate
{
public partial class MigrateCommand
{
public static MigrateCommand FromArgs(string[] args, string msbuildPath = null)
{
var msbuildArgs = new List<string>();
var parser = Parser.Instance;
var result = parser.ParseFrom("dotnet migrate", args);
Reporter.Output.WriteLine(result.Diagram());
result.ShowHelpIfRequested();
return result["dotnet"]["migrate"].Value<MigrateCommand>();
}
public static int Run(string[] args)
{
@ -19,64 +38,19 @@ namespace Microsoft.DotNet.Tools.Migrate
DebugHelper.HandleDebugSwitch(ref args);
CommandLineApplication app = new CommandLineApplication();
app.Name = "dotnet migrate";
app.FullName = LocalizableStrings.AppFullName;
app.Description = LocalizableStrings.AppDescription;
app.HandleResponseFiles = true;
app.HelpOption("-h|--help");
CommandArgument projectArgument = app.Argument(
$"<{LocalizableStrings.CmdProjectArgument}>",
LocalizableStrings.CmdProjectArgumentDescription);
CommandOption template = app.Option(
"-t|--template-file",
LocalizableStrings.CmdTemplateDescription,
CommandOptionType.SingleValue);
CommandOption sdkVersion = app.Option(
"-v|--sdk-package-version",
LocalizableStrings.CmdVersionDescription,
CommandOptionType.SingleValue);
CommandOption xprojFile = app.Option(
"-x|--xproj-file",
LocalizableStrings.CmdXprojFileDescription,
CommandOptionType.SingleValue);
CommandOption skipProjectReferences = app.Option(
"-s|--skip-project-references",
LocalizableStrings.CmdSkipProjectReferencesDescription,
CommandOptionType.BoolValue);
CommandOption reportFile = app.Option(
"-r|--report-file",
LocalizableStrings.CmdReportFileDescription,
CommandOptionType.SingleValue);
CommandOption structuredReportOutput = app.Option(
"--format-report-file-json",
LocalizableStrings.CmdReportOutputDescription,
CommandOptionType.BoolValue);
CommandOption skipBackup = app.Option("--skip-backup",
LocalizableStrings.CmdSkipBackupDescription,
CommandOptionType.BoolValue);
app.OnExecute(() =>
MigrateCommand cmd;
try
{
MigrateCommand migrateCommand = new MigrateCommand(
template.Value(),
projectArgument.Value,
sdkVersion.Value(),
xprojFile.Value(),
reportFile.Value(),
skipProjectReferences.BoolValue.HasValue ? skipProjectReferences.BoolValue.Value : false,
structuredReportOutput.BoolValue.HasValue ? structuredReportOutput.BoolValue.Value : false,
skipBackup.BoolValue.HasValue ? skipBackup.BoolValue.Value : false);
return migrateCommand.Execute();
});
cmd = FromArgs(args);
}
catch (CommandCreationException e)
{
return e.ExitCode;
}
try
{
return app.Execute(args);
return cmd.Execute();
}
catch (GracefulException e)
{

View file

@ -19,14 +19,6 @@ namespace Microsoft.DotNet.Tools.Pack
public const string CmdIncludeSourceDescription = "Include PDBs and source files. Source files go into the src folder in the resulting nuget package";
public const string CmdConfig = "CONFIGURATION";
public const string CmdConfigDescription = "Configuration to use for building the project. Default for most projects is \"Debug\".";
public const string CmdVersionSuffix = "VERSION_SUFFIX";
public const string CmdVersionSuffixDescription = "Defines the value for the $(VersionSuffix) property in the project.";
public const string CmdServiceableDescription = "Set the serviceable flag in the package. For more information, please see https://aka.ms/nupkgservicing.";
public const string CmdArgumentProject = "PROJECT";

View file

@ -7,6 +7,7 @@ using Microsoft.DotNet.Cli.Utils;
using Microsoft.DotNet.Tools.MSBuild;
using Microsoft.DotNet.Cli;
using System.Diagnostics;
using Parser = Microsoft.DotNet.Cli.Parser;
namespace Microsoft.DotNet.Tools.Pack
{
@ -19,112 +20,24 @@ namespace Microsoft.DotNet.Tools.Pack
public static PackCommand FromArgs(string[] args, string msbuildPath = null)
{
DebugHelper.HandleDebugSwitch(ref args);
var parser = Parser.Instance;
CommandLineApplication cmd = new CommandLineApplication(throwOnUnexpectedArg: false)
var result = parser.ParseFrom("dotnet pack", args);
Reporter.Output.WriteLine(result.Diagram());
result.ShowHelpIfRequested();
var parsedPack = result["dotnet"]["pack"];
var msbuildArgs = new List<string>()
{
Name = "pack",
FullName = LocalizableStrings.AppFullName,
Description = LocalizableStrings.AppDescription,
HandleRemainingArguments = true,
ArgumentSeparatorHelpText = HelpMessageStrings.MSBuildAdditionalArgsHelpText
"/t:pack"
};
cmd.HelpOption("-h|--help");
msbuildArgs.AddRange(parsedPack.OptionValuesToBeForwarded());
var output = cmd.Option(
$"-o|--output <{LocalizableStrings.CmdOutputDir}>",
LocalizableStrings.CmdOutputDirDescription,
CommandOptionType.SingleValue);
var noBuild = cmd.Option(
"--no-build",
LocalizableStrings.CmdNoBuildOptionDescription,
CommandOptionType.NoValue);
var includeSymbols = cmd.Option(
"--include-symbols",
LocalizableStrings.CmdIncludeSymbolsDescription,
CommandOptionType.NoValue);
var includeSource = cmd.Option(
"--include-source",
LocalizableStrings.CmdIncludeSourceDescription,
CommandOptionType.NoValue);
var configuration = cmd.Option(
$"-c|--configuration <{LocalizableStrings.CmdConfig}>",
LocalizableStrings.CmdConfigDescription,
CommandOptionType.SingleValue);
var versionSuffix = cmd.Option(
$"--version-suffix <{LocalizableStrings.CmdVersionSuffix}>",
LocalizableStrings.CmdVersionSuffixDescription,
CommandOptionType.SingleValue);
var serviceable = cmd.Option(
"-s|--serviceable",
LocalizableStrings.CmdServiceableDescription,
CommandOptionType.NoValue);
var argRoot = cmd.Argument(
$"<{LocalizableStrings.CmdArgumentProject}>",
LocalizableStrings.CmdArgumentDescription,
multipleValues:true);
CommandOption verbosityOption = AddVerbosityOption(cmd);
List<string> msbuildArgs = null;
cmd.OnExecute(() =>
{
msbuildArgs = new List<string>()
{
"/t:pack"
};
if (noBuild.HasValue())
{
msbuildArgs.Add($"/p:NoBuild=true");
}
if (includeSymbols.HasValue())
{
msbuildArgs.Add($"/p:IncludeSymbols=true");
}
if (includeSource.HasValue())
{
msbuildArgs.Add($"/p:IncludeSource=true");
}
if (output.HasValue())
{
msbuildArgs.Add($"/p:PackageOutputPath={output.Value()}");
}
if (configuration.HasValue())
{
msbuildArgs.Add($"/p:Configuration={configuration.Value()}");
}
if (versionSuffix.HasValue())
{
msbuildArgs.Add($"/p:VersionSuffix={versionSuffix.Value()}");
}
if (serviceable.HasValue())
{
msbuildArgs.Add($"/p:Serviceable=true");
}
if (verbosityOption.HasValue())
{
msbuildArgs.Add($"/verbosity:{verbosityOption.Value()}");
}
msbuildArgs.AddRange(argRoot.Values);
msbuildArgs.AddRange(cmd.RemainingArguments);
return 0;
});
int exitCode = cmd.Execute(args);
if (msbuildArgs == null)
{
throw new CommandCreationException(exitCode);
}
msbuildArgs.AddRange(parsedPack.Arguments);
return new PackCommand(msbuildArgs, msbuildPath);
}

View file

@ -1,38 +1,44 @@
// 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.
using System.Linq;
using Microsoft.DotNet.Cli.CommandLine;
using LocalizableStrings = Microsoft.DotNet.Tools.Pack.LocalizableStrings;
namespace Microsoft.DotNet.Cli
{
internal static class PackCommandParser
{
public static Command Pack() =>
Create.Command("pack",
".NET Core NuGet Package Packer",
CommonOptions.HelpOption(),
Create.Option("-o|--output",
"Directory in which to place built packages.",
Accept.ExactlyOneArgument()
.With(name: "OUTPUT_DIR")),
Create.Option("--no-build",
"Skip building the project prior to packing. By default, the project will be built."),
Create.Option("--include-symbols",
"Include packages with symbols in addition to regular packages in output directory."),
Create.Option("--include-source",
"Include PDBs and source files. Source files go into the src folder in the resulting nuget package"),
Create.Option("-c|--configuration",
"Configuration to use for building the project. Default for most projects is \"Debug\".",
Accept.ExactlyOneArgument()
.With(name: "CONFIGURATION")
.WithSuggestionsFrom("DEBUG",
"RELEASE")),
Create.Option("--version-suffix",
"Defines the value for the $(VersionSuffix) property in the project.",
Accept.ExactlyOneArgument()
.With(name: "VERSION_SUFFIX")),
Create.Option("-s|--serviceable",
"Set the serviceable flag in the package. For more information, please see https://aka.ms/nupkgservicing."),
CommonOptions.VerbosityOption());
Create.Command(
"pack",
LocalizableStrings.AppFullName,
Accept.ZeroOrMoreArguments(),
CommonOptions.HelpOption(),
Create.Option(
"-o|--output",
LocalizableStrings.CmdOutputDirDescription,
Accept.ExactlyOneArgument()
.With(name: LocalizableStrings.CmdOutputDir)
.ForwardAs(o => $"/p:PackageOutputPath={o.Arguments.Single()}")),
Create.Option(
"--no-build",
LocalizableStrings.CmdNoBuildOptionDescription,
Accept.NoArguments().ForwardAs("/p:NoBuild=true")),
Create.Option(
"--include-symbols",
LocalizableStrings.CmdIncludeSymbolsDescription,
Accept.NoArguments().ForwardAs("/p:IncludeSymbols=true")),
Create.Option(
"--include-source",
LocalizableStrings.CmdIncludeSourceDescription,
Accept.NoArguments().ForwardAs("/p:IncludeSource=true")),
CommonOptions.ConfigurationOption(),
CommonOptions.VersionSuffixOption(),
Create.Option(
"-s|--serviceable",
LocalizableStrings.CmdServiceableDescription,
Accept.NoArguments().ForwardAs("/p:Serviceable=true")),
CommonOptions.VerbosityOption());
}
}

View file

@ -9,30 +9,14 @@ namespace Microsoft.DotNet.Tools.Publish
public const string AppDescription = "Publisher for the .NET Platform";
public const string ProjectArgument = "PROJECT";
public const string ProjectArgDescription = "The MSBuild project file to publish. If a project file is not specified, MSBuild searches the current working directory for a file that has a file extension that ends in `proj` and uses that file.";
public const string FrameworkOption = "FRAMEWORK";
public const string FrameworkOptionDescription = "Target framework to publish for. The target framework has to be specified in the project file.";
public const string RuntimeOption = "RUNTIME_IDENTIFIER";
public const string RuntimeOptionDescription = "Publish the project for a given runtime. This is used when creating self-contained deployment. Default is to publish a framework-dependent app.";
public const string OutputOption = "OUTPUT_DIR";
public const string OutputOptionDescription = "Output directory in which to place the published artifacts.";
public const string ConfigurationOption = "CONFIGURATION";
public const string ConfigurationOptionDescription = "Configuration to use for building the project. Default for most projects is \"Debug\".";
public const string VersionSuffixOption = "VERSION_SUFFIX";
public const string VersionSuffixOptionDescription = "Defines the value for the $(VersionSuffix) property in the project.";
public const string FilterProjOption = "profile.xml";
public const string FilterProjOptionDescription = "The XML file that contains the list of packages to be excluded from publish step.";

View file

@ -3,6 +3,7 @@
using System.Linq;
using Microsoft.DotNet.Cli.CommandLine;
using LocalizableStrings = Microsoft.DotNet.Tools.Publish.LocalizableStrings;
namespace Microsoft.DotNet.Cli
{
@ -11,39 +12,24 @@ namespace Microsoft.DotNet.Cli
public static Command Publish() =>
Create.Command(
"publish",
".NET Publisher",
LocalizableStrings.AppFullName,
Accept.ZeroOrMoreArguments(),
CommonOptions.HelpOption(),
Create.Option("-f|--framework",
"Target framework to publish for. The target framework has to be specified in the project file.",
CommonOptions.FrameworkOption(),
CommonOptions.RuntimeOption(),
Create.Option(
"-o|--output",
LocalizableStrings.OutputOptionDescription,
Accept.ExactlyOneArgument()
.WithSuggestionsFrom(_ => Suggest.TargetFrameworksFromProjectFile())
.With(name: "FRAMEWORK")
.ForwardAs(o => $"/p:TargetFramework={o.Arguments.Single()}")),
Create.Option("-r|--runtime",
"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: LocalizableStrings.OutputOption)
.ForwardAs(o => $"/p:PublishDir={o.Arguments.Single()}")),
CommonOptions.ConfigurationOption(),
Create.Option(
"--filter",
LocalizableStrings.FilterProjOptionDescription,
Accept.ExactlyOneArgument()
.WithSuggestionsFrom(_ => Suggest.RunTimesFromProjectFile())
.With(name: "RUNTIME_IDENTIFIER")
.ForwardAs(o => $"/p:RuntimeIdentifier={o.Arguments.Single()}")),
Create.Option("-o|--output",
"Output directory in which to place the published artifacts.",
Accept.ExactlyOneArgument()
.With(name: "OUTPUT_DIR")
.ForwardAs(o => $"/p:PublishDir={o.Arguments.Single()}")),
Create.Option("-c|--configuration", "Configuration to use for building the project. Default for most projects is \"Debug\".",
Accept.ExactlyOneArgument()
.With(name: "CONFIGURATION")
.WithSuggestionsFrom("DEBUG", "RELEASE")
.ForwardAs(o => $"/p:Configuration={o.Arguments.Single()}")),
Create.Option("--version-suffix", "Defines the value for the $(VersionSuffix) property in the project.",
Accept.ExactlyOneArgument()
.With(name: "VERSION_SUFFIX")
.ForwardAs(o => $"/p:VersionSuffix={o.Arguments.Single()}")),
Create.Option("--filter", "The XML file that contains the list of packages to be excluded from publish step.",
Accept.ExactlyOneArgument()
.With(name: "PROFILE_XML")
.ForwardAs(o => $"/p:FilterProjectFiles={o.Arguments.Single()}")),
.With(name: LocalizableStrings.FilterProjOption)
.ForwardAs(o => $"/p:FilterProjectFiles={o.Arguments.Single()}")),
CommonOptions.VerbosityOption());
}
}

View file

@ -33,7 +33,7 @@ namespace Microsoft.DotNet.Tools.Restore
result.ShowHelpIfRequested();
var restore = result["dotnet"]["restore"];
var parsedRestore = result["dotnet"]["restore"];
var msbuildArgs = new List<string>
{
@ -42,9 +42,9 @@ namespace Microsoft.DotNet.Tools.Restore
"/ConsoleLoggerParameters:Verbosity=Minimal"
};
msbuildArgs.AddRange(restore.OptionValuesToBeForwarded());
msbuildArgs.AddRange(parsedRestore.OptionValuesToBeForwarded());
msbuildArgs.AddRange(restore.Arguments);
msbuildArgs.AddRange(parsedRestore.Arguments);
return new RestoreCommand(msbuildArgs, msbuildPath);
}

View file

@ -3,6 +3,7 @@
using System.Linq;
using Microsoft.DotNet.Cli.CommandLine;
using LocalizableStrings = Microsoft.DotNet.Tools.Restore.LocalizableStrings;
namespace Microsoft.DotNet.Cli
{
@ -11,52 +12,52 @@ namespace Microsoft.DotNet.Cli
public static Command Restore() =>
Create.Command(
"restore",
".NET dependency restorer",
LocalizableStrings.AppFullName,
Accept.ZeroOrMoreArguments(),
CommonOptions.HelpOption(),
Create.Option(
"-s|--source",
"Specifies a NuGet package source to use during the restore.",
LocalizableStrings.CmdSourceOptionDescription,
Accept.OneOrMoreArguments()
.With(name: "SOURCE")
.With(name: LocalizableStrings.CmdSourceOption)
.ForwardAs(o => $"/p:RestoreSources={string.Join("%3B", o.Arguments)}")),
Create.Option(
"-r|--runtime",
"Target runtime to restore packages for.",
LocalizableStrings.CmdRuntimeOptionDescription,
Accept.OneOrMoreArguments()
.WithSuggestionsFrom(_ => Suggest.RunTimesFromProjectFile())
.With(name: "RUNTIME_IDENTIFIER")
.With(name: LocalizableStrings.CmdRuntimeOption)
.ForwardAs(o => $"/p:RuntimeIdentifiers={string.Join("%3B", o.Arguments)}")),
Create.Option(
"--packages",
"Directory to install packages in.",
LocalizableStrings.CmdPackagesOptionDescription,
Accept.ExactlyOneArgument()
.With(name: "PACKAGES_DIRECTORY")
.With(name: LocalizableStrings.CmdPackagesOption)
.ForwardAs(o => $"/p:RestorePackagesPath={o.Arguments.Single()}")),
Create.Option(
"--disable-parallel",
"Disables restoring multiple projects in parallel.",
LocalizableStrings.CmdDisableParallelOptionDescription,
Accept.NoArguments()
.ForwardAs("/p:RestoreDisableParallel=true")),
Create.Option(
"--configfile",
"The NuGet configuration file to use.",
LocalizableStrings.CmdConfigFileOptionDescription,
Accept.ExactlyOneArgument()
.With(name: "FILE")
.With(name: LocalizableStrings.CmdConfigFileOption)
.ForwardAs(o => $"/p:RestoreConfigFile={o.Arguments.Single()}")),
Create.Option(
"--no-cache",
"Do not cache packages and http requests.",
LocalizableStrings.CmdNoCacheOptionDescription,
Accept.NoArguments()
.ForwardAs("/p:RestoreNoCache=true")),
Create.Option(
"--ignore-failed-sources",
"Treat package source failures as warnings.",
LocalizableStrings.CmdIgnoreFailedSourcesOptionDescription,
Accept.NoArguments()
.ForwardAs("/p:RestoreIgnoreFailedSources=true")),
Create.Option(
"--no-dependencies",
"Set this flag to ignore project to project references and only restore the root project",
LocalizableStrings.CmdNoDependenciesOptionDescription,
Accept.NoArguments()
.ForwardAs("/p:RestoreRecursive=false")),
CommonOptions.VerbosityOption());

View file

@ -9,12 +9,6 @@ namespace Microsoft.DotNet.Tools.Run
public const string AppDescription = "Command used to run .NET apps";
public const string CommandOptionConfigurationDescription = "Configuration to use for building the project. Default for most projects is \"Debug\".";
public const string CommandOptionFramework = "FRAMEWORK";
public const string CommandOptionFrameworkDescription = "Build and run the app using the specified framework. The framework has to be specified in the project file. ";
public const string CommandOptionProjectDescription = "The path to the project file to run (defaults to the current directory if there is only one project).";
public const string RunCommandException = "The build failed. Please fix the build errors and run again.";

View file

@ -4,47 +4,42 @@
using System;
using Microsoft.DotNet.Cli.CommandLine;
using Microsoft.DotNet.Cli.Utils;
using Microsoft.DotNet.Cli;
using Parser = Microsoft.DotNet.Cli.Parser;
namespace Microsoft.DotNet.Tools.Run
{
public partial class RunCommand
{
public static RunCommand FromArgs(string[] args, string msbuildPath = null)
{
var parser = Parser.Instance;
var result = parser.ParseFrom("dotnet run", args);
Reporter.Output.WriteLine(result.Diagram());
result.ShowHelpIfRequested();
return result["dotnet"]["run"].Value<RunCommand>();
}
public static int Run(string[] args)
{
DebugHelper.HandleDebugSwitch(ref args);
CommandLineApplication app = new CommandLineApplication(throwOnUnexpectedArg: false);
app.Name = "dotnet run";
app.FullName = LocalizableStrings.AppFullName;
app.Description = LocalizableStrings.AppDescription;
app.HandleResponseFiles = true;
app.AllowArgumentSeparator = true;
app.ArgumentSeparatorHelpText = LocalizableStrings.RunCommandAdditionalArgsHelpText;
app.HelpOption("-h|--help");
CommandOption configuration = app.Option(
"-c|--configuration", LocalizableStrings.CommandOptionConfigurationDescription,
CommandOptionType.SingleValue);
CommandOption framework = app.Option(
$"-f|--framework <{LocalizableStrings.CommandOptionFramework}>", LocalizableStrings.CommandOptionFrameworkDescription,
CommandOptionType.SingleValue);
CommandOption project = app.Option(
"-p|--project", LocalizableStrings.CommandOptionProjectDescription,
CommandOptionType.SingleValue);
app.OnExecute(() =>
RunCommand cmd;
try
{
RunCommand runCmd = new RunCommand();
cmd = FromArgs(args);
}
catch (CommandCreationException e)
{
return e.ExitCode;
}
runCmd.Configuration = configuration.Value();
runCmd.Framework = framework.Value();
runCmd.Project = project.Value();
runCmd.Args = app.RemainingArguments;
return runCmd.Start();
});
return app.Execute(args);
return cmd.Start();
}
}
}

View file

@ -1,25 +1,36 @@
// 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.
using System.Collections.Generic;
using Microsoft.DotNet.Cli.CommandLine;
using Microsoft.DotNet.Tools.Run;
using LocalizableStrings = Microsoft.DotNet.Tools.Run.LocalizableStrings;
namespace Microsoft.DotNet.Cli
{
internal static class RunCommandParser
{
public static Command Run() =>
Create.Command("run",
".NET Run Command",
CommonOptions.HelpOption(),
Create.Option("-c|--configuration",
@"Configuration to use for building the project. Default for most projects is ""Debug"".",
Accept.ExactlyOneArgument()
.WithSuggestionsFrom("DEBUG", "RELEASE")),
Create.Option("-f|--framework",
"Build and run the app using the specified framework. The framework has to be specified in the project file.",
Accept.AnyOneOf(Suggest.TargetFrameworksFromProjectFile)),
Create.Option("-p|--project",
"The path to the project file to run (defaults to the current directory if there is only one project).",
Accept.ZeroOrOneArgument()));
Create.Command(
"run",
LocalizableStrings.AppFullName,
Accept.ZeroOrMoreArguments()
.MaterializeAs(o =>
{
return new RunCommand()
{
Configuration = o.SingleArgumentOrDefault("--configuration"),
Framework = o.SingleArgumentOrDefault("--framework"),
Project = o.SingleArgumentOrDefault("--project"),
Args = (IReadOnlyList<string>)o.Arguments
};
}),
CommonOptions.HelpOption(),
CommonOptions.ConfigurationOption(),
CommonOptions.FrameworkOption(),
Create.Option(
"-p|--project",
LocalizableStrings.CommandOptionProjectDescription,
Accept.ExactlyOneArgument()));
}
}

View file

@ -32,6 +32,8 @@ namespace Microsoft.DotNet.Tools.Test
public const string CmdTestAdapterPathDescription = @"Use custom adapters from the given path in the test run.
Example: --test-adapter-path <PATH_TO_ADAPTER>";
public const string CmdTestAdapterPath = "PATH_TO_ADAPTER";
public const string CmdLoggerOption = "LoggerUri/FriendlyName";
public const string CmdLoggerDescription = @"Specify a logger for test results.

View file

@ -3,282 +3,77 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using Microsoft.DotNet.Cli;
using Microsoft.DotNet.Cli.CommandLine;
using Microsoft.DotNet.Cli.Utils;
using Microsoft.DotNet.Tools.MSBuild;
using System.IO;
using System.Text.RegularExpressions;
using Parser = Microsoft.DotNet.Cli.Parser;
namespace Microsoft.DotNet.Tools.Test
{
public class TestCommand
public class TestCommand : MSBuildForwardingApp
{
public TestCommand(IEnumerable<string> msbuildArgs, string msbuildPath = null)
: base(msbuildArgs, msbuildPath)
{
}
public static TestCommand FromArgs(string[] args, string msbuildPath=null)
{
var msbuildArgs = new List<string>()
{
"/t:VSTest",
"/v:quiet",
"/nologo"
};
var parser = Parser.Instance;
var result = parser.ParseFrom("dotnet test", args);
Reporter.Output.WriteLine(result.Diagram());
result.ShowHelpIfRequested();
var parsedTest = result["dotnet"]["test"];
msbuildArgs.AddRange(parsedTest.OptionValuesToBeForwarded());
msbuildArgs.AddRange(parsedTest.Arguments);
var runSettingsOptions =
result.UnparsedTokens
.Select(t => GetSemiColonEsacpedstring(t));
if (runSettingsOptions.Any())
{
var runSettingsArg = string.Join(";", runSettingsOptions);
msbuildArgs.Add($"/p:VSTestCLIRunSettings=\"{runSettingsArg}\"");
}
return new TestCommand(msbuildArgs, msbuildPath);
}
public static int Run(string[] args)
{
DebugHelper.HandleDebugSwitch(ref args);
var cmd = new CommandLineApplication(throwOnUnexpectedArg: false)
TestCommand cmd;
try
{
Name = "dotnet test",
FullName = LocalizableStrings.AppFullName,
Description = LocalizableStrings.AppDescription,
HandleRemainingArguments = true,
ArgumentSeparatorHelpText = LocalizableStrings.RunSettingsArgsHelpText
};
cmd.HelpOption("-h|--help");
var argRoot = cmd.Argument(
$"<{LocalizableStrings.CmdArgProject}>",
LocalizableStrings.CmdArgDescription,
multipleValues: false);
var settingOption = cmd.Option(
$"-s|--settings <{LocalizableStrings.CmdSettingsFile}>",
LocalizableStrings.CmdSettingsDescription,
CommandOptionType.SingleValue);
var listTestsOption = cmd.Option(
"-t|--list-tests",
LocalizableStrings.CmdListTestsDescription,
CommandOptionType.NoValue);
var testCaseFilterOption = cmd.Option(
$"--filter <{LocalizableStrings.CmdTestCaseFilterExpression}>",
LocalizableStrings.CmdTestCaseFilterDescription,
CommandOptionType.SingleValue);
var testAdapterPathOption = cmd.Option(
"-a|--test-adapter-path",
LocalizableStrings.CmdTestAdapterPathDescription,
CommandOptionType.SingleValue);
var loggerOption = cmd.Option(
$"-l|--logger <{LocalizableStrings.CmdLoggerOption}>",
LocalizableStrings.CmdLoggerDescription,
CommandOptionType.SingleValue);
var configurationOption = cmd.Option(
$"-c|--configuration <{LocalizableStrings.CmdConfiguration}>",
LocalizableStrings.CmdConfigDescription,
CommandOptionType.SingleValue);
var frameworkOption = cmd.Option(
$"-f|--framework <{LocalizableStrings.CmdFramework}>",
LocalizableStrings.CmdFrameworkDescription,
CommandOptionType.SingleValue);
var outputOption = cmd.Option(
$"-o|--output <{LocalizableStrings.CmdOutputDir}>",
LocalizableStrings.CmdOutputDescription,
CommandOptionType.SingleValue);
var diagOption = cmd.Option(
$"-d|--diag <{LocalizableStrings.CmdPathToLogFile}>",
LocalizableStrings.CmdPathTologFileDescription,
CommandOptionType.SingleValue);
var noBuildtOption = cmd.Option(
"--no-build",
LocalizableStrings.CmdNoBuildDescription,
CommandOptionType.NoValue);
CommandOption verbosityOption = MSBuildForwardingApp.AddVerbosityOption(cmd);
cmd.OnExecute(() =>
{
var msbuildArgs = new List<string>()
{
"/t:VSTest"
};
msbuildArgs.Add("/nologo");
if (settingOption.HasValue())
{
msbuildArgs.Add($"/p:VSTestSetting={settingOption.Value()}");
}
if (listTestsOption.HasValue())
{
msbuildArgs.Add($"/p:VSTestListTests=true");
}
if (testCaseFilterOption.HasValue())
{
msbuildArgs.Add($"/p:VSTestTestCaseFilter={testCaseFilterOption.Value()}");
}
if (testAdapterPathOption.HasValue())
{
msbuildArgs.Add($"/p:VSTestTestAdapterPath={testAdapterPathOption.Value()}");
}
if (loggerOption.HasValue())
{
msbuildArgs.Add($"/p:VSTestLogger={string.Join(";", GetSemiColonEscapedArgs(loggerOption.Values))}");
}
if (configurationOption.HasValue())
{
msbuildArgs.Add($"/p:Configuration={configurationOption.Value()}");
}
if (frameworkOption.HasValue())
{
msbuildArgs.Add($"/p:TargetFramework={frameworkOption.Value()}");
}
if (outputOption.HasValue())
{
msbuildArgs.Add($"/p:OutputPath={outputOption.Value()}");
}
if (diagOption.HasValue())
{
msbuildArgs.Add($"/p:VSTestDiag={diagOption.Value()}");
}
if (noBuildtOption.HasValue())
{
msbuildArgs.Add($"/p:VSTestNoBuild=true");
}
if (verbosityOption.HasValue())
{
msbuildArgs.Add($"/verbosity:{verbosityOption.Value()}");
}
else
{
msbuildArgs.Add("/verbosity:quiet");
}
string defaultproject = GetSingleTestProjectToRunTestIfNotProvided(argRoot.Value, cmd.RemainingArguments);
if (!string.IsNullOrEmpty(defaultproject))
{
msbuildArgs.Add(defaultproject);
}
if (!string.IsNullOrEmpty(argRoot.Value))
{
msbuildArgs.Add(argRoot.Value);
}
// Get runsetings options specified after --
if (cmd.RemainingArguments != null && cmd.RemainingArguments.Count > 0)
{
var runSettingsOptions = GetRunSettingsOptions(cmd.RemainingArguments);
msbuildArgs.Add(string.Format("/p:VSTestCLIRunSettings=\"{0}\"", string.Join(";", runSettingsOptions)));
}
// Add remaining arguments that the parser did not understand,
msbuildArgs.AddRange(cmd.RemainingArguments);
return new MSBuildForwardingApp(msbuildArgs).Execute();
});
return cmd.Execute(args);
}
private static string GetSingleTestProjectToRunTestIfNotProvided(string args, List<string> remainingArguments)
{
string result = string.Empty;
int projectFound = NumberOfTestProjectInRemainingArgs(remainingArguments) + NumberOfTestProjectInArgsRoot(args);
if (projectFound > 1)
{
throw new GracefulException(
$"Specify a single project file to run tests from.");
cmd = FromArgs(args);
}
else if (projectFound == 0)
catch (CommandCreationException e)
{
result = GetDefaultTestProject();
return e.ExitCode;
}
return result;
}
private static int NumberOfTestProjectInArgsRoot(string args)
{
Regex pattern = new Regex(@"^.*\..*proj$");
if (!string.IsNullOrEmpty(args))
{
return pattern.IsMatch(args) ? 1 : 0;
}
return 0;
}
private static int NumberOfTestProjectInRemainingArgs(List<string> remainingArguments)
{
int count = 0;
if (remainingArguments.Count != 0)
{
Regex pattern = new Regex(@"^.*\..*proj$");
foreach (var x in remainingArguments)
{
if (pattern.IsMatch(x))
{
count++;
}
}
}
return count;
}
private static string GetDefaultTestProject()
{
string directory = Directory.GetCurrentDirectory();
string[] projectFiles = Directory.GetFiles(directory, "*.*proj");
if (projectFiles.Length == 0)
{
throw new GracefulException(
$"Couldn't find a project to run test from. Ensure a project exists in {directory}." + Environment.NewLine +
"Or pass the path to the project");
}
else if (projectFiles.Length > 1)
{
throw new GracefulException(
$"Specify which project file to use because this '{directory}' contains more than one project file.");
}
return projectFiles[0];
}
private static string[] GetRunSettingsOptions(List<string> remainingArgs)
{
List<string> runsettingsArgs = new List<string>();
List<string> argsToRemove = new List<string>();
bool readRunSettings = false;
foreach (string arg in remainingArgs)
{
if (!readRunSettings)
{
if (arg.Equals("--"))
{
readRunSettings = true;
argsToRemove.Add(arg);
}
continue;
}
runsettingsArgs.Add(GetSemiColonEsacpedstring(arg));
argsToRemove.Add(arg);
}
foreach (string arg in argsToRemove)
{
remainingArgs.Remove(arg);
}
return runsettingsArgs.ToArray();
return cmd.Execute();
}
private static string GetSemiColonEsacpedstring(string arg)

View file

@ -1,54 +1,94 @@
using System.Collections.Generic;
using System.Linq;
using Microsoft.DotNet.Cli.CommandLine;
using LocalizableStrings = Microsoft.DotNet.Tools.Test.LocalizableStrings;
namespace Microsoft.DotNet.Cli
{
internal static class TestCommandParser
{
public static Command Test() =>
Create.Command("test",
".NET Test Driver",
Create.Option("-h|--help",
"Show help information"),
Create.Option("-s|--settings",
"Settings to use when running tests.",
Accept.ExactlyOneArgument()
.With(name: "SETTINGS_FILE")),
Create.Option("-t|--list-tests",
"Lists discovered tests"),
Create.Option("--filter",
@"Run tests that match the given expression.
Examples:
Run tests with priority set to 1: --filter ""Priority = 1""
Run a test with the specified full name: --filter ""FullyQualifiedName=Namespace.ClassName.MethodName""
Run tests that contain the specified name: --filter ""FullyQualifiedName~Namespace.Class""
More info on filtering support: https://aka.ms/vstest-filtering",
Accept.ExactlyOneArgument()
.With(name: "EXPRESSION")),
Create.Option("-a|--test-adapter-path",
"Use custom adapters from the given path in the test run.\r\n Example: --test-adapter-path <PATH_TO_ADAPTER>"),
Create.Option("-l|--logger",
"Specify a logger for test results.\r\n Example: --logger \"trx[;LogFileName=<Defaults to unique file name>]\"",
Accept.ExactlyOneArgument()
.With(name: "LoggerUri/FriendlyName")),
Create.Option("-c|--configuration", "Configuration to use for building the project. Default for most projects is \"Debug\".",
Accept.ExactlyOneArgument()
.With(name: "CONFIGURATION")
.WithSuggestionsFrom("DEBUG", "RELEASE")),
Create.Option("-f|--framework",
"Looks for test binaries for a specific framework",
Accept.AnyOneOf(Suggest.TargetFrameworksFromProjectFile)
.With(name: "FRAMEWORK")),
Create.Option("-o|--output",
"Directory in which to find the binaries to be run",
Accept.ExactlyOneArgument()
.With(name: "OUTPUT_DIR")),
Create.Option("-d|--diag",
"Enable verbose logs for test platform.\r\n Logs are written to the provided file.",
Accept.ExactlyOneArgument()
.With(name: "PATH_TO_FILE")),
Create.Option("--no-build",
"Do not build project before testing."),
CommonOptions.VerbosityOption());
Create.Command(
"test",
LocalizableStrings.AppFullName,
Accept.ZeroOrMoreArguments(),
CommonOptions.HelpOption(),
Create.Option(
"-s|--settings",
LocalizableStrings.CmdSettingsDescription,
Accept.ExactlyOneArgument()
.With(name: LocalizableStrings.CmdSettingsFile)
.ForwardAs(o => $"/p:VSTestSetting={o.Arguments.Single()}")),
Create.Option(
"-t|--list-tests",
LocalizableStrings.CmdListTestsDescription,
Accept.NoArguments()
.ForwardAs(o => "/p:VSTestListTests=true")),
Create.Option(
"--filter",
LocalizableStrings.CmdTestCaseFilterDescription,
Accept.ExactlyOneArgument()
.With(name: LocalizableStrings.CmdTestCaseFilterExpression)
.ForwardAs(o => $"/p:VSTestTestCaseFilter={o.Arguments.Single()}")),
Create.Option(
"-a|--test-adapter-path",
LocalizableStrings.CmdTestAdapterPathDescription,
Accept.ExactlyOneArgument()
.With(name: LocalizableStrings.CmdTestAdapterPath)
.ForwardAs(o => $"/p:VSTestTestAdapterPath={o.Arguments.Single()}")),
Create.Option(
"-l|--logger",
LocalizableStrings.CmdLoggerDescription,
Accept.ExactlyOneArgument()
.With(name: LocalizableStrings.CmdLoggerOption)
.ForwardAs(o =>
{
var loggersString = string.Join(";", GetSemiColonEscapedArgs(o.Arguments));
return $"/p:VSTestLogger={loggersString}";
})),
CommonOptions.ConfigurationOption(),
CommonOptions.FrameworkOption(),
Create.Option(
"-o|--output",
LocalizableStrings.CmdOutputDescription,
Accept.ExactlyOneArgument()
.With(name: LocalizableStrings.CmdOutputDir)
.ForwardAs(o => $"/p:OutputPath={o.Arguments.Single()}")),
Create.Option(
"-d|--diag",
LocalizableStrings.CmdPathTologFileDescription,
Accept.ExactlyOneArgument()
.With(name: LocalizableStrings.CmdPathToLogFile)
.ForwardAs(o => $"/p:VSTestDiag={o.Arguments.Single()}")),
Create.Option(
"--no-build",
LocalizableStrings.CmdNoBuildDescription,
Accept.NoArguments()
.ForwardAs(o => "/p:VSTestNoBuild=true")),
CommonOptions.VerbosityOption());
private static string GetSemiColonEsacpedstring(string arg)
{
if (arg.IndexOf(";") != -1)
{
return arg.Replace(";", "%3b");
}
return arg;
}
private static string[] GetSemiColonEscapedArgs(IReadOnlyCollection<string> args)
{
int counter = 0;
string[] array = new string[args.Count];
foreach (string arg in args)
{
array[counter++] = GetSemiColonEsacpedstring(arg);
}
return array;
}
}
}

View file

@ -18,16 +18,16 @@ namespace Microsoft.DotNet.Cli.MSBuild.Tests
[InlineData(new string[] { "--output", "foo" }, "/t:Build /p:OutputPath=foo")]
[InlineData(new string[] { "-o", "foo1 foo2" }, "/t:Build \"/p:OutputPath=foo1 foo2\"")]
[InlineData(new string[] { "--no-incremental" }, "/t:Rebuild")]
[InlineData(new string[] { "-f", "framework" }, "/t:Build /p:TargetFramework=framework")]
[InlineData(new string[] { "--framework", "framework" }, "/t:Build /p:TargetFramework=framework")]
[InlineData(new string[] { "-r", "runtime" }, "/t:Build /p:RuntimeIdentifier=runtime")]
[InlineData(new string[] { "--runtime", "runtime" }, "/t:Build /p:RuntimeIdentifier=runtime")]
[InlineData(new string[] { "-c", "configuration" }, "/t:Build /p:Configuration=configuration")]
[InlineData(new string[] { "--configuration", "configuration" }, "/t:Build /p:Configuration=configuration")]
[InlineData(new string[] { "-f", "tfm" }, "/t:Build /p:TargetFramework=tfm")]
[InlineData(new string[] { "--framework", "tfm" }, "/t:Build /p:TargetFramework=tfm")]
[InlineData(new string[] { "-r", "rid" }, "/t:Build /p:RuntimeIdentifier=rid")]
[InlineData(new string[] { "--runtime", "rid" }, "/t:Build /p:RuntimeIdentifier=rid")]
[InlineData(new string[] { "-c", "config" }, "/t:Build /p:Configuration=config")]
[InlineData(new string[] { "--configuration", "config" }, "/t:Build /p:Configuration=config")]
[InlineData(new string[] { "--version-suffix", "mysuffix" }, "/t:Build /p:VersionSuffix=mysuffix")]
[InlineData(new string[] { "--no-dependencies" }, "/t:Build /p:BuildProjectReferences=false")]
[InlineData(new string[] { "-v", "verbosity" }, "/t:Build /verbosity:verbosity")]
[InlineData(new string[] { "--verbosity", "verbosity" }, "/t:Build /verbosity:verbosity")]
[InlineData(new string[] { "-v", "diag" }, "/t:Build /verbosity:diag")]
[InlineData(new string[] { "--verbosity", "diag" }, "/t:Build /verbosity:diag")]
[InlineData(new string[] { "--no-incremental", "-o", "myoutput", "-r", "myruntime", "-v", "diag" }, "/t:Rebuild /p:OutputPath=myoutput /p:RuntimeIdentifier=myruntime /verbosity:diag")]
public void MsbuildInvocationIsCorrect(string[] args, string expectedAdditionalArgs)
{

View file

@ -27,10 +27,10 @@ namespace Microsoft.DotNet.Cli.MSBuild.Tests
}
[Theory]
[InlineData(new string[] { "-f", "<framework>" }, @"/p:TargetFramework=<framework>")]
[InlineData(new string[] { "--framework", "<framework>" }, @"/p:TargetFramework=<framework>")]
[InlineData(new string[] { "-r", "<runtime>" }, @"/p:RuntimeIdentifier=<runtime>")]
[InlineData(new string[] { "--runtime", "<runtime>" }, @"/p:RuntimeIdentifier=<runtime>")]
[InlineData(new string[] { "-f", "<tfm>" }, @"/p:TargetFramework=<tfm>")]
[InlineData(new string[] { "--framework", "<tfm>" }, @"/p:TargetFramework=<tfm>")]
[InlineData(new string[] { "-r", "<rid>" }, @"/p:RuntimeIdentifier=<rid>")]
[InlineData(new string[] { "--runtime", "<rid>" }, @"/p:RuntimeIdentifier=<rid>")]
public void MsbuildInvocationIsCorrect(string[] args, string expectedAdditionalArgs)
{
args = ArgsPrefix.Concat(args).ToArray();

View file

@ -28,8 +28,8 @@ namespace Microsoft.DotNet.Cli.MSBuild.Tests
[InlineData(new string[] { "--framework", "<framework>" }, "/p:TargetFramework=<framework>")]
[InlineData(new string[] { "-c", "<configuration>" }, "/p:Configuration=<configuration>")]
[InlineData(new string[] { "--configuration", "<configuration>" }, "/p:Configuration=<configuration>")]
[InlineData(new string[] { "-v", "<verbosity>" }, "/verbosity:<verbosity>")]
[InlineData(new string[] { "--verbosity", "<verbosity>" }, "/verbosity:<verbosity>")]
[InlineData(new string[] { "-v", "diag" }, "/verbosity:diag")]
[InlineData(new string[] { "--verbosity", "diag" }, "/verbosity:diag")]
public void MsbuildInvocationIsCorrect(string[] args, string expectedAdditionalArgs)
{
expectedAdditionalArgs = (string.IsNullOrEmpty(expectedAdditionalArgs) ? "" : $" {expectedAdditionalArgs}");

View file

@ -15,18 +15,18 @@ namespace Microsoft.DotNet.Cli.MSBuild.Tests
[Theory]
[InlineData(new string[] { }, "")]
[InlineData(new string[] { "-o", "<output>" }, "/p:PackageOutputPath=<output>")]
[InlineData(new string[] { "--output", "<output>" }, "/p:PackageOutputPath=<output>")]
[InlineData(new string[] { "-o", "<packageoutputpath>" }, "/p:PackageOutputPath=<packageoutputpath>")]
[InlineData(new string[] { "--output", "<packageoutputpath>" }, "/p:PackageOutputPath=<packageoutputpath>")]
[InlineData(new string[] { "--no-build" }, "/p:NoBuild=true")]
[InlineData(new string[] { "--include-symbols" }, "/p:IncludeSymbols=true")]
[InlineData(new string[] { "--include-source" }, "/p:IncludeSource=true")]
[InlineData(new string[] { "-c", "<configuration>" }, "/p:Configuration=<configuration>")]
[InlineData(new string[] { "--configuration", "<configuration>" }, "/p:Configuration=<configuration>")]
[InlineData(new string[] { "--version-suffix", "<version-suffix>" }, "/p:VersionSuffix=<version-suffix>")]
[InlineData(new string[] { "-c", "<config>" }, "/p:Configuration=<config>")]
[InlineData(new string[] { "--configuration", "<config>" }, "/p:Configuration=<config>")]
[InlineData(new string[] { "--version-suffix", "<versionsuffix>" }, "/p:VersionSuffix=<versionsuffix>")]
[InlineData(new string[] { "-s" }, "/p:Serviceable=true")]
[InlineData(new string[] { "--serviceable" }, "/p:Serviceable=true")]
[InlineData(new string[] { "-v", "<verbosity>" }, @"/verbosity:<verbosity>")]
[InlineData(new string[] { "--verbosity", "<verbosity>" }, @"/verbosity:<verbosity>")]
[InlineData(new string[] { "-v", "diag" }, "/verbosity:diag")]
[InlineData(new string[] { "--verbosity", "diag" }, "/verbosity:diag")]
[InlineData(new string[] { "<project>" }, "<project>")]
public void MsbuildInvocationIsCorrect(string[] args, string expectedAdditionalArgs)
{

View file

@ -24,16 +24,16 @@ namespace Microsoft.DotNet.Cli.MSBuild.Tests
[Theory]
[InlineData(new string[] { }, "")]
[InlineData(new string[] { "-f", "<framework>" }, "/p:TargetFramework=<framework>")]
[InlineData(new string[] { "--framework", "<framework>" }, "/p:TargetFramework=<framework>")]
[InlineData(new string[] { "-r", "<runtime>" }, "/p:RuntimeIdentifier=<runtime>")]
[InlineData(new string[] { "--runtime", "<runtime>" }, "/p:RuntimeIdentifier=<runtime>")]
[InlineData(new string[] { "-o", "<output>" }, "/p:PublishDir=<output>")]
[InlineData(new string[] { "--output", "<output>" }, "/p:PublishDir=<output>")]
[InlineData(new string[] { "-c", "<configuration>" }, "/p:Configuration=<configuration>")]
[InlineData(new string[] { "--configuration", "<configuration>" }, "/p:Configuration=<configuration>")]
[InlineData(new string[] { "--version-suffix", "<version-suffix>" }, "/p:VersionSuffix=<version-suffix>")]
[InlineData(new string[] { "--filter", "<filter>" }, "/p:FilterProjectFiles=<filter>")]
[InlineData(new string[] { "-f", "<tfm>" }, "/p:TargetFramework=<tfm>")]
[InlineData(new string[] { "--framework", "<tfm>" }, "/p:TargetFramework=<tfm>")]
[InlineData(new string[] { "-r", "<rid>" }, "/p:RuntimeIdentifier=<rid>")]
[InlineData(new string[] { "--runtime", "<rid>" }, "/p:RuntimeIdentifier=<rid>")]
[InlineData(new string[] { "-o", "<publishdir>" }, "/p:PublishDir=<publishdir>")]
[InlineData(new string[] { "--output", "<publishdir>" }, "/p:PublishDir=<publishdir>")]
[InlineData(new string[] { "-c", "<config>" }, "/p:Configuration=<config>")]
[InlineData(new string[] { "--configuration", "<config>" }, "/p:Configuration=<config>")]
[InlineData(new string[] { "--version-suffix", "<versionsuffix>" }, "/p:VersionSuffix=<versionsuffix>")]
[InlineData(new string[] { "--filter", "<filterprojectfiles>" }, "/p:FilterProjectFiles=<filterprojectfiles>")]
[InlineData(new string[] { "-v", "minimal" }, "/verbosity:minimal")]
[InlineData(new string[] { "--verbosity", "minimal" }, "/verbosity:minimal")]
[InlineData(new string[] { "<project>" }, "<project>")]
@ -51,16 +51,16 @@ namespace Microsoft.DotNet.Cli.MSBuild.Tests
[Theory]
[InlineData(new string[] { }, "")]
[InlineData(new string[] { "-f", "<framework>" }, "/p:TargetFramework=<framework>")]
[InlineData(new string[] { "--framework", "<framework>" }, "/p:TargetFramework=<framework>")]
[InlineData(new string[] { "-r", "<runtime>" }, "/p:RuntimeIdentifier=<runtime>")]
[InlineData(new string[] { "--runtime", "<runtime>" }, "/p:RuntimeIdentifier=<runtime>")]
[InlineData(new string[] { "-o", "<output>" }, "/p:PublishDir=<output>")]
[InlineData(new string[] { "--output", "<output>" }, "/p:PublishDir=<output>")]
[InlineData(new string[] { "-c", "<configuration>" }, "/p:Configuration=<configuration>")]
[InlineData(new string[] { "--configuration", "<configuration>" }, "/p:Configuration=<configuration>")]
[InlineData(new string[] { "--version-suffix", "<version-suffix>" }, "/p:VersionSuffix=<version-suffix>")]
[InlineData(new string[] { "--filter", "<filter>" }, "/p:FilterProjectFiles=<filter>")]
[InlineData(new string[] { "-f", "<tfm>" }, "/p:TargetFramework=<tfm>")]
[InlineData(new string[] { "--framework", "<tfm>" }, "/p:TargetFramework=<tfm>")]
[InlineData(new string[] { "-r", "<rid>" }, "/p:RuntimeIdentifier=<rid>")]
[InlineData(new string[] { "--runtime", "<rid>" }, "/p:RuntimeIdentifier=<rid>")]
[InlineData(new string[] { "-o", "<publishdir>" }, "/p:PublishDir=<publishdir>")]
[InlineData(new string[] { "--output", "<publishdir>" }, "/p:PublishDir=<publishdir>")]
[InlineData(new string[] { "-c", "<config>" }, "/p:Configuration=<config>")]
[InlineData(new string[] { "--configuration", "<config>" }, "/p:Configuration=<config>")]
[InlineData(new string[] { "--version-suffix", "<versionsuffix>" }, "/p:VersionSuffix=<versionsuffix>")]
[InlineData(new string[] { "--filter", "<filterprojectfiles>" }, "/p:FilterProjectFiles=<filterprojectfiles>")]
[InlineData(new string[] { "-v", "minimal" }, "/verbosity:minimal")]
[InlineData(new string[] { "--verbosity", "minimal" }, "/verbosity:minimal")]
public void OptionForwardingIsCorrect(string[] args, string expectedAdditionalArgs)

View file

@ -64,4 +64,4 @@ namespace Microsoft.DotNet.Tests.ParserTests
.BeEquivalentTo("one");
}
}
}
}