Merge pull request #5935 from jonsequitur/tab-completion

Replace CommandLineApplication with new command line parser, enable tab completion
This commit is contained in:
Livar 2017-03-21 17:11:17 -07:00 committed by GitHub
commit 0eff67d207
127 changed files with 2411 additions and 1659 deletions

View file

@ -16,6 +16,8 @@
<TemplateEngineTemplate2_0Version>1.0.0-beta1-20170209-117</TemplateEngineTemplate2_0Version>
<PlatformAbstractionsVersion>1.0.3</PlatformAbstractionsVersion>
<DependencyModelVersion>1.0.3</DependencyModelVersion>
<CliCommandLineParserVersion>0.1.0-alpha-88</CliCommandLineParserVersion>
</PropertyGroup>
<!-- infrastructure and test only dependencies -->

View file

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

View file

@ -71,7 +71,11 @@ namespace Microsoft.DotNet.Cli.Build
protected override string GenerateCommandLineCommands()
{
return $"{Command} {Args}";
var commandLineCommands = $"{Command} {Args}";
LogToolCommand($"[DotNetTool] {commandLineCommands}");
return commandLineCommands;
}
protected override void LogToolCommand(string message)

View file

@ -0,0 +1,14 @@
#!/bin/bash
# bash parameter completion for the dotnet CLI
_dotnet_bash_complete()
{
local word=${COMP_WORDS[COMP_CWORD]}
local dotnetPath=${COMP_WORDS[1]}
local completions=("$(dotnet complete --position ${COMP_POINT} "${COMP_LINE}")")
COMPREPLY=( $(compgen -W "$completions" -- "$word") )
}
complete -f -F _dotnet_bash_complete dotnet

View file

@ -0,0 +1,7 @@
# PowerShell parameter completion shim for the dotnet CLI
Register-ArgumentCompleter -Native -CommandName dotnet -ScriptBlock {
param($commandName, $wordToComplete, $cursorPosition)
C:\dev\github\cli\artifacts\win10-x64\stage2\dotnet.exe complete --position $cursorPosition "$wordToComplete" | ForEach-Object {
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_)
}
}

View file

@ -0,0 +1,12 @@
# zsh parameter completion for the dotnet CLI
_dotnet_zsh_complete()
{
local dotnetPath=$words[1]
local completions=("$(dotnet complete "$words")")
reply=( "${(ps:\n:)completions}" )
}
compctl -K _dotnet_zsh_complete dotnet

View file

@ -287,7 +287,7 @@ namespace Microsoft.DotNet.Tools.Common
return result;
}
public static bool HasExtension(string filePath, string extension)
public static bool HasExtension(this string filePath, string extension)
{
var comparison = StringComparison.Ordinal;
@ -313,9 +313,12 @@ namespace Microsoft.DotNet.Tools.Common
return Path.GetFullPath(path);
}
public static void EnsureAllPathsExist(List<string> paths, string pathDoesNotExistLocalizedFormatString)
public static void EnsureAllPathsExist(
IReadOnlyCollection<string> paths,
string pathDoesNotExistLocalizedFormatString)
{
var notExisting = new List<string>();
foreach (var p in paths)
{
if (!File.Exists(p))
@ -329,8 +332,11 @@ namespace Microsoft.DotNet.Tools.Common
throw new GracefulException(
string.Join(
Environment.NewLine,
notExisting.Select((p) => string.Format(pathDoesNotExistLocalizedFormatString, p))));
notExisting.Select(p => string.Format(pathDoesNotExistLocalizedFormatString, p))));
}
}
public static bool IsDirectory(this string path) =>
File.GetAttributes(path).HasFlag(FileAttributes.Directory);
}
}

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

@ -0,0 +1,48 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.DotNet.Cli.CommandLine;
namespace Microsoft.DotNet.Cli
{
public static class ArgumentForwardingExtensions
{
public static ArgumentsRule Forward(
this ArgumentsRule rule) =>
rule.MaterializeAs(o => new ForwardedArgument(o.Arguments.SingleOrDefault()));
public static ArgumentsRule ForwardAs(
this ArgumentsRule rule,
string value) =>
rule.MaterializeAs(o => new ForwardedArgument(value));
public static ArgumentsRule ForwardAsSingle(
this ArgumentsRule rule,
Func<AppliedOption, string> format) =>
rule.MaterializeAs(o =>
new ForwardedArgument(format(o)));
public static ArgumentsRule ForwardAsMany(
this ArgumentsRule rule,
Func<AppliedOption, IEnumerable<string>> format) =>
rule.MaterializeAs(o =>
new ForwardedArgument(format(o).ToArray()));
public static IEnumerable<string> OptionValuesToBeForwarded(
this AppliedOption command) =>
command.AppliedOptions
.Select(o => o.Value())
.OfType<ForwardedArgument>()
.SelectMany(o => o.Values);
private class ForwardedArgument
{
public ForwardedArgument(params string[] values)
{
Values = values;
}
public string[] Values { get; }
}
}
}

View file

@ -133,8 +133,15 @@ namespace Microsoft.DotNet.Cli
Command = VSTestCommand.Run,
// aka.ms target: https://docs.microsoft.com/dotnet/articles/core/tools/dotnet-vstest
DocLink = "https://aka.ms/dotnet-vstest"
},
["complete"] = new BuiltInCommandMetadata
{
Command = CompleteCommand.Run
},
["parse"] = new BuiltInCommandMetadata
{
Command = ParseCommand.Run
}
};
}
}

22
src/dotnet/CommandBase.cs Normal file
View file

@ -0,0 +1,22 @@
// 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 Microsoft.DotNet.Cli.CommandLine;
namespace Microsoft.DotNet.Cli
{
public abstract class CommandBase
{
protected CommandBase(ParseResult parseResult)
{
ShowHelpOrErrorIfAppropriate(parseResult);
}
protected virtual void ShowHelpOrErrorIfAppropriate(ParseResult parseResult)
{
parseResult.ShowHelpOrErrorIfAppropriate();
}
public abstract int Execute();
}
}

View file

@ -8,22 +8,30 @@ namespace Microsoft.DotNet.Cli.CommandLine
{
internal class CommandParsingException : Exception
{
private bool _isRequireSubCommandMissing;
private readonly bool _isRequireSubCommandMissing;
public CommandParsingException(
string message,
string helpText = null) : base(message)
{
HelpText = helpText ?? "";
Data.Add("CLI_User_Displayed_Exception", true);
}
public CommandParsingException(
CommandLineApplication command,
string message,
bool isRequireSubCommandMissing = false)
: base(message)
: this(message)
{
Command = command;
_isRequireSubCommandMissing = isRequireSubCommandMissing;
Data.Add("CLI_User_Displayed_Exception", true);
}
public CommandLineApplication Command { get; }
public string HelpText { get; } = "";
public override string Message
{
get

View file

@ -158,8 +158,8 @@ namespace Microsoft.DotNet.Tools
/// sln
public const string ArgumentsProjectDescription = "The project file to operate on. If a file is not specified, the command will search the current directory for one.";
public const string ArgumentsSolutionDescription = "Solution file to operate on. If not specified, the command will search the current directory for one.";
public const string CmdSlnFile = "<SLN_FILE>";
public const string CmdProjectFile = "<PROJECT>";
public const string CmdSlnFile = "SLN_FILE";
public const string CmdProjectFile = "PROJECT";
/// commands
public const string CmdFramework = "FRAMEWORK";

View file

@ -0,0 +1,68 @@
using System;
using System.IO;
using System.Linq;
using Microsoft.DotNet.Cli.CommandLine;
using Microsoft.DotNet.Tools.Common;
namespace Microsoft.DotNet.Cli
{
internal static class CommonOptions
{
public static Option HelpOption() =>
Create.Option(
"-h|--help",
"Show help information",
Accept.NoArguments(),
materialize: o => o.Option.Command().HelpView());
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]",
Accept.AnyOneOf(
"q", "quiet",
"m", "minimal",
"n", "normal",
"d", "detailed",
"diag", "diagnostic")
.ForwardAsSingle(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")
.ForwardAsSingle(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")
.ForwardAsSingle(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")
.ForwardAsSingle(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")
.ForwardAsSingle(o => $"/p:VersionSuffix={o.Arguments.Single()}"));
public static ArgumentsRule DefaultToCurrentDirectory(this ArgumentsRule rule) =>
rule.With(defaultValue: () => PathUtility.EnsureTrailingSlash(Directory.GetCurrentDirectory()));
}
}

View file

@ -1,16 +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 Microsoft.DotNet.Cli.CommandLine;
namespace Microsoft.DotNet.Cli
{
internal abstract class DotNetSubCommandBase : CommandLineApplication
{
internal DotNetSubCommandBase() : base(throwOnUnexpectedArg: false)
{
}
public abstract int Run(string fileOrDirectory);
}
}

View file

@ -3,12 +3,10 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Microsoft.DotNet.Cli.CommandLine;
using Microsoft.DotNet.Cli.Utils;
using Microsoft.DotNet.Tools;
using Microsoft.DotNet.Tools.Common;
namespace Microsoft.DotNet.Cli
{
@ -18,65 +16,36 @@ namespace Microsoft.DotNet.Cli
protected abstract string FullCommandNameLocalized { get; }
protected abstract string ArgumentName { get; }
protected abstract string ArgumentDescriptionLocalized { get; }
internal abstract List<Func<DotNetSubCommandBase>> SubCommands { get; }
protected ParseResult ParseResult { get; private set; }
internal abstract Dictionary<string, Func<AppliedOption, CommandBase>> SubCommands { get; }
public int RunCommand(string[] args)
{
DebugHelper.HandleDebugSwitch(ref args);
CommandLineApplication command = new CommandLineApplication(throwOnUnexpectedArg: true)
{
Name = $"dotnet {CommandName}",
FullName = FullCommandNameLocalized,
};
var parser = Parser.Instance;
command.HelpOption("-h|--help");
ParseResult = parser.ParseFrom($"dotnet {CommandName}", args);
command.Argument(ArgumentName, ArgumentDescriptionLocalized);
var subcommandName = ParseResult.Command().Name;
foreach (var subCommandCreator in SubCommands)
{
var subCommand = subCommandCreator();
command.AddCommand(subCommand);
subCommand.OnExecute(() => {
try
{
if (!command.Arguments.Any())
{
throw new GracefulException(CommonLocalizableStrings.RequiredArgumentNotPassed, ArgumentDescriptionLocalized);
}
var create = SubCommands[subcommandName];
var projectOrDirectory = command.Arguments.First().Value;
if (string.IsNullOrEmpty(projectOrDirectory))
{
projectOrDirectory = PathUtility.EnsureTrailingSlash(Directory.GetCurrentDirectory());
}
var command = create(ParseResult["dotnet"][CommandName]);
return subCommand.Run(projectOrDirectory);
return command.Execute();
}
catch (KeyNotFoundException)
{
throw new GracefulException(CommonLocalizableStrings.RequiredCommandNotPassed);
}
catch (GracefulException e)
{
Reporter.Error.WriteLine(e.Message.Red());
subCommand.ShowHelp();
return 1;
}
});
}
try
{
return command.Execute(args);
}
catch (GracefulException e)
{
Reporter.Error.WriteLine(e.Message.Red());
command.ShowHelp();
return 1;
}
catch (CommandParsingException e)
{
Reporter.Error.WriteLine(e.Message.Red());
ParseResult.ShowHelp();
return 1;
}
}

View file

@ -0,0 +1,17 @@
using System;
using Microsoft.DotNet.Cli.Utils;
namespace Microsoft.DotNet.Cli
{
///
/// <summary>Allows control flow to be interrupted in order to display help in the console.</summary>
///
[Obsolete("This is intended to facilitate refactoring during parser replacement and should not be used after that work is done.")]
public class HelpException : Exception
{
public HelpException(string message) : base(message)
{
Data.Add(ExceptionExtensions.CLI_User_Displayed_Exception, true);
}
}
}

View file

@ -24,6 +24,7 @@ namespace Microsoft.DotNet.Tools
private ProjectCollection _projects;
private List<NuGetFramework> _cachedTfms = null;
private IEnumerable<string> cachedRuntimeIdentifiers;
private MsbuildProject(ProjectCollection projects, ProjectRootElement project)
{
@ -149,6 +150,12 @@ namespace Microsoft.DotNet.Tools
return ProjectRootElement.GetAllItemsWithElementType(ProjectItemElementType);
}
public IEnumerable<string> GetRuntimeIdentifiers()
{
return cachedRuntimeIdentifiers ??
(cachedRuntimeIdentifiers = GetEvaluatedProject().GetRuntimeIdentifiers());
}
public IEnumerable<NuGetFramework> GetTargetFrameworks()
{
if (_cachedTfms != null)

View file

@ -0,0 +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;
using System.Linq;
using Microsoft.DotNet.Cli.CommandLine;
namespace Microsoft.DotNet.Cli
{
public static class ParseResultExtensions
{
public static void ShowHelp(this ParseResult parseResult) =>
Console.WriteLine(parseResult.Command().HelpView());
public static void ShowHelpOrErrorIfAppropriate(this ParseResult parseResult)
{
var appliedCommand = parseResult.AppliedCommand();
if (appliedCommand.HasOption("help") ||
appliedCommand.Arguments.Contains("-?") ||
appliedCommand.Arguments.Contains("/?"))
{
// NOTE: this is a temporary stage in refactoring toward the ClicCommandLineParser being used at the CLI entry point.
throw new HelpException(parseResult.Command().HelpView());
}
if (parseResult.Errors.Any())
{
throw new CommandParsingException(
message: string.Join(Environment.NewLine,
parseResult.Errors.Select(e => e.Message)),
helpText: parseResult?.Command()?.HelpView());
}
}
}
}

58
src/dotnet/Parser.cs Normal file
View file

@ -0,0 +1,58 @@
// 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 Microsoft.DotNet.Cli.CommandLine;
using static System.Environment;
using static Microsoft.DotNet.Cli.CommandLine.LocalizableStrings;
using LocalizableStrings = Microsoft.DotNet.Tools.Run.LocalizableStrings;
namespace Microsoft.DotNet.Cli
{
public static class Parser
{
static Parser()
{
ConfigureCommandLineLocalizedStrings();
}
private static void ConfigureCommandLineLocalizedStrings()
{
DefaultHelpViewText.AdditionalArgumentsSection =
$"{UsageCommandsAdditionalArgsHeader}:{NewLine} {LocalizableStrings.RunCommandAdditionalArgsHelpText}";
DefaultHelpViewText.ArgumentsSection.Title = UsageArgumentsHeader;
DefaultHelpViewText.CommandsSection.Title = UsageCommandsHeader;
DefaultHelpViewText.OptionsSection.Title = UsageOptionsHeader;
DefaultHelpViewText.Synopsis.AdditionalArguments = UsageCommandAdditionalArgs;
DefaultHelpViewText.Synopsis.Command = UsageCommandToken;
DefaultHelpViewText.Synopsis.Options = UsageOptionsToken;
DefaultHelpViewText.Synopsis.Title = UsageHeader;
}
public static CommandLine.Parser Instance { get; } = new CommandLine.Parser(
options: Create.Command("dotnet",
".NET Command Line Tools",
Accept.NoArguments(),
NewCommandParser.New(),
RestoreCommandParser.Restore(),
BuildCommandParser.Build(),
PublishCommandParser.Publish(),
RunCommandParser.Run(),
TestCommandParser.Test(),
PackCommandParser.Pack(),
MigrateCommandParser.Migrate(),
CleanCommandParser.Clean(),
SlnCommandParser.Sln(),
AddCommandParser.Add(),
RemoveCommandParser.Remove(),
ListCommandParser.List(),
NuGetCommandParser.NuGet(),
CacheCommandParser.Cache(),
Create.Command("msbuild", ""),
Create.Command("vstest", ""),
CompleteCommandParser.Complete(),
CommonOptions.HelpOption(),
Create.Option("--info", ""),
Create.Option("-d", ""),
Create.Option("--debug", "")));
}
}

View file

@ -0,0 +1,14 @@
using System.Linq;
using Microsoft.DotNet.Cli.CommandLine;
namespace Microsoft.DotNet.Cli
{
public static class ParserExtensions
{
public static ParseResult ParseFrom(
this CommandLine.Parser parser,
string context,
string[] args) =>
parser.Parse(context.Split(' ').Concat(args).ToArray());
}
}

View file

@ -4,11 +4,13 @@
using System;
using System.Linq;
using System.Text;
using Microsoft.DotNet.Cli.CommandLine;
using Microsoft.DotNet.Cli.Utils;
using Microsoft.DotNet.Configurer;
using Microsoft.DotNet.PlatformAbstractions;
using Microsoft.DotNet.Tools.Help;
using NuGet.Frameworks;
using Command = Microsoft.DotNet.Cli.Utils.Command;
namespace Microsoft.DotNet.Cli
{
@ -34,11 +36,28 @@ namespace Microsoft.DotNet.Cli
return ProcessArgs(args);
}
}
catch (HelpException e)
{
Reporter.Output.WriteLine(e.Message);
return 0;
}
catch (Exception e) when (e.ShouldBeDisplayedAsError())
{
Reporter.Error.WriteLine(CommandContext.IsVerbose() ?
e.ToString().Red().Bold() :
e.Message.Red().Bold());
Reporter.Error.WriteLine(CommandContext.IsVerbose()
? e.ToString().Red().Bold()
: e.Message.Red().Bold());
var commandParsingException = e as CommandParsingException;
if (commandParsingException != null)
{
Reporter.Output.WriteLine(commandParsingException.HelpText);
}
return 1;
}
catch (Exception e) when (!e.ShouldBeDisplayedAsError())
{
Reporter.Error.WriteLine(e.ToString().Red().Bold());
return 1;
}

View file

@ -1,9 +1,7 @@
// 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 Microsoft.Build.Construction;
using Microsoft.Build.Evaluation;
using Microsoft.DotNet.ProjectJsonMigration;
using NuGet.Frameworks;
using System.Collections.Generic;
using System.Linq;
@ -12,6 +10,15 @@ namespace Microsoft.DotNet.Tools.ProjectExtensions
{
internal static class ProjectExtensions
{
public static IEnumerable<string> GetRuntimeIdentifiers(this Project project)
{
return project
.GetPropertyCommaSeparatedValues("RuntimeIdentifier")
.Concat(project.GetPropertyCommaSeparatedValues("RuntimeIdentifiers"))
.Select(value => value.ToLower())
.Distinct();
}
public static IEnumerable<NuGetFramework> GetTargetFrameworks(this Project project)
{
var targetFramewoksStrings = project

View file

@ -0,0 +1,25 @@
// 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;
using Microsoft.DotNet.Tools;
using LocalizableStrings = Microsoft.DotNet.Tools.Add.LocalizableStrings;
namespace Microsoft.DotNet.Cli
{
internal static class AddCommandParser
{
public static Command Add() =>
Create.Command(
"add",
LocalizableStrings.NetAddCommand,
Accept.ExactlyOneArgument()
.DefaultToCurrentDirectory()
.With(name: CommonLocalizableStrings.CmdProjectFile,
description: CommonLocalizableStrings.ArgumentsProjectDescription), AddPackageParser.AddPackage(),
AddProjectToProjectReferenceParser.AddProjectReference(),
CommonOptions.HelpOption());
}
}

View file

@ -3,7 +3,9 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.DotNet.Cli;
using Microsoft.DotNet.Cli.CommandLine;
using Microsoft.DotNet.Cli.Utils;
using Microsoft.DotNet.Tools.Add.PackageReference;
using Microsoft.DotNet.Tools.Add.ProjectToProjectReference;
@ -16,11 +18,21 @@ namespace Microsoft.DotNet.Tools.Add
protected override string FullCommandNameLocalized => LocalizableStrings.NetAddCommand;
protected override string ArgumentName => Constants.ProjectArgumentName;
protected override string ArgumentDescriptionLocalized => CommonLocalizableStrings.ArgumentsProjectDescription;
internal override List<Func<DotNetSubCommandBase>> SubCommands =>
new List<Func<DotNetSubCommandBase>>
internal override Dictionary<string, Func<AppliedOption, CommandBase>> SubCommands =>
new Dictionary<string, Func<AppliedOption, CommandBase>>
{
AddProjectToProjectReferenceCommand.Create,
AddPackageReferenceCommand.Create,
["reference"] =
add => new AddProjectToProjectReferenceCommand(
add["reference"],
add.Value<string>(),
ParseResult),
["package"] =
add => new AddPackageReferenceCommand(
add["package"],
add.Value<string>(),
ParseResult)
};
public static int Run(string[] args)

View file

@ -0,0 +1,78 @@
// 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.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Threading;
using Microsoft.DotNet.Cli.CommandLine;
using Newtonsoft.Json.Linq;
using LocalizableStrings = Microsoft.DotNet.Tools.Add.PackageReference.LocalizableStrings;
namespace Microsoft.DotNet.Cli
{
internal static class AddPackageParser
{
public static Command AddPackage()
{
return Create.Command(
"package",
LocalizableStrings.AppFullName,
Accept.ExactlyOneArgument(errorMessage: o => LocalizableStrings.SpecifyExactlyOnePackageReference)
.WithSuggestionsFrom(QueryNuGet)
.With(name: LocalizableStrings.CmdPackage,
description: LocalizableStrings.CmdPackageDescription),
CommonOptions.HelpOption(),
Create.Option("-v|--version",
LocalizableStrings.CmdVersionDescription,
Accept.ExactlyOneArgument()
.With(name: LocalizableStrings.CmdVersion)
.ForwardAsSingle(o => $"--version {o.Arguments.Single()}")),
Create.Option("-f|--framework",
LocalizableStrings.CmdFrameworkDescription,
Accept.ExactlyOneArgument()
.With(name: LocalizableStrings.CmdFramework)
.ForwardAsSingle(o => $"--framework {o.Arguments.Single()}")),
Create.Option("-n|--no-restore ",
LocalizableStrings.CmdNoRestoreDescription),
Create.Option("-s|--source",
LocalizableStrings.CmdSourceDescription,
Accept.ExactlyOneArgument()
.With(name: LocalizableStrings.CmdSource)
.ForwardAsSingle(o => $"--source {o.Arguments.Single()}")),
Create.Option("--package-directory",
LocalizableStrings.CmdPackageDirectoryDescription,
Accept.ExactlyOneArgument()
.With(name: LocalizableStrings.CmdPackageDirectory)
.ForwardAsSingle(o => $"--package-directory {o.Arguments.Single()}")));
}
public static IEnumerable<string> QueryNuGet(string match)
{
var httpClient = new HttpClient();
string result;
try
{
var cancellation = new CancellationTokenSource(TimeSpan.FromSeconds(10));
var response = httpClient.GetAsync($"https://api-v2v3search-0.nuget.org/query?q={match}&skip=0&take=100&prerelease=true", cancellation.Token)
.Result;
result = response.Content.ReadAsStringAsync().Result;
}
catch (Exception)
{
yield break;
}
var json = JObject.Parse(result);
foreach (var id in json["data"])
{
yield return id["id"].Value<string>();
}
}
}
}

View file

@ -1,105 +1,81 @@
// 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 Microsoft.Build.Evaluation;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Microsoft.DotNet.Cli;
using Microsoft.DotNet.Cli.CommandLine;
using Microsoft.DotNet.Cli.Utils;
using Microsoft.DotNet.Tools.Common;
using Microsoft.DotNet.Tools.MSBuild;
using Microsoft.DotNet.Tools.NuGet;
using NuGet.Frameworks;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
namespace Microsoft.DotNet.Tools.Add.PackageReference
{
internal class AddPackageReferenceCommand : DotNetSubCommandBase
internal class AddPackageReferenceCommand : CommandBase
{
private CommandOption _versionOption;
private CommandOption _frameworkOption;
private CommandOption _noRestoreOption;
private CommandOption _sourceOption;
private CommandOption _packageDirectoryOption;
private CommandArgument _packageNameArgument;
private readonly AppliedOption _appliedCommand;
public static DotNetSubCommandBase Create()
private readonly string _packageId;
private readonly string _fileOrDirectory;
public AddPackageReferenceCommand(
AppliedOption appliedCommand,
string fileOrDirectory,
ParseResult parseResult) : base(parseResult)
{
var command = new AddPackageReferenceCommand
if (appliedCommand == null)
{
Name = "package",
FullName = LocalizableStrings.AppFullName,
Description = LocalizableStrings.AppDescription,
HandleRemainingArguments = false
};
command.HelpOption("-h|--help");
command._packageNameArgument = command.Argument(
$"<{LocalizableStrings.CmdPackage}>",
LocalizableStrings.CmdPackageDescription,
multipleValues: false);
command._versionOption = command.Option(
$"-v|--version <{LocalizableStrings.CmdVersion}>",
description: LocalizableStrings.CmdVersionDescription,
optionType: CommandOptionType.SingleValue);
command._frameworkOption = command.Option(
$"-f|--framework <{LocalizableStrings.CmdFramework}>",
LocalizableStrings.CmdFrameworkDescription,
CommandOptionType.SingleValue);
command._noRestoreOption = command.Option(
"-n|--no-restore ",
LocalizableStrings.CmdNoRestoreDescription,
CommandOptionType.NoValue);
command._sourceOption = command.Option(
$"-s|--source <{LocalizableStrings.CmdSource}>",
LocalizableStrings.CmdSourceDescription,
CommandOptionType.SingleValue);
command._packageDirectoryOption = command.Option(
$"--package-directory <{LocalizableStrings.CmdPackageDirectory}>",
LocalizableStrings.CmdPackageDirectoryDescription,
CommandOptionType.SingleValue);
return command;
throw new ArgumentNullException(nameof(appliedCommand));
}
if (fileOrDirectory == null)
{
throw new ArgumentNullException(nameof(fileOrDirectory));
}
public override int Run(string fileOrDirectory)
_appliedCommand = appliedCommand;
_fileOrDirectory = fileOrDirectory;
_packageId = appliedCommand.Value<string>();
}
protected override void ShowHelpOrErrorIfAppropriate(ParseResult parseResult)
{
if (_packageNameArgument.Values.Count != 1 || string.IsNullOrWhiteSpace(_packageNameArgument.Value) || RemainingArguments.Count > 0)
if (parseResult.UnmatchedTokens.Any())
{
throw new GracefulException(LocalizableStrings.SpecifyExactlyOnePackageReference);
}
base.ShowHelpOrErrorIfAppropriate(parseResult);
}
public override int Execute()
{
var projectFilePath = string.Empty;
if (!File.Exists(fileOrDirectory))
if (!File.Exists(_fileOrDirectory))
{
projectFilePath = MsbuildProject.GetProjectFileFromDirectory(fileOrDirectory).FullName;
projectFilePath = MsbuildProject.GetProjectFileFromDirectory(_fileOrDirectory).FullName;
}
else
{
projectFilePath = fileOrDirectory;
projectFilePath = _fileOrDirectory;
}
var tempDgFilePath = string.Empty;
if (!_noRestoreOption.HasValue())
if (!_appliedCommand.HasOption("no-restore"))
{
// Create a Dependency Graph file for the project
tempDgFilePath = Path.GetTempFileName();
GetProjectDependencyGraph(projectFilePath, tempDgFilePath);
}
var result = NuGetCommand.Run(TransformArgs(_packageNameArgument.Value, tempDgFilePath, projectFilePath));
var result = NuGetCommand.Run(
TransformArgs(
_packageId,
tempDgFilePath,
projectFilePath));
DisposeTemporaryFile(tempDgFilePath);
return result;
@ -136,7 +112,8 @@ namespace Microsoft.DotNet.Tools.Add.PackageReference
private string[] TransformArgs(string packageId, string tempDgFilePath, string projectFilePath)
{
var args = new List<string>(){
var args = new List<string>
{
"package",
"add",
"--package",
@ -145,27 +122,11 @@ namespace Microsoft.DotNet.Tools.Add.PackageReference
projectFilePath
};
if (_versionOption.HasValue())
{
args.Add("--version");
args.Add(_versionOption.Value());
}
if (_sourceOption.HasValue())
{
args.Add("--source");
args.Add(_sourceOption.Value());
}
if (_frameworkOption.HasValue())
{
args.Add("--framework");
args.Add(_frameworkOption.Value());
}
if (_packageDirectoryOption.HasValue())
{
args.Add("--package-directory");
args.Add(_packageDirectoryOption.Value());
}
if (_noRestoreOption.HasValue())
args.AddRange(_appliedCommand
.OptionValuesToBeForwarded()
.SelectMany(a => a.Split(' ')));
if (_appliedCommand.HasOption("no-restore"))
{
args.Add("--no-restore");
}

View file

@ -0,0 +1,26 @@
// 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 Microsoft.DotNet.Cli.CommandLine;
using LocalizableStrings = Microsoft.DotNet.Tools.Add.ProjectToProjectReference.LocalizableStrings;
namespace Microsoft.DotNet.Cli
{
internal static class AddProjectToProjectReferenceParser
{
public static Command AddProjectReference()
{
return Create.Command(
"reference",
LocalizableStrings.AppFullName,
Accept.OneOrMoreArguments()
.With(name: "args",
description: LocalizableStrings.AppHelpText),
CommonOptions.HelpOption(),
Create.Option("-f|--framework", LocalizableStrings.CmdFrameworkDescription,
Accept.ExactlyOneArgument()
.WithSuggestionsFrom(_ => Suggest.TargetFrameworksFromProjectFile())
.With(name: Tools.Add.PackageReference.LocalizableStrings.CmdFramework)));
}
}
}

View file

@ -1,57 +1,52 @@
// 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.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using Microsoft.Build.Evaluation;
using Microsoft.DotNet.Cli;
using Microsoft.DotNet.Cli.CommandLine;
using Microsoft.DotNet.Cli.Utils;
using Microsoft.DotNet.Tools.Common;
using NuGet.Frameworks;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
namespace Microsoft.DotNet.Tools.Add.ProjectToProjectReference
{
internal class AddProjectToProjectReferenceCommand : DotNetSubCommandBase
internal class AddProjectToProjectReferenceCommand : CommandBase
{
private CommandOption _frameworkOption;
private readonly AppliedOption _appliedCommand;
private readonly string _fileOrDirectory;
public static DotNetSubCommandBase Create()
public AddProjectToProjectReferenceCommand(
AppliedOption appliedCommand,
string fileOrDirectory,
ParseResult parseResult) : base(parseResult)
{
var command = new AddProjectToProjectReferenceCommand()
if (appliedCommand == null)
{
Name = "reference",
FullName = LocalizableStrings.AppFullName,
Description = LocalizableStrings.AppDescription,
HandleRemainingArguments = true,
ArgumentSeparatorHelpText = LocalizableStrings.AppHelpText,
};
command.HelpOption("-h|--help");
command._frameworkOption = command.Option(
$"-f|--framework <{CommonLocalizableStrings.CmdFramework}>",
LocalizableStrings.CmdFrameworkDescription,
CommandOptionType.SingleValue);
return command;
throw new ArgumentNullException(nameof(appliedCommand));
}
if (fileOrDirectory == null)
{
throw new ArgumentNullException(nameof(fileOrDirectory));
}
public override int Run(string fileOrDirectory)
_appliedCommand = appliedCommand;
_fileOrDirectory = fileOrDirectory;
}
public override int Execute()
{
var projects = new ProjectCollection();
MsbuildProject msbuildProj = MsbuildProject.FromFileOrDirectory(projects, fileOrDirectory);
MsbuildProject msbuildProj = MsbuildProject.FromFileOrDirectory(projects, _fileOrDirectory);
if (RemainingArguments.Count == 0)
{
throw new GracefulException(CommonLocalizableStrings.SpecifyAtLeastOneReferenceToAdd);
}
var frameworkString = _appliedCommand.ValueOrDefault<string>("framework");
string frameworkString = _frameworkOption.Value();
PathUtility.EnsureAllPathsExist(RemainingArguments, CommonLocalizableStrings.ReferenceDoesNotExist);
List<MsbuildProject> refs = RemainingArguments
PathUtility.EnsureAllPathsExist(_appliedCommand.Arguments, CommonLocalizableStrings.ReferenceDoesNotExist);
List<MsbuildProject> refs = _appliedCommand.Arguments
.Select((r) => MsbuildProject.FromFile(projects, r))
.ToList();
@ -95,11 +90,12 @@ namespace Microsoft.DotNet.Tools.Add.ProjectToProjectReference
}
}
var relativePathReferences = RemainingArguments.Select((r) =>
PathUtility.GetRelativePath(msbuildProj.ProjectDirectory, Path.GetFullPath(r))).ToList();
var relativePathReferences = _appliedCommand.Arguments.Select((r) =>
PathUtility.GetRelativePath(msbuildProj.ProjectDirectory, Path.GetFullPath(r)))
.ToList();
int numberOfAddedReferences = msbuildProj.AddProjectToProjectReferences(
_frameworkOption.Value(),
frameworkString,
relativePathReferences);
if (numberOfAddedReferences != 0)

View file

@ -0,0 +1,68 @@
// 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);
result.ShowHelpOrErrorIfAppropriate();
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

@ -0,0 +1,42 @@
// 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;
using LocalizableStrings = Microsoft.DotNet.Tools.Build.LocalizableStrings;
namespace Microsoft.DotNet.Cli
{
internal static class BuildCommandParser
{
public static Command Build() =>
Create.Command(
"build",
LocalizableStrings.AppFullName,
Accept.ZeroOrMoreArguments()
.With(name: CommonLocalizableStrings.CmdProjectFile,
description:
"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."),
CommonOptions.HelpOption(),
Create.Option(
"-o|--output",
LocalizableStrings.OutputOptionDescription,
Accept.ExactlyOneArgument()
.With(name: LocalizableStrings.OutputOptionName)
.ForwardAsSingle(o => $"/p:OutputPath={o.Arguments.Single()}")),
CommonOptions.FrameworkOption(),
CommonOptions.RuntimeOption(),
CommonOptions.ConfigurationOption(),
CommonOptions.VersionSuffixOption(),
Create.Option(
"--no-incremental",
LocalizableStrings.NoIncrementialOptionDescription),
Create.Option(
"--no-dependencies",
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,77 @@
// 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.IO;
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)
.ForwardAsMany(o =>
{
var materializedString = $"{o.Arguments.First()}";
if (o.Arguments.Count == 1)
{
return new[]
{
materializedString
};
}
else
{
return new[]
{
materializedString,
$"/p:AdditionalProjects={string.Join("%3B", o.Arguments.Skip(1))}"
};
}
})),
CommonOptions.FrameworkOption(),
Create.Option(
"--framework-version",
LocalizableStrings.FrameworkVersionOptionDescription,
Accept.ExactlyOneArgument()
.With(name: LocalizableStrings.FrameworkVersionOption)
.ForwardAsSingle(o => $"/p:RuntimeFrameworkVersion={o.Arguments.Single()}")),
CommonOptions.RuntimeOption(),
CommonOptions.ConfigurationOption(),
Create.Option(
"-o|--output",
LocalizableStrings.OutputOptionDescription,
Accept.ExactlyOneArgument()
.With(name: LocalizableStrings.OutputOption)
.ForwardAsSingle(o => $"/p:ComposeDir={Path.GetFullPath(o.Arguments.Single())}")),
Create.Option(
"-w|--working-dir",
LocalizableStrings.IntermediateWorkingDirOptionDescription,
Accept.ExactlyOneArgument()
.With(name: LocalizableStrings.IntermediateWorkingDirOption)
.ForwardAsSingle(o => $"/p:ComposeWorkingDir={o.Arguments.Single()}")),
Create.Option(
"--preserve-working-dir",
LocalizableStrings.PreserveIntermediateWorkingDirOptionDescription,
Accept.NoArguments()
.ForwardAsSingle(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,120 +23,26 @@ 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);
result.ShowHelpOrErrorIfAppropriate();
CommandOption runtimeOption = app.Option(
$"-r|--runtime <{LocalizableStrings.RuntimeOption}>", LocalizableStrings.RuntimeOptionDescription,
CommandOptionType.SingleValue);
var appliedBuildOptions = result["dotnet"]["cache"];
CommandOption outputOption = app.Option(
$"-o|--output <{LocalizableStrings.OutputOption}>", LocalizableStrings.OutputOptionDescription,
CommandOptionType.SingleValue);
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();
throw new InvalidOperationException(LocalizableStrings.SpecifyEntries);
}
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)}");
}
msbuildArgs.AddRange(appliedBuildOptions.OptionValuesToBeForwarded());
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:RuntimeFrameworkVersion={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);
}
msbuildArgs.AddRange(appliedBuildOptions.Arguments);
return new CacheCommand(msbuildArgs, msbuildPath);
}

View file

@ -0,0 +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",
LocalizableStrings.AppFullName,
Accept.ZeroOrMoreArguments(),
CommonOptions.HelpOption(),
Create.Option("-o|--output",
LocalizableStrings.CmdOutputDirDescription,
Accept.ExactlyOneArgument()
.With(name: LocalizableStrings.CmdOutputDir)
.ForwardAsSingle(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,21 @@ 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);
result.ShowHelpOrErrorIfAppropriate();
List<string> msbuildArgs = null;
app.OnExecute(() =>
{
msbuildArgs = new List<string>();
var parsedClean = result["dotnet"]["clean"];
if (!string.IsNullOrEmpty(projectArgument.Value))
{
msbuildArgs.Add(projectArgument.Value);
}
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

@ -0,0 +1,71 @@
// 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.IO;
using System.Linq;
using System.Text;
using Microsoft.DotNet.Cli.CommandLine;
using Microsoft.DotNet.Cli.Utils;
namespace Microsoft.DotNet.Cli
{
public class CompleteCommand
{
public static int Run(string[] args)
{
try
{
DebugHelper.HandleDebugSwitch(ref args);
// get the parser for the current subcommand
var parser = Parser.Instance;
// parse the arguments
var result = parser.ParseFrom("dotnet complete", args);
var complete = result["dotnet"]["complete"];
var suggestions = Suggestions(complete);
var log = new StringBuilder();
log.AppendLine($"args: {string.Join(" ", args.Select(a => $"\"{a}\""))}");
log.AppendLine("diagram: " + result.Diagram());
File.WriteAllText("parse.log", log.ToString());
foreach (var suggestion in suggestions)
{
Console.WriteLine(suggestion);
}
}
catch (Exception e)
{
File.WriteAllText("dotnet completion exception.log", e.ToString());
throw;
}
return 0;
}
private static string[] Suggestions(AppliedOption complete)
{
var input = complete.Arguments.SingleOrDefault() ?? "";
var positionOption = complete.AppliedOptions.SingleOrDefault(a => a.Name == "position");
if (positionOption != null)
{
var position = positionOption.Value<int>();
if (position > input.Length)
{
input += " ";
}
}
var result = Parser.Instance.Parse(input);
return result.Suggestions()
.ToArray();
}
}
}

View file

@ -0,0 +1,21 @@
// 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;
namespace Microsoft.DotNet.Cli
{
internal static class CompleteCommandParser
{
public static Command Complete() =>
Create.Command(
"complete", "",
Accept.ExactlyOneArgument()
.With(name: "path"),
Create.Option("--position", "",
Accept.ExactlyOneArgument()
.With(name: "command")
.MaterializeAs(o => int.Parse(o.Arguments.Single()))));
}
}

View file

@ -0,0 +1,41 @@
using System;
using System.Linq;
using Microsoft.DotNet.Cli.CommandLine;
using Microsoft.DotNet.Cli.Utils;
namespace Microsoft.DotNet.Cli
{
public class ParseCommand
{
public static int Run(string[] args)
{
DebugHelper.HandleDebugSwitch(ref args);
ParseResult result;
try
{
result = Parser.Instance.Parse(
args.Single());
}
catch (Exception e)
{
throw new InvalidOperationException("The parser threw an exception.", e);
}
Console.WriteLine(result.Diagram());
if (result.Errors.Any())
{
Console.WriteLine();
Console.WriteLine("ERRORS");
Console.WriteLine();
foreach (var error in result.Errors)
{
Console.WriteLine($"[{error?.Option?.Name ?? "???"}] {error.Message}");
}
}
return 0;
}
}
}

View file

@ -0,0 +1,58 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Microsoft.Build.Evaluation;
using Microsoft.DotNet.Cli.Utils;
using Microsoft.DotNet.Tools;
using static System.Array;
namespace Microsoft.DotNet.Cli
{
internal static class Suggest
{
public static IEnumerable<string> TargetFrameworksFromProjectFile()
{
var msBuildProject = GetMSBuildProject();
if (msBuildProject == null)
{
yield break;
}
foreach (var tfm in msBuildProject.GetTargetFrameworks())
{
yield return tfm.GetShortFolderName();
}
}
private static void Report(Exception e) =>
Reporter.Verbose.WriteLine($"Exception occurred while getting suggestions: {e}");
public static IEnumerable<string> RunTimesFromProjectFile() =>
GetMSBuildProject()
.GetRuntimeIdentifiers() ??
Empty<string>();
public static IEnumerable<string> ProjectReferencesFromProjectFile() =>
GetMSBuildProject()
?.GetProjectToProjectReferences()
.Select(r => r.Include) ??
Empty<string>();
private static MsbuildProject GetMSBuildProject()
{
try
{
return MsbuildProject.FromFileOrDirectory(
new ProjectCollection(),
Directory.GetCurrentDirectory());
}
catch (Exception e)
{
Report(e);
return null;
}
}
}
}

View file

@ -0,0 +1,26 @@
// 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 Microsoft.DotNet.Cli.CommandLine;
using Microsoft.DotNet.Tools;
using LocalizableStrings = Microsoft.DotNet.Tools.List.LocalizableStrings;
namespace Microsoft.DotNet.Cli
{
internal static class ListCommandParser
{
public static Command List() =>
Create.Command("list",
LocalizableStrings.NetListCommand,
Accept.ZeroOrOneArgument()
.With(name: CommonLocalizableStrings.CmdProjectFile,
description:
CommonLocalizableStrings.ArgumentsProjectDescription)
.DefaultToCurrentDirectory(),
CommonOptions.HelpOption(),
Create.Command("reference",
Tools.List.ProjectToProjectReferences.LocalizableStrings.AppFullName,
Accept.ZeroOrOneArgument(),
CommonOptions.HelpOption()));
}
}

View file

@ -4,6 +4,7 @@
using System;
using System.Collections.Generic;
using Microsoft.DotNet.Cli;
using Microsoft.DotNet.Cli.CommandLine;
using Microsoft.DotNet.Cli.Utils;
using Microsoft.DotNet.Tools.List.ProjectToProjectReferences;
@ -15,10 +16,16 @@ namespace Microsoft.DotNet.Tools.List
protected override string FullCommandNameLocalized => LocalizableStrings.NetListCommand;
protected override string ArgumentName => Constants.ProjectArgumentName;
protected override string ArgumentDescriptionLocalized => CommonLocalizableStrings.ArgumentsProjectDescription;
internal override List<Func<DotNetSubCommandBase>> SubCommands =>
new List<Func<DotNetSubCommandBase>>
internal override Dictionary<string, Func<AppliedOption, CommandBase>> SubCommands =>
new Dictionary<string, Func<AppliedOption, CommandBase>>
{
ListProjectToProjectReferencesCommand.Create,
{
"reference",
o => new ListProjectToProjectReferencesCommand(
o,
ParseResult)
}
};
public static int Run(string[] args)

View file

@ -1,32 +1,34 @@
// 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.Build.Evaluation;
using Microsoft.DotNet.Cli;
using Microsoft.DotNet.Cli.CommandLine;
using Microsoft.DotNet.Cli.Utils;
using System.Linq;
namespace Microsoft.DotNet.Tools.List.ProjectToProjectReferences
{
internal class ListProjectToProjectReferencesCommand : DotNetSubCommandBase
internal class ListProjectToProjectReferencesCommand : CommandBase
{
public static DotNetSubCommandBase Create()
{
var command = new ListProjectToProjectReferencesCommand()
{
Name = "reference",
FullName = LocalizableStrings.AppFullName,
Description = LocalizableStrings.AppDescription,
};
private readonly string _fileOrDirectory;
command.HelpOption("-h|--help");
return command;
public ListProjectToProjectReferencesCommand(
AppliedOption appliedCommand,
ParseResult parseResult) : base(parseResult)
{
if (appliedCommand == null)
{
throw new ArgumentNullException(nameof(appliedCommand));
}
public override int Run(string fileOrDirectory)
_fileOrDirectory = appliedCommand.Arguments.Single();
}
public override int Execute()
{
var msbuildProj = MsbuildProject.FromFileOrDirectory(new ProjectCollection(), fileOrDirectory);
var msbuildProj = MsbuildProject.FromFileOrDirectory(new ProjectCollection(), _fileOrDirectory);
var p2ps = msbuildProj.GetProjectToProjectReferences();
if (!p2ps.Any())
@ -34,7 +36,7 @@ namespace Microsoft.DotNet.Tools.List.ProjectToProjectReferences
Reporter.Output.WriteLine(string.Format(
CommonLocalizableStrings.NoReferencesFound,
CommonLocalizableStrings.P2P,
fileOrDirectory));
_fileOrDirectory));
return 0;
}

View file

@ -0,0 +1,46 @@
// 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",
Accept.ZeroOrOneArgument()
.MaterializeAs(o =>
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,30 @@
// 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);
result.ShowHelpOrErrorIfAppropriate();
return result["dotnet"]["migrate"].Value<MigrateCommand>();
}
public static int Run(string[] args)
{
@ -19,64 +36,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

@ -0,0 +1,39 @@
// 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 Microsoft.DotNet.Cli.CommandLine;
namespace Microsoft.DotNet.Cli
{
internal static class NewCommandParser
{
public static Command New() =>
Create.Command("new",
"Initialize .NET projects.",
Accept
.ExactlyOneArgument()
.WithSuggestionsFrom(
"console",
"classlib",
"mstest",
"xunit",
"web",
"mvc",
"webapi",
"sln"),
Create.Option("-l|--list",
"List templates containing the specified name."),
Create.Option("-lang|--language",
"Specifies the language of the template to create",
Accept.WithSuggestionsFrom("C#", "F#")
.With(defaultValue: () => "C#")),
Create.Option("-n|--name",
"The name for the output being created. If no name is specified, the name of the current directory is used."),
Create.Option("-o|--output",
"Location to place the generated output."),
Create.Option("-h|--help",
"Displays help for this command."),
Create.Option("-all|--show-all",
"Shows all templates"));
}
}

View file

@ -0,0 +1,78 @@
// 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 Microsoft.DotNet.Cli.CommandLine;
namespace Microsoft.DotNet.Cli
{
internal static class NuGetCommandParser
{
public static Command NuGet() =>
Create.Command("nuget",
"NuGet Command Line 4.0.0.0",
CommonOptions.HelpOption(),
Create.Option("--version",
"Show version information"),
Create.Option("-v|--verbosity",
"The verbosity of logging to use. Allowed values: Debug, Verbose, Information, Minimal, Warning, Error.",
Accept.ExactlyOneArgument()
.With(name: "verbosity")),
Create.Command("delete",
"Deletes a package from the server.",
Accept.ExactlyOneArgument()
.With(name: "root",
description: "The Package Id and version."),
CommonOptions.HelpOption(),
Create.Option("--force-english-output",
"Forces the application to run using an invariant, English-based culture."),
Create.Option("-s|--source",
"Specifies the server URL",
Accept.ExactlyOneArgument()
.With(name: "source")),
Create.Option("--non-interactive",
"Do not prompt for user input or confirmations."),
Create.Option("-k|--api-key",
"The API key for the server.",
Accept.ExactlyOneArgument()
.With(name: "apiKey"))),
Create.Command("locals",
"Clears or lists local NuGet resources such as http requests cache, packages cache or machine-wide global packages folder.",
Accept.AnyOneOf(@"all",
@"http-cache",
@"global-packages",
@"temp")
.With(description: "Cache Location(s) Specifies the cache location(s) to list or clear."),
CommonOptions.HelpOption(),
Create.Option("--force-english-output",
"Forces the application to run using an invariant, English-based culture."),
Create.Option("-c|--clear", "Clear the selected local resources or cache location(s)."),
Create.Option("-l|--list", "List the selected local resources or cache location(s).")),
Create.Command("push",
"Pushes a package to the server and publishes it.",
CommonOptions.HelpOption(),
Create.Option("--force-english-output",
"Forces the application to run using an invariant, English-based culture."),
Create.Option("-s|--source",
"Specifies the server URL",
Accept.ExactlyOneArgument()
.With(name: "source")),
Create.Option("-ss|--symbol-source",
"Specifies the symbol server URL. If not specified, nuget.smbsrc.net is used when pushing to nuget.org.",
Accept.ExactlyOneArgument()
.With(name: "source")),
Create.Option("-t|--timeout",
"Specifies the timeout for pushing to a server in seconds. Defaults to 300 seconds (5 minutes).",
Accept.ExactlyOneArgument()
.With(name: "timeout")),
Create.Option("-k|--api-key", "The API key for the server.",
Accept.ExactlyOneArgument()
.With(name: "apiKey")),
Create.Option("-sk|--symbol-api-key", "The API key for the symbol server.",
Accept.ExactlyOneArgument()
.With(name: "apiKey")),
Create.Option("-d|--disable-buffering",
"Disable buffering when pushing to an HTTP(S) server to decrease memory usage."),
Create.Option("-n|--no-symbols",
"If a symbols package exists, it will not be pushed to a symbols server.")));
}
}

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,22 @@ 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)
{
Name = "pack",
FullName = LocalizableStrings.AppFullName,
Description = LocalizableStrings.AppDescription,
HandleRemainingArguments = true,
ArgumentSeparatorHelpText = HelpMessageStrings.MSBuildAdditionalArgsHelpText
};
var result = parser.ParseFrom("dotnet pack", args);
cmd.HelpOption("-h|--help");
result.ShowHelpOrErrorIfAppropriate();
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);
var parsedPack = result["dotnet"]["pack"];
List<string> msbuildArgs = null;
cmd.OnExecute(() =>
{
msbuildArgs = new List<string>()
var msbuildArgs = new List<string>()
{
"/t:pack"
};
if (noBuild.HasValue())
{
msbuildArgs.Add($"/p:NoBuild=true");
}
msbuildArgs.AddRange(parsedPack.OptionValuesToBeForwarded());
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

@ -0,0 +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",
LocalizableStrings.AppFullName,
Accept.ZeroOrMoreArguments(),
CommonOptions.HelpOption(),
Create.Option(
"-o|--output",
LocalizableStrings.CmdOutputDirDescription,
Accept.ExactlyOneArgument()
.With(name: LocalizableStrings.CmdOutputDir)
.ForwardAsSingle(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

@ -1,16 +1,16 @@
// 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;
using Microsoft.DotNet.Cli.CommandLine;
using Microsoft.DotNet.Cli.Utils;
using Microsoft.DotNet.Tools.MSBuild;
using System.Collections.Generic;
using System.Diagnostics;
using Parser = Microsoft.DotNet.Cli.Parser;
namespace Microsoft.DotNet.Tools.Publish
{
public partial class PublishCommand : MSBuildForwardingApp
public class PublishCommand : MSBuildForwardingApp
{
private PublishCommand(IEnumerable<string> msbuildArgs, string msbuildPath = null)
: base(msbuildArgs, msbuildPath)
@ -21,100 +21,21 @@ namespace Microsoft.DotNet.Tools.Publish
{
DebugHelper.HandleDebugSwitch(ref args);
CommandLineApplication app = new CommandLineApplication(throwOnUnexpectedArg: false);
app.Name = "dotnet publish";
app.FullName = LocalizableStrings.AppFullName;
app.Description = LocalizableStrings.AppDescription;
app.HandleRemainingArguments = true;
app.ArgumentSeparatorHelpText = HelpMessageStrings.MSBuildAdditionalArgsHelpText;
app.HelpOption("-h|--help");
var msbuildArgs = new List<string>();
CommandArgument projectArgument = app.Argument($"<{LocalizableStrings.ProjectArgument}>",
LocalizableStrings.ProjectArgDescription);
var parser = Parser.Instance;
CommandOption frameworkOption = app.Option(
$"-f|--framework <{LocalizableStrings.FrameworkOption}>", LocalizableStrings.FrameworkOptionDescription,
CommandOptionType.SingleValue);
var result = parser.ParseFrom("dotnet publish", args);
CommandOption runtimeOption = app.Option(
$"-r|--runtime <{LocalizableStrings.RuntimeOption}>", LocalizableStrings.RuntimeOptionDescription,
CommandOptionType.SingleValue);
CommandOption outputOption = app.Option(
$"-o|--output <{LocalizableStrings.OutputOption}>", LocalizableStrings.OutputOptionDescription,
CommandOptionType.SingleValue);
CommandOption configurationOption = app.Option(
$"-c|--configuration <{LocalizableStrings.ConfigurationOption}>", LocalizableStrings.ConfigurationOptionDescription,
CommandOptionType.SingleValue);
CommandOption versionSuffixOption = app.Option(
$"--version-suffix <{LocalizableStrings.VersionSuffixOption}>", LocalizableStrings.VersionSuffixOptionDescription,
CommandOptionType.SingleValue);
CommandOption filterProjOption = app.Option(
$"--filter <{LocalizableStrings.FilterProjOption}>", LocalizableStrings.FilterProjOptionDescription,
CommandOptionType.MultipleValue);
CommandOption verbosityOption = AddVerbosityOption(app);
List<string> msbuildArgs = null;
app.OnExecute(() =>
{
msbuildArgs = new List<string>();
result.ShowHelpOrErrorIfAppropriate();
msbuildArgs.Add("/t:Publish");
if (!string.IsNullOrEmpty(projectArgument.Value))
{
msbuildArgs.Add(projectArgument.Value);
}
var appliedPublishOption = result["dotnet"]["publish"];
if (!string.IsNullOrEmpty(frameworkOption.Value()))
{
msbuildArgs.Add($"/p:TargetFramework={frameworkOption.Value()}");
}
msbuildArgs.AddRange(appliedPublishOption.OptionValuesToBeForwarded());
if (!string.IsNullOrEmpty(runtimeOption.Value()))
{
msbuildArgs.Add($"/p:RuntimeIdentifier={runtimeOption.Value()}");
}
if (!string.IsNullOrEmpty(outputOption.Value()))
{
msbuildArgs.Add($"/p:PublishDir={outputOption.Value()}");
}
if (!string.IsNullOrEmpty(configurationOption.Value()))
{
msbuildArgs.Add($"/p:Configuration={configurationOption.Value()}");
}
if (!string.IsNullOrEmpty(versionSuffixOption.Value()))
{
msbuildArgs.Add($"/p:VersionSuffix={versionSuffixOption.Value()}");
}
if (filterProjOption.HasValue())
{
msbuildArgs.Add($"/p:FilterProjectFiles={string.Join("%3B", filterProjOption.Values)}");
}
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);
}
msbuildArgs.AddRange(appliedPublishOption.Arguments);
return new PublishCommand(msbuildArgs, msbuildPath);
}

View file

@ -0,0 +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.Linq;
using Microsoft.DotNet.Cli.CommandLine;
using LocalizableStrings = Microsoft.DotNet.Tools.Publish.LocalizableStrings;
namespace Microsoft.DotNet.Cli
{
internal static class PublishCommandParser
{
public static Command Publish() =>
Create.Command(
"publish",
LocalizableStrings.AppFullName,
Accept.ZeroOrMoreArguments(),
CommonOptions.HelpOption(),
CommonOptions.FrameworkOption(),
CommonOptions.RuntimeOption(),
Create.Option(
"-o|--output",
LocalizableStrings.OutputOptionDescription,
Accept.ExactlyOneArgument()
.With(name: LocalizableStrings.OutputOption)
.ForwardAsSingle(o => $"/p:PublishDir={o.Arguments.Single()}")),
CommonOptions.ConfigurationOption(),
CommonOptions.VersionSuffixOption(),
Create.Option(
"--filter",
LocalizableStrings.FilterProjOptionDescription,
Accept.OneOrMoreArguments()
.With(name: LocalizableStrings.FilterProjOption)
.ForwardAsSingle(o => $"/p:FilterProjectFiles={string.Join("%3B", o.Arguments)}")),
CommonOptions.VerbosityOption());
}
}

View file

@ -4,6 +4,7 @@
using System;
using System.Collections.Generic;
using Microsoft.DotNet.Cli;
using Microsoft.DotNet.Cli.CommandLine;
using Microsoft.DotNet.Cli.Utils;
using Microsoft.DotNet.Tools.Remove.PackageReference;
using Microsoft.DotNet.Tools.Remove.ProjectToProjectReference;
@ -16,11 +17,21 @@ namespace Microsoft.DotNet.Tools.Remove
protected override string FullCommandNameLocalized => LocalizableStrings.NetRemoveCommand;
protected override string ArgumentName => Constants.ProjectArgumentName;
protected override string ArgumentDescriptionLocalized => CommonLocalizableStrings.ArgumentsProjectDescription;
internal override List<Func<DotNetSubCommandBase>> SubCommands =>
new List<Func<DotNetSubCommandBase>>
internal override Dictionary<string, Func<AppliedOption, CommandBase>> SubCommands =>
new Dictionary<string, Func<AppliedOption, CommandBase>>
{
RemoveProjectToProjectReferenceCommand.Create,
RemovePackageReferenceCommand.Create
["reference"] =
remove => new RemoveProjectToProjectReferenceCommand(
remove["reference"],
remove.Value<string>(),
ParseResult),
["package"] =
remove => new RemovePackageReferenceCommand(
remove["package"],
remove.Value<string>(),
ParseResult)
};
public static int Run(string[] args)

View file

@ -0,0 +1,24 @@
// 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 Microsoft.DotNet.Cli.CommandLine;
using Microsoft.DotNet.Tools;
using LocalizableStrings = Microsoft.DotNet.Tools.Remove.LocalizableStrings;
namespace Microsoft.DotNet.Cli
{
internal static class RemoveCommandParser
{
public static Command Remove() =>
Create.Command("remove",
LocalizableStrings.NetRemoveCommand,
Accept.ExactlyOneArgument()
.DefaultToCurrentDirectory()
.With(name: CommonLocalizableStrings.CmdProjectFile,
description: CommonLocalizableStrings.ArgumentsProjectDescription)
.DefaultToCurrentDirectory(),
CommonOptions.HelpOption(),
RemovePackageParser.RemovePackage(),
RemoveProjectToProjectReferenceParser.RemoveReference());
}
}

View file

@ -1,61 +1,57 @@
// 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 Microsoft.Build.Evaluation;
using System;
using System.IO;
using System.Linq;
using Microsoft.DotNet.Cli;
using Microsoft.DotNet.Cli.CommandLine;
using Microsoft.DotNet.Cli.Utils;
using Microsoft.DotNet.Tools.Common;
using Microsoft.DotNet.Tools.MSBuild;
using Microsoft.DotNet.Tools.NuGet;
using NuGet.Frameworks;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
namespace Microsoft.DotNet.Tools.Remove.PackageReference
{
internal class RemovePackageReferenceCommand : DotNetSubCommandBase
internal class RemovePackageReferenceCommand : CommandBase
{
private readonly AppliedOption _appliedCommand;
private readonly string _fileOrDirectory;
public static DotNetSubCommandBase Create()
public RemovePackageReferenceCommand(
AppliedOption appliedCommand,
string fileOrDirectory,
ParseResult parseResult) : base(parseResult)
{
var command = new RemovePackageReferenceCommand
if (appliedCommand == null)
{
Name = "package",
FullName = LocalizableStrings.AppFullName,
Description = LocalizableStrings.AppDescription,
HandleRemainingArguments = true,
ArgumentSeparatorHelpText = LocalizableStrings.AppHelpText,
};
command.HelpOption("-h|--help");
return command;
throw new ArgumentNullException(nameof(appliedCommand));
}
public override int Run(string fileOrDirectory)
if (fileOrDirectory == null)
{
if (RemainingArguments.Count != 1)
throw new ArgumentNullException(nameof(fileOrDirectory));
}
if (_appliedCommand.Arguments.Count != 1)
{
throw new GracefulException(LocalizableStrings.SpecifyExactlyOnePackageReference);
}
_appliedCommand = appliedCommand;
_fileOrDirectory = fileOrDirectory;
}
public override int Execute()
{
var projectFilePath = string.Empty;
if (!File.Exists(fileOrDirectory))
if (!File.Exists(_fileOrDirectory))
{
projectFilePath = MsbuildProject.GetProjectFileFromDirectory(fileOrDirectory).FullName;
projectFilePath = MsbuildProject.GetProjectFileFromDirectory(_fileOrDirectory).FullName;
}
else
{
projectFilePath = fileOrDirectory;
projectFilePath = _fileOrDirectory;
}
var packageToRemove = RemainingArguments.First();
var packageToRemove = _appliedCommand.Arguments.Single();
var result = NuGetCommand.Run(TransformArgs(packageToRemove, projectFilePath));
return result;
@ -63,7 +59,8 @@ namespace Microsoft.DotNet.Tools.Remove.PackageReference
private string[] TransformArgs(string packageId, string projectFilePath)
{
return new string[]{
return new string[]
{
"package",
"remove",
"--package",

View file

@ -0,0 +1,14 @@
using Microsoft.DotNet.Cli.CommandLine;
using LocalizableStrings = Microsoft.DotNet.Tools.Remove.ProjectToProjectReference.LocalizableStrings;
namespace Microsoft.DotNet.Cli
{
internal static class RemovePackageParser
{
public static Command RemovePackage() =>
Create.Command(
"package",
LocalizableStrings.AppFullName,
CommonOptions.HelpOption());
}
}

View file

@ -1,6 +1,8 @@
// 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.Build.Evaluation;
using Microsoft.DotNet.Cli;
using Microsoft.DotNet.Cli.CommandLine;
@ -8,42 +10,42 @@ using Microsoft.DotNet.Cli.Utils;
namespace Microsoft.DotNet.Tools.Remove.ProjectToProjectReference
{
internal class RemoveProjectToProjectReferenceCommand : DotNetSubCommandBase
internal class RemoveProjectToProjectReferenceCommand : CommandBase
{
private CommandOption _frameworkOption;
private readonly AppliedOption _appliedCommand;
private readonly string _fileOrDirectory;
public static DotNetSubCommandBase Create()
public RemoveProjectToProjectReferenceCommand(
AppliedOption appliedCommand,
string fileOrDirectory,
ParseResult parseResult) : base(parseResult)
{
var command = new RemoveProjectToProjectReferenceCommand()
if (appliedCommand == null)
{
Name = "reference",
FullName = LocalizableStrings.AppFullName,
Description = LocalizableStrings.AppDescription,
HandleRemainingArguments = true,
ArgumentSeparatorHelpText = LocalizableStrings.AppHelpText,
};
command.HelpOption("-h|--help");
command._frameworkOption = command.Option(
$"-f|--framework <{CommonLocalizableStrings.CmdFramework}>",
LocalizableStrings.CmdFrameworkDescription,
CommandOptionType.SingleValue);
return command;
throw new ArgumentNullException(nameof(appliedCommand));
}
public override int Run(string fileOrDirectory)
if (fileOrDirectory == null)
{
var msbuildProj = MsbuildProject.FromFileOrDirectory(new ProjectCollection(), fileOrDirectory);
if (RemainingArguments.Count == 0)
throw new ArgumentNullException(nameof(fileOrDirectory));
}
if (appliedCommand.Arguments.Count == 0)
{
throw new GracefulException(CommonLocalizableStrings.SpecifyAtLeastOneReferenceToRemove);
}
_appliedCommand = appliedCommand;
_fileOrDirectory = fileOrDirectory;
}
public override int Execute()
{
var msbuildProj = MsbuildProject.FromFileOrDirectory(new ProjectCollection(), _fileOrDirectory);
int numberOfRemovedReferences = msbuildProj.RemoveProjectToProjectReferences(
_frameworkOption.Value(),
RemainingArguments);
_appliedCommand.ValueOrDefault<string>("framework"),
_appliedCommand.Arguments);
if (numberOfRemovedReferences != 0)
{

View file

@ -0,0 +1,25 @@
using Microsoft.DotNet.Cli.CommandLine;
using Microsoft.DotNet.Tools;
using LocalizableStrings = Microsoft.DotNet.Tools.Remove.ProjectToProjectReference.LocalizableStrings;
namespace Microsoft.DotNet.Cli
{
internal static class RemoveProjectToProjectReferenceParser
{
public static Command RemoveReference() =>
Create.Command(
"reference",
LocalizableStrings.AppFullName,
Accept
.OneOrMoreArguments()
.WithSuggestionsFrom(_ => Suggest.ProjectReferencesFromProjectFile())
.With(name: "args",
description: LocalizableStrings.AppHelpText),
CommonOptions.HelpOption(),
Create.Option(
"-f|--framework",
LocalizableStrings.CmdFrameworkDescription,
Accept.ExactlyOneArgument()
.With(name: CommonLocalizableStrings.CmdFramework)));
}
}

View file

@ -1,12 +1,14 @@
// 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.Collections.Generic;
using System.Linq;
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.Restore
{
@ -21,133 +23,26 @@ namespace Microsoft.DotNet.Tools.Restore
{
DebugHelper.HandleDebugSwitch(ref args);
CommandLineApplication cmd = new CommandLineApplication(throwOnUnexpectedArg: false)
{
Name = "restore",
FullName = LocalizableStrings.AppFullName,
Description = LocalizableStrings.AppDescription,
HandleRemainingArguments = true,
ArgumentSeparatorHelpText = HelpMessageStrings.MSBuildAdditionalArgsHelpText
};
Reporter.Output.WriteLine(string.Join(" ", args));
cmd.HelpOption("-h|--help");
var parser = Parser.Instance;
var argRoot = cmd.Argument(
$"[{LocalizableStrings.CmdArgument}]",
LocalizableStrings.CmdArgumentDescription,
multipleValues: true);
var result = parser.ParseFrom("dotnet restore", args);
var sourceOption = cmd.Option(
$"-s|--source <{LocalizableStrings.CmdSourceOption}>",
LocalizableStrings.CmdSourceOptionDescription,
CommandOptionType.MultipleValue);
result.ShowHelpOrErrorIfAppropriate();
var runtimeOption = cmd.Option(
$"-r|--runtime <{LocalizableStrings.CmdRuntimeOption}>",
LocalizableStrings.CmdRuntimeOptionDescription,
CommandOptionType.MultipleValue);
var parsedRestore = result["dotnet"]["restore"];
var packagesOption = cmd.Option(
$"--packages <{LocalizableStrings.CmdPackagesOption}>",
LocalizableStrings.CmdPackagesOptionDescription,
CommandOptionType.SingleValue);
var disableParallelOption = cmd.Option(
"--disable-parallel",
LocalizableStrings.CmdDisableParallelOptionDescription,
CommandOptionType.NoValue);
var configFileOption = cmd.Option(
$"--configfile <{LocalizableStrings.CmdConfigFileOption}>",
LocalizableStrings.CmdConfigFileOptionDescription,
CommandOptionType.SingleValue);
var noCacheOption = cmd.Option(
"--no-cache",
LocalizableStrings.CmdNoCacheOptionDescription,
CommandOptionType.NoValue);
var ignoreFailedSourcesOption = cmd.Option(
"--ignore-failed-sources",
LocalizableStrings.CmdIgnoreFailedSourcesOptionDescription,
CommandOptionType.NoValue);
var noDependenciesOption = cmd.Option(
"--no-dependencies",
LocalizableStrings.CmdNoDependenciesOptionDescription,
CommandOptionType.NoValue);
CommandOption verbosityOption = MSBuildForwardingApp.AddVerbosityOption(cmd);
List<string> msbuildArgs = null;
cmd.OnExecute(() =>
{
msbuildArgs = new List<string>()
var msbuildArgs = new List<string>
{
"/NoLogo",
"/t:Restore",
"/ConsoleLoggerParameters:Verbosity=Minimal"
};
if (sourceOption.HasValue())
{
msbuildArgs.Add($"/p:RestoreSources={string.Join("%3B", sourceOption.Values)}");
}
msbuildArgs.AddRange(parsedRestore.OptionValuesToBeForwarded());
if (runtimeOption.HasValue())
{
msbuildArgs.Add($"/p:RuntimeIdentifiers={string.Join("%3B", runtimeOption.Values)}");
}
if (packagesOption.HasValue())
{
msbuildArgs.Add($"/p:RestorePackagesPath={packagesOption.Value()}");
}
if (disableParallelOption.HasValue())
{
msbuildArgs.Add($"/p:RestoreDisableParallel=true");
}
if (configFileOption.HasValue())
{
msbuildArgs.Add($"/p:RestoreConfigFile={configFileOption.Value()}");
}
if (noCacheOption.HasValue())
{
msbuildArgs.Add($"/p:RestoreNoCache=true");
}
if (ignoreFailedSourcesOption.HasValue())
{
msbuildArgs.Add($"/p:RestoreIgnoreFailedSources=true");
}
if (noDependenciesOption.HasValue())
{
msbuildArgs.Add($"/p:RestoreRecursive=false");
}
if (verbosityOption.HasValue())
{
msbuildArgs.Add($"/verbosity:{verbosityOption.Value()}");
}
// Add in arguments
msbuildArgs.AddRange(argRoot.Values);
// Add remaining arguments that the parser did not understand
msbuildArgs.AddRange(cmd.RemainingArguments);
return 0;
});
int exitCode = cmd.Execute(args);
if (msbuildArgs == null)
{
throw new CommandCreationException(exitCode);
}
msbuildArgs.AddRange(parsedRestore.Arguments);
return new RestoreCommand(msbuildArgs, msbuildPath);
}

View file

@ -0,0 +1,65 @@
// 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.Restore.LocalizableStrings;
namespace Microsoft.DotNet.Cli
{
internal static class RestoreCommandParser
{
public static Command Restore() =>
Create.Command(
"restore",
LocalizableStrings.AppFullName,
Accept.ZeroOrMoreArguments(),
CommonOptions.HelpOption(),
Create.Option(
"-s|--source",
LocalizableStrings.CmdSourceOptionDescription,
Accept.OneOrMoreArguments()
.With(name: LocalizableStrings.CmdSourceOption)
.ForwardAsSingle(o => $"/p:RestoreSources={string.Join("%3B", o.Arguments)}")),
Create.Option(
"-r|--runtime",
LocalizableStrings.CmdRuntimeOptionDescription,
Accept.OneOrMoreArguments()
.WithSuggestionsFrom(_ => Suggest.RunTimesFromProjectFile())
.With(name: LocalizableStrings.CmdRuntimeOption)
.ForwardAsSingle(o => $"/p:RuntimeIdentifiers={string.Join("%3B", o.Arguments)}")),
Create.Option(
"--packages",
LocalizableStrings.CmdPackagesOptionDescription,
Accept.ExactlyOneArgument()
.With(name: LocalizableStrings.CmdPackagesOption)
.ForwardAsSingle(o => $"/p:RestorePackagesPath={o.Arguments.Single()}")),
Create.Option(
"--disable-parallel",
LocalizableStrings.CmdDisableParallelOptionDescription,
Accept.NoArguments()
.ForwardAs("/p:RestoreDisableParallel=true")),
Create.Option(
"--configfile",
LocalizableStrings.CmdConfigFileOptionDescription,
Accept.ExactlyOneArgument()
.With(name: LocalizableStrings.CmdConfigFileOption)
.ForwardAsSingle(o => $"/p:RestoreConfigFile={o.Arguments.Single()}")),
Create.Option(
"--no-cache",
LocalizableStrings.CmdNoCacheOptionDescription,
Accept.NoArguments()
.ForwardAs("/p:RestoreNoCache=true")),
Create.Option(
"--ignore-failed-sources",
LocalizableStrings.CmdIgnoreFailedSourcesOptionDescription,
Accept.NoArguments()
.ForwardAs("/p:RestoreIgnoreFailedSources=true")),
Create.Option(
"--no-dependencies",
LocalizableStrings.CmdNoDependenciesOptionDescription,
Accept.NoArguments()
.ForwardAs("/p:RestoreRecursive=false")),
CommonOptions.VerbosityOption());
}
}

View file

@ -9,9 +9,7 @@ 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 CommandOptionNoBuildDescription = "Skip building the project prior to running. By default, the project will be built.";
public const string CommandOptionFrameworkDescription = "Build and run the app using the specified framework. The framework has to be specified in the project file. ";

View file

@ -4,51 +4,40 @@
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);
result.ShowHelpOrErrorIfAppropriate();
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");
RunCommand cmd;
CommandOption configuration = app.Option(
"-c|--configuration", LocalizableStrings.CommandOptionConfigurationDescription,
CommandOptionType.SingleValue);
CommandOption framework = app.Option(
$"-f|--framework <{LocalizableStrings.CommandOptionFramework}>", LocalizableStrings.CommandOptionFrameworkDescription,
CommandOptionType.SingleValue);
CommandOption noBuild = app.Option(
"--no-build", LocalizableStrings.CommandOptionNoBuild,
CommandOptionType.BoolValue);
CommandOption project = app.Option(
"-p|--project", LocalizableStrings.CommandOptionProjectDescription,
CommandOptionType.SingleValue);
app.OnExecute(() =>
try
{
RunCommand runCmd = new RunCommand();
cmd = FromArgs(args);
}
catch (CommandCreationException e)
{
return e.ExitCode;
}
runCmd.Configuration = configuration.Value();
runCmd.Framework = framework.Value();
runCmd.NoBuild = noBuild.BoolValue ?? false;
runCmd.Project = project.Value();
runCmd.Args = app.RemainingArguments;
return runCmd.Start();
});
return app.Execute(args);
return cmd.Start();
}
}
}

View file

@ -17,15 +17,11 @@ namespace Microsoft.DotNet.Tools.Run
public string Framework { get; set; }
public bool NoBuild { get; set; }
public string Project { get; set; }
public IReadOnlyList<string> Args { get; set; }
public IReadOnlyCollection<string> Args { get; set; }
private List<string> _args;
private bool ShouldBuild => !NoBuild;
public RunCommand()
{
}
public int Start()
{
Initialize();

View file

@ -0,0 +1,41 @@
// 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 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",
LocalizableStrings.AppFullName,
treatUnmatchedTokensAsErrors: false,
arguments: Accept.ZeroOrMoreArguments()
.MaterializeAs(o => new RunCommand
{
Configuration = o.SingleArgumentOrDefault("--configuration"),
Framework = o.SingleArgumentOrDefault("--framework"),
NoBuild = o.HasOption("--no-build"),
Project = o.SingleArgumentOrDefault("--project"),
Args = o.Arguments
}),
options: new[]
{
CommonOptions.HelpOption(),
CommonOptions.ConfigurationOption(),
CommonOptions.FrameworkOption(),
Create.Option(
"-p|--project",
LocalizableStrings.CommandOptionProjectDescription,
Accept.ExactlyOneArgument()),
Create.Option(
"--no-build",
LocalizableStrings.CommandOptionNoBuildDescription,
Accept.NoArguments())
});
}
}

View file

@ -4,6 +4,7 @@
using System;
using System.Collections.Generic;
using Microsoft.DotNet.Cli;
using Microsoft.DotNet.Cli.CommandLine;
using Microsoft.DotNet.Cli.Utils;
using Microsoft.DotNet.Tools.Sln.Add;
using Microsoft.DotNet.Tools.Sln.List;
@ -17,12 +18,28 @@ namespace Microsoft.DotNet.Tools.Sln
protected override string FullCommandNameLocalized => LocalizableStrings.AppFullName;
protected override string ArgumentName => Constants.SolutionArgumentName;
protected override string ArgumentDescriptionLocalized => CommonLocalizableStrings.ArgumentsSolutionDescription;
internal override List<Func<DotNetSubCommandBase>> SubCommands =>
new List<Func<DotNetSubCommandBase>>
internal override Dictionary<string, Func<AppliedOption, CommandBase>> SubCommands =>
new Dictionary<string, Func<AppliedOption, CommandBase>>
{
AddProjectToSolutionCommand.Create,
ListProjectsInSolutionCommand.Create,
RemoveProjectFromSolutionCommand.Create
["add"] =
sln => new AddProjectToSolutionCommand(
sln["add"],
sln.Value<string>(),
ParseResult),
["list"] =
sln => new ListProjectsInSolutionCommand(
sln["list"],
sln.Value<string>(),
ParseResult),
["remove"] =
sln =>
new RemoveProjectFromSolutionCommand(
sln["remove"],
sln.Value<string>(),
ParseResult)
};
public static int Run(string[] args)

View file

@ -0,0 +1,25 @@
// 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 Microsoft.DotNet.Cli.CommandLine;
using Microsoft.DotNet.Tools;
using LocalizableStrings = Microsoft.DotNet.Tools.Sln.LocalizableStrings;
namespace Microsoft.DotNet.Cli
{
internal static class SlnCommandParser
{
public static Command Sln() =>
Create.Command(
"sln",
LocalizableStrings.AppFullName,
Accept.ExactlyOneArgument()
.DefaultToCurrentDirectory()
.With(name: CommonLocalizableStrings.CmdSlnFile,
description: CommonLocalizableStrings.ArgumentsSolutionDescription),
CommonOptions.HelpOption(),
SlnAddParser.SlnAdd(),
SlnListParser.SlnList(),
SlnRemoveParser.SlnRemove());
}
}

View file

@ -1,49 +1,53 @@
// 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.IO;
using System.Linq;
using Microsoft.DotNet.Cli;
using Microsoft.DotNet.Cli.CommandLine;
using Microsoft.DotNet.Cli.Sln.Internal;
using Microsoft.DotNet.Cli.Utils;
using Microsoft.DotNet.Tools.Common;
using Microsoft.DotNet.Tools.Sln;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
namespace Microsoft.DotNet.Tools.Sln.Add
{
internal class AddProjectToSolutionCommand : DotNetSubCommandBase
internal class AddProjectToSolutionCommand : CommandBase
{
public static DotNetSubCommandBase Create()
{
var command = new AddProjectToSolutionCommand()
{
Name = "add",
FullName = LocalizableStrings.AddAppFullName,
Description = LocalizableStrings.AddSubcommandHelpText,
HandleRemainingArguments = true,
ArgumentSeparatorHelpText = LocalizableStrings.AddSubcommandHelpText,
};
private readonly AppliedOption _appliedCommand;
private readonly string _fileOrDirectory;
command.HelpOption("-h|--help");
public AddProjectToSolutionCommand(
AppliedOption appliedCommand,
string fileOrDirectory,
ParseResult parseResult) : base(parseResult)
{
if (appliedCommand == null)
{
throw new ArgumentNullException(nameof(appliedCommand));
}
_appliedCommand = appliedCommand;
return command;
_fileOrDirectory = fileOrDirectory;
}
public override int Run(string fileOrDirectory)
public override int Execute()
{
SlnFile slnFile = SlnFileFactory.CreateFromFileOrDirectory(fileOrDirectory);
SlnFile slnFile = SlnFileFactory.CreateFromFileOrDirectory(_fileOrDirectory);
if (RemainingArguments.Count == 0)
if (_appliedCommand.Arguments.Count == 0)
{
throw new GracefulException(CommonLocalizableStrings.SpecifyAtLeastOneProjectToAdd);
}
PathUtility.EnsureAllPathsExist(RemainingArguments, CommonLocalizableStrings.ProjectDoesNotExist);
var fullProjectPaths = RemainingArguments.Select((p) => Path.GetFullPath(p)).ToList();
PathUtility.EnsureAllPathsExist(_appliedCommand.Arguments, CommonLocalizableStrings.ProjectDoesNotExist);
var fullProjectPaths = _appliedCommand.Arguments
.Select(Path.GetFullPath)
.ToList();
var preAddProjectCount = slnFile.Projects.Count;
int preAddProjectCount = slnFile.Projects.Count;
foreach (var fullProjectPath in fullProjectPaths)
{
slnFile.AddProject(fullProjectPath);

View file

@ -0,0 +1,20 @@
// 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 Microsoft.DotNet.Cli.CommandLine;
using Microsoft.DotNet.Tools;
using LocalizableStrings = Microsoft.DotNet.Tools.Sln.LocalizableStrings;
namespace Microsoft.DotNet.Cli
{
public static class SlnAddParser
{
public static Command SlnAdd() =>
Create.Command("add",
LocalizableStrings.AddAppFullName,
Accept.OneOrMoreArguments(o => CommonLocalizableStrings.SpecifyAtLeastOneProjectToAdd)
.With(name: "args",
description: LocalizableStrings.AddSubcommandHelpText),
CommonOptions.HelpOption());
}
}

View file

@ -1,33 +1,35 @@
// 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;
using Microsoft.DotNet.Cli.CommandLine;
using Microsoft.DotNet.Cli.Sln.Internal;
using Microsoft.DotNet.Cli.Utils;
using Microsoft.DotNet.Tools.Common;
using Microsoft.DotNet.Tools.Sln;
namespace Microsoft.DotNet.Tools.Sln.List
{
internal class ListProjectsInSolutionCommand : DotNetSubCommandBase
internal class ListProjectsInSolutionCommand : CommandBase
{
public static DotNetSubCommandBase Create()
{
var command = new ListProjectsInSolutionCommand()
{
Name = "list",
FullName = LocalizableStrings.ListAppFullName,
Description = LocalizableStrings.ListSubcommandHelpText,
};
private readonly string _fileOrDirectory;
command.HelpOption("-h|--help");
return command;
public ListProjectsInSolutionCommand(
AppliedOption appliedCommand,
string fileOrDirectory,
ParseResult parseResult) : base(parseResult)
{
if (appliedCommand == null)
{
throw new ArgumentNullException(nameof(appliedCommand));
}
_fileOrDirectory = fileOrDirectory;
}
public override int Run(string fileOrDirectory)
public override int Execute()
{
SlnFile slnFile = SlnFileFactory.CreateFromFileOrDirectory(fileOrDirectory);
SlnFile slnFile = SlnFileFactory.CreateFromFileOrDirectory(_fileOrDirectory);
if (slnFile.Projects.Count == 0)
{
Reporter.Output.WriteLine(CommonLocalizableStrings.NoProjectsFound);

View file

@ -0,0 +1,16 @@
// 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 Microsoft.DotNet.Cli.CommandLine;
using LocalizableStrings = Microsoft.DotNet.Tools.Sln.LocalizableStrings;
namespace Microsoft.DotNet.Cli
{
public static class SlnListParser
{
public static Command SlnList() =>
Create.Command("list",
LocalizableStrings.ListAppFullName,
CommonOptions.HelpOption());
}
}

View file

@ -1,49 +1,50 @@
// 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.IO;
using System.Linq;
using Microsoft.DotNet.Cli;
using Microsoft.DotNet.Cli.CommandLine;
using Microsoft.DotNet.Cli.Sln.Internal;
using Microsoft.DotNet.Cli.Utils;
using Microsoft.DotNet.Tools.Common;
using Microsoft.DotNet.Tools.Sln;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
namespace Microsoft.DotNet.Tools.Sln.Remove
{
internal class RemoveProjectFromSolutionCommand : DotNetSubCommandBase
internal class RemoveProjectFromSolutionCommand : CommandBase
{
public static DotNetSubCommandBase Create()
{
var command = new RemoveProjectFromSolutionCommand()
{
Name = "remove",
FullName = LocalizableStrings.RemoveAppFullName,
Description = LocalizableStrings.RemoveSubcommandHelpText,
HandleRemainingArguments = true,
ArgumentSeparatorHelpText = LocalizableStrings.RemoveSubcommandHelpText,
};
private readonly AppliedOption _appliedCommand;
private readonly string _fileOrDirectory;
command.HelpOption("-h|--help");
return command;
public RemoveProjectFromSolutionCommand(
AppliedOption appliedCommand,
string fileOrDirectory,
ParseResult parseResult) : base(parseResult)
{
if (appliedCommand == null)
{
throw new ArgumentNullException(nameof(appliedCommand));
}
public override int Run(string fileOrDirectory)
{
SlnFile slnFile = SlnFileFactory.CreateFromFileOrDirectory(fileOrDirectory);
if (RemainingArguments.Count == 0)
if (appliedCommand.Arguments.Count == 0)
{
throw new GracefulException(CommonLocalizableStrings.SpecifyAtLeastOneProjectToRemove);
}
var relativeProjectPaths = RemainingArguments.Select((p) =>
_appliedCommand = appliedCommand;
_fileOrDirectory = fileOrDirectory;
}
public override int Execute()
{
SlnFile slnFile = SlnFileFactory.CreateFromFileOrDirectory(_fileOrDirectory);
var relativeProjectPaths = _appliedCommand.Arguments.Select(p =>
PathUtility.GetRelativePath(
PathUtility.EnsureTrailingSlash(slnFile.BaseDirectory),
Path.GetFullPath(p))).ToList();
Path.GetFullPath(p)))
.ToList();
bool slnChanged = false;
foreach (var path in relativeProjectPaths)

View file

@ -0,0 +1,20 @@
// 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 Microsoft.DotNet.Cli.CommandLine;
using Microsoft.DotNet.Tools;
using LocalizableStrings = Microsoft.DotNet.Tools.Sln.LocalizableStrings;
namespace Microsoft.DotNet.Cli
{
public static class SlnRemoveParser
{
public static Command SlnRemove() =>
Create.Command("remove",
LocalizableStrings.RemoveAppFullName,
Accept.OneOrMoreArguments(o => CommonLocalizableStrings.SpecifyAtLeastOneProjectToRemove)
.With(name: "args",
description: LocalizableStrings.RemoveSubcommandHelpText),
CommonOptions.HelpOption());
}
}

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,285 +3,78 @@
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);
result.ShowHelpOrErrorIfAppropriate();
var parsedTest = result["dotnet"]["test"];
msbuildArgs.AddRange(parsedTest.OptionValuesToBeForwarded());
msbuildArgs.AddRange(parsedTest.Arguments);
var runSettingsOptions =
result.UnparsedTokens
.Select(GetSemiColonEscapedString);
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(() =>
cmd = FromArgs(args);
}
catch (CommandCreationException e)
{
var msbuildArgs = new List<string>()
{
"/t:VSTest"
};
msbuildArgs.Add("/nologo");
if (settingOption.HasValue())
{
msbuildArgs.Add($"/p:VSTestSetting={settingOption.Value()}");
return e.ExitCode;
}
if (listTestsOption.HasValue())
{
msbuildArgs.Add($"/p:VSTestListTests=true");
return cmd.Execute();
}
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.");
}
else if (projectFound == 0)
{
result = GetDefaultTestProject();
}
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();
}
private static string GetSemiColonEsacpedstring(string arg)
private static string GetSemiColonEscapedString(string arg)
{
if (arg.IndexOf(";") != -1)
{
@ -298,7 +91,7 @@ namespace Microsoft.DotNet.Tools.Test
foreach (string arg in args)
{
array[counter++] = GetSemiColonEsacpedstring(arg);
array[counter++] = GetSemiColonEscapedString(arg);
}
return array;

View file

@ -0,0 +1,96 @@
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",
LocalizableStrings.AppFullName,
Accept.ZeroOrMoreArguments()
.With(name: LocalizableStrings.CmdArgProject,
description: LocalizableStrings.CmdArgDescription),
CommonOptions.HelpOption(),
Create.Option(
"-s|--settings",
LocalizableStrings.CmdSettingsDescription,
Accept.ExactlyOneArgument()
.With(name: LocalizableStrings.CmdSettingsFile)
.ForwardAsSingle(o => $"/p:VSTestSetting={o.Arguments.Single()}")),
Create.Option(
"-t|--list-tests",
LocalizableStrings.CmdListTestsDescription,
Accept.NoArguments()
.ForwardAsSingle(o => "/p:VSTestListTests=true")),
Create.Option(
"--filter",
LocalizableStrings.CmdTestCaseFilterDescription,
Accept.ExactlyOneArgument()
.With(name: LocalizableStrings.CmdTestCaseFilterExpression)
.ForwardAsSingle(o => $"/p:VSTestTestCaseFilter={o.Arguments.Single()}")),
Create.Option(
"-a|--test-adapter-path",
LocalizableStrings.CmdTestAdapterPathDescription,
Accept.ExactlyOneArgument()
.With(name: LocalizableStrings.CmdTestAdapterPath)
.ForwardAsSingle(o => $"/p:VSTestTestAdapterPath={o.Arguments.Single()}")),
Create.Option(
"-l|--logger",
LocalizableStrings.CmdLoggerDescription,
Accept.ExactlyOneArgument()
.With(name: LocalizableStrings.CmdLoggerOption)
.ForwardAsSingle(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)
.ForwardAsSingle(o => $"/p:OutputPath={o.Arguments.Single()}")),
Create.Option(
"-d|--diag",
LocalizableStrings.CmdPathTologFileDescription,
Accept.ExactlyOneArgument()
.With(name: LocalizableStrings.CmdPathToLogFile)
.ForwardAsSingle(o => $"/p:VSTestDiag={o.Arguments.Single()}")),
Create.Option(
"--no-build",
LocalizableStrings.CmdNoBuildDescription,
Accept.NoArguments()
.ForwardAsSingle(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

@ -10,6 +10,7 @@
<SignAssembly>true</SignAssembly>
<PublicSign Condition=" '$(OS)' != 'Windows_NT' ">true</PublicSign>
<PackageTargetFallback>$(PackageTargetFallback);dotnet5.4</PackageTargetFallback>
<RootNamespace>Microsoft.DotNet.Cli</RootNamespace>
</PropertyGroup>
<ItemGroup>
@ -39,9 +40,14 @@
<PackageReference Include="Microsoft.Win32.Registry" Version="4.3.0" />
<PackageReference Include="Microsoft.Build" Version="$(CLI_MSBuild_Version)" />
<PackageReference Include="Microsoft.DotNet.PlatformAbstractions" Version="$(PlatformAbstractionsVersion)" />
<PackageReference Include="Microsoft.DotNet.Cli.CommandLine" Version="0.1.0-alpha-115" />
<PackageReference Include="Microsoft.TemplateEngine.Abstractions" Version="$(TemplateEngineVersion)" />
<PackageReference Include="Microsoft.TemplateEngine.Cli" Version="$(TemplateEngineVersion)" />
<PackageReference Include="Microsoft.TemplateEngine.Orchestrator.RunnableProjects" Version="$(TemplateEngineVersion)" />
<PackageReference Include="Microsoft.TemplateEngine.Utils" Version="$(TemplateEngineVersion)" />
</ItemGroup>
<ItemGroup>
<Folder Include="dotnet-complete\commands\" />
</ItemGroup>
</Project>

View file

@ -25,10 +25,6 @@ namespace Microsoft.DotNet.Tests.ArgumentForwarding
public ArgumentForwardingTests()
{
Environment.SetEnvironmentVariable(
Constants.MSBUILD_EXE_PATH,
Path.Combine(new RepoDirectoriesProvider().Stage2Sdk, "MSBuild.dll"));
// This test has a dependency on an argument reflector
// Make sure it's been binplaced properly
FindAndEnsureReflectorPresent();
@ -176,6 +172,10 @@ namespace Microsoft.DotNet.Tests.ArgumentForwarding
.CaptureStdOut()
.Execute();
Console.WriteLine($"STDOUT: {commandResult.StdOut}");
Console.WriteLine($"STDERR: {commandResult.StdErr}");
commandResult.ExitCode.Should().Be(0);
return ParseReflectorOutput(commandResult.StdOut);
@ -251,7 +251,7 @@ namespace Microsoft.DotNet.Tests.ArgumentForwarding
{
StartInfo = new ProcessStartInfo
{
FileName = Env.GetCommandPath("dotnet", ".exe", ""),
FileName = new Muxer().MuxerPath,
Arguments = $"{ReflectorPath} {testUserArgument}",
UseShellExecute = false,
RedirectStandardOutput = true,

View file

@ -104,12 +104,23 @@ EndGlobal
SlnFile slnFile = SlnFile.Read(tmpFile.Path);
Console.WriteLine(new
{
slnFile_FormatVersion = slnFile.FormatVersion,
slnFile_ProductDescription = slnFile.ProductDescription,
slnFile_VisualStudioVersion = slnFile.VisualStudioVersion,
slnFile_MinimumVisualStudioVersion = slnFile.MinimumVisualStudioVersion,
slnFile_BaseDirectory = slnFile.BaseDirectory,
slnFile_FullPath = slnFile.FullPath,
tmpFilePath = tmpFile.Path
}.ToString());
slnFile.FormatVersion.Should().Be("12.00");
slnFile.ProductDescription.Should().Be("Visual Studio 15");
slnFile.VisualStudioVersion.Should().Be("15.0.26006.2");
slnFile.MinimumVisualStudioVersion.Should().Be("10.0.40219.1");
slnFile.BaseDirectory.Should().Be(Path.GetDirectoryName(tmpFile.Path));
slnFile.FullPath.Should().Be(tmpFile.Path);
slnFile.FullPath.Should().Be(Path.GetFullPath(tmpFile.Path));
slnFile.Projects.Count.Should().Be(2);
var project = slnFile.Projects[0];

View file

@ -67,7 +67,7 @@ namespace Microsoft.DotNet.Cli.Utils.Tests
string msg1 = "Unhandled Exception: AppThrowing.MyException: "
+ "Exception of type 'AppThrowing.MyException' was thrown.";
string msg2 = "at AppThrowing.MyException.Main(String[] args)";
new TestCommand("dotnet")
new DotnetCommand()
.WithWorkingDirectory(appWithToolDepRoot)
.ExecuteWithCapturedOutput("throwingtool")
.Should().Fail()

View file

@ -5,15 +5,10 @@ using Microsoft.DotNet.Cli.Utils;
namespace Microsoft.DotNet.Tools.Test.Utilities
{
public sealed class AddReferenceCommand : TestCommand
public sealed class AddReferenceCommand : DotnetCommand
{
private string _projectName = null;
public AddReferenceCommand()
: base("dotnet")
{
}
public override CommandResult Execute(string args = "")
{
args = $"add {_projectName} reference {args}";

View file

@ -7,7 +7,7 @@ using NuGet.Frameworks;
namespace Microsoft.DotNet.Tools.Test.Utilities
{
public sealed class BuildCommand : TestCommand
public sealed class BuildCommand : DotnetCommand
{
private bool _captureOutput;
@ -26,11 +26,6 @@ namespace Microsoft.DotNet.Tools.Test.Utilities
private DirectoryInfo _workingDirectory;
public BuildCommand()
: base("dotnet")
{
}
public override CommandResult Execute(string args = "")
{
args = $"build {GetNoDependencies()} {GetProjectFile()} {GetOutputPath()} {GetConfiguration()} {GetFramework()} {GetRuntime()} {args}";

View file

@ -7,7 +7,7 @@ using System.Collections.Generic;
namespace Microsoft.DotNet.Tools.Test.Utilities
{
public sealed class CacheCommand : TestCommand
public sealed class CacheCommand : DotnetCommand
{
private List<string> _profileProject = new List<string>();
private string _framework;
@ -16,11 +16,6 @@ namespace Microsoft.DotNet.Tools.Test.Utilities
private string _frameworkVersion;
private string _intermediateWorkingDirectory;
public CacheCommand()
: base("dotnet")
{
}
public CacheCommand WithEntries(string profileProject)
{
_profileProject.Add($"--entries {profileProject}");

View file

@ -7,13 +7,8 @@ using System.Runtime.InteropServices;
namespace Microsoft.DotNet.Tools.Test.Utilities
{
public sealed class CleanCommand : TestCommand
public sealed class CleanCommand : DotnetCommand
{
public CleanCommand()
: base("dotnet")
{
}
public override CommandResult Execute(string args = "")
{
args = $"clean {args}";

View file

@ -7,13 +7,8 @@ using System.Runtime.InteropServices;
namespace Microsoft.DotNet.Tools.Test.Utilities
{
public class DependencyToolInvokerCommand : TestCommand
public class DependencyToolInvokerCommand : DotnetCommand
{
public DependencyToolInvokerCommand()
: base("dotnet")
{
}
public CommandResult Execute(string commandName, string framework, string additionalArgs)
{
var args = $"dependency-tool-invoker {commandName} --framework {framework} {additionalArgs}";

View file

@ -5,7 +5,7 @@ using Microsoft.DotNet.Cli.Utils;
namespace Microsoft.DotNet.Tools.Test.Utilities
{
public sealed class DotnetCommand : TestCommand
public class DotnetCommand : TestCommand
{
public DotnetCommand()
: base(DotnetUnderTest.FullName)

View file

@ -5,14 +5,10 @@ using Microsoft.DotNet.Cli.Utils;
namespace Microsoft.DotNet.Tools.Test.Utilities
{
public class DotnetTestCommand : TestCommand
public class DotnetTestCommand : DotnetCommand
{
private string _runtime;
public DotnetTestCommand() : base("dotnet")
{
}
public override CommandResult Execute(string args = "")
{
args = $"test {GetRuntime()} {args}";

View file

@ -5,13 +5,8 @@ using Microsoft.DotNet.Cli.Utils;
namespace Microsoft.DotNet.Tools.Test.Utilities
{
public sealed class HelpCommand : TestCommand
public sealed class HelpCommand : DotnetCommand
{
public HelpCommand()
: base("dotnet")
{
}
public override CommandResult Execute(string args = "")
{
args = $"help {args}";

View file

@ -5,15 +5,10 @@ using Microsoft.DotNet.Cli.Utils;
namespace Microsoft.DotNet.Tools.Test.Utilities
{
public sealed class ListReferenceCommand : TestCommand
public sealed class ListReferenceCommand : DotnetCommand
{
private string _projectName = null;
public ListReferenceCommand()
: base("dotnet")
{
}
public override CommandResult Execute(string args = "")
{
args = $"list {_projectName} reference {args}";

View file

@ -5,13 +5,8 @@ using Microsoft.DotNet.Cli.Utils;
namespace Microsoft.DotNet.Tools.Test.Utilities
{
public sealed class MSBuildCommand : TestCommand
public sealed class MSBuildCommand : DotnetCommand
{
public MSBuildCommand()
: base("dotnet")
{
}
public override CommandResult Execute(string args = "")
{
args = $"msbuild {args}";

View file

@ -5,14 +5,8 @@ using Microsoft.DotNet.Cli.Utils;
namespace Microsoft.DotNet.Tools.Test.Utilities
{
public sealed class MigrateCommand : TestCommand
public sealed class MigrateCommand : DotnetCommand
{
public MigrateCommand()
: base("dotnet")
{
}
public override CommandResult Execute(string args="")
{
args = $"migrate {args}";

View file

@ -5,14 +5,8 @@ using Microsoft.DotNet.Cli.Utils;
namespace Microsoft.DotNet.Tools.Test.Utilities
{
public sealed class NewCommand : TestCommand
public sealed class NewCommand : DotnetCommand
{
public NewCommand()
: base("dotnet")
{
}
public override CommandResult Execute(string args = "")
{
args = $"new {args}";

View file

@ -6,14 +6,8 @@ using Xunit;
namespace Microsoft.DotNet.Tools.Test.Utilities
{
public sealed class NewCommandShim : TestCommand
public sealed class NewCommandShim : DotnetCommand
{
public NewCommandShim()
: base("dotnet")
{
}
public override CommandResult Execute(string args = "")
{
args = $"new {args} --debug:ephemeral-hive";

View file

@ -6,7 +6,7 @@ using Microsoft.DotNet.Cli.Utils;
namespace Microsoft.DotNet.Tools.Test.Utilities
{
public sealed class PackCommand : TestCommand
public sealed class PackCommand : DotnetCommand
{
private string _projectPath;
private string _outputDirectory;
@ -90,7 +90,6 @@ namespace Microsoft.DotNet.Tools.Test.Utilities
string configuration="",
string versionSuffix="",
bool serviceable = false)
: base("dotnet")
{
_projectPath = projectPath;
_outputDirectory = output;

View file

@ -7,18 +7,13 @@ using System.Collections.Generic;
namespace Microsoft.DotNet.Tools.Test.Utilities
{
public sealed class PublishCommand : TestCommand
public sealed class PublishCommand : DotnetCommand
{
private string _framework;
private string _output;
private string _runtime;
private List<string> _profileFilterProject = new List<string>();
public PublishCommand()
: base("dotnet")
{
}
public PublishCommand WithFramework(string framework)
{
_framework = framework;

View file

@ -5,15 +5,10 @@ using Microsoft.DotNet.Cli.Utils;
namespace Microsoft.DotNet.Tools.Test.Utilities
{
public sealed class RemoveReferenceCommand : TestCommand
public sealed class RemoveReferenceCommand : DotnetCommand
{
private string _projectName = null;
public RemoveReferenceCommand()
: base("dotnet")
{
}
public override CommandResult Execute(string args = "")
{
args = $"remove {_projectName} reference {args}";

View file

@ -5,15 +5,10 @@ using Microsoft.DotNet.Cli.Utils;
namespace Microsoft.DotNet.Tools.Test.Utilities
{
public sealed class RestoreCommand : TestCommand
public sealed class RestoreCommand : DotnetCommand
{
private string _runtime;
public RestoreCommand()
: base("dotnet")
{
}
public RestoreCommand WithRuntime(string runtime)
{
_runtime = runtime;

Some files were not shown because too many files have changed in this diff Show more