Improve the help text (#5002)
* WIP Improve help text * Improve help text * Address PR comments * Address PR comments * Address PR comments
This commit is contained in:
parent
148351c12d
commit
76722fd403
20 changed files with 486 additions and 640 deletions
|
@ -48,5 +48,7 @@ namespace Microsoft.DotNet.Cli.Utils
|
||||||
};
|
};
|
||||||
|
|
||||||
public static readonly string MSBUILD_EXE_PATH = "MSBUILD_EXE_PATH";
|
public static readonly string MSBUILD_EXE_PATH = "MSBUILD_EXE_PATH";
|
||||||
|
|
||||||
|
public static readonly string ProjectOrSolutionArgumentName = "<PROJECT_OR_SOLUTION>";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,14 @@ namespace Microsoft.DotNet.Cli.CommandLine
|
||||||
{
|
{
|
||||||
internal class CommandLineApplication
|
internal class CommandLineApplication
|
||||||
{
|
{
|
||||||
|
private enum ParseOptionResult
|
||||||
|
{
|
||||||
|
Succeeded,
|
||||||
|
ShowHelp,
|
||||||
|
ShowVersion,
|
||||||
|
UnexpectedArgs,
|
||||||
|
}
|
||||||
|
|
||||||
// Indicates whether the parser should throw an exception when it runs into an unexpected argument.
|
// Indicates whether the parser should throw an exception when it runs into an unexpected argument.
|
||||||
// If this field is set to false, the parser will stop parsing when it sees an unexpected argument, and all
|
// If this field is set to false, the parser will stop parsing when it sees an unexpected argument, and all
|
||||||
// remaining arguments, including the first unexpected argument, will be stored in RemainingArguments property.
|
// remaining arguments, including the first unexpected argument, will be stored in RemainingArguments property.
|
||||||
|
@ -45,8 +53,14 @@ namespace Microsoft.DotNet.Cli.CommandLine
|
||||||
public List<CommandLineApplication> Commands { get; private set; }
|
public List<CommandLineApplication> Commands { get; private set; }
|
||||||
public bool HandleResponseFiles { get; set; }
|
public bool HandleResponseFiles { get; set; }
|
||||||
public bool AllowArgumentSeparator { get; set; }
|
public bool AllowArgumentSeparator { get; set; }
|
||||||
|
public bool HandleRemainingArguments { get; set; }
|
||||||
public string ArgumentSeparatorHelpText { get; set; }
|
public string ArgumentSeparatorHelpText { get; set; }
|
||||||
|
|
||||||
|
public CommandLineApplication Command(string name, bool throwOnUnexpectedArg = true)
|
||||||
|
{
|
||||||
|
return Command(name, _ => { }, throwOnUnexpectedArg);
|
||||||
|
}
|
||||||
|
|
||||||
public CommandLineApplication Command(string name, Action<CommandLineApplication> configuration,
|
public CommandLineApplication Command(string name, Action<CommandLineApplication> configuration,
|
||||||
bool throwOnUnexpectedArg = true)
|
bool throwOnUnexpectedArg = true)
|
||||||
{
|
{
|
||||||
|
@ -103,7 +117,6 @@ namespace Microsoft.DotNet.Cli.CommandLine
|
||||||
public int Execute(params string[] args)
|
public int Execute(params string[] args)
|
||||||
{
|
{
|
||||||
CommandLineApplication command = this;
|
CommandLineApplication command = this;
|
||||||
CommandOption option = null;
|
|
||||||
IEnumerator<CommandArgument> arguments = null;
|
IEnumerator<CommandArgument> arguments = null;
|
||||||
|
|
||||||
if (HandleResponseFiles)
|
if (HandleResponseFiles)
|
||||||
|
@ -114,172 +127,159 @@ namespace Microsoft.DotNet.Cli.CommandLine
|
||||||
for (var index = 0; index < args.Length; index++)
|
for (var index = 0; index < args.Length; index++)
|
||||||
{
|
{
|
||||||
var arg = args[index];
|
var arg = args[index];
|
||||||
var processed = false;
|
|
||||||
if (!processed && option == null)
|
bool isLongOption = arg.StartsWith("--");
|
||||||
|
if (isLongOption || arg.StartsWith("-"))
|
||||||
{
|
{
|
||||||
string[] longOption = null;
|
CommandOption option;
|
||||||
string[] shortOption = null;
|
var result = ParseOption(isLongOption, command, args, ref index, out option);
|
||||||
|
if (result == ParseOptionResult.ShowHelp)
|
||||||
if (arg.StartsWith("--"))
|
|
||||||
{
|
{
|
||||||
longOption = arg.Substring(2).Split(new[] { ':', '=' }, 2);
|
command.ShowHelp();
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
else if (arg.StartsWith("-"))
|
else if (result == ParseOptionResult.ShowVersion)
|
||||||
{
|
{
|
||||||
shortOption = arg.Substring(1).Split(new[] { ':', '=' }, 2);
|
command.ShowVersion();
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
if (longOption != null)
|
else if (result == ParseOptionResult.UnexpectedArgs)
|
||||||
{
|
{
|
||||||
processed = true;
|
break;
|
||||||
string longOptionName = longOption[0];
|
|
||||||
option = command.Options.SingleOrDefault(opt => string.Equals(opt.LongName, longOptionName, StringComparison.Ordinal));
|
|
||||||
|
|
||||||
if (option == null)
|
|
||||||
{
|
|
||||||
if (string.IsNullOrEmpty(longOptionName) && !command._throwOnUnexpectedArg && AllowArgumentSeparator)
|
|
||||||
{
|
|
||||||
// a stand-alone "--" is the argument separator, so skip it and
|
|
||||||
// handle the rest of the args as unexpected args
|
|
||||||
index++;
|
|
||||||
}
|
|
||||||
|
|
||||||
HandleUnexpectedArg(command, args, index, argTypeName: "option");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If we find a help/version option, show information and stop parsing
|
|
||||||
if (command.OptionHelp == option)
|
|
||||||
{
|
|
||||||
command.ShowHelp();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
else if (command.OptionVersion == option)
|
|
||||||
{
|
|
||||||
command.ShowVersion();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (longOption.Length == 2)
|
|
||||||
{
|
|
||||||
if (!option.TryParse(longOption[1]))
|
|
||||||
{
|
|
||||||
command.ShowHint();
|
|
||||||
throw new CommandParsingException(command, $"Unexpected value '{longOption[1]}' for option '{option.LongName}'");
|
|
||||||
}
|
|
||||||
option = null;
|
|
||||||
}
|
|
||||||
else if (option.OptionType == CommandOptionType.NoValue || option.OptionType == CommandOptionType.BoolValue)
|
|
||||||
{
|
|
||||||
// No value is needed for this option
|
|
||||||
option.TryParse(null);
|
|
||||||
option = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (shortOption != null)
|
|
||||||
{
|
|
||||||
processed = true;
|
|
||||||
option = command.Options.SingleOrDefault(opt => string.Equals(opt.ShortName, shortOption[0], StringComparison.Ordinal));
|
|
||||||
|
|
||||||
// If not a short option, try symbol option
|
|
||||||
if (option == null)
|
|
||||||
{
|
|
||||||
option = command.Options.SingleOrDefault(opt => string.Equals(opt.SymbolName, shortOption[0], StringComparison.Ordinal));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (option == null)
|
|
||||||
{
|
|
||||||
HandleUnexpectedArg(command, args, index, argTypeName: "option");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If we find a help/version option, show information and stop parsing
|
|
||||||
if (command.OptionHelp == option)
|
|
||||||
{
|
|
||||||
command.ShowHelp();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
else if (command.OptionVersion == option)
|
|
||||||
{
|
|
||||||
command.ShowVersion();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (shortOption.Length == 2)
|
|
||||||
{
|
|
||||||
if (!option.TryParse(shortOption[1]))
|
|
||||||
{
|
|
||||||
command.ShowHint();
|
|
||||||
throw new CommandParsingException(command, $"Unexpected value '{shortOption[1]}' for option '{option.LongName}'");
|
|
||||||
}
|
|
||||||
option = null;
|
|
||||||
}
|
|
||||||
else if (option.OptionType == CommandOptionType.NoValue || option.OptionType == CommandOptionType.BoolValue)
|
|
||||||
{
|
|
||||||
// No value is needed for this option
|
|
||||||
option.TryParse(null);
|
|
||||||
option = null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
if (!processed && option != null)
|
|
||||||
{
|
{
|
||||||
processed = true;
|
var subcommand = ParseSubCommand(arg, command);
|
||||||
if (!option.TryParse(arg))
|
if (subcommand != null)
|
||||||
{
|
{
|
||||||
command.ShowHint();
|
command = subcommand;
|
||||||
throw new CommandParsingException(command, $"Unexpected value '{arg}' for option '{option.LongName}'");
|
|
||||||
}
|
}
|
||||||
option = null;
|
else
|
||||||
}
|
|
||||||
|
|
||||||
if (!processed && arguments == null)
|
|
||||||
{
|
|
||||||
var currentCommand = command;
|
|
||||||
foreach (var subcommand in command.Commands)
|
|
||||||
{
|
{
|
||||||
if (string.Equals(subcommand.Name, arg, StringComparison.OrdinalIgnoreCase))
|
if (arguments == null)
|
||||||
{
|
{
|
||||||
processed = true;
|
arguments = new CommandArgumentEnumerator(command.Arguments.GetEnumerator());
|
||||||
command = subcommand;
|
}
|
||||||
|
|
||||||
|
if (arguments.MoveNext())
|
||||||
|
{
|
||||||
|
arguments.Current.Values.Add(arg);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
HandleUnexpectedArg(command, args, index, argTypeName: "command or argument");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we detect a subcommand
|
|
||||||
if (command != currentCommand)
|
|
||||||
{
|
|
||||||
processed = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (!processed)
|
|
||||||
{
|
|
||||||
if (arguments == null)
|
|
||||||
{
|
|
||||||
arguments = new CommandArgumentEnumerator(command.Arguments.GetEnumerator());
|
|
||||||
}
|
|
||||||
if (arguments.MoveNext())
|
|
||||||
{
|
|
||||||
processed = true;
|
|
||||||
arguments.Current.Values.Add(arg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!processed)
|
|
||||||
{
|
|
||||||
HandleUnexpectedArg(command, args, index, argTypeName: "command or argument");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (option != null)
|
|
||||||
{
|
|
||||||
command.ShowHint();
|
|
||||||
throw new CommandParsingException(command, $"Missing value for option '{option.LongName}'");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return command.Invoke();
|
return command.Invoke();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private ParseOptionResult ParseOption(
|
||||||
|
bool isLongOption,
|
||||||
|
CommandLineApplication command,
|
||||||
|
string[] args,
|
||||||
|
ref int index,
|
||||||
|
out CommandOption option)
|
||||||
|
{
|
||||||
|
option = null;
|
||||||
|
ParseOptionResult result = ParseOptionResult.Succeeded;
|
||||||
|
var arg = args[index];
|
||||||
|
|
||||||
|
int optionPrefixLength = isLongOption ? 2 : 1;
|
||||||
|
string[] optionComponents = arg.Substring(optionPrefixLength).Split(new[] { ':', '=' }, 2);
|
||||||
|
string optionName = optionComponents[0];
|
||||||
|
|
||||||
|
if (isLongOption)
|
||||||
|
{
|
||||||
|
option = command.Options.SingleOrDefault(
|
||||||
|
opt => string.Equals(opt.LongName, optionName, StringComparison.Ordinal));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
option = command.Options.SingleOrDefault(
|
||||||
|
opt => string.Equals(opt.ShortName, optionName, StringComparison.Ordinal));
|
||||||
|
|
||||||
|
if (option == null)
|
||||||
|
{
|
||||||
|
option = command.Options.SingleOrDefault(
|
||||||
|
opt => string.Equals(opt.SymbolName, optionName, StringComparison.Ordinal));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (option == null)
|
||||||
|
{
|
||||||
|
if (isLongOption && string.IsNullOrEmpty(optionName) &&
|
||||||
|
!command._throwOnUnexpectedArg && AllowArgumentSeparator)
|
||||||
|
{
|
||||||
|
// a stand-alone "--" is the argument separator, so skip it and
|
||||||
|
// handle the rest of the args as unexpected args
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
|
||||||
|
HandleUnexpectedArg(command, args, index, argTypeName: "option");
|
||||||
|
result = ParseOptionResult.UnexpectedArgs;
|
||||||
|
}
|
||||||
|
else if (command.OptionHelp == option)
|
||||||
|
{
|
||||||
|
result = ParseOptionResult.ShowHelp;
|
||||||
|
}
|
||||||
|
else if (command.OptionVersion == option)
|
||||||
|
{
|
||||||
|
result = ParseOptionResult.ShowVersion;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (optionComponents.Length == 2)
|
||||||
|
{
|
||||||
|
if (!option.TryParse(optionComponents[1]))
|
||||||
|
{
|
||||||
|
command.ShowHint();
|
||||||
|
throw new CommandParsingException(command,
|
||||||
|
$"Unexpected value '{optionComponents[1]}' for option '{optionName}'");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (option.OptionType == CommandOptionType.NoValue ||
|
||||||
|
option.OptionType == CommandOptionType.BoolValue)
|
||||||
|
{
|
||||||
|
// No value is needed for this option
|
||||||
|
option.TryParse(null);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
index++;
|
||||||
|
arg = args[index];
|
||||||
|
if (!option.TryParse(arg))
|
||||||
|
{
|
||||||
|
command.ShowHint();
|
||||||
|
throw new CommandParsingException(command, $"Unexpected value '{arg}' for option '{optionName}'");
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private CommandLineApplication ParseSubCommand(string arg, CommandLineApplication command)
|
||||||
|
{
|
||||||
|
foreach (var subcommand in command.Commands)
|
||||||
|
{
|
||||||
|
if (string.Equals(subcommand.Name, arg, StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
return subcommand;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
// Helper method that adds a help option
|
// Helper method that adds a help option
|
||||||
public CommandOption HelpOption(string template)
|
public CommandOption HelpOption(string template)
|
||||||
{
|
{
|
||||||
|
@ -331,10 +331,19 @@ namespace Microsoft.DotNet.Cli.CommandLine
|
||||||
public void ShowHelp(string commandName = null)
|
public void ShowHelp(string commandName = null)
|
||||||
{
|
{
|
||||||
var headerBuilder = new StringBuilder("Usage:");
|
var headerBuilder = new StringBuilder("Usage:");
|
||||||
|
var usagePrefixLength = headerBuilder.Length;
|
||||||
for (var cmd = this; cmd != null; cmd = cmd.Parent)
|
for (var cmd = this; cmd != null; cmd = cmd.Parent)
|
||||||
{
|
{
|
||||||
cmd.IsShowingInformation = true;
|
cmd.IsShowingInformation = true;
|
||||||
headerBuilder.Insert(6, string.Format(" {0}", cmd.Name));
|
if (cmd != this && cmd.Arguments.Any())
|
||||||
|
{
|
||||||
|
var args = string.Join(" ", cmd.Arguments.Select(arg => arg.Name));
|
||||||
|
headerBuilder.Insert(usagePrefixLength, string.Format(" {0} {1}", cmd.Name, args));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
headerBuilder.Insert(usagePrefixLength, string.Format(" {0}", cmd.Name));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CommandLineApplication target;
|
CommandLineApplication target;
|
||||||
|
@ -364,18 +373,39 @@ namespace Microsoft.DotNet.Cli.CommandLine
|
||||||
var argumentsBuilder = new StringBuilder();
|
var argumentsBuilder = new StringBuilder();
|
||||||
var argumentSeparatorBuilder = new StringBuilder();
|
var argumentSeparatorBuilder = new StringBuilder();
|
||||||
|
|
||||||
if (target.Arguments.Any())
|
int maxArgLen = 0;
|
||||||
|
for (var cmd = target; cmd != null; cmd = cmd.Parent)
|
||||||
{
|
{
|
||||||
headerBuilder.Append(" [arguments]");
|
if (cmd.Arguments.Any())
|
||||||
|
|
||||||
argumentsBuilder.AppendLine();
|
|
||||||
argumentsBuilder.AppendLine("Arguments:");
|
|
||||||
var maxArgLen = MaxArgumentLength(target.Arguments);
|
|
||||||
var outputFormat = string.Format(" {{0, -{0}}}{{1}}", maxArgLen + 2);
|
|
||||||
foreach (var arg in target.Arguments)
|
|
||||||
{
|
{
|
||||||
argumentsBuilder.AppendFormat(outputFormat, arg.Name, arg.Description);
|
if (cmd == target)
|
||||||
argumentsBuilder.AppendLine();
|
{
|
||||||
|
headerBuilder.Append(" [arguments]");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (argumentsBuilder.Length == 0)
|
||||||
|
{
|
||||||
|
argumentsBuilder.AppendLine();
|
||||||
|
argumentsBuilder.AppendLine("Arguments:");
|
||||||
|
}
|
||||||
|
|
||||||
|
maxArgLen = Math.Max(maxArgLen, MaxArgumentLength(cmd.Arguments));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var cmd = target; cmd != null; cmd = cmd.Parent)
|
||||||
|
{
|
||||||
|
if (cmd.Arguments.Any())
|
||||||
|
{
|
||||||
|
var outputFormat = " {0}{1}";
|
||||||
|
foreach (var arg in cmd.Arguments)
|
||||||
|
{
|
||||||
|
argumentsBuilder.AppendFormat(
|
||||||
|
outputFormat,
|
||||||
|
arg.Name.PadRight(maxArgLen + 2),
|
||||||
|
arg.Description);
|
||||||
|
argumentsBuilder.AppendLine();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -416,9 +446,17 @@ namespace Microsoft.DotNet.Cli.CommandLine
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (target.AllowArgumentSeparator)
|
if (target.AllowArgumentSeparator || target.HandleRemainingArguments)
|
||||||
{
|
{
|
||||||
headerBuilder.Append(" [[--] <arg>...]]");
|
if (target.AllowArgumentSeparator)
|
||||||
|
{
|
||||||
|
headerBuilder.Append(" [[--] <arg>...]]");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
headerBuilder.Append(" [args]");
|
||||||
|
}
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(target.ArgumentSeparatorHelpText))
|
if (!string.IsNullOrEmpty(target.ArgumentSeparatorHelpText))
|
||||||
{
|
{
|
||||||
argumentSeparatorBuilder.AppendLine();
|
argumentSeparatorBuilder.AppendLine();
|
||||||
|
|
|
@ -2,17 +2,9 @@
|
||||||
{
|
{
|
||||||
internal class CommonLocalizableStrings
|
internal class CommonLocalizableStrings
|
||||||
{
|
{
|
||||||
public const string CouldNotFindAnyProjectInDirectory = "Could not find any project in `{0}`.";
|
|
||||||
public const string MoreThanOneProjectInDirectory = "Found more than one project in `{0}`. Please specify which one to use.";
|
|
||||||
public const string ProjectAlreadyHasAreference = "Project already has a reference to `{0}`.";
|
public const string ProjectAlreadyHasAreference = "Project already has a reference to `{0}`.";
|
||||||
public const string ProjectReferenceCouldNotBeFound = "Project reference `{0}` could not be found.";
|
public const string ProjectReferenceCouldNotBeFound = "Project reference `{0}` could not be found.";
|
||||||
public const string ProjectReferenceRemoved = "Project reference `{0}` removed.";
|
public const string ProjectReferenceRemoved = "Project reference `{0}` removed.";
|
||||||
|
|
||||||
// General purpose words
|
|
||||||
public const string RequiredArgument = "Required argument";
|
|
||||||
public const string Option = "Option";
|
|
||||||
public const string Argument = "Argument";
|
|
||||||
public const string Help = "Help";
|
|
||||||
|
|
||||||
// Project related
|
// Project related
|
||||||
public const string Project = "Project";
|
public const string Project = "Project";
|
||||||
|
@ -30,9 +22,7 @@
|
||||||
public const string Library = "Library";
|
public const string Library = "Library";
|
||||||
public const string Program = "Program";
|
public const string Program = "Program";
|
||||||
public const string Application = "Application";
|
public const string Application = "Application";
|
||||||
public const string ReferenceDoesNotExist = "Reference {0} does not exist. If you still want to add it, please use --force option. Please note that this may have adverse effects on the project. ";
|
|
||||||
public const string ReferenceAddedToTheProject = "Reference `{0}` added to the project.";
|
public const string ReferenceAddedToTheProject = "Reference `{0}` added to the project.";
|
||||||
|
|
||||||
|
|
||||||
// Verbs
|
// Verbs
|
||||||
public const string Add = "Add";
|
public const string Add = "Add";
|
||||||
|
@ -101,9 +91,9 @@
|
||||||
|
|
||||||
// dotnet <verb>
|
// dotnet <verb>
|
||||||
/// Project
|
/// Project
|
||||||
public const string CouldNotFindProjectIn = "Could not find any project in `{0}`.";
|
public const string CouldNotFindAnyProjectInDirectory = "Could not find any project in `{0}`.";
|
||||||
public const string CouldNotFindProjectOrDirectory = "Could not find project or directory `{0}`.";
|
public const string CouldNotFindProjectOrDirectory = "Could not find project or directory `{0}`.";
|
||||||
public const string FoundMoreThanOneProjectIn = "Found more than one project in `{0}`. Please specify which one to use.";
|
public const string MoreThanOneProjectInDirectory = "Found more than one project in `{0}`. Please specify which one to use.";
|
||||||
public const string FoundInvalidProject = "Found a project `{0}` but it is invalid.";
|
public const string FoundInvalidProject = "Found a project `{0}` but it is invalid.";
|
||||||
public const string InvalidProject = "Invalid project `{0}`.";
|
public const string InvalidProject = "Invalid project `{0}`.";
|
||||||
|
|
||||||
|
@ -117,15 +107,15 @@
|
||||||
public const string SolutionAlreadyContainsAProject = "Solution {0} already contains project {1}.";
|
public const string SolutionAlreadyContainsAProject = "Solution {0} already contains project {1}.";
|
||||||
|
|
||||||
/// add p2p
|
/// add p2p
|
||||||
public const string ReferenceDoesNotExistForce = "Reference {0} does not exist. If you still want to add it, please use --force option. Please note that this may have adverse effects on the project. ";
|
public const string ReferenceDoesNotExist = "Reference {0} does not exist.";
|
||||||
public const string ReferenceIsInvalid = "Reference `{0}` is invalid.";
|
public const string ReferenceIsInvalid = "Reference `{0}` is invalid.";
|
||||||
public const string SpecifyAtLeastOneReferenceToAdd = "You must specify at least one reference to add. Please run dotnet add --help for more information.";
|
public const string SpecifyAtLeastOneReferenceToAdd = "You must specify at least one reference to add.";
|
||||||
public const string ProjectAlreadyHasAReference = "Project {0} already has a reference `{1}`.";
|
public const string ProjectAlreadyHasAReference = "Project {0} already has a reference `{1}`.";
|
||||||
|
|
||||||
/// add package
|
/// add package
|
||||||
public const string PackageReferenceDoesNotExist = "Package reference `{0}` does not exist.";
|
public const string PackageReferenceDoesNotExist = "Package reference `{0}` does not exist.";
|
||||||
public const string PackageReferenceIsInvalid = "Package reference `{0}` is invalid.";
|
public const string PackageReferenceIsInvalid = "Package reference `{0}` is invalid.";
|
||||||
public const string SpecifyAtLeastOnePackageReferenceToAdd = "You must specify at least one reference to add. Please run dotnet add --help for more information.";
|
public const string SpecifyAtLeastOnePackageReferenceToAdd = "You must specify at least one package to add.";
|
||||||
public const string PackageReferenceAddedToTheProject = "Package reference `{0}` added to the project.";
|
public const string PackageReferenceAddedToTheProject = "Package reference `{0}` added to the project.";
|
||||||
public const string ProjectAlreadyHasAPackageReference = "Project {0} already has a reference `{1}`.";
|
public const string ProjectAlreadyHasAPackageReference = "Project {0} already has a reference `{1}`.";
|
||||||
public const string PleaseSpecifyVersion = "Please specify a version of the package.";
|
public const string PleaseSpecifyVersion = "Please specify a version of the package.";
|
||||||
|
@ -133,7 +123,7 @@
|
||||||
/// add sln
|
/// add sln
|
||||||
public const string ProjectDoesNotExist = "Project `{0}` does not exist.";
|
public const string ProjectDoesNotExist = "Project `{0}` does not exist.";
|
||||||
public const string ProjectIsInvalid = "Project `{0}` is invalid.";
|
public const string ProjectIsInvalid = "Project `{0}` is invalid.";
|
||||||
public const string SpecifyAtLeastOneProjectToAdd = "You must specify at least one project to add. Please run dotnet add --help for more information.";
|
public const string SpecifyAtLeastOneProjectToAdd = "You must specify at least one project to add.";
|
||||||
public const string ProjectAddedToTheSolution = "Project `{0}` added to the solution.";
|
public const string ProjectAddedToTheSolution = "Project `{0}` added to the solution.";
|
||||||
public const string SolutionAlreadyHasAProject = "Solution {0} already contains project {1}.";
|
public const string SolutionAlreadyHasAProject = "Solution {0} already contains project {1}.";
|
||||||
|
|
||||||
|
@ -162,6 +152,12 @@
|
||||||
public const string NoReferencesFound = "There are no {0} references in project {1}. ;; {0} is the type of the item being requested (project, package, p2p) and {1} is the object operated on (a project file or a solution file). ";
|
public const string NoReferencesFound = "There are no {0} references in project {1}. ;; {0} is the type of the item being requested (project, package, p2p) and {1} is the object operated on (a project file or a solution file). ";
|
||||||
public const string NoProjectsFound = "No projects found in the solution.";
|
public const string NoProjectsFound = "No projects found in the solution.";
|
||||||
|
|
||||||
|
/// arguments
|
||||||
|
public const string ArgumentsProjectOrSolutionDescription = "The project or solution to operation on. If a file is not specified, the current directory is searched.";
|
||||||
|
|
||||||
|
/// commands
|
||||||
|
public const string CmdFramework = "FRAMEWORK";
|
||||||
|
|
||||||
/// update pkg
|
/// update pkg
|
||||||
public const string PleaseSpecifyNewVersion = "Please specify new version of the package.";
|
public const string PleaseSpecifyNewVersion = "Please specify new version of the package.";
|
||||||
public const string PleaseSpecifyWhichPackageToUpdate = "Please specify which package to update.";
|
public const string PleaseSpecifyWhichPackageToUpdate = "Please specify which package to update.";
|
||||||
|
|
|
@ -1,76 +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.Utils;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
|
||||||
|
|
||||||
namespace Microsoft.DotNet.Tools
|
|
||||||
{
|
|
||||||
public abstract class DispatchCommand
|
|
||||||
{
|
|
||||||
protected abstract string HelpText { get; }
|
|
||||||
protected abstract Dictionary<string, Func<string[], int>> BuiltInCommands { get; }
|
|
||||||
|
|
||||||
public int Start(string[] args)
|
|
||||||
{
|
|
||||||
DebugHelper.HandleDebugSwitch(ref args);
|
|
||||||
|
|
||||||
if (args.Length == 0 || args[0] == "--help" || args[0] == "-h")
|
|
||||||
{
|
|
||||||
Reporter.Output.WriteLine(HelpText);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
string commandObject;
|
|
||||||
string command;
|
|
||||||
if (IsValidCommandName(args[0]))
|
|
||||||
{
|
|
||||||
command = args[0];
|
|
||||||
commandObject = GetCurrentDirectoryWithDirSeparator();
|
|
||||||
args = args.Skip(1).Prepend(commandObject).ToArray();
|
|
||||||
}
|
|
||||||
else if (args.Length == 1)
|
|
||||||
{
|
|
||||||
Reporter.Error.WriteLine(string.Format(CommonLocalizableStrings.RequiredArgumentNotPassed, "<command>").Red());
|
|
||||||
Reporter.Output.WriteLine(HelpText);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
commandObject = args[0];
|
|
||||||
command = args[1];
|
|
||||||
|
|
||||||
args = args.Skip(2).Prepend(commandObject).ToArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
Func<string[], int> builtin;
|
|
||||||
if (BuiltInCommands.TryGetValue(command, out builtin))
|
|
||||||
{
|
|
||||||
return builtin(args);
|
|
||||||
}
|
|
||||||
|
|
||||||
Reporter.Error.WriteLine(string.Format(CommonLocalizableStrings.RequiredArgumentIsInvalid, "<command>").Red());
|
|
||||||
Reporter.Output.WriteLine(HelpText);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool IsValidCommandName(string s)
|
|
||||||
{
|
|
||||||
return BuiltInCommands.ContainsKey(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static string GetCurrentDirectoryWithDirSeparator()
|
|
||||||
{
|
|
||||||
string ret = Directory.GetCurrentDirectory();
|
|
||||||
if (ret[ret.Length - 1] != Path.DirectorySeparatorChar)
|
|
||||||
{
|
|
||||||
ret += Path.DirectorySeparatorChar;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
57
src/dotnet/DotNetTopLevelCommandBase.cs
Normal file
57
src/dotnet/DotNetTopLevelCommandBase.cs
Normal file
|
@ -0,0 +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 System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Microsoft.DotNet.Cli.CommandLine;
|
||||||
|
using Microsoft.DotNet.Cli.Utils;
|
||||||
|
using Microsoft.DotNet.Tools;
|
||||||
|
using Microsoft.DotNet.Tools.Add.ProjectToProjectReference;
|
||||||
|
|
||||||
|
namespace Microsoft.DotNet.Cli
|
||||||
|
{
|
||||||
|
public abstract class DotNetTopLevelCommandBase
|
||||||
|
{
|
||||||
|
protected abstract string CommandName { get; }
|
||||||
|
protected abstract string FullCommandNameLocalized { get; }
|
||||||
|
internal abstract List<Func<CommandLineApplication, CommandLineApplication>> SubCommands { get; }
|
||||||
|
|
||||||
|
public int RunCommand(string[] args)
|
||||||
|
{
|
||||||
|
DebugHelper.HandleDebugSwitch(ref args);
|
||||||
|
|
||||||
|
CommandLineApplication app = new CommandLineApplication(throwOnUnexpectedArg: true)
|
||||||
|
{
|
||||||
|
Name = $"dotnet {CommandName}",
|
||||||
|
FullName = FullCommandNameLocalized,
|
||||||
|
};
|
||||||
|
|
||||||
|
app.HelpOption("-h|--help");
|
||||||
|
|
||||||
|
app.Argument(
|
||||||
|
Constants.ProjectOrSolutionArgumentName,
|
||||||
|
CommonLocalizableStrings.ArgumentsProjectOrSolutionDescription);
|
||||||
|
|
||||||
|
foreach (var subCommandCreator in SubCommands)
|
||||||
|
{
|
||||||
|
subCommandCreator(app);
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return app.Execute(args);
|
||||||
|
}
|
||||||
|
catch (GracefulException e)
|
||||||
|
{
|
||||||
|
Reporter.Error.WriteLine(e.Message.Red());
|
||||||
|
app.ShowHelp();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
catch (CommandParsingException e)
|
||||||
|
{
|
||||||
|
Reporter.Error.WriteLine(e.Message.Red());
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,23 +3,5 @@ namespace Microsoft.DotNet.Tools.Add
|
||||||
internal class LocalizableStrings
|
internal class LocalizableStrings
|
||||||
{
|
{
|
||||||
public const string NetAddCommand = ".NET Add Command";
|
public const string NetAddCommand = ".NET Add Command";
|
||||||
|
|
||||||
public const string Usage = "Usage";
|
|
||||||
|
|
||||||
public const string Options = "Options";
|
|
||||||
|
|
||||||
public const string HelpDefinition = "Show help information";
|
|
||||||
|
|
||||||
public const string Arguments = "Arguments";
|
|
||||||
|
|
||||||
public const string ArgumentsObjectDefinition = "The object of the operation. If a project file is not specified, it defaults to the current directory.";
|
|
||||||
|
|
||||||
public const string ArgumentsCommandDefinition = "Command to be executed on <object>.";
|
|
||||||
|
|
||||||
public const string ArgsDefinition = "Any extra arguments passed to the command. Use `dotnet add <command> --help` to get help about these arguments.";
|
|
||||||
|
|
||||||
public const string Commands = "Commands";
|
|
||||||
|
|
||||||
public const string CommandP2PDefinition = "Add project to project (p2p) reference to a project";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,47 +1,28 @@
|
||||||
// Copyright (c) .NET Foundation and contributors. All rights reserved.
|
// Copyright (c) .NET Foundation and contributors. All rights reserved.
|
||||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||||
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using Microsoft.DotNet.Cli.CommandLine;
|
|
||||||
using Microsoft.DotNet.Cli.Utils;
|
|
||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using Microsoft.DotNet.Cli;
|
||||||
using Microsoft.Build.Construction;
|
using Microsoft.DotNet.Cli.CommandLine;
|
||||||
using Microsoft.DotNet.ProjectJsonMigration;
|
|
||||||
using NuGet.Frameworks;
|
|
||||||
using Microsoft.DotNet.Tools.Add.ProjectToProjectReference;
|
using Microsoft.DotNet.Tools.Add.ProjectToProjectReference;
|
||||||
|
|
||||||
namespace Microsoft.DotNet.Tools.Add
|
namespace Microsoft.DotNet.Tools.Add
|
||||||
{
|
{
|
||||||
public class AddCommand : DispatchCommand
|
public class AddCommand : DotNetTopLevelCommandBase
|
||||||
{
|
{
|
||||||
protected override string HelpText => $@"{LocalizableStrings.NetAddCommand}
|
protected override string CommandName => "add";
|
||||||
|
protected override string FullCommandNameLocalized => LocalizableStrings.NetAddCommand;
|
||||||
{LocalizableStrings.Usage}: dotnet add [options] <object> <command> [[--] <arg>...]]
|
internal override List<Func<CommandLineApplication, CommandLineApplication>> SubCommands =>
|
||||||
|
new List<Func<CommandLineApplication, CommandLineApplication>>
|
||||||
{LocalizableStrings.Options}:
|
{
|
||||||
-h|--help {LocalizableStrings.HelpDefinition}
|
AddProjectToProjectReferenceCommand.CreateApplication,
|
||||||
|
};
|
||||||
{LocalizableStrings.Arguments}:
|
|
||||||
<object> {LocalizableStrings.ArgumentsObjectDefinition}
|
|
||||||
<command> {LocalizableStrings.ArgumentsCommandDefinition}
|
|
||||||
|
|
||||||
Args:
|
|
||||||
{LocalizableStrings.ArgsDefinition}
|
|
||||||
|
|
||||||
{LocalizableStrings.Commands}:
|
|
||||||
p2p {LocalizableStrings.CommandP2PDefinition}";
|
|
||||||
|
|
||||||
protected override Dictionary<string, Func<string[], int>> BuiltInCommands => new Dictionary<string, Func<string[], int>>
|
|
||||||
{
|
|
||||||
["p2p"] = AddProjectToProjectReferenceCommand.Run,
|
|
||||||
};
|
|
||||||
|
|
||||||
public static int Run(string[] args)
|
public static int Run(string[] args)
|
||||||
{
|
{
|
||||||
var cmd = new AddCommand();
|
var command = new AddCommand();
|
||||||
return cmd.Start(args);
|
return command.RunCommand(args);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,21 +5,9 @@ namespace Microsoft.DotNet.Tools.Add.ProjectToProjectReference
|
||||||
public const string AppFullName = ".NET Add Project to Project (p2p) reference Command";
|
public const string AppFullName = ".NET Add Project to Project (p2p) reference Command";
|
||||||
|
|
||||||
public const string AppDescription = "Command to add project to project (p2p) reference";
|
public const string AppDescription = "Command to add project to project (p2p) reference";
|
||||||
|
|
||||||
public const string SpecifyAtLeastOneReferenceToAdd = "You must specify at least one reference to add. Please run dotnet add --help for more information.";
|
|
||||||
|
|
||||||
public const string AppHelpText = "Project to project references to add";
|
public const string AppHelpText = "Project to project references to add";
|
||||||
|
|
||||||
public const string CmdProject = "PROJECT";
|
|
||||||
|
|
||||||
public const string CmdProjectDescription = "The project file to modify. If a project file is not specified, it searches the current working directory for an MSBuild file that has a file extension that ends in `proj` and uses that file.";
|
|
||||||
|
|
||||||
public const string CmdFramework = "FRAMEWORK";
|
|
||||||
|
|
||||||
public const string CmdFrameworkDescription = "Add reference only when targetting a specific framework";
|
public const string CmdFrameworkDescription = "Add reference only when targetting a specific framework";
|
||||||
|
|
||||||
public const string CmdForceDescription = "Add reference even if it does not exist, do not convert paths to relative";
|
|
||||||
|
|
||||||
public const string ProjectException = "Project";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,8 +4,10 @@
|
||||||
using Microsoft.Build.Evaluation;
|
using Microsoft.Build.Evaluation;
|
||||||
using Microsoft.DotNet.Cli.CommandLine;
|
using Microsoft.DotNet.Cli.CommandLine;
|
||||||
using Microsoft.DotNet.Cli.Utils;
|
using Microsoft.DotNet.Cli.Utils;
|
||||||
|
using Microsoft.DotNet.Tools.Common;
|
||||||
using NuGet.Frameworks;
|
using NuGet.Frameworks;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
|
@ -13,53 +15,46 @@ namespace Microsoft.DotNet.Tools.Add.ProjectToProjectReference
|
||||||
{
|
{
|
||||||
public class AddProjectToProjectReferenceCommand
|
public class AddProjectToProjectReferenceCommand
|
||||||
{
|
{
|
||||||
public static int Run(string[] args)
|
internal static CommandLineApplication CreateApplication(CommandLineApplication parentApp)
|
||||||
{
|
{
|
||||||
DebugHelper.HandleDebugSwitch(ref args);
|
CommandLineApplication app = parentApp.Command("p2p", throwOnUnexpectedArg: false);
|
||||||
|
app.FullName = LocalizableStrings.AppFullName;
|
||||||
CommandLineApplication app = new CommandLineApplication(throwOnUnexpectedArg: false)
|
app.Description = LocalizableStrings.AppDescription;
|
||||||
{
|
app.HandleRemainingArguments = true;
|
||||||
Name = "dotnet add p2p",
|
app.ArgumentSeparatorHelpText = LocalizableStrings.AppHelpText;
|
||||||
FullName = LocalizableStrings.AppFullName,
|
|
||||||
Description = LocalizableStrings.AppDescription,
|
|
||||||
AllowArgumentSeparator = true,
|
|
||||||
ArgumentSeparatorHelpText = LocalizableStrings.AppHelpText
|
|
||||||
};
|
|
||||||
|
|
||||||
app.HelpOption("-h|--help");
|
app.HelpOption("-h|--help");
|
||||||
|
|
||||||
CommandArgument projectArgument = app.Argument(
|
|
||||||
$"<{LocalizableStrings.CmdProject}>",
|
|
||||||
LocalizableStrings.CmdProjectDescription);
|
|
||||||
|
|
||||||
CommandOption frameworkOption = app.Option(
|
CommandOption frameworkOption = app.Option(
|
||||||
$"-f|--framework <{LocalizableStrings.CmdFramework}>",
|
$"-f|--framework <{CommonLocalizableStrings.CmdFramework}>",
|
||||||
LocalizableStrings.CmdFrameworkDescription,
|
LocalizableStrings.CmdFrameworkDescription,
|
||||||
CommandOptionType.SingleValue);
|
CommandOptionType.SingleValue);
|
||||||
|
|
||||||
CommandOption forceOption = app.Option(
|
app.OnExecute(() =>
|
||||||
"--force",
|
{
|
||||||
LocalizableStrings.CmdForceDescription,
|
try
|
||||||
CommandOptionType.NoValue);
|
|
||||||
|
|
||||||
app.OnExecute(() => {
|
|
||||||
if (string.IsNullOrEmpty(projectArgument.Value))
|
|
||||||
{
|
{
|
||||||
throw new GracefulException(CommonLocalizableStrings.RequiredArgumentNotPassed, $"<{LocalizableStrings.ProjectException}>");
|
if (!parentApp.Arguments.Any())
|
||||||
}
|
{
|
||||||
|
throw new GracefulException(CommonLocalizableStrings.RequiredArgumentNotPassed, Constants.ProjectOrSolutionArgumentName);
|
||||||
|
}
|
||||||
|
|
||||||
var projects = new ProjectCollection();
|
var projectOrDirectory = parentApp.Arguments.First().Value;
|
||||||
var msbuildProj = MsbuildProject.FromFileOrDirectory(projects, projectArgument.Value);
|
if (string.IsNullOrEmpty(projectOrDirectory))
|
||||||
|
{
|
||||||
|
projectOrDirectory = PathUtility.EnsureTrailingSlash(Directory.GetCurrentDirectory());
|
||||||
|
}
|
||||||
|
|
||||||
if (app.RemainingArguments.Count == 0)
|
var projects = new ProjectCollection();
|
||||||
{
|
var msbuildProj = MsbuildProject.FromFileOrDirectory(projects, projectOrDirectory);
|
||||||
throw new GracefulException(LocalizableStrings.SpecifyAtLeastOneReferenceToAdd);
|
|
||||||
}
|
|
||||||
|
|
||||||
string frameworkString = frameworkOption.Value();
|
if (app.RemainingArguments.Count == 0)
|
||||||
List<string> references = app.RemainingArguments;
|
{
|
||||||
if (!forceOption.HasValue())
|
throw new GracefulException(CommonLocalizableStrings.SpecifyAtLeastOneReferenceToAdd);
|
||||||
{
|
}
|
||||||
|
|
||||||
|
string frameworkString = frameworkOption.Value();
|
||||||
|
List<string> references = app.RemainingArguments;
|
||||||
MsbuildProject.EnsureAllReferencesExist(references);
|
MsbuildProject.EnsureAllReferencesExist(references);
|
||||||
IEnumerable<MsbuildProject> refs = references.Select((r) => MsbuildProject.FromFile(projects, r));
|
IEnumerable<MsbuildProject> refs = references.Select((r) => MsbuildProject.FromFile(projects, r));
|
||||||
|
|
||||||
|
@ -101,30 +96,27 @@ namespace Microsoft.DotNet.Tools.Add.ProjectToProjectReference
|
||||||
}
|
}
|
||||||
|
|
||||||
msbuildProj.ConvertPathsToRelative(ref references);
|
msbuildProj.ConvertPathsToRelative(ref references);
|
||||||
}
|
|
||||||
|
|
||||||
int numberOfAddedReferences = msbuildProj.AddProjectToProjectReferences(
|
|
||||||
frameworkOption.Value(),
|
|
||||||
references);
|
|
||||||
|
|
||||||
if (numberOfAddedReferences != 0)
|
int numberOfAddedReferences = msbuildProj.AddProjectToProjectReferences(
|
||||||
|
frameworkOption.Value(),
|
||||||
|
references);
|
||||||
|
|
||||||
|
if (numberOfAddedReferences != 0)
|
||||||
|
{
|
||||||
|
msbuildProj.ProjectRootElement.Save();
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
catch (GracefulException e)
|
||||||
{
|
{
|
||||||
msbuildProj.ProjectRootElement.Save();
|
Reporter.Error.WriteLine(e.Message.Red());
|
||||||
|
app.ShowHelp();
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
try
|
return app;
|
||||||
{
|
|
||||||
return app.Execute(args);
|
|
||||||
}
|
|
||||||
catch (GracefulException e)
|
|
||||||
{
|
|
||||||
Reporter.Error.WriteLine(e.Message.Red());
|
|
||||||
app.ShowHelp();
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string GetProjectNotCompatibleWithFrameworksDisplayString(MsbuildProject project, IEnumerable<string> frameworksDisplayStrings)
|
private static string GetProjectNotCompatibleWithFrameworksDisplayString(MsbuildProject project, IEnumerable<string> frameworksDisplayStrings)
|
||||||
|
|
|
@ -2,24 +2,6 @@
|
||||||
{
|
{
|
||||||
internal class LocalizableStrings
|
internal class LocalizableStrings
|
||||||
{
|
{
|
||||||
public const string Usage = "Usage";
|
public const string NetListCommand = ".NET List Command";
|
||||||
|
|
||||||
public const string Arguments = "Arguments";
|
|
||||||
|
|
||||||
public const string ExtraArgs = "Args";
|
|
||||||
|
|
||||||
public const string ListCommandDescription = ".NET List Command";
|
|
||||||
|
|
||||||
public const string Commands = "Commands";
|
|
||||||
|
|
||||||
public const string CommandDefinition = "Command to be executed on <object>.";
|
|
||||||
|
|
||||||
public const string ExtraArgumentsDefinition = "Any extra arguments passed to the command. Use `dotnet list <command> --help` to get help about these arguments.";
|
|
||||||
|
|
||||||
public const string HelpDefinition = "Show help";
|
|
||||||
|
|
||||||
public const string ObjectDefinition = "The object of the operation. If a project file is not specified, it defaults to the current directory.";
|
|
||||||
|
|
||||||
public const string P2PsDefinition = "List project to project (p2p) references from a project";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,38 +3,26 @@
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using Microsoft.DotNet.Cli;
|
||||||
|
using Microsoft.DotNet.Cli.CommandLine;
|
||||||
using Microsoft.DotNet.Tools.List.ProjectToProjectReferences;
|
using Microsoft.DotNet.Tools.List.ProjectToProjectReferences;
|
||||||
|
|
||||||
namespace Microsoft.DotNet.Tools.List
|
namespace Microsoft.DotNet.Tools.List
|
||||||
{
|
{
|
||||||
public class ListCommand : DispatchCommand
|
public class ListCommand : DotNetTopLevelCommandBase
|
||||||
{
|
{
|
||||||
protected override string HelpText => $@"{LocalizableStrings.ListCommandDescription}
|
protected override string CommandName => "list";
|
||||||
|
protected override string FullCommandNameLocalized => LocalizableStrings.NetListCommand;
|
||||||
{LocalizableStrings.Usage}: dotnet list [options] <object> <command> [[--] <arg>...]]
|
internal override List<Func<CommandLineApplication, CommandLineApplication>> SubCommands =>
|
||||||
|
new List<Func<CommandLineApplication, CommandLineApplication>>
|
||||||
Options:
|
{
|
||||||
-h|--help {LocalizableStrings.HelpDefinition}
|
ListProjectToProjectReferencesCommand.CreateApplication,
|
||||||
|
};
|
||||||
{LocalizableStrings.Arguments}:
|
|
||||||
<object> {LocalizableStrings.ObjectDefinition}
|
|
||||||
<command> {LocalizableStrings.CommandDefinition}
|
|
||||||
|
|
||||||
{LocalizableStrings.ExtraArgs}:
|
|
||||||
{LocalizableStrings.ExtraArgumentsDefinition}
|
|
||||||
|
|
||||||
{LocalizableStrings.Commands}:
|
|
||||||
p2ps {LocalizableStrings.P2PsDefinition}";
|
|
||||||
|
|
||||||
protected override Dictionary<string, Func<string[], int>> BuiltInCommands => new Dictionary<string, Func<string[], int>>
|
|
||||||
{
|
|
||||||
["p2ps"] = ListProjectToProjectReferencesCommand.Run,
|
|
||||||
};
|
|
||||||
|
|
||||||
public static int Run(string[] args)
|
public static int Run(string[] args)
|
||||||
{
|
{
|
||||||
var cmd = new ListCommand();
|
var command = new ListCommand();
|
||||||
return cmd.Start(args);
|
return command.RunCommand(args);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,10 +6,6 @@ namespace Microsoft.DotNet.Tools.List.ProjectToProjectReferences
|
||||||
|
|
||||||
public const string AppDescription = "Command to list project to project (p2p) references";
|
public const string AppDescription = "Command to list project to project (p2p) references";
|
||||||
|
|
||||||
public const string ProjectArgumentValueName = "PROJECT";
|
|
||||||
|
|
||||||
public const string ProjectArgumentDescription = "The project file to modify. If a project file is not specified, it searches the current working directory for an MSBuild file that has a file extension that ends in `proj` and uses that file.";
|
|
||||||
|
|
||||||
public const string NoReferencesFound = "There are no {0} references in project {1}.\n{0} is the type of the item being requested (project, package, p2p) and {1} is the object operated on (a project file or a solution file). ";
|
public const string NoReferencesFound = "There are no {0} references in project {1}.\n{0} is the type of the item being requested (project, package, p2p) and {1} is the object operated on (a project file or a solution file). ";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,63 +4,64 @@
|
||||||
using Microsoft.Build.Evaluation;
|
using Microsoft.Build.Evaluation;
|
||||||
using Microsoft.DotNet.Cli.CommandLine;
|
using Microsoft.DotNet.Cli.CommandLine;
|
||||||
using Microsoft.DotNet.Cli.Utils;
|
using Microsoft.DotNet.Cli.Utils;
|
||||||
|
using Microsoft.DotNet.Tools.Common;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
||||||
namespace Microsoft.DotNet.Tools.List.ProjectToProjectReferences
|
namespace Microsoft.DotNet.Tools.List.ProjectToProjectReferences
|
||||||
{
|
{
|
||||||
public class ListProjectToProjectReferencesCommand
|
public class ListProjectToProjectReferencesCommand
|
||||||
{
|
{
|
||||||
public static int Run(string[] args)
|
internal static CommandLineApplication CreateApplication(CommandLineApplication parentApp)
|
||||||
{
|
{
|
||||||
DebugHelper.HandleDebugSwitch(ref args);
|
CommandLineApplication app = parentApp.Command("p2ps", throwOnUnexpectedArg: false);
|
||||||
|
app.FullName = LocalizableStrings.AppFullName;
|
||||||
CommandLineApplication app = new CommandLineApplication(throwOnUnexpectedArg: false)
|
app.Description = LocalizableStrings.AppDescription;
|
||||||
{
|
|
||||||
Name = "dotnet list p2ps",
|
|
||||||
FullName = LocalizableStrings.AppFullName,
|
|
||||||
Description = LocalizableStrings.AppDescription
|
|
||||||
};
|
|
||||||
|
|
||||||
app.HelpOption("-h|--help");
|
app.HelpOption("-h|--help");
|
||||||
|
|
||||||
CommandArgument projectArgument = app.Argument($"<{LocalizableStrings.ProjectArgumentValueName}>", LocalizableStrings.ProjectArgumentDescription);
|
|
||||||
|
|
||||||
app.OnExecute(() => {
|
app.OnExecute(() => {
|
||||||
if (string.IsNullOrEmpty(projectArgument.Value))
|
try
|
||||||
{
|
{
|
||||||
throw new GracefulException(CommonLocalizableStrings.RequiredArgumentNotPassed, $"<{LocalizableStrings.ProjectArgumentValueName}>");
|
if (!parentApp.Arguments.Any())
|
||||||
}
|
{
|
||||||
|
throw new GracefulException(CommonLocalizableStrings.RequiredArgumentNotPassed, Constants.ProjectOrSolutionArgumentName);
|
||||||
|
}
|
||||||
|
|
||||||
var msbuildProj = MsbuildProject.FromFileOrDirectory(new ProjectCollection(), projectArgument.Value);
|
var projectOrDirectory = parentApp.Arguments.First().Value;
|
||||||
|
if (string.IsNullOrEmpty(projectOrDirectory))
|
||||||
|
{
|
||||||
|
projectOrDirectory = PathUtility.EnsureTrailingSlash(Directory.GetCurrentDirectory());
|
||||||
|
}
|
||||||
|
|
||||||
|
var msbuildProj = MsbuildProject.FromFileOrDirectory(new ProjectCollection(), projectOrDirectory);
|
||||||
|
|
||||||
|
var p2ps = msbuildProj.GetProjectToProjectReferences();
|
||||||
|
if (p2ps.Count() == 0)
|
||||||
|
{
|
||||||
|
Reporter.Output.WriteLine(string.Format(LocalizableStrings.NoReferencesFound, CommonLocalizableStrings.P2P, projectOrDirectory));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Reporter.Output.WriteLine($"{CommonLocalizableStrings.ProjectReferenceOneOrMore}");
|
||||||
|
Reporter.Output.WriteLine(new string('-', CommonLocalizableStrings.ProjectReferenceOneOrMore.Length));
|
||||||
|
foreach (var p2p in p2ps)
|
||||||
|
{
|
||||||
|
Reporter.Output.WriteLine(p2p.Include);
|
||||||
|
}
|
||||||
|
|
||||||
var p2ps = msbuildProj.GetProjectToProjectReferences();
|
|
||||||
if (p2ps.Count() == 0)
|
|
||||||
{
|
|
||||||
Reporter.Output.WriteLine(string.Format(LocalizableStrings.NoReferencesFound, CommonLocalizableStrings.P2P, projectArgument.Value));
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
catch (GracefulException e)
|
||||||
Reporter.Output.WriteLine($"{CommonLocalizableStrings.ProjectReferenceOneOrMore}");
|
|
||||||
Reporter.Output.WriteLine(new string('-', CommonLocalizableStrings.ProjectReferenceOneOrMore.Length));
|
|
||||||
foreach (var p2p in p2ps)
|
|
||||||
{
|
{
|
||||||
Reporter.Output.WriteLine(p2p.Include);
|
Reporter.Error.WriteLine(e.Message.Red());
|
||||||
|
app.ShowHelp();
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
try
|
return app;
|
||||||
{
|
|
||||||
return app.Execute(args);
|
|
||||||
}
|
|
||||||
catch (GracefulException e)
|
|
||||||
{
|
|
||||||
Reporter.Error.WriteLine(e.Message.Red());
|
|
||||||
app.ShowHelp();
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,23 +3,5 @@ namespace Microsoft.DotNet.Tools.Remove
|
||||||
internal class LocalizableStrings
|
internal class LocalizableStrings
|
||||||
{
|
{
|
||||||
public const string NetRemoveCommand = ".NET Remove Command";
|
public const string NetRemoveCommand = ".NET Remove Command";
|
||||||
|
|
||||||
public const string Usage = "Usage";
|
|
||||||
|
|
||||||
public const string Options = "Options";
|
|
||||||
|
|
||||||
public const string HelpDefinition = "Show help information";
|
|
||||||
|
|
||||||
public const string Arguments = "Arguments";
|
|
||||||
|
|
||||||
public const string ArgumentsObjectDefinition = "The object of the operation. If a project file is not specified, it defaults to the current directory.";
|
|
||||||
|
|
||||||
public const string ArgumentsCommandDefinition = "Command to be executed on <object>.";
|
|
||||||
|
|
||||||
public const string ArgsDefinition = "Any extra arguments passed to the command. Use `dotnet add <command> --help` to get help about these arguments.";
|
|
||||||
|
|
||||||
public const string Commands = "Commands";
|
|
||||||
|
|
||||||
public const string CommandP2PDefinition = "Remove project to project (p2p) reference from a project";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,47 +1,28 @@
|
||||||
// Copyright (c) .NET Foundation and contributors. All rights reserved.
|
// Copyright (c) .NET Foundation and contributors. All rights reserved.
|
||||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||||
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using Microsoft.DotNet.Cli.CommandLine;
|
|
||||||
using Microsoft.DotNet.Cli.Utils;
|
|
||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using Microsoft.DotNet.Cli;
|
||||||
using Microsoft.Build.Construction;
|
using Microsoft.DotNet.Cli.CommandLine;
|
||||||
using Microsoft.DotNet.ProjectJsonMigration;
|
|
||||||
using NuGet.Frameworks;
|
|
||||||
using Microsoft.DotNet.Tools.Remove.ProjectToProjectReference;
|
using Microsoft.DotNet.Tools.Remove.ProjectToProjectReference;
|
||||||
|
|
||||||
namespace Microsoft.DotNet.Tools.Remove
|
namespace Microsoft.DotNet.Tools.Remove
|
||||||
{
|
{
|
||||||
public class RemoveCommand : DispatchCommand
|
public class RemoveCommand : DotNetTopLevelCommandBase
|
||||||
{
|
{
|
||||||
protected override string HelpText => $@"{LocalizableStrings.NetRemoveCommand};
|
protected override string CommandName => "remove";
|
||||||
|
protected override string FullCommandNameLocalized => LocalizableStrings.NetRemoveCommand;
|
||||||
{LocalizableStrings.Usage}: dotnet remove [options] <object> <command> [[--] <arg>...]]
|
internal override List<Func<CommandLineApplication, CommandLineApplication>> SubCommands =>
|
||||||
|
new List<Func<CommandLineApplication, CommandLineApplication>>
|
||||||
{LocalizableStrings.Options}:
|
{
|
||||||
-h|--help {LocalizableStrings.HelpDefinition}
|
RemoveProjectToProjectReferenceCommand.CreateApplication,
|
||||||
|
};
|
||||||
{LocalizableStrings.Arguments}:
|
|
||||||
<object> {LocalizableStrings.ArgumentsObjectDefinition}
|
|
||||||
<command> {LocalizableStrings.ArgumentsCommandDefinition}
|
|
||||||
|
|
||||||
Args:
|
|
||||||
{LocalizableStrings.ArgsDefinition}
|
|
||||||
|
|
||||||
{LocalizableStrings.Commands}:
|
|
||||||
p2p {LocalizableStrings.CommandP2PDefinition}";
|
|
||||||
|
|
||||||
protected override Dictionary<string, Func<string[], int>> BuiltInCommands => new Dictionary<string, Func<string[], int>>
|
|
||||||
{
|
|
||||||
["p2p"] = RemoveProjectToProjectReferenceCommand.Run,
|
|
||||||
};
|
|
||||||
|
|
||||||
public static int Run(string[] args)
|
public static int Run(string[] args)
|
||||||
{
|
{
|
||||||
var cmd = new RemoveCommand();
|
var command = new RemoveCommand();
|
||||||
return cmd.Start(args);
|
return command.RunCommand(args);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,46 +6,10 @@ namespace Microsoft.DotNet.Tools.Remove.ProjectToProjectReference
|
||||||
|
|
||||||
public const string AppDescription = "Command to remove project to project (p2p) reference";
|
public const string AppDescription = "Command to remove project to project (p2p) reference";
|
||||||
|
|
||||||
public const string AppArgumentSeparatorHelpText = "Project to project references to remove";
|
public const string AppHelpText = "Project to project references to remove";
|
||||||
|
|
||||||
public const string CmdArgProject = "PROJECT";
|
|
||||||
|
|
||||||
public const string CmdArgumentDescription = "The project file to modify. If a project file is not specified, it searches the current working directory for an MSBuild file that has a file extension that ends in `proj` and uses that file.";
|
|
||||||
|
|
||||||
public const string CmdFramework = "FRAMEWORK";
|
|
||||||
|
|
||||||
public const string CmdFrameworkDescription = "Remove reference only when targetting a specific framework";
|
public const string CmdFrameworkDescription = "Remove reference only when targetting a specific framework";
|
||||||
|
|
||||||
public const string ProjectException = "Project";
|
|
||||||
|
|
||||||
public const string ReferenceNotFoundInTheProject = "Specified reference {0} does not exist in project {1}.";
|
|
||||||
|
|
||||||
public const string ReferenceRemoved = "Reference `{0}` deleted from the project.";
|
|
||||||
|
|
||||||
public const string SpecifyAtLeastOneReferenceToRemove = "You must specify at least one reference to delete. Please run dotnet delete --help for more information.";
|
public const string SpecifyAtLeastOneReferenceToRemove = "You must specify at least one reference to delete. Please run dotnet delete --help for more information.";
|
||||||
|
|
||||||
public const string ReferenceDeleted = "Reference `{0}` deleted.";
|
|
||||||
|
|
||||||
public const string SpecifyAtLeastOneReferenceToDelete = "You must specify at least one reference to delete. Please run dotnet delete --help for more information.";
|
|
||||||
|
|
||||||
public const string NetRemoveCommand = ".NET Remove Command";
|
|
||||||
|
|
||||||
public const string Usage = "Usage";
|
|
||||||
|
|
||||||
public const string Options = "Options";
|
|
||||||
|
|
||||||
public const string HelpDefinition = "Show help information";
|
|
||||||
|
|
||||||
public const string Arguments = "Arguments";
|
|
||||||
|
|
||||||
public const string ArgumentsObjectDefinition = "The object of the operation. If a project file is not specified, it defaults to the current directory.";
|
|
||||||
|
|
||||||
public const string ArgumentsCommandDefinition = "Command to be executed on <object>.";
|
|
||||||
|
|
||||||
public const string ArgsDefinition = "Any extra arguments passed to the command. Use `dotnet add <command> --help` to get help about these arguments.";
|
|
||||||
|
|
||||||
public const string Commands = "Commands";
|
|
||||||
|
|
||||||
public const string CommandP2PDefinition = "Remove project to project (p2p) reference from a project";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,73 +4,73 @@
|
||||||
using Microsoft.Build.Evaluation;
|
using Microsoft.Build.Evaluation;
|
||||||
using Microsoft.DotNet.Cli.CommandLine;
|
using Microsoft.DotNet.Cli.CommandLine;
|
||||||
using Microsoft.DotNet.Cli.Utils;
|
using Microsoft.DotNet.Cli.Utils;
|
||||||
|
using Microsoft.DotNet.Tools.Common;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
namespace Microsoft.DotNet.Tools.Remove.ProjectToProjectReference
|
namespace Microsoft.DotNet.Tools.Remove.ProjectToProjectReference
|
||||||
{
|
{
|
||||||
public class RemoveProjectToProjectReferenceCommand
|
public class RemoveProjectToProjectReferenceCommand
|
||||||
{
|
{
|
||||||
public static int Run(string[] args)
|
internal static CommandLineApplication CreateApplication(CommandLineApplication parentApp)
|
||||||
{
|
{
|
||||||
DebugHelper.HandleDebugSwitch(ref args);
|
CommandLineApplication app = parentApp.Command("p2p", throwOnUnexpectedArg: false);
|
||||||
|
app.FullName = LocalizableStrings.AppFullName;
|
||||||
CommandLineApplication app = new CommandLineApplication(throwOnUnexpectedArg: false)
|
app.Description = LocalizableStrings.AppDescription;
|
||||||
{
|
app.HandleRemainingArguments = true;
|
||||||
Name = "dotnet remove p2p",
|
app.ArgumentSeparatorHelpText = LocalizableStrings.AppHelpText;
|
||||||
FullName = LocalizableStrings.AppFullName,
|
|
||||||
Description = LocalizableStrings.AppDescription,
|
|
||||||
AllowArgumentSeparator = true,
|
|
||||||
ArgumentSeparatorHelpText = LocalizableStrings.AppArgumentSeparatorHelpText
|
|
||||||
};
|
|
||||||
|
|
||||||
app.HelpOption("-h|--help");
|
app.HelpOption("-h|--help");
|
||||||
|
|
||||||
CommandArgument projectArgument = app.Argument(
|
|
||||||
$"<{LocalizableStrings.CmdArgProject}>",
|
|
||||||
LocalizableStrings.CmdArgumentDescription);
|
|
||||||
|
|
||||||
CommandOption frameworkOption = app.Option(
|
CommandOption frameworkOption = app.Option(
|
||||||
$"-f|--framework <{LocalizableStrings.CmdFramework}>",
|
$"-f|--framework <{CommonLocalizableStrings.CmdFramework}>",
|
||||||
LocalizableStrings.CmdFrameworkDescription,
|
LocalizableStrings.CmdFrameworkDescription,
|
||||||
CommandOptionType.SingleValue);
|
CommandOptionType.SingleValue);
|
||||||
|
|
||||||
app.OnExecute(() => {
|
app.OnExecute(() => {
|
||||||
if (string.IsNullOrEmpty(projectArgument.Value))
|
try
|
||||||
{
|
{
|
||||||
throw new GracefulException(CommonLocalizableStrings.RequiredArgumentNotPassed, $"<{LocalizableStrings.ProjectException}>");
|
if (!parentApp.Arguments.Any())
|
||||||
|
{
|
||||||
|
throw new GracefulException(CommonLocalizableStrings.RequiredArgumentNotPassed, Constants.ProjectOrSolutionArgumentName);
|
||||||
|
}
|
||||||
|
|
||||||
|
var projectOrDirectory = parentApp.Arguments.First().Value;
|
||||||
|
if (string.IsNullOrEmpty(projectOrDirectory))
|
||||||
|
{
|
||||||
|
projectOrDirectory = PathUtility.EnsureTrailingSlash(Directory.GetCurrentDirectory());
|
||||||
|
}
|
||||||
|
|
||||||
|
var msbuildProj = MsbuildProject.FromFileOrDirectory(new ProjectCollection(), projectOrDirectory);
|
||||||
|
|
||||||
|
if (app.RemainingArguments.Count == 0)
|
||||||
|
{
|
||||||
|
throw new GracefulException(LocalizableStrings.SpecifyAtLeastOneReferenceToRemove);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<string> references = app.RemainingArguments;
|
||||||
|
|
||||||
|
int numberOfRemovedReferences = msbuildProj.RemoveProjectToProjectReferences(
|
||||||
|
frameworkOption.Value(),
|
||||||
|
references);
|
||||||
|
|
||||||
|
if (numberOfRemovedReferences != 0)
|
||||||
|
{
|
||||||
|
msbuildProj.ProjectRootElement.Save();
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
catch (GracefulException e)
|
||||||
var msbuildProj = MsbuildProject.FromFileOrDirectory(new ProjectCollection(), projectArgument.Value);
|
|
||||||
|
|
||||||
if (app.RemainingArguments.Count == 0)
|
|
||||||
{
|
{
|
||||||
throw new GracefulException(LocalizableStrings.SpecifyAtLeastOneReferenceToRemove);
|
Reporter.Error.WriteLine(e.Message.Red());
|
||||||
|
app.ShowHelp();
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
List<string> references = app.RemainingArguments;
|
|
||||||
|
|
||||||
int numberOfRemovedReferences = msbuildProj.RemoveProjectToProjectReferences(
|
|
||||||
frameworkOption.Value(),
|
|
||||||
references);
|
|
||||||
|
|
||||||
if (numberOfRemovedReferences != 0)
|
|
||||||
{
|
|
||||||
msbuildProj.ProjectRootElement.Save();
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
try
|
return app;
|
||||||
{
|
|
||||||
return app.Execute(args);
|
|
||||||
}
|
|
||||||
catch (GracefulException e)
|
|
||||||
{
|
|
||||||
Reporter.Error.WriteLine(e.Message.Red());
|
|
||||||
app.ShowHelp();
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -80,6 +80,16 @@ namespace Microsoft.DotNet.Cli.Add.P2P.Tests
|
||||||
cmd.StdOut.Should().Contain("Usage");
|
cmd.StdOut.Should().Contain("Usage");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void WhenTooManyArgumentsArePassedItPrintsError()
|
||||||
|
{
|
||||||
|
var cmd = new AddP2PCommand()
|
||||||
|
.WithProject("one two three")
|
||||||
|
.Execute("proj.csproj");
|
||||||
|
cmd.ExitCode.Should().NotBe(0);
|
||||||
|
cmd.StdErr.Should().Contain("Unrecognized command or argument");
|
||||||
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
[InlineData("idontexist.csproj")]
|
[InlineData("idontexist.csproj")]
|
||||||
[InlineData("ihave?inv@lid/char\\acters")]
|
[InlineData("ihave?inv@lid/char\\acters")]
|
||||||
|
@ -569,25 +579,6 @@ namespace Microsoft.DotNet.Cli.Add.P2P.Tests
|
||||||
lib.CsProjContent().Should().BeEquivalentTo(contentBefore);
|
lib.CsProjContent().Should().BeEquivalentTo(contentBefore);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void WhenPassedReferenceDoesNotExistAndForceSwitchIsPassedItAddsIt()
|
|
||||||
{
|
|
||||||
var lib = NewLibWithFrameworks();
|
|
||||||
const string nonExisting = "IDoNotExist.csproj";
|
|
||||||
|
|
||||||
int noCondBefore = lib.CsProj().NumberOfItemGroupsWithoutCondition();
|
|
||||||
var cmd = new AddP2PCommand()
|
|
||||||
.WithWorkingDirectory(lib.Path)
|
|
||||||
.WithProject(lib.CsProjName)
|
|
||||||
.Execute($"--force \"{nonExisting}\"");
|
|
||||||
cmd.Should().Pass();
|
|
||||||
cmd.StdOut.Should().Contain("added to the project");
|
|
||||||
cmd.StdErr.Should().BeEmpty();
|
|
||||||
var csproj = lib.CsProj();
|
|
||||||
csproj.NumberOfItemGroupsWithoutCondition().Should().Be(noCondBefore + 1);
|
|
||||||
csproj.NumberOfProjectReferencesWithIncludeContaining(nonExisting).Should().Be(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void WhenPassedReferenceIsUsingSlashesItNormalizesItToBackslashes()
|
public void WhenPassedReferenceIsUsingSlashesItNormalizesItToBackslashes()
|
||||||
{
|
{
|
||||||
|
@ -598,13 +589,13 @@ namespace Microsoft.DotNet.Cli.Add.P2P.Tests
|
||||||
var cmd = new AddP2PCommand()
|
var cmd = new AddP2PCommand()
|
||||||
.WithWorkingDirectory(lib.Path)
|
.WithWorkingDirectory(lib.Path)
|
||||||
.WithProject(lib.CsProjName)
|
.WithProject(lib.CsProjName)
|
||||||
.Execute($"--force \"{setup.ValidRefCsprojPath.Replace('\\', '/')}\"");
|
.Execute($"\"{setup.ValidRefCsprojPath.Replace('\\', '/')}\"");
|
||||||
cmd.Should().Pass();
|
cmd.Should().Pass();
|
||||||
cmd.StdOut.Should().Contain("added to the project");
|
cmd.StdOut.Should().Contain("added to the project");
|
||||||
cmd.StdErr.Should().BeEmpty();
|
cmd.StdErr.Should().BeEmpty();
|
||||||
var csproj = lib.CsProj();
|
var csproj = lib.CsProj();
|
||||||
csproj.NumberOfItemGroupsWithoutCondition().Should().Be(noCondBefore + 1);
|
csproj.NumberOfItemGroupsWithoutCondition().Should().Be(noCondBefore + 1);
|
||||||
csproj.NumberOfProjectReferencesWithIncludeContaining(setup.ValidRefCsprojPath.Replace('/', '\\')).Should().Be(1);
|
csproj.NumberOfProjectReferencesWithIncludeContaining(setup.ValidRefCsprojRelPath.Replace('/', '\\')).Should().Be(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
@ -626,25 +617,6 @@ namespace Microsoft.DotNet.Cli.Add.P2P.Tests
|
||||||
csproj.NumberOfProjectReferencesWithIncludeContaining(setup.ValidRefCsprojRelToOtherProjPath.Replace('/', '\\')).Should().Be(1);
|
csproj.NumberOfProjectReferencesWithIncludeContaining(setup.ValidRefCsprojRelToOtherProjPath.Replace('/', '\\')).Should().Be(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void WhenReferenceIsRelativeAndProjectIsNotInCurrentDirectoryAndForceSwitchIsPassedItDoesNotChangeIt()
|
|
||||||
{
|
|
||||||
var setup = Setup();
|
|
||||||
var proj = new ProjDir(setup.LibDir);
|
|
||||||
|
|
||||||
int noCondBefore = proj.CsProj().NumberOfItemGroupsWithoutCondition();
|
|
||||||
var cmd = new AddP2PCommand()
|
|
||||||
.WithWorkingDirectory(setup.TestRoot)
|
|
||||||
.WithProject(setup.LibCsprojPath)
|
|
||||||
.Execute($"--force \"{setup.ValidRefCsprojRelPath}\"");
|
|
||||||
cmd.Should().Pass();
|
|
||||||
cmd.StdOut.Should().Contain("added to the project");
|
|
||||||
cmd.StdErr.Should().BeEmpty();
|
|
||||||
var csproj = proj.CsProj();
|
|
||||||
csproj.NumberOfItemGroupsWithoutCondition().Should().Be(noCondBefore + 1);
|
|
||||||
csproj.NumberOfProjectReferencesWithIncludeContaining(setup.ValidRefCsprojRelPath.Replace('/', '\\')).Should().Be(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void ItCanAddReferenceWithConditionOnCompatibleFramework()
|
public void ItCanAddReferenceWithConditionOnCompatibleFramework()
|
||||||
{
|
{
|
||||||
|
|
|
@ -17,7 +17,7 @@ namespace Microsoft.DotNet.Cli.List.P2P.Tests
|
||||||
const string ConditionFrameworkNet451 = "== 'net451'";
|
const string ConditionFrameworkNet451 = "== 'net451'";
|
||||||
const string FrameworkNetCoreApp10Arg = "-f netcoreapp1.0";
|
const string FrameworkNetCoreApp10Arg = "-f netcoreapp1.0";
|
||||||
const string ConditionFrameworkNetCoreApp10 = "== 'netcoreapp1.0'";
|
const string ConditionFrameworkNetCoreApp10 = "== 'netcoreapp1.0'";
|
||||||
const string UsageText = "Usage: dotnet list p2ps";
|
const string UsageText = "Usage: dotnet list <PROJECT_OR_SOLUTION> p2ps";
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
[InlineData("--help")]
|
[InlineData("--help")]
|
||||||
|
@ -29,6 +29,16 @@ namespace Microsoft.DotNet.Cli.List.P2P.Tests
|
||||||
cmd.StdOut.Should().Contain("Usage");
|
cmd.StdOut.Should().Contain("Usage");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void WhenTooManyArgumentsArePassedItPrintsError()
|
||||||
|
{
|
||||||
|
var cmd = new AddP2PCommand()
|
||||||
|
.WithProject("one two three")
|
||||||
|
.Execute("proj.csproj");
|
||||||
|
cmd.ExitCode.Should().NotBe(0);
|
||||||
|
cmd.StdErr.Should().Contain("Unrecognized command or argument");
|
||||||
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
[InlineData("idontexist.csproj")]
|
[InlineData("idontexist.csproj")]
|
||||||
[InlineData("ihave?inv@lid/char\\acters")]
|
[InlineData("ihave?inv@lid/char\\acters")]
|
||||||
|
@ -101,38 +111,38 @@ namespace Microsoft.DotNet.Cli.List.P2P.Tests
|
||||||
[Fact]
|
[Fact]
|
||||||
public void ItPrintsSingleReference()
|
public void ItPrintsSingleReference()
|
||||||
{
|
{
|
||||||
var lib = NewLib();
|
var lib = NewLib("ItPrintsSingleReference", "lib");
|
||||||
string ref1 = "someref.csproj";
|
string ref1 = NewLib("ItPrintsSingleReference", "ref").CsProjPath;
|
||||||
AddFakeRef(ref1, lib);
|
AddValidRef(ref1, lib);
|
||||||
|
|
||||||
var cmd = new ListP2PsCommand()
|
var cmd = new ListP2PsCommand()
|
||||||
.WithProject(lib.CsProjPath)
|
.WithProject(lib.CsProjPath)
|
||||||
.Execute();
|
.Execute();
|
||||||
cmd.Should().Pass();
|
cmd.Should().Pass();
|
||||||
cmd.StdOut.Should().Contain("Project reference(s)");
|
cmd.StdOut.Should().Contain("Project reference(s)");
|
||||||
cmd.StdOut.Should().Contain(ref1);
|
cmd.StdOut.Should().Contain(@"..\ItPrintsSingleReferenceref\ItPrintsSingleReferenceref.csproj");
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void ItPrintsMultipleReferences()
|
public void ItPrintsMultipleReferences()
|
||||||
{
|
{
|
||||||
var lib = NewLib();
|
var lib = NewLib("ItPrintsSingleReference", "lib");
|
||||||
string ref1 = "someref.csproj";
|
string ref1 = NewLib("ItPrintsSingleReference", "ref1").CsProjPath;
|
||||||
string ref2 = @"..\someref2.csproj";
|
string ref2 = NewLib("ItPrintsSingleReference", "ref2").CsProjPath;
|
||||||
string ref3 = @"..\abc\abc.csproj";
|
string ref3 = NewLib("ItPrintsSingleReference", "ref3").CsProjPath;
|
||||||
|
|
||||||
AddFakeRef(ref1, lib);
|
AddValidRef(ref1, lib);
|
||||||
AddFakeRef(ref2, lib);
|
AddValidRef(ref2, lib);
|
||||||
AddFakeRef(ref3, lib);
|
AddValidRef(ref3, lib);
|
||||||
|
|
||||||
var cmd = new ListP2PsCommand()
|
var cmd = new ListP2PsCommand()
|
||||||
.WithProject(lib.CsProjPath)
|
.WithProject(lib.CsProjPath)
|
||||||
.Execute();
|
.Execute();
|
||||||
cmd.Should().Pass();
|
cmd.Should().Pass();
|
||||||
cmd.StdOut.Should().Contain("Project reference(s)");
|
cmd.StdOut.Should().Contain("Project reference(s)");
|
||||||
cmd.StdOut.Should().Contain(ref1);
|
cmd.StdOut.Should().Contain(@"..\ItPrintsSingleReferenceref1\ItPrintsSingleReferenceref1.csproj");
|
||||||
cmd.StdOut.Should().Contain(ref2);
|
cmd.StdOut.Should().Contain(@"..\ItPrintsSingleReferenceref2\ItPrintsSingleReferenceref2.csproj");
|
||||||
cmd.StdOut.Should().Contain(ref3);
|
cmd.StdOut.Should().Contain(@"..\ItPrintsSingleReferenceref3\ItPrintsSingleReferenceref3.csproj");
|
||||||
}
|
}
|
||||||
|
|
||||||
private TestSetup Setup([System.Runtime.CompilerServices.CallerMemberName] string callingMethod = nameof(Setup), string identifier = "")
|
private TestSetup Setup([System.Runtime.CompilerServices.CallerMemberName] string callingMethod = nameof(Setup), string identifier = "")
|
||||||
|
@ -169,11 +179,11 @@ namespace Microsoft.DotNet.Cli.List.P2P.Tests
|
||||||
return dir;
|
return dir;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void AddFakeRef(string path, ProjDir proj)
|
private void AddValidRef(string path, ProjDir proj)
|
||||||
{
|
{
|
||||||
new AddP2PCommand()
|
new AddP2PCommand()
|
||||||
.WithProject(proj.CsProjPath)
|
.WithProject(proj.CsProjPath)
|
||||||
.Execute($"--force \"{path}\"")
|
.Execute($"\"{path}\"")
|
||||||
.Should().Pass();
|
.Should().Pass();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -106,6 +106,16 @@ namespace Microsoft.DotNet.Cli.Remove.P2P.Tests
|
||||||
cmd.StdOut.Should().Contain("Usage");
|
cmd.StdOut.Should().Contain("Usage");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void WhenTooManyArgumentsArePassedItPrintsError()
|
||||||
|
{
|
||||||
|
var cmd = new AddP2PCommand()
|
||||||
|
.WithProject("one two three")
|
||||||
|
.Execute("proj.csproj");
|
||||||
|
cmd.ExitCode.Should().NotBe(0);
|
||||||
|
cmd.StdErr.Should().Contain("Unrecognized command or argument");
|
||||||
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
[InlineData("idontexist.csproj")]
|
[InlineData("idontexist.csproj")]
|
||||||
[InlineData("ihave?inv@lid/char\\acters")]
|
[InlineData("ihave?inv@lid/char\\acters")]
|
||||||
|
@ -356,7 +366,7 @@ namespace Microsoft.DotNet.Cli.Remove.P2P.Tests
|
||||||
{
|
{
|
||||||
var setup = Setup();
|
var setup = Setup();
|
||||||
var lib = GetLibRef(setup);
|
var lib = GetLibRef(setup);
|
||||||
var libref = AddValidRef(setup, lib, "--force");
|
var libref = AddValidRef(setup, lib);
|
||||||
|
|
||||||
int noCondBefore = lib.CsProj().NumberOfItemGroupsWithoutCondition();
|
int noCondBefore = lib.CsProj().NumberOfItemGroupsWithoutCondition();
|
||||||
var cmd = new RemoveP2PCommand()
|
var cmd = new RemoveP2PCommand()
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue