Merge pull request #5057 from dotnet/dev/jgoshi/removeProj
Implement dotnet remove project
This commit is contained in:
commit
9c3141b63f
33 changed files with 1141 additions and 541 deletions
|
@ -16,7 +16,7 @@
|
|||
|
||||
<ItemGroup>
|
||||
<Compile Include="**\*.cs" Exclude="bin\**;obj\**;**\*.xproj;packages\**" />
|
||||
<Compile Include="..\..\..\src\dotnet\CommandLine\*.cs" Exclude="bin\**;obj\**;**\*.xproj;packages\**" />
|
||||
<Compile Include="..\..\..\src\dotnet\CommandLine\*.cs;..\..\..\src\dotnet\CommonLocalizableStrings.cs;" Exclude="bin\**;obj\**;**\*.xproj;packages\**" />
|
||||
<EmbeddedResource Include="**\*.resx" />
|
||||
<EmbeddedResource Include="compiler\resources\**\*" />
|
||||
</ItemGroup>
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 15
|
||||
VisualStudioVersion = 15.0.26006.2
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "App", "App\App.csproj", "{7072A694-548F-4CAE-A58F-12D257D5F486}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Lib", "Lib\Lib.csproj", "{B38B1FA5-B4C9-456A-8B71-8FCD62ACF400}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Lib", "Lib\Lib.csproj", "{B38B1FA5-B4C9-456A-8B71-8FCD62ACF400}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Debug|x64 = Debug|x64
|
||||
Debug|x86 = Debug|x86
|
||||
Release|Any CPU = Release|Any CPU
|
||||
Release|x64 = Release|x64
|
||||
Release|x86 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{7072A694-548F-4CAE-A58F-12D257D5F486}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{7072A694-548F-4CAE-A58F-12D257D5F486}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{7072A694-548F-4CAE-A58F-12D257D5F486}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{7072A694-548F-4CAE-A58F-12D257D5F486}.Debug|x64.Build.0 = Debug|x64
|
||||
{7072A694-548F-4CAE-A58F-12D257D5F486}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{7072A694-548F-4CAE-A58F-12D257D5F486}.Debug|x86.Build.0 = Debug|x86
|
||||
{7072A694-548F-4CAE-A58F-12D257D5F486}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{7072A694-548F-4CAE-A58F-12D257D5F486}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{7072A694-548F-4CAE-A58F-12D257D5F486}.Release|x64.ActiveCfg = Release|x64
|
||||
{7072A694-548F-4CAE-A58F-12D257D5F486}.Release|x64.Build.0 = Release|x64
|
||||
{7072A694-548F-4CAE-A58F-12D257D5F486}.Release|x86.ActiveCfg = Release|x86
|
||||
{7072A694-548F-4CAE-A58F-12D257D5F486}.Release|x86.Build.0 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
|
@ -0,0 +1,19 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk" ToolsVersion="15.0">
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>netcoreapp1.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Include="**\*.cs" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Lib\Lib.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.NETCore.App" Version="1.0.1" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
|
@ -0,0 +1,10 @@
|
|||
using System;
|
||||
|
||||
class Program
|
||||
{
|
||||
static void Main(string[] args)
|
||||
{
|
||||
Console.WriteLine("Hello from the main app");
|
||||
Console.WriteLine(Lib.Library.GetMessage());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk" ToolsVersion="15.0">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netstandard1.4</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Include="**\*.cs" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="NETStandard.Library" Version="1.6" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
|
@ -0,0 +1,12 @@
|
|||
using System;
|
||||
|
||||
namespace Lib
|
||||
{
|
||||
public class Library
|
||||
{
|
||||
public static string GetMessage()
|
||||
{
|
||||
return "Message from Lib";
|
||||
}
|
||||
}
|
||||
}
|
|
@ -56,15 +56,34 @@ namespace Microsoft.DotNet.Cli.CommandLine
|
|||
public bool HandleRemainingArguments { get; set; }
|
||||
public string ArgumentSeparatorHelpText { get; set; }
|
||||
|
||||
public CommandLineApplication Command(string name, bool throwOnUnexpectedArg = true)
|
||||
public CommandLineApplication AddCommand(string name, bool throwOnUnexpectedArg = true)
|
||||
{
|
||||
return Command(name, _ => { }, throwOnUnexpectedArg);
|
||||
return AddCommand(name, _ => { }, throwOnUnexpectedArg);
|
||||
}
|
||||
|
||||
public CommandLineApplication Command(string name, Action<CommandLineApplication> configuration,
|
||||
public CommandLineApplication AddCommand(string name, Action<CommandLineApplication> configuration,
|
||||
bool throwOnUnexpectedArg = true)
|
||||
{
|
||||
var command = new CommandLineApplication(throwOnUnexpectedArg) { Name = name, Parent = this };
|
||||
var command = new CommandLineApplication(throwOnUnexpectedArg) { Name = name };
|
||||
return AddCommand(command, configuration, throwOnUnexpectedArg);
|
||||
}
|
||||
|
||||
public CommandLineApplication AddCommand(CommandLineApplication command, bool throwOnUnexpectedArg = true)
|
||||
{
|
||||
return AddCommand(command, _ => { }, throwOnUnexpectedArg);
|
||||
}
|
||||
|
||||
public CommandLineApplication AddCommand(
|
||||
CommandLineApplication command,
|
||||
Action<CommandLineApplication> configuration,
|
||||
bool throwOnUnexpectedArg = true)
|
||||
{
|
||||
if (command == null || configuration == null)
|
||||
{
|
||||
throw new NullReferenceException();
|
||||
}
|
||||
|
||||
command.Parent = this;
|
||||
Commands.Add(command);
|
||||
configuration(command);
|
||||
return command;
|
||||
|
|
|
@ -2,11 +2,14 @@
|
|||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
using System;
|
||||
using Microsoft.DotNet.Tools;
|
||||
|
||||
namespace Microsoft.DotNet.Cli.CommandLine
|
||||
{
|
||||
internal class CommandParsingException : Exception
|
||||
{
|
||||
private bool _isRequireSubCommandMissing;
|
||||
|
||||
public CommandParsingException(
|
||||
CommandLineApplication command,
|
||||
string message,
|
||||
|
@ -14,10 +17,19 @@ namespace Microsoft.DotNet.Cli.CommandLine
|
|||
: base(message)
|
||||
{
|
||||
Command = command;
|
||||
IsRequireSubCommandMissing = isRequireSubCommandMissing;
|
||||
_isRequireSubCommandMissing = isRequireSubCommandMissing;
|
||||
}
|
||||
|
||||
public CommandLineApplication Command { get; }
|
||||
public bool IsRequireSubCommandMissing { get; }
|
||||
|
||||
public override string Message
|
||||
{
|
||||
get
|
||||
{
|
||||
return _isRequireSubCommandMissing
|
||||
? CommonLocalizableStrings.RequiredCommandNotPassed
|
||||
: base.Message;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
16
src/dotnet/DotNetSubCommandBase.cs
Normal file
16
src/dotnet/DotNetSubCommandBase.cs
Normal 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;
|
||||
|
||||
namespace Microsoft.DotNet.Cli
|
||||
{
|
||||
internal abstract class DotNetSubCommandBase : CommandLineApplication
|
||||
{
|
||||
internal DotNetSubCommandBase() : base(throwOnUnexpectedArg: false)
|
||||
{
|
||||
}
|
||||
|
||||
public abstract int Run(string fileOrDirectory);
|
||||
}
|
||||
}
|
|
@ -3,10 +3,12 @@
|
|||
|
||||
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.Add.ProjectToProjectReference;
|
||||
using Microsoft.DotNet.Tools.Common;
|
||||
|
||||
namespace Microsoft.DotNet.Cli
|
||||
{
|
||||
|
@ -14,46 +16,67 @@ namespace Microsoft.DotNet.Cli
|
|||
{
|
||||
protected abstract string CommandName { get; }
|
||||
protected abstract string FullCommandNameLocalized { get; }
|
||||
internal abstract List<Func<CommandLineApplication, CommandLineApplication>> SubCommands { get; }
|
||||
internal abstract List<Func<DotNetSubCommandBase>> SubCommands { get; }
|
||||
|
||||
public int RunCommand(string[] args)
|
||||
{
|
||||
DebugHelper.HandleDebugSwitch(ref args);
|
||||
|
||||
CommandLineApplication app = new CommandLineApplication(throwOnUnexpectedArg: true)
|
||||
CommandLineApplication command = new CommandLineApplication(throwOnUnexpectedArg: true)
|
||||
{
|
||||
Name = $"dotnet {CommandName}",
|
||||
FullName = FullCommandNameLocalized,
|
||||
};
|
||||
|
||||
app.HelpOption("-h|--help");
|
||||
command.HelpOption("-h|--help");
|
||||
|
||||
app.Argument(
|
||||
command.Argument(
|
||||
Constants.ProjectOrSolutionArgumentName,
|
||||
CommonLocalizableStrings.ArgumentsProjectOrSolutionDescription);
|
||||
|
||||
foreach (var subCommandCreator in SubCommands)
|
||||
{
|
||||
subCommandCreator(app);
|
||||
var subCommand = subCommandCreator();
|
||||
command.AddCommand(subCommand);
|
||||
|
||||
subCommand.OnExecute(() => {
|
||||
try
|
||||
{
|
||||
if (!command.Arguments.Any())
|
||||
{
|
||||
throw new GracefulException(CommonLocalizableStrings.RequiredArgumentNotPassed, Constants.ProjectOrSolutionArgumentName);
|
||||
}
|
||||
|
||||
var projectOrDirectory = command.Arguments.First().Value;
|
||||
if (string.IsNullOrEmpty(projectOrDirectory))
|
||||
{
|
||||
projectOrDirectory = PathUtility.EnsureTrailingSlash(Directory.GetCurrentDirectory());
|
||||
}
|
||||
|
||||
return subCommand.Run(projectOrDirectory);
|
||||
}
|
||||
catch (GracefulException e)
|
||||
{
|
||||
Reporter.Error.WriteLine(e.Message.Red());
|
||||
subCommand.ShowHelp();
|
||||
return 1;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
return app.Execute(args);
|
||||
return command.Execute(args);
|
||||
}
|
||||
catch (GracefulException e)
|
||||
{
|
||||
Reporter.Error.WriteLine(e.Message.Red());
|
||||
app.ShowHelp();
|
||||
command.ShowHelp();
|
||||
return 1;
|
||||
}
|
||||
catch (CommandParsingException e)
|
||||
{
|
||||
string errorMessage = e.IsRequireSubCommandMissing
|
||||
? CommonLocalizableStrings.RequiredCommandNotPassed
|
||||
: e.Message;
|
||||
|
||||
Reporter.Error.WriteLine(errorMessage.Red());
|
||||
Reporter.Error.WriteLine(e.Message.Red());
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.DotNet.Cli;
|
||||
using Microsoft.DotNet.Cli.CommandLine;
|
||||
using Microsoft.DotNet.Tools.Add.ProjectToProjectReference;
|
||||
using Microsoft.DotNet.Tools.Add.ProjectToSolution;
|
||||
|
||||
|
@ -14,11 +13,11 @@ namespace Microsoft.DotNet.Tools.Add
|
|||
{
|
||||
protected override string CommandName => "add";
|
||||
protected override string FullCommandNameLocalized => LocalizableStrings.NetAddCommand;
|
||||
internal override List<Func<CommandLineApplication, CommandLineApplication>> SubCommands =>
|
||||
new List<Func<CommandLineApplication, CommandLineApplication>>
|
||||
internal override List<Func<DotNetSubCommandBase>> SubCommands =>
|
||||
new List<Func<DotNetSubCommandBase>>
|
||||
{
|
||||
AddProjectToSolutionCommand.CreateApplication,
|
||||
AddProjectToProjectReferenceCommand.CreateApplication,
|
||||
AddProjectToSolutionCommand.Create,
|
||||
AddProjectToProjectReferenceCommand.Create,
|
||||
};
|
||||
|
||||
public static int Run(string[] args)
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
using Microsoft.Build.Evaluation;
|
||||
using Microsoft.DotNet.Cli;
|
||||
using Microsoft.DotNet.Cli.CommandLine;
|
||||
using Microsoft.DotNet.Cli.Utils;
|
||||
using Microsoft.DotNet.Tools.Common;
|
||||
|
@ -13,111 +14,100 @@ using System.Text;
|
|||
|
||||
namespace Microsoft.DotNet.Tools.Add.ProjectToProjectReference
|
||||
{
|
||||
public class AddProjectToProjectReferenceCommand
|
||||
internal class AddProjectToProjectReferenceCommand : DotNetSubCommandBase
|
||||
{
|
||||
internal static CommandLineApplication CreateApplication(CommandLineApplication parentApp)
|
||||
private CommandOption _frameworkOption;
|
||||
|
||||
public static DotNetSubCommandBase Create()
|
||||
{
|
||||
CommandLineApplication app = parentApp.Command("p2p", throwOnUnexpectedArg: false);
|
||||
app.FullName = LocalizableStrings.AppFullName;
|
||||
app.Description = LocalizableStrings.AppDescription;
|
||||
app.HandleRemainingArguments = true;
|
||||
app.ArgumentSeparatorHelpText = LocalizableStrings.AppHelpText;
|
||||
|
||||
app.HelpOption("-h|--help");
|
||||
|
||||
CommandOption frameworkOption = app.Option(
|
||||
$"-f|--framework <{CommonLocalizableStrings.CmdFramework}>",
|
||||
LocalizableStrings.CmdFrameworkDescription,
|
||||
CommandOptionType.SingleValue);
|
||||
|
||||
app.OnExecute(() =>
|
||||
var command = new AddProjectToProjectReferenceCommand()
|
||||
{
|
||||
try
|
||||
Name = "p2p",
|
||||
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;
|
||||
}
|
||||
|
||||
public override int Run(string fileOrDirectory)
|
||||
{
|
||||
var projects = new ProjectCollection();
|
||||
MsbuildProject msbuildProj = MsbuildProject.FromFileOrDirectory(projects, fileOrDirectory);
|
||||
|
||||
if (RemainingArguments.Count == 0)
|
||||
{
|
||||
throw new GracefulException(CommonLocalizableStrings.SpecifyAtLeastOneReferenceToAdd);
|
||||
}
|
||||
|
||||
string frameworkString = _frameworkOption.Value();
|
||||
PathUtility.EnsureAllPathsExist(RemainingArguments, CommonLocalizableStrings.ReferenceDoesNotExist);
|
||||
List<MsbuildProject> refs = RemainingArguments
|
||||
.Select((r) => MsbuildProject.FromFile(projects, r))
|
||||
.ToList();
|
||||
|
||||
if (frameworkString == null)
|
||||
{
|
||||
foreach (var tfm in msbuildProj.GetTargetFrameworks())
|
||||
{
|
||||
if (!parentApp.Arguments.Any())
|
||||
foreach (var @ref in refs)
|
||||
{
|
||||
throw new GracefulException(CommonLocalizableStrings.RequiredArgumentNotPassed, Constants.ProjectOrSolutionArgumentName);
|
||||
}
|
||||
|
||||
var projectOrDirectory = parentApp.Arguments.First().Value;
|
||||
if (string.IsNullOrEmpty(projectOrDirectory))
|
||||
{
|
||||
projectOrDirectory = PathUtility.EnsureTrailingSlash(Directory.GetCurrentDirectory());
|
||||
}
|
||||
|
||||
var projects = new ProjectCollection();
|
||||
var msbuildProj = MsbuildProject.FromFileOrDirectory(projects, projectOrDirectory);
|
||||
|
||||
if (app.RemainingArguments.Count == 0)
|
||||
{
|
||||
throw new GracefulException(CommonLocalizableStrings.SpecifyAtLeastOneReferenceToAdd);
|
||||
}
|
||||
|
||||
string frameworkString = frameworkOption.Value();
|
||||
List<string> references = app.RemainingArguments;
|
||||
PathUtility.EnsureAllPathsExist(references, CommonLocalizableStrings.ReferenceDoesNotExist);
|
||||
IEnumerable<MsbuildProject> refs = references.Select((r) => MsbuildProject.FromFile(projects, r));
|
||||
|
||||
if (frameworkString == null)
|
||||
{
|
||||
foreach (var tfm in msbuildProj.GetTargetFrameworks())
|
||||
if (!@ref.CanWorkOnFramework(tfm))
|
||||
{
|
||||
foreach (var @ref in refs)
|
||||
{
|
||||
if (!@ref.CanWorkOnFramework(tfm))
|
||||
{
|
||||
Reporter.Error.Write(GetProjectNotCompatibleWithFrameworksDisplayString(
|
||||
@ref,
|
||||
msbuildProj.GetTargetFrameworks().Select((fx) => fx.GetShortFolderName())));
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var framework = NuGetFramework.Parse(frameworkString);
|
||||
if (!msbuildProj.IsTargettingFramework(framework))
|
||||
{
|
||||
Reporter.Error.WriteLine(string.Format(CommonLocalizableStrings.ProjectDoesNotTargetFramework, msbuildProj.ProjectRootElement.FullPath, frameworkString));
|
||||
Reporter.Error.Write(GetProjectNotCompatibleWithFrameworksDisplayString(
|
||||
@ref,
|
||||
msbuildProj.GetTargetFrameworks().Select((fx) => fx.GetShortFolderName())));
|
||||
return 1;
|
||||
}
|
||||
|
||||
foreach (var @ref in refs)
|
||||
{
|
||||
if (!@ref.CanWorkOnFramework(framework))
|
||||
{
|
||||
Reporter.Error.Write(GetProjectNotCompatibleWithFrameworksDisplayString(
|
||||
@ref,
|
||||
new string[] { frameworkString }));
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var relativePathReferences = references.Select((r) =>
|
||||
PathUtility.GetRelativePath(msbuildProj.ProjectDirectory, Path.GetFullPath(r))).ToList();
|
||||
|
||||
int numberOfAddedReferences = msbuildProj.AddProjectToProjectReferences(
|
||||
frameworkOption.Value(),
|
||||
relativePathReferences);
|
||||
|
||||
if (numberOfAddedReferences != 0)
|
||||
{
|
||||
msbuildProj.ProjectRootElement.Save();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
catch (GracefulException e)
|
||||
}
|
||||
else
|
||||
{
|
||||
var framework = NuGetFramework.Parse(frameworkString);
|
||||
if (!msbuildProj.IsTargettingFramework(framework))
|
||||
{
|
||||
Reporter.Error.WriteLine(e.Message.Red());
|
||||
app.ShowHelp();
|
||||
Reporter.Error.WriteLine(string.Format(
|
||||
CommonLocalizableStrings.ProjectDoesNotTargetFramework,
|
||||
msbuildProj.ProjectRootElement.FullPath,
|
||||
frameworkString));
|
||||
return 1;
|
||||
}
|
||||
});
|
||||
|
||||
return app;
|
||||
foreach (var @ref in refs)
|
||||
{
|
||||
if (!@ref.CanWorkOnFramework(framework))
|
||||
{
|
||||
Reporter.Error.Write(GetProjectNotCompatibleWithFrameworksDisplayString(
|
||||
@ref,
|
||||
new string[] { frameworkString }));
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var relativePathReferences = RemainingArguments.Select((r) =>
|
||||
PathUtility.GetRelativePath(msbuildProj.ProjectDirectory, Path.GetFullPath(r))).ToList();
|
||||
|
||||
int numberOfAddedReferences = msbuildProj.AddProjectToProjectReferences(
|
||||
_frameworkOption.Value(),
|
||||
relativePathReferences);
|
||||
|
||||
if (numberOfAddedReferences != 0)
|
||||
{
|
||||
msbuildProj.ProjectRootElement.Save();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
private static string GetProjectNotCompatibleWithFrameworksDisplayString(MsbuildProject project, IEnumerable<string> frameworksDisplayStrings)
|
||||
|
|
|
@ -3,83 +3,64 @@
|
|||
|
||||
using Microsoft.Build.Construction;
|
||||
using Microsoft.Build.Evaluation;
|
||||
using Microsoft.DotNet.Cli.CommandLine;
|
||||
using Microsoft.DotNet.Cli;
|
||||
using Microsoft.DotNet.Cli.Sln.Internal;
|
||||
using Microsoft.DotNet.Cli.Utils;
|
||||
using Microsoft.DotNet.Tools.Common;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
|
||||
namespace Microsoft.DotNet.Tools.Add.ProjectToSolution
|
||||
{
|
||||
public class AddProjectToSolutionCommand
|
||||
internal class AddProjectToSolutionCommand : DotNetSubCommandBase
|
||||
{
|
||||
internal static CommandLineApplication CreateApplication(CommandLineApplication parentApp)
|
||||
public static DotNetSubCommandBase Create()
|
||||
{
|
||||
CommandLineApplication app = parentApp.Command("project", throwOnUnexpectedArg: false);
|
||||
app.FullName = LocalizableStrings.AppFullName;
|
||||
app.Description = LocalizableStrings.AppDescription;
|
||||
app.HandleRemainingArguments = true;
|
||||
app.ArgumentSeparatorHelpText = LocalizableStrings.AppHelpText;
|
||||
|
||||
app.HelpOption("-h|--help");
|
||||
|
||||
app.OnExecute(() =>
|
||||
var command = new AddProjectToSolutionCommand()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!parentApp.Arguments.Any())
|
||||
{
|
||||
throw new GracefulException(CommonLocalizableStrings.RequiredArgumentNotPassed, Constants.ProjectOrSolutionArgumentName);
|
||||
}
|
||||
Name = "project",
|
||||
FullName = LocalizableStrings.AppFullName,
|
||||
Description = LocalizableStrings.AppDescription,
|
||||
HandleRemainingArguments = true,
|
||||
ArgumentSeparatorHelpText = LocalizableStrings.AppHelpText,
|
||||
};
|
||||
|
||||
var projectOrDirectory = parentApp.Arguments.First().Value;
|
||||
if (string.IsNullOrEmpty(projectOrDirectory))
|
||||
{
|
||||
projectOrDirectory = PathUtility.EnsureTrailingSlash(Directory.GetCurrentDirectory());
|
||||
}
|
||||
command.HelpOption("-h|--help");
|
||||
|
||||
SlnFile slnFile = SlnFileFactory.CreateFromFileOrDirectory(projectOrDirectory);
|
||||
|
||||
if (app.RemainingArguments.Count == 0)
|
||||
{
|
||||
throw new GracefulException(CommonLocalizableStrings.SpecifyAtLeastOneProjectToAdd);
|
||||
}
|
||||
|
||||
List<string> projectPaths = app.RemainingArguments;
|
||||
PathUtility.EnsureAllPathsExist(projectPaths, CommonLocalizableStrings.ProjectDoesNotExist);
|
||||
var relativeProjectPaths = projectPaths.Select((p) =>
|
||||
PathUtility.GetRelativePath(
|
||||
PathUtility.EnsureTrailingSlash(slnFile.BaseDirectory),
|
||||
Path.GetFullPath(p))).ToList();
|
||||
|
||||
int preAddProjectCount = slnFile.Projects.Count;
|
||||
foreach (var project in relativeProjectPaths)
|
||||
{
|
||||
AddProject(slnFile, project);
|
||||
}
|
||||
|
||||
if (slnFile.Projects.Count > preAddProjectCount)
|
||||
{
|
||||
slnFile.Write();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
catch (GracefulException e)
|
||||
{
|
||||
Reporter.Error.WriteLine(e.Message.Red());
|
||||
app.ShowHelp();
|
||||
return 1;
|
||||
}
|
||||
});
|
||||
|
||||
return app;
|
||||
return command;
|
||||
}
|
||||
|
||||
private static void AddProject(SlnFile slnFile, string projectPath)
|
||||
public override int Run(string fileOrDirectory)
|
||||
{
|
||||
SlnFile slnFile = SlnFileFactory.CreateFromFileOrDirectory(fileOrDirectory);
|
||||
|
||||
if (RemainingArguments.Count == 0)
|
||||
{
|
||||
throw new GracefulException(CommonLocalizableStrings.SpecifyAtLeastOneProjectToAdd);
|
||||
}
|
||||
|
||||
PathUtility.EnsureAllPathsExist(RemainingArguments, CommonLocalizableStrings.ProjectDoesNotExist);
|
||||
var relativeProjectPaths = RemainingArguments.Select((p) =>
|
||||
PathUtility.GetRelativePath(
|
||||
PathUtility.EnsureTrailingSlash(slnFile.BaseDirectory),
|
||||
Path.GetFullPath(p))).ToList();
|
||||
|
||||
int preAddProjectCount = slnFile.Projects.Count;
|
||||
foreach (var project in relativeProjectPaths)
|
||||
{
|
||||
AddProject(slnFile, project);
|
||||
}
|
||||
|
||||
if (slnFile.Projects.Count > preAddProjectCount)
|
||||
{
|
||||
slnFile.Write();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
private void AddProject(SlnFile slnFile, string projectPath)
|
||||
{
|
||||
var projectPathNormalized = PathUtility.GetPathWithBackSlashes(projectPath);
|
||||
|
||||
|
|
|
@ -1,13 +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;
|
||||
|
||||
namespace Microsoft.DotNet.Tools.List
|
||||
{
|
||||
public interface IListSubCommand
|
||||
{
|
||||
string LocalizedErrorMessageNoItemsFound { get; }
|
||||
IList<string> Items { get; }
|
||||
}
|
||||
}
|
|
@ -1,71 +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;
|
||||
using Microsoft.DotNet.Cli.Utils;
|
||||
using Microsoft.DotNet.Tools.Common;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
|
||||
namespace Microsoft.DotNet.Tools.List
|
||||
{
|
||||
public abstract class ListSubCommandBase
|
||||
{
|
||||
protected abstract string CommandName { get; }
|
||||
protected abstract string LocalizedDisplayName { get; }
|
||||
protected abstract string LocalizedDescription { get; }
|
||||
protected abstract IListSubCommand CreateIListSubCommand(string fileOrDirectory);
|
||||
|
||||
internal CommandLineApplication Create(CommandLineApplication parentApp)
|
||||
{
|
||||
CommandLineApplication app = parentApp.Command(CommandName, throwOnUnexpectedArg: false);
|
||||
app.FullName = LocalizedDisplayName;
|
||||
app.Description = LocalizedDescription;
|
||||
|
||||
app.HelpOption("-h|--help");
|
||||
|
||||
app.OnExecute(() => {
|
||||
try
|
||||
{
|
||||
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 listCommand = CreateIListSubCommand(projectOrDirectory);
|
||||
if (listCommand.Items.Count == 0)
|
||||
{
|
||||
Reporter.Output.WriteLine(listCommand.LocalizedErrorMessageNoItemsFound);
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reporter.Output.WriteLine($"{CommonLocalizableStrings.ProjectReferenceOneOrMore}");
|
||||
Reporter.Output.WriteLine(new string('-', CommonLocalizableStrings.ProjectReferenceOneOrMore.Length));
|
||||
foreach (var item in listCommand.Items)
|
||||
{
|
||||
Reporter.Output.WriteLine(item);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
catch (GracefulException e)
|
||||
{
|
||||
Reporter.Error.WriteLine(e.Message.Red());
|
||||
app.ShowHelp();
|
||||
return 1;
|
||||
}
|
||||
});
|
||||
|
||||
return app;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -4,7 +4,6 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.DotNet.Cli;
|
||||
using Microsoft.DotNet.Cli.CommandLine;
|
||||
using Microsoft.DotNet.Tools.List.ProjectToProjectReferences;
|
||||
using Microsoft.DotNet.Tools.List.ProjectsInSolution;
|
||||
|
||||
|
@ -14,11 +13,11 @@ namespace Microsoft.DotNet.Tools.List
|
|||
{
|
||||
protected override string CommandName => "list";
|
||||
protected override string FullCommandNameLocalized => LocalizableStrings.NetListCommand;
|
||||
internal override List<Func<CommandLineApplication, CommandLineApplication>> SubCommands =>
|
||||
new List<Func<CommandLineApplication, CommandLineApplication>>
|
||||
internal override List<Func<DotNetSubCommandBase>> SubCommands =>
|
||||
new List<Func<DotNetSubCommandBase>>
|
||||
{
|
||||
ListProjectsInSolutionCommand.CreateApplication,
|
||||
ListProjectToProjectReferencesCommand.CreateApplication,
|
||||
ListProjectsInSolutionCommand.Create,
|
||||
ListProjectToProjectReferencesCommand.Create,
|
||||
};
|
||||
|
||||
public static int Run(string[] args)
|
||||
|
|
|
@ -2,52 +2,50 @@
|
|||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
using Microsoft.Build.Evaluation;
|
||||
using Microsoft.DotNet.Cli.CommandLine;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.DotNet.Tools.List;
|
||||
using Microsoft.DotNet.Cli;
|
||||
using Microsoft.DotNet.Cli.Utils;
|
||||
using System.Linq;
|
||||
|
||||
namespace Microsoft.DotNet.Tools.List.ProjectToProjectReferences
|
||||
{
|
||||
public class ListProjectToProjectReferences : IListSubCommand
|
||||
internal class ListProjectToProjectReferencesCommand : DotNetSubCommandBase
|
||||
{
|
||||
private string _fileOrDirectory = null;
|
||||
private IList<string> _items = new List<string>();
|
||||
|
||||
public ListProjectToProjectReferences(string fileOrDirectory)
|
||||
public static DotNetSubCommandBase Create()
|
||||
{
|
||||
var command = new ListProjectToProjectReferencesCommand()
|
||||
{
|
||||
Name = "p2ps",
|
||||
FullName = LocalizableStrings.AppFullName,
|
||||
Description = LocalizableStrings.AppDescription,
|
||||
};
|
||||
|
||||
command.HelpOption("-h|--help");
|
||||
|
||||
return command;
|
||||
}
|
||||
|
||||
public override int Run(string fileOrDirectory)
|
||||
{
|
||||
_fileOrDirectory = fileOrDirectory;
|
||||
var msbuildProj = MsbuildProject.FromFileOrDirectory(new ProjectCollection(), fileOrDirectory);
|
||||
|
||||
var p2ps = msbuildProj.GetProjectToProjectReferences();
|
||||
if (!p2ps.Any())
|
||||
{
|
||||
Reporter.Output.WriteLine(string.Format(
|
||||
CommonLocalizableStrings.NoReferencesFound,
|
||||
CommonLocalizableStrings.P2P,
|
||||
fileOrDirectory));
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reporter.Output.WriteLine($"{CommonLocalizableStrings.ProjectReferenceOneOrMore}");
|
||||
Reporter.Output.WriteLine(new string('-', CommonLocalizableStrings.ProjectReferenceOneOrMore.Length));
|
||||
foreach (var p2p in p2ps)
|
||||
{
|
||||
_items.Add(p2p.Include);
|
||||
Reporter.Output.WriteLine(p2p.Include);
|
||||
}
|
||||
}
|
||||
|
||||
public string LocalizedErrorMessageNoItemsFound => string.Format(
|
||||
LocalizableStrings.NoReferencesFound,
|
||||
CommonLocalizableStrings.P2P,
|
||||
_fileOrDirectory);
|
||||
|
||||
public IList<string> Items => _items;
|
||||
}
|
||||
|
||||
public class ListProjectToProjectReferencesCommand : ListSubCommandBase
|
||||
{
|
||||
protected override string CommandName => "p2ps";
|
||||
protected override string LocalizedDisplayName => LocalizableStrings.AppFullName;
|
||||
protected override string LocalizedDescription => LocalizableStrings.AppDescription;
|
||||
|
||||
protected override IListSubCommand CreateIListSubCommand(string fileOrDirectory)
|
||||
{
|
||||
return new ListProjectToProjectReferences(fileOrDirectory);
|
||||
}
|
||||
|
||||
internal static CommandLineApplication CreateApplication(CommandLineApplication parentApp)
|
||||
{
|
||||
var command = new ListProjectToProjectReferencesCommand();
|
||||
return command.Create(parentApp);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,46 +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 Microsoft.DotNet.Cli.CommandLine;
|
||||
using Microsoft.DotNet.Cli;
|
||||
using Microsoft.DotNet.Cli.Sln.Internal;
|
||||
using Microsoft.DotNet.Cli.Utils;
|
||||
using Microsoft.DotNet.Tools.Common;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.DotNet.Tools.List;
|
||||
|
||||
namespace Microsoft.DotNet.Tools.List.ProjectsInSolution
|
||||
{
|
||||
public class ListProjectsInSolution : IListSubCommand
|
||||
internal class ListProjectsInSolutionCommand : DotNetSubCommandBase
|
||||
{
|
||||
private IList<string> _items = new List<string>();
|
||||
public static DotNetSubCommandBase Create()
|
||||
{
|
||||
var command = new ListProjectsInSolutionCommand()
|
||||
{
|
||||
Name = "projects",
|
||||
FullName = LocalizableStrings.AppFullName,
|
||||
Description = LocalizableStrings.AppDescription,
|
||||
};
|
||||
|
||||
public ListProjectsInSolution(string fileOrDirectory)
|
||||
command.HelpOption("-h|--help");
|
||||
|
||||
return command;
|
||||
}
|
||||
|
||||
public override int Run(string fileOrDirectory)
|
||||
{
|
||||
SlnFile slnFile = SlnFileFactory.CreateFromFileOrDirectory(fileOrDirectory);
|
||||
foreach (var slnProject in slnFile.Projects)
|
||||
if (slnFile.Projects.Count == 0)
|
||||
{
|
||||
_items.Add(slnProject.FilePath);
|
||||
Reporter.Output.WriteLine(CommonLocalizableStrings.NoProjectsFound);
|
||||
}
|
||||
}
|
||||
|
||||
public string LocalizedErrorMessageNoItemsFound => CommonLocalizableStrings.NoProjectsFound;
|
||||
public IList<string> Items => _items;
|
||||
}
|
||||
|
||||
public class ListProjectsInSolutionCommand : ListSubCommandBase
|
||||
{
|
||||
protected override string CommandName => "projects";
|
||||
protected override string LocalizedDisplayName => LocalizableStrings.AppFullName;
|
||||
protected override string LocalizedDescription => LocalizableStrings.AppDescription;
|
||||
|
||||
protected override IListSubCommand CreateIListSubCommand(string fileOrDirectory)
|
||||
{
|
||||
return new ListProjectsInSolution(fileOrDirectory);
|
||||
}
|
||||
|
||||
internal static CommandLineApplication CreateApplication(CommandLineApplication parentApp)
|
||||
{
|
||||
var command = new ListProjectsInSolutionCommand();
|
||||
return command.Create(parentApp);
|
||||
else
|
||||
{
|
||||
Reporter.Output.WriteLine($"{CommonLocalizableStrings.ProjectReferenceOneOrMore}");
|
||||
Reporter.Output.WriteLine(new string('-', CommonLocalizableStrings.ProjectReferenceOneOrMore.Length));
|
||||
foreach (var slnProject in slnFile.Projects)
|
||||
{
|
||||
Reporter.Output.WriteLine(slnProject.FilePath);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.DotNet.Cli;
|
||||
using Microsoft.DotNet.Cli.CommandLine;
|
||||
using Microsoft.DotNet.Tools.Remove.ProjectFromSolution;
|
||||
using Microsoft.DotNet.Tools.Remove.ProjectToProjectReference;
|
||||
|
||||
namespace Microsoft.DotNet.Tools.Remove
|
||||
|
@ -13,10 +13,11 @@ namespace Microsoft.DotNet.Tools.Remove
|
|||
{
|
||||
protected override string CommandName => "remove";
|
||||
protected override string FullCommandNameLocalized => LocalizableStrings.NetRemoveCommand;
|
||||
internal override List<Func<CommandLineApplication, CommandLineApplication>> SubCommands =>
|
||||
new List<Func<CommandLineApplication, CommandLineApplication>>
|
||||
internal override List<Func<DotNetSubCommandBase>> SubCommands =>
|
||||
new List<Func<DotNetSubCommandBase>>
|
||||
{
|
||||
RemoveProjectToProjectReferenceCommand.CreateApplication,
|
||||
RemoveProjectFromSolutionCommand.Create,
|
||||
RemoveProjectToProjectReferenceCommand.Create,
|
||||
};
|
||||
|
||||
public static int Run(string[] args)
|
||||
|
|
|
@ -12,7 +12,5 @@ namespace Microsoft.DotNet.Tools.Remove.ProjectToProjectReference
|
|||
public const string AppHelpText = "Project to project references to remove";
|
||||
|
||||
public const string CmdFrameworkDescription = "Remove reference only when targetting a specific framework";
|
||||
|
||||
public const string SpecifyAtLeastOneReferenceToRemove = "You must specify at least one reference to delete. Please run dotnet delete --help for more information.";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,75 +2,55 @@
|
|||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
using Microsoft.Build.Evaluation;
|
||||
using Microsoft.DotNet.Cli;
|
||||
using Microsoft.DotNet.Cli.CommandLine;
|
||||
using Microsoft.DotNet.Cli.Utils;
|
||||
using Microsoft.DotNet.Tools.Common;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
|
||||
namespace Microsoft.DotNet.Tools.Remove.ProjectToProjectReference
|
||||
{
|
||||
public class RemoveProjectToProjectReferenceCommand
|
||||
internal class RemoveProjectToProjectReferenceCommand : DotNetSubCommandBase
|
||||
{
|
||||
internal static CommandLineApplication CreateApplication(CommandLineApplication parentApp)
|
||||
private CommandOption _frameworkOption;
|
||||
|
||||
public static DotNetSubCommandBase Create()
|
||||
{
|
||||
CommandLineApplication app = parentApp.Command("p2p", throwOnUnexpectedArg: false);
|
||||
app.FullName = LocalizableStrings.AppFullName;
|
||||
app.Description = LocalizableStrings.AppDescription;
|
||||
app.HandleRemainingArguments = true;
|
||||
app.ArgumentSeparatorHelpText = LocalizableStrings.AppHelpText;
|
||||
var command = new RemoveProjectToProjectReferenceCommand()
|
||||
{
|
||||
Name = "p2p",
|
||||
FullName = LocalizableStrings.AppFullName,
|
||||
Description = LocalizableStrings.AppDescription,
|
||||
HandleRemainingArguments = true,
|
||||
ArgumentSeparatorHelpText = LocalizableStrings.AppHelpText,
|
||||
};
|
||||
|
||||
app.HelpOption("-h|--help");
|
||||
command.HelpOption("-h|--help");
|
||||
|
||||
CommandOption frameworkOption = app.Option(
|
||||
$"-f|--framework <{CommonLocalizableStrings.CmdFramework}>",
|
||||
LocalizableStrings.CmdFrameworkDescription,
|
||||
CommandOptionType.SingleValue);
|
||||
command._frameworkOption = command.Option(
|
||||
$"-f|--framework <{CommonLocalizableStrings.CmdFramework}>",
|
||||
LocalizableStrings.CmdFrameworkDescription,
|
||||
CommandOptionType.SingleValue);
|
||||
|
||||
app.OnExecute(() => {
|
||||
try
|
||||
{
|
||||
if (!parentApp.Arguments.Any())
|
||||
{
|
||||
throw new GracefulException(CommonLocalizableStrings.RequiredArgumentNotPassed, Constants.ProjectOrSolutionArgumentName);
|
||||
}
|
||||
return command;
|
||||
}
|
||||
|
||||
var projectOrDirectory = parentApp.Arguments.First().Value;
|
||||
if (string.IsNullOrEmpty(projectOrDirectory))
|
||||
{
|
||||
projectOrDirectory = PathUtility.EnsureTrailingSlash(Directory.GetCurrentDirectory());
|
||||
}
|
||||
public override int Run(string fileOrDirectory)
|
||||
{
|
||||
var msbuildProj = MsbuildProject.FromFileOrDirectory(new ProjectCollection(), fileOrDirectory);
|
||||
if (RemainingArguments.Count == 0)
|
||||
{
|
||||
throw new GracefulException(CommonLocalizableStrings.SpecifyAtLeastOneReferenceToRemove);
|
||||
}
|
||||
|
||||
var msbuildProj = MsbuildProject.FromFileOrDirectory(new ProjectCollection(), projectOrDirectory);
|
||||
int numberOfRemovedReferences = msbuildProj.RemoveProjectToProjectReferences(
|
||||
_frameworkOption.Value(),
|
||||
RemainingArguments);
|
||||
|
||||
if (app.RemainingArguments.Count == 0)
|
||||
{
|
||||
throw new GracefulException(LocalizableStrings.SpecifyAtLeastOneReferenceToRemove);
|
||||
}
|
||||
if (numberOfRemovedReferences != 0)
|
||||
{
|
||||
msbuildProj.ProjectRootElement.Save();
|
||||
}
|
||||
|
||||
List<string> references = app.RemainingArguments;
|
||||
|
||||
int numberOfRemovedReferences = msbuildProj.RemoveProjectToProjectReferences(
|
||||
frameworkOption.Value(),
|
||||
references);
|
||||
|
||||
if (numberOfRemovedReferences != 0)
|
||||
{
|
||||
msbuildProj.ProjectRootElement.Save();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
catch (GracefulException e)
|
||||
{
|
||||
Reporter.Error.WriteLine(e.Message.Red());
|
||||
app.ShowHelp();
|
||||
return 1;
|
||||
}
|
||||
});
|
||||
|
||||
return app;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +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.
|
||||
|
||||
namespace Microsoft.DotNet.Tools.Remove.ProjectFromSolution
|
||||
{
|
||||
internal class LocalizableStrings
|
||||
{
|
||||
public const string AppFullName = ".NET Remove Project from Solution Command";
|
||||
|
||||
public const string AppDescription = "Command to remove projects from a solution";
|
||||
|
||||
public const string AppHelpText = "Projects to remove from a solution";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,89 @@
|
|||
// 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;
|
||||
using Microsoft.DotNet.Cli.Sln.Internal;
|
||||
using Microsoft.DotNet.Cli.Utils;
|
||||
using Microsoft.DotNet.Tools.Common;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
|
||||
namespace Microsoft.DotNet.Tools.Remove.ProjectFromSolution
|
||||
{
|
||||
internal class RemoveProjectFromSolutionCommand : DotNetSubCommandBase
|
||||
{
|
||||
public static DotNetSubCommandBase Create()
|
||||
{
|
||||
var command = new RemoveProjectFromSolutionCommand()
|
||||
{
|
||||
Name = "project",
|
||||
FullName = LocalizableStrings.AppFullName,
|
||||
Description = LocalizableStrings.AppDescription,
|
||||
HandleRemainingArguments = true,
|
||||
ArgumentSeparatorHelpText = LocalizableStrings.AppHelpText,
|
||||
};
|
||||
|
||||
command.HelpOption("-h|--help");
|
||||
|
||||
return command;
|
||||
}
|
||||
|
||||
public override int Run(string fileOrDirectory)
|
||||
{
|
||||
SlnFile slnFile = SlnFileFactory.CreateFromFileOrDirectory(fileOrDirectory);
|
||||
|
||||
if (RemainingArguments.Count == 0)
|
||||
{
|
||||
throw new GracefulException(CommonLocalizableStrings.SpecifyAtLeastOneProjectToRemove);
|
||||
}
|
||||
|
||||
var relativeProjectPaths = RemainingArguments.Select((p) =>
|
||||
PathUtility.GetRelativePath(
|
||||
PathUtility.EnsureTrailingSlash(slnFile.BaseDirectory),
|
||||
Path.GetFullPath(p))).ToList();
|
||||
|
||||
bool slnChanged = false;
|
||||
foreach (var path in relativeProjectPaths)
|
||||
{
|
||||
slnChanged |= RemoveProject(slnFile, path);
|
||||
}
|
||||
|
||||
if (slnChanged)
|
||||
{
|
||||
slnFile.Write();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
private bool RemoveProject(SlnFile slnFile, string projectPath)
|
||||
{
|
||||
var projectPathNormalized = PathUtility.GetPathWithBackSlashes(projectPath);
|
||||
|
||||
var projectsToRemove = slnFile.Projects.Where((p) =>
|
||||
string.Equals(p.FilePath, projectPathNormalized, StringComparison.OrdinalIgnoreCase)).ToList();
|
||||
|
||||
bool projectRemoved = false;
|
||||
if (projectsToRemove.Count == 0)
|
||||
{
|
||||
Reporter.Output.WriteLine(string.Format(
|
||||
CommonLocalizableStrings.ProjectReferenceCouldNotBeFound,
|
||||
projectPath));
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var slnProject in projectsToRemove)
|
||||
{
|
||||
slnFile.Projects.Remove(slnProject);
|
||||
Reporter.Output.WriteLine(
|
||||
string.Format(CommonLocalizableStrings.ProjectReferenceRemoved, slnProject.FilePath));
|
||||
}
|
||||
|
||||
projectRemoved = true;
|
||||
}
|
||||
|
||||
return projectRemoved;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -14,6 +14,21 @@ namespace Microsoft.DotNet.Cli.Add.P2P.Tests
|
|||
{
|
||||
public class GivenDotnetAddP2P : TestBase
|
||||
{
|
||||
private const string HelpText = @".NET Add Project to Project (p2p) reference Command
|
||||
|
||||
Usage: dotnet add <PROJECT_OR_SOLUTION> p2p [options] [args]
|
||||
|
||||
Arguments:
|
||||
<PROJECT_OR_SOLUTION> The project or solution to operation on. If a file is not specified, the current directory is searched.
|
||||
|
||||
Options:
|
||||
-h|--help Show help information
|
||||
-f|--framework <FRAMEWORK> Add reference only when targetting a specific framework
|
||||
|
||||
Args:
|
||||
Project to project references to add
|
||||
";
|
||||
|
||||
const string FrameworkNet451Arg = "-f net451";
|
||||
const string ConditionFrameworkNet451 = "== 'net451'";
|
||||
const string FrameworkNetCoreApp10Arg = "-f netcoreapp1.0";
|
||||
|
@ -77,7 +92,18 @@ namespace Microsoft.DotNet.Cli.Add.P2P.Tests
|
|||
{
|
||||
var cmd = new AddP2PCommand().Execute(helpArg);
|
||||
cmd.Should().Pass();
|
||||
cmd.StdOut.Should().Contain("Usage");
|
||||
cmd.StdOut.Should().Be(HelpText);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("")]
|
||||
[InlineData("unknownCommandName")]
|
||||
public void WhenNoCommandIsPassedItPrintsError(string commandName)
|
||||
{
|
||||
var cmd = new DotnetCommand()
|
||||
.ExecuteWithCapturedOutput($"add {commandName}");
|
||||
cmd.Should().Fail();
|
||||
cmd.StdErr.Should().Be("Required command was not provided.");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
@ -87,7 +113,8 @@ namespace Microsoft.DotNet.Cli.Add.P2P.Tests
|
|||
.WithProject("one two three")
|
||||
.Execute("proj.csproj");
|
||||
cmd.ExitCode.Should().NotBe(0);
|
||||
cmd.StdErr.Should().Contain("Unrecognized command or argument");
|
||||
cmd.StdErr.Should().Be("Unrecognized command or argument 'two'");
|
||||
cmd.StdOut.Should().Be("Specify --help for a list of available options and commands.");
|
||||
}
|
||||
|
||||
[Theory]
|
||||
|
@ -102,8 +129,8 @@ namespace Microsoft.DotNet.Cli.Add.P2P.Tests
|
|||
.WithProject(projName)
|
||||
.Execute($"\"{setup.ValidRefCsprojPath}\"");
|
||||
cmd.ExitCode.Should().NotBe(0);
|
||||
cmd.StdErr.Should().Contain("Could not find");
|
||||
cmd.StdOut.Should().Contain("Usage");
|
||||
cmd.StdErr.Should().Be($"Could not find project or directory `{projName}`.");
|
||||
cmd.StdOut.Should().Be(HelpText);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
@ -117,8 +144,8 @@ namespace Microsoft.DotNet.Cli.Add.P2P.Tests
|
|||
.WithProject(projName)
|
||||
.Execute($"\"{setup.ValidRefCsprojPath}\"");
|
||||
cmd.ExitCode.Should().NotBe(0);
|
||||
cmd.StdErr.Should().Contain(" is invalid.");
|
||||
cmd.StdOut.Should().Contain("Usage");
|
||||
cmd.StdErr.Should().Be("Project `Broken/Broken.csproj` is invalid.");
|
||||
cmd.StdOut.Should().Be(HelpText);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
@ -126,12 +153,13 @@ namespace Microsoft.DotNet.Cli.Add.P2P.Tests
|
|||
{
|
||||
var setup = Setup();
|
||||
|
||||
var workingDir = Path.Combine(setup.TestRoot, "MoreThanOne");
|
||||
var cmd = new AddP2PCommand()
|
||||
.WithWorkingDirectory(Path.Combine(setup.TestRoot, "MoreThanOne"))
|
||||
.WithWorkingDirectory(workingDir)
|
||||
.Execute($"\"{setup.ValidRefCsprojRelToOtherProjPath}\"");
|
||||
cmd.ExitCode.Should().NotBe(0);
|
||||
cmd.StdErr.Should().Contain("more than one");
|
||||
cmd.StdOut.Should().Contain("Usage");
|
||||
cmd.StdErr.Should().Be($"Found more than one project in `{workingDir + Path.DirectorySeparatorChar}`. Please specify which one to use.");
|
||||
cmd.StdOut.Should().Be(HelpText);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
@ -143,8 +171,8 @@ namespace Microsoft.DotNet.Cli.Add.P2P.Tests
|
|||
.WithWorkingDirectory(setup.TestRoot)
|
||||
.Execute($"\"{setup.ValidRefCsprojPath}\"");
|
||||
cmd.ExitCode.Should().NotBe(0);
|
||||
cmd.StdErr.Should().Contain("not find any");
|
||||
cmd.StdOut.Should().Contain("Usage");
|
||||
cmd.StdErr.Should().Be($"Could not find any project in `{setup.TestRoot + Path.DirectorySeparatorChar}`.");
|
||||
cmd.StdOut.Should().Be(HelpText);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
@ -152,14 +180,14 @@ namespace Microsoft.DotNet.Cli.Add.P2P.Tests
|
|||
{
|
||||
var lib = NewLibWithFrameworks();
|
||||
var setup = Setup();
|
||||
|
||||
|
||||
int noCondBefore = lib.CsProj().NumberOfItemGroupsWithoutCondition();
|
||||
var cmd = new AddP2PCommand()
|
||||
.WithWorkingDirectory(setup.TestRoot)
|
||||
.WithProject(lib.CsProjPath)
|
||||
.Execute($"\"{setup.ValidRefCsprojPath}\"");
|
||||
cmd.Should().Pass();
|
||||
cmd.StdOut.Should().Contain("added to the project");
|
||||
cmd.StdOut.Should().Be("Reference `DotnetAddP2PProjects\\ValidRef\\ValidRef.csproj` added to the project.");
|
||||
cmd.StdErr.Should().BeEmpty();
|
||||
var csproj = lib.CsProj();
|
||||
csproj.NumberOfItemGroupsWithoutCondition().Should().Be(noCondBefore + 1);
|
||||
|
@ -178,7 +206,7 @@ namespace Microsoft.DotNet.Cli.Add.P2P.Tests
|
|||
.WithProject(lib.CsProjPath)
|
||||
.Execute($"{FrameworkNet451Arg} \"{setup.ValidRefCsprojPath}\"");
|
||||
cmd.Should().Pass();
|
||||
cmd.StdOut.Should().Contain("added to the project");
|
||||
cmd.StdOut.Should().Be("Reference `DotnetAddP2PProjects\\ValidRef\\ValidRef.csproj` added to the project.");
|
||||
cmd.StdErr.Should().BeEmpty();
|
||||
var csproj = lib.CsProj();
|
||||
csproj.NumberOfItemGroupsWithConditionContaining(ConditionFrameworkNet451).Should().Be(condBefore + 1);
|
||||
|
@ -203,7 +231,7 @@ namespace Microsoft.DotNet.Cli.Add.P2P.Tests
|
|||
.WithProject(lib.CsProjName)
|
||||
.Execute($"\"{setup.ValidRefCsprojPath}\"");
|
||||
cmd.Should().Pass();
|
||||
cmd.StdOut.Should().Contain("added to the project");
|
||||
cmd.StdOut.Should().Be("Reference `DotnetAddP2PProjects\\ValidRef\\ValidRef.csproj` added to the project.");
|
||||
var csproj = lib.CsProj();
|
||||
csproj.NumberOfItemGroupsWithoutCondition().Should().Be(noCondBefore);
|
||||
csproj.NumberOfProjectReferencesWithIncludeContaining(setup.ValidRefCsprojName).Should().Be(1);
|
||||
|
@ -227,7 +255,7 @@ namespace Microsoft.DotNet.Cli.Add.P2P.Tests
|
|||
.WithProject(lib.CsProjPath)
|
||||
.Execute($"{FrameworkNet451Arg} \"{setup.ValidRefCsprojPath}\"");
|
||||
cmd.Should().Pass();
|
||||
cmd.StdOut.Should().Contain("added to the project");
|
||||
cmd.StdOut.Should().Be("Reference `DotnetAddP2PProjects\\ValidRef\\ValidRef.csproj` added to the project.");
|
||||
var csproj = lib.CsProj();
|
||||
csproj.NumberOfItemGroupsWithConditionContaining(ConditionFrameworkNet451).Should().Be(condBefore);
|
||||
csproj.NumberOfProjectReferencesWithIncludeAndConditionContaining(setup.ValidRefCsprojName, ConditionFrameworkNet451).Should().Be(1);
|
||||
|
@ -251,7 +279,7 @@ namespace Microsoft.DotNet.Cli.Add.P2P.Tests
|
|||
.WithProject(lib.CsProjPath)
|
||||
.Execute($"{FrameworkNet451Arg} \"{setup.ValidRefCsprojPath}\"");
|
||||
cmd.Should().Pass();
|
||||
cmd.StdOut.Should().Contain("added to the project");
|
||||
cmd.StdOut.Should().Be("Reference `DotnetAddP2PProjects\\ValidRef\\ValidRef.csproj` added to the project.");
|
||||
var csproj = lib.CsProj();
|
||||
csproj.NumberOfItemGroupsWithConditionContaining(ConditionFrameworkNet451).Should().Be(condBefore + 1);
|
||||
csproj.NumberOfProjectReferencesWithIncludeAndConditionContaining(setup.ValidRefCsprojName, ConditionFrameworkNet451).Should().Be(1);
|
||||
|
@ -275,7 +303,7 @@ namespace Microsoft.DotNet.Cli.Add.P2P.Tests
|
|||
.WithProject(lib.CsProjPath)
|
||||
.Execute($"\"{setup.ValidRefCsprojPath}\"");
|
||||
cmd.Should().Pass();
|
||||
|
||||
cmd.StdOut.Should().Be("Reference `DotnetAddP2PProjects\\ValidRef\\ValidRef.csproj` added to the project.");
|
||||
var csproj = lib.CsProj();
|
||||
csproj.NumberOfItemGroupsWithoutCondition().Should().Be(noCondBefore + 1);
|
||||
csproj.NumberOfProjectReferencesWithIncludeContaining(setup.ValidRefCsprojName).Should().Be(1);
|
||||
|
@ -299,7 +327,7 @@ namespace Microsoft.DotNet.Cli.Add.P2P.Tests
|
|||
.WithProject(lib.CsProjName)
|
||||
.Execute($"\"{setup.ValidRefCsprojPath}\"");
|
||||
cmd.Should().Pass();
|
||||
cmd.StdOut.Should().Contain("already has a reference");
|
||||
cmd.StdOut.Should().Be("Project already has a reference to `DotnetAddP2PProjects\\ValidRef\\ValidRef.csproj`.");
|
||||
|
||||
var csproj = lib.CsProj();
|
||||
csproj.NumberOfItemGroupsWithoutCondition().Should().Be(noCondBefore);
|
||||
|
@ -318,7 +346,7 @@ namespace Microsoft.DotNet.Cli.Add.P2P.Tests
|
|||
.WithProject(proj.CsProjPath)
|
||||
.Execute($"{FrameworkNet451Arg} \"{setup.LibCsprojRelPath}\"");
|
||||
cmd.Should().Pass();
|
||||
cmd.StdOut.Should().Contain("already has a reference");
|
||||
cmd.StdOut.Should().Be("Project already has a reference to `..\\Lib\\Lib.csproj`.");
|
||||
proj.CsProjContent().Should().BeEquivalentTo(contentBefore);
|
||||
}
|
||||
|
||||
|
@ -340,7 +368,7 @@ namespace Microsoft.DotNet.Cli.Add.P2P.Tests
|
|||
.WithProject(lib.CsProjPath)
|
||||
.Execute($"{FrameworkNet451Arg} \"{setup.ValidRefCsprojPath}\"");
|
||||
cmd.Should().Pass();
|
||||
cmd.StdOut.Should().Contain("already has a reference");
|
||||
cmd.StdOut.Should().Be("Project already has a reference to `DotnetAddP2PProjects\\ValidRef\\ValidRef.csproj`.");
|
||||
lib.CsProjContent().Should().BeEquivalentTo(csprojContentBefore);
|
||||
}
|
||||
|
||||
|
@ -356,7 +384,7 @@ namespace Microsoft.DotNet.Cli.Add.P2P.Tests
|
|||
.WithProject(proj.CsProjName)
|
||||
.Execute($"{FrameworkNet451Arg} \"{setup.LibCsprojRelPath}\"");
|
||||
cmd.Should().Pass();
|
||||
cmd.StdOut.Should().Contain("already has a reference");
|
||||
cmd.StdOut.Should().Be("Project already has a reference to `..\\Lib\\Lib.csproj`.");
|
||||
proj.CsProjContent().Should().BeEquivalentTo(contentBefore);
|
||||
}
|
||||
|
||||
|
@ -372,7 +400,7 @@ namespace Microsoft.DotNet.Cli.Add.P2P.Tests
|
|||
.WithProject(proj.CsProjName)
|
||||
.Execute($"\"{setup.LibCsprojRelPath}\"");
|
||||
cmd.Should().Pass();
|
||||
cmd.StdOut.Should().Contain("already has a reference");
|
||||
cmd.StdOut.Should().Be("Project already has a reference to `..\\Lib\\Lib.csproj`.");
|
||||
proj.CsProjContent().Should().BeEquivalentTo(contentBefore);
|
||||
}
|
||||
|
||||
|
@ -388,7 +416,7 @@ namespace Microsoft.DotNet.Cli.Add.P2P.Tests
|
|||
.WithProject(proj.CsProjPath)
|
||||
.Execute($"\"{setup.ValidRefCsprojPath}\"");
|
||||
cmd.Should().Pass();
|
||||
cmd.StdOut.Should().Contain("added to the project");
|
||||
cmd.StdOut.Should().Be("Reference `..\\ValidRef\\ValidRef.csproj` added to the project.");
|
||||
var csproj = proj.CsProj();
|
||||
csproj.NumberOfItemGroupsWithoutCondition().Should().Be(noCondBefore + 1);
|
||||
csproj.NumberOfProjectReferencesWithIncludeContaining(setup.ValidRefCsprojName).Should().Be(1);
|
||||
|
@ -406,7 +434,7 @@ namespace Microsoft.DotNet.Cli.Add.P2P.Tests
|
|||
.WithProject(proj.CsProjName)
|
||||
.Execute($"{FrameworkNet451Arg} \"{setup.LibCsprojRelPath}\"");
|
||||
cmd.Should().Pass();
|
||||
cmd.StdOut.Should().Contain("already has a reference");
|
||||
cmd.StdOut.Should().Be("Project already has a reference to `..\\Lib\\Lib.csproj`.");
|
||||
proj.CsProjContent().Should().BeEquivalentTo(contentBefore);
|
||||
}
|
||||
|
||||
|
@ -422,7 +450,7 @@ namespace Microsoft.DotNet.Cli.Add.P2P.Tests
|
|||
.WithProject(proj.CsProjPath)
|
||||
.Execute($"{FrameworkNet451Arg} \"{setup.ValidRefCsprojPath}\"");
|
||||
cmd.Should().Pass();
|
||||
cmd.StdOut.Should().Contain("added to the project");
|
||||
cmd.StdOut.Should().Be("Reference `..\\ValidRef\\ValidRef.csproj` added to the project.");
|
||||
var csproj = proj.CsProj();
|
||||
csproj.NumberOfItemGroupsWithConditionContaining(ConditionFrameworkNet451).Should().Be(condBefore + 1);
|
||||
csproj.NumberOfProjectReferencesWithIncludeAndConditionContaining(setup.ValidRefCsprojName, ConditionFrameworkNet451).Should().Be(1);
|
||||
|
@ -440,7 +468,7 @@ namespace Microsoft.DotNet.Cli.Add.P2P.Tests
|
|||
.WithProject(proj.CsProjPath)
|
||||
.Execute($"\"{setup.ValidRefCsprojPath}\"");
|
||||
cmd.Should().Pass();
|
||||
cmd.StdOut.Should().Contain("added to the project");
|
||||
cmd.StdOut.Should().Be("Reference `..\\ValidRef\\ValidRef.csproj` added to the project.");
|
||||
var csproj = proj.CsProj();
|
||||
csproj.NumberOfItemGroupsWithoutCondition().Should().Be(noCondBefore);
|
||||
csproj.NumberOfProjectReferencesWithIncludeContaining(setup.ValidRefCsprojName).Should().Be(1);
|
||||
|
@ -449,6 +477,9 @@ namespace Microsoft.DotNet.Cli.Add.P2P.Tests
|
|||
[Fact]
|
||||
public void ItAddsMultipleRefsNoCondToTheSameItemGroup()
|
||||
{
|
||||
const string OutputText = @"Reference `DotnetAddP2PProjects\Lib\Lib.csproj` added to the project.
|
||||
Reference `DotnetAddP2PProjects\ValidRef\ValidRef.csproj` added to the project.";
|
||||
|
||||
var lib = NewLibWithFrameworks();
|
||||
var setup = Setup();
|
||||
|
||||
|
@ -458,7 +489,7 @@ namespace Microsoft.DotNet.Cli.Add.P2P.Tests
|
|||
.WithProject(lib.CsProjPath)
|
||||
.Execute($"\"{setup.LibCsprojPath}\" \"{setup.ValidRefCsprojPath}\"");
|
||||
cmd.Should().Pass();
|
||||
cmd.StdOut.Should().Contain("added to the project").And.NotContain("already has a reference");
|
||||
cmd.StdOut.Should().Be(OutputText);
|
||||
var csproj = lib.CsProj();
|
||||
csproj.NumberOfItemGroupsWithoutCondition().Should().Be(noCondBefore + 1);
|
||||
csproj.NumberOfProjectReferencesWithIncludeContaining(setup.ValidRefCsprojName).Should().Be(1);
|
||||
|
@ -468,6 +499,9 @@ namespace Microsoft.DotNet.Cli.Add.P2P.Tests
|
|||
[Fact]
|
||||
public void ItAddsMultipleRefsWithCondToTheSameItemGroup()
|
||||
{
|
||||
const string OutputText = @"Reference `DotnetAddP2PProjects\Lib\Lib.csproj` added to the project.
|
||||
Reference `DotnetAddP2PProjects\ValidRef\ValidRef.csproj` added to the project.";
|
||||
|
||||
var lib = NewLibWithFrameworks();
|
||||
var setup = Setup();
|
||||
|
||||
|
@ -477,7 +511,7 @@ namespace Microsoft.DotNet.Cli.Add.P2P.Tests
|
|||
.WithProject(lib.CsProjPath)
|
||||
.Execute($"{FrameworkNet451Arg} \"{setup.LibCsprojPath}\" \"{setup.ValidRefCsprojPath}\"");
|
||||
cmd.Should().Pass();
|
||||
cmd.StdOut.Should().Contain("added to the project").And.NotContain("already has a reference");
|
||||
cmd.StdOut.Should().Be(OutputText);
|
||||
var csproj = lib.CsProj();
|
||||
csproj.NumberOfItemGroupsWithConditionContaining(ConditionFrameworkNet451).Should().Be(noCondBefore + 1);
|
||||
csproj.NumberOfProjectReferencesWithIncludeAndConditionContaining(setup.ValidRefCsprojName, ConditionFrameworkNet451).Should().Be(1);
|
||||
|
@ -495,7 +529,7 @@ namespace Microsoft.DotNet.Cli.Add.P2P.Tests
|
|||
.WithWorkingDirectory(lib.Path)
|
||||
.Execute($"\"{setup.ValidRefCsprojPath}\"");
|
||||
cmd.Should().Pass();
|
||||
cmd.StdOut.Should().Contain("added to the project");
|
||||
cmd.StdOut.Should().Be("Reference `DotnetAddP2PProjects\\ValidRef\\ValidRef.csproj` added to the project.");
|
||||
cmd.StdErr.Should().BeEmpty();
|
||||
var csproj = lib.CsProj();
|
||||
csproj.NumberOfItemGroupsWithoutCondition().Should().Be(noCondBefore + 1);
|
||||
|
@ -513,7 +547,7 @@ namespace Microsoft.DotNet.Cli.Add.P2P.Tests
|
|||
.WithProject(lib.CsProjName)
|
||||
.Execute($"\"{setup.ValidRefCsprojPath}\"");
|
||||
cmd.Should().Pass();
|
||||
cmd.StdOut.Should().Contain("added to the project");
|
||||
cmd.StdOut.Should().Be("Reference `DotnetAddP2PProjects\\ValidRef\\ValidRef.csproj` added to the project.");
|
||||
cmd.StdErr.Should().BeEmpty();
|
||||
|
||||
int state = 0;
|
||||
|
@ -558,7 +592,7 @@ namespace Microsoft.DotNet.Cli.Add.P2P.Tests
|
|||
.WithProject(lib.CsProjName)
|
||||
.Execute("\"IDoNotExist.csproj\"");
|
||||
cmd.Should().Fail();
|
||||
cmd.StdErr.Should().Contain("does not exist");
|
||||
cmd.StdErr.Should().Be("Reference IDoNotExist.csproj does not exist.");
|
||||
lib.CsProjContent().Should().BeEquivalentTo(contentBefore);
|
||||
}
|
||||
|
||||
|
@ -574,8 +608,7 @@ namespace Microsoft.DotNet.Cli.Add.P2P.Tests
|
|||
.WithProject(lib.CsProjPath)
|
||||
.Execute($"\"{setup.ValidRefCsprojPath}\" \"IDoNotExist.csproj\"");
|
||||
cmd.Should().Fail();
|
||||
cmd.StdErr.Should().Contain("does not exist");
|
||||
cmd.StdErr.Should().NotMatchRegex("(.*does not exist.*){2,}");
|
||||
cmd.StdErr.Should().Be("Reference IDoNotExist.csproj does not exist.");
|
||||
lib.CsProjContent().Should().BeEquivalentTo(contentBefore);
|
||||
}
|
||||
|
||||
|
@ -591,7 +624,7 @@ namespace Microsoft.DotNet.Cli.Add.P2P.Tests
|
|||
.WithProject(lib.CsProjName)
|
||||
.Execute($"\"{setup.ValidRefCsprojPath.Replace('\\', '/')}\"");
|
||||
cmd.Should().Pass();
|
||||
cmd.StdOut.Should().Contain("added to the project");
|
||||
cmd.StdOut.Should().Be("Reference `DotnetAddP2PProjects\\ValidRef\\ValidRef.csproj` added to the project.");
|
||||
cmd.StdErr.Should().BeEmpty();
|
||||
var csproj = lib.CsProj();
|
||||
csproj.NumberOfItemGroupsWithoutCondition().Should().Be(noCondBefore + 1);
|
||||
|
@ -610,7 +643,7 @@ namespace Microsoft.DotNet.Cli.Add.P2P.Tests
|
|||
.WithProject(setup.LibCsprojPath)
|
||||
.Execute($"\"{setup.ValidRefCsprojRelPath}\"");
|
||||
cmd.Should().Pass();
|
||||
cmd.StdOut.Should().Contain("added to the project");
|
||||
cmd.StdOut.Should().Be("Reference `..\\ValidRef\\ValidRef.csproj` added to the project.");
|
||||
cmd.StdErr.Should().BeEmpty();
|
||||
var csproj = proj.CsProj();
|
||||
csproj.NumberOfItemGroupsWithoutCondition().Should().Be(noCondBefore + 1);
|
||||
|
@ -629,7 +662,7 @@ namespace Microsoft.DotNet.Cli.Add.P2P.Tests
|
|||
.WithProject(lib.CsProjPath)
|
||||
.Execute($"{FrameworkNet451Arg} \"{net45lib.CsProjPath}\"");
|
||||
cmd.Should().Pass();
|
||||
cmd.StdOut.Should().Contain("added to the project");
|
||||
cmd.StdOut.Should().Be("Reference `..\\Net45Lib\\Net45Lib.csproj` added to the project.");
|
||||
var csproj = lib.CsProj();
|
||||
csproj.NumberOfItemGroupsWithConditionContaining(ConditionFrameworkNet451).Should().Be(condBefore + 1);
|
||||
csproj.NumberOfProjectReferencesWithIncludeAndConditionContaining(net45lib.CsProjName, ConditionFrameworkNet451).Should().Be(1);
|
||||
|
@ -647,7 +680,7 @@ namespace Microsoft.DotNet.Cli.Add.P2P.Tests
|
|||
.WithProject(net452netcoreapp10lib.CsProjPath)
|
||||
.Execute($"\"{lib.CsProjPath}\"");
|
||||
cmd.Should().Pass();
|
||||
cmd.StdOut.Should().Contain("added to the project");
|
||||
cmd.StdOut.Should().Be("Reference `..\\Lib\\Lib.csproj` added to the project.");
|
||||
var csproj = net452netcoreapp10lib.CsProj();
|
||||
csproj.NumberOfItemGroupsWithoutCondition().Should().Be(noCondBefore + 1);
|
||||
csproj.NumberOfProjectReferencesWithIncludeContaining(lib.CsProjName).Should().Be(1);
|
||||
|
@ -669,8 +702,8 @@ namespace Microsoft.DotNet.Cli.Add.P2P.Tests
|
|||
.WithProject(lib.CsProjPath)
|
||||
.Execute($"-f {framework} \"{net45lib.CsProjPath}\"");
|
||||
cmd.Should().Fail();
|
||||
cmd.StdErr.Should().MatchRegex(ProjectDoesNotTargetFrameworkErrorMessageRegEx);
|
||||
cmd.StdErr.Should().Contain($"`{framework}`");
|
||||
cmd.StdErr.Should().Be($"Project `{setup.LibCsprojPath}` does not target framework `{framework}`.");
|
||||
|
||||
lib.CsProjContent().Should().BeEquivalentTo(csProjContent);
|
||||
}
|
||||
|
||||
|
|
|
@ -14,6 +14,20 @@ namespace Microsoft.DotNet.Cli.Add.Proj.Tests
|
|||
{
|
||||
public class GivenDotnetAddProj : TestBase
|
||||
{
|
||||
private string HelpText = @".NET Add Project to Solution Command
|
||||
|
||||
Usage: dotnet add <PROJECT_OR_SOLUTION> project [options] [args]
|
||||
|
||||
Arguments:
|
||||
<PROJECT_OR_SOLUTION> The project or solution to operation on. If a file is not specified, the current directory is searched.
|
||||
|
||||
Options:
|
||||
-h|--help Show help information
|
||||
|
||||
Args:
|
||||
Projects to add to solution
|
||||
";
|
||||
|
||||
[Theory]
|
||||
[InlineData("--help")]
|
||||
[InlineData("-h")]
|
||||
|
@ -22,7 +36,18 @@ namespace Microsoft.DotNet.Cli.Add.Proj.Tests
|
|||
var cmd = new DotnetCommand()
|
||||
.ExecuteWithCapturedOutput($"add project {helpArg}");
|
||||
cmd.Should().Pass();
|
||||
cmd.StdOut.Should().Contain("Usage");
|
||||
cmd.StdOut.Should().Be(HelpText);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("")]
|
||||
[InlineData("unknownCommandName")]
|
||||
public void WhenNoCommandIsPassedItPrintsError(string commandName)
|
||||
{
|
||||
var cmd = new DotnetCommand()
|
||||
.ExecuteWithCapturedOutput($"add {commandName}");
|
||||
cmd.Should().Fail();
|
||||
cmd.StdErr.Should().Be("Required command was not provided.");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
@ -31,7 +56,8 @@ namespace Microsoft.DotNet.Cli.Add.Proj.Tests
|
|||
var cmd = new DotnetCommand()
|
||||
.ExecuteWithCapturedOutput("add one.sln two.sln three.sln project");
|
||||
cmd.Should().Fail();
|
||||
cmd.StdErr.Should().Contain("Unrecognized command or argument");
|
||||
cmd.StdErr.Should().Be("Unrecognized command or argument 'two.sln'");
|
||||
cmd.StdOut.Should().Be("Specify --help for a list of available options and commands.");
|
||||
}
|
||||
|
||||
[Theory]
|
||||
|
@ -45,86 +71,103 @@ namespace Microsoft.DotNet.Cli.Add.Proj.Tests
|
|||
var cmd = new DotnetCommand()
|
||||
.ExecuteWithCapturedOutput($"add {solutionName} project p.csproj");
|
||||
cmd.Should().Fail();
|
||||
cmd.StdErr.Should().Contain("Could not find");
|
||||
cmd.StdOut.Should().Contain("Usage:");
|
||||
cmd.StdErr.Should().Be($"Could not find solution or directory `{solutionName}`.");
|
||||
cmd.StdOut.Should().Be(HelpText);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void WhenInvalidSolutionIsPassedItPrintsErrorAndUsage()
|
||||
{
|
||||
var projectDirectory = TestAssetsManager.CreateTestInstance("InvalidSolution")
|
||||
.WithLockFiles()
|
||||
.Path;
|
||||
var projectDirectory = TestAssets
|
||||
.Get("InvalidSolution")
|
||||
.CreateInstance()
|
||||
.WithSourceFiles()
|
||||
.Root
|
||||
.FullName;
|
||||
|
||||
var projectToAdd = Path.Combine("Lib", "Lib.csproj");
|
||||
var cmd = new DotnetCommand()
|
||||
.WithWorkingDirectory(projectDirectory)
|
||||
.ExecuteWithCapturedOutput($"add InvalidSolution.sln project {projectToAdd}");
|
||||
cmd.Should().Fail();
|
||||
cmd.StdErr.Should().Contain("Invalid solution ");
|
||||
cmd.StdOut.Should().Contain("Usage:");
|
||||
cmd.StdErr.Should().Be("Invalid solution `InvalidSolution.sln`.");
|
||||
cmd.StdOut.Should().Be(HelpText);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void WhenInvalidSolutionIsFoundItPrintsErrorAndUsage()
|
||||
{
|
||||
var projectDirectory = TestAssetsManager.CreateTestInstance("InvalidSolution")
|
||||
.WithLockFiles()
|
||||
.Path;
|
||||
var projectDirectory = TestAssets
|
||||
.Get("InvalidSolution")
|
||||
.CreateInstance()
|
||||
.WithSourceFiles()
|
||||
.Root
|
||||
.FullName;
|
||||
|
||||
var solutionPath = Path.Combine(projectDirectory, "InvalidSolution.sln");
|
||||
var projectToAdd = Path.Combine("Lib", "Lib.csproj");
|
||||
var cmd = new DotnetCommand()
|
||||
.WithWorkingDirectory(projectDirectory)
|
||||
.ExecuteWithCapturedOutput($"add project {projectToAdd}");
|
||||
cmd.Should().Fail();
|
||||
cmd.StdErr.Should().Contain("Invalid solution ");
|
||||
cmd.StdOut.Should().Contain("Usage:");
|
||||
cmd.StdErr.Should().Be($"Invalid solution `{solutionPath}`.");
|
||||
cmd.StdOut.Should().Be(HelpText);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void WhenNoProjectIsPassedItPrintsErrorAndUsage()
|
||||
{
|
||||
var projectDirectory = TestAssetsManager.CreateTestInstance("TestAppWithSlnAndCsprojFiles")
|
||||
.WithLockFiles()
|
||||
.Path;
|
||||
var projectDirectory = TestAssets
|
||||
.Get("TestAppWithSlnAndCsprojFiles")
|
||||
.CreateInstance()
|
||||
.WithSourceFiles()
|
||||
.Root
|
||||
.FullName;
|
||||
|
||||
var cmd = new DotnetCommand()
|
||||
.WithWorkingDirectory(projectDirectory)
|
||||
.ExecuteWithCapturedOutput(@"add App.sln project");
|
||||
cmd.Should().Fail();
|
||||
cmd.StdErr.Should().Contain("You must specify at least one project to add.");
|
||||
cmd.StdOut.Should().Contain("Usage:");
|
||||
cmd.StdErr.Should().Be("You must specify at least one project to add.");
|
||||
cmd.StdOut.Should().Be(HelpText);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void WhenNoSolutionExistsInTheDirectoryItPrintsErrorAndUsage()
|
||||
{
|
||||
var projectDirectory = TestAssetsManager.CreateTestInstance("TestAppWithSlnAndCsprojFiles")
|
||||
.WithLockFiles()
|
||||
.Path;
|
||||
var projectDirectory = TestAssets
|
||||
.Get("TestAppWithSlnAndCsprojFiles")
|
||||
.CreateInstance()
|
||||
.WithSourceFiles()
|
||||
.Root
|
||||
.FullName;
|
||||
|
||||
var solutionPath = Path.Combine(projectDirectory, "App");
|
||||
var cmd = new DotnetCommand()
|
||||
.WithWorkingDirectory(Path.Combine(projectDirectory, "App"))
|
||||
.WithWorkingDirectory(solutionPath)
|
||||
.ExecuteWithCapturedOutput(@"add project App.csproj");
|
||||
cmd.Should().Fail();
|
||||
cmd.StdErr.Should().Contain("does not exist");
|
||||
cmd.StdOut.Should().Contain("Usage:");
|
||||
cmd.StdErr.Should().Be($"Specified solution file {solutionPath + Path.DirectorySeparatorChar} does not exist, or there is no solution file in the directory.");
|
||||
cmd.StdOut.Should().Be(HelpText);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void WhenMoreThanOneSolutionExistsInTheDirectoryItPrintsErrorAndUsage()
|
||||
{
|
||||
var projectDirectory = TestAssetsManager.CreateTestInstance("TestAppWithMultipleSlnFiles")
|
||||
.WithLockFiles()
|
||||
.Path;
|
||||
var projectDirectory = TestAssets
|
||||
.Get("TestAppWithMultipleSlnFiles")
|
||||
.CreateInstance()
|
||||
.WithSourceFiles()
|
||||
.Root
|
||||
.FullName;
|
||||
|
||||
var projectToAdd = Path.Combine("Lib", "Lib.csproj");
|
||||
var cmd = new DotnetCommand()
|
||||
.WithWorkingDirectory(projectDirectory)
|
||||
.ExecuteWithCapturedOutput($"add project {projectToAdd}");
|
||||
cmd.Should().Fail();
|
||||
cmd.StdErr.Should().Contain("more than one");
|
||||
cmd.StdOut.Should().Contain("Usage");
|
||||
cmd.StdErr.Should().Be($"Found more than one solution file in {projectDirectory + Path.DirectorySeparatorChar}. Please specify which one to use.");
|
||||
cmd.StdOut.Should().Be(HelpText);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
|
@ -134,9 +177,12 @@ namespace Microsoft.DotNet.Cli.Add.Proj.Tests
|
|||
string testAsset,
|
||||
string projectGuid)
|
||||
{
|
||||
var projectDirectory = TestAssetsManager.CreateTestInstance(testAsset)
|
||||
.WithLockFiles()
|
||||
.Path;
|
||||
var projectDirectory = TestAssets
|
||||
.Get(testAsset)
|
||||
.CreateInstance()
|
||||
.WithSourceFiles()
|
||||
.Root
|
||||
.FullName;
|
||||
|
||||
var projectToAdd = "Lib/Lib.csproj";
|
||||
var normalizedProjectPath = @"Lib\Lib.csproj";
|
||||
|
@ -144,7 +190,7 @@ namespace Microsoft.DotNet.Cli.Add.Proj.Tests
|
|||
.WithWorkingDirectory(projectDirectory)
|
||||
.ExecuteWithCapturedOutput($"add App.sln project {projectToAdd}");
|
||||
cmd.Should().Pass();
|
||||
cmd.StdOut.Should().Contain("added to the solution");
|
||||
cmd.StdOut.Should().Be($"Project `{Path.Combine("Lib", "Lib.csproj")}` added to the solution.");
|
||||
cmd.StdErr.Should().BeEmpty();
|
||||
|
||||
var slnFile = SlnFile.Read(Path.Combine(projectDirectory, "App.sln"));
|
||||
|
@ -174,25 +220,32 @@ namespace Microsoft.DotNet.Cli.Add.Proj.Tests
|
|||
[Fact]
|
||||
public void WhenSolutionAlreadyContainsProjectItDoesntDuplicate()
|
||||
{
|
||||
var projectDirectory = TestAssetsManager.CreateTestInstance("TestAppWithSlnAndExistingCsprojReferences")
|
||||
.WithLockFiles()
|
||||
.Path;
|
||||
var projectDirectory = TestAssets
|
||||
.Get("TestAppWithSlnAndExistingCsprojReferences")
|
||||
.CreateInstance()
|
||||
.WithSourceFiles()
|
||||
.Root
|
||||
.FullName;
|
||||
|
||||
var solutionPath = Path.Combine(projectDirectory, "App.sln");
|
||||
var projectToAdd = Path.Combine("Lib", "Lib.csproj");
|
||||
var cmd = new DotnetCommand()
|
||||
.WithWorkingDirectory(projectDirectory)
|
||||
.ExecuteWithCapturedOutput($"add App.sln project {projectToAdd}");
|
||||
cmd.Should().Pass();
|
||||
cmd.StdOut.Should().Contain("already contains project");
|
||||
cmd.StdOut.Should().Be($"Solution {solutionPath} already contains project {projectToAdd}.");
|
||||
cmd.StdErr.Should().BeEmpty();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void WhenPassedMultipleProjectsAndOneOfthemDoesNotExistItCancelsWholeOperation()
|
||||
{
|
||||
var projectDirectory = TestAssetsManager.CreateTestInstance("TestAppWithSlnAndCsprojFiles")
|
||||
.WithLockFiles()
|
||||
.Path;
|
||||
var projectDirectory = TestAssets
|
||||
.Get("TestAppWithSlnAndCsprojFiles")
|
||||
.CreateInstance()
|
||||
.WithSourceFiles()
|
||||
.Root
|
||||
.FullName;
|
||||
|
||||
var slnFullPath = Path.Combine(projectDirectory, "App.sln");
|
||||
var contentBefore = File.ReadAllText(slnFullPath);
|
||||
|
@ -202,8 +255,7 @@ namespace Microsoft.DotNet.Cli.Add.Proj.Tests
|
|||
.WithWorkingDirectory(projectDirectory)
|
||||
.ExecuteWithCapturedOutput($"add App.sln project {projectToAdd} idonotexist.csproj");
|
||||
cmd.Should().Fail();
|
||||
cmd.StdErr.Should().Contain("does not exist");
|
||||
cmd.StdErr.Should().NotMatchRegex("(.*does not exist.*){2,}");
|
||||
cmd.StdErr.Should().Be("Project `idonotexist.csproj` does not exist.");
|
||||
|
||||
File.ReadAllText(slnFullPath)
|
||||
.Should().BeEquivalentTo(contentBefore);
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
<GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>
|
||||
<AssemblyName>dotnet-add-proj.Tests</AssemblyName>
|
||||
<PackageTargetFallback Condition=" '$(TargetFramework)' == 'netcoreapp1.0' ">$(PackageTargetFallback);dotnet5.4;portable-net451+win8</PackageTargetFallback>
|
||||
<DefineConstants>$(DefineConstants);DISABLE_TRACE</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="**\*.cs" />
|
||||
|
@ -21,10 +20,6 @@
|
|||
<ProjectReference Include="..\..\src\Microsoft.DotNet.TestFramework\Microsoft.DotNet.TestFramework.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition=" '$(TargetFramework)' == 'net46' ">
|
||||
<Reference Include="System.Runtime" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.NET.Sdk">
|
||||
<Version>$(CLI_NETSDK_Version)</Version>
|
||||
|
|
|
@ -13,11 +13,20 @@ namespace Microsoft.DotNet.Cli.List.P2P.Tests
|
|||
{
|
||||
public class GivenDotnetListP2Ps : TestBase
|
||||
{
|
||||
private const string HelpText = @".NET Core Project-to-Project dependency viewer
|
||||
|
||||
Usage: dotnet list <PROJECT_OR_SOLUTION> p2ps [options]
|
||||
|
||||
Arguments:
|
||||
<PROJECT_OR_SOLUTION> The project or solution to operation on. If a file is not specified, the current directory is searched.
|
||||
|
||||
Options:
|
||||
-h|--help Show help information";
|
||||
|
||||
const string FrameworkNet451Arg = "-f net451";
|
||||
const string ConditionFrameworkNet451 = "== 'net451'";
|
||||
const string FrameworkNetCoreApp10Arg = "-f netcoreapp1.0";
|
||||
const string ConditionFrameworkNetCoreApp10 = "== 'netcoreapp1.0'";
|
||||
const string UsageText = "Usage: dotnet list <PROJECT_OR_SOLUTION> p2ps";
|
||||
|
||||
[Theory]
|
||||
[InlineData("--help")]
|
||||
|
@ -26,7 +35,18 @@ namespace Microsoft.DotNet.Cli.List.P2P.Tests
|
|||
{
|
||||
var cmd = new ListP2PsCommand().Execute(helpArg);
|
||||
cmd.Should().Pass();
|
||||
cmd.StdOut.Should().Contain("Usage");
|
||||
cmd.StdOut.Should().Be(HelpText);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("")]
|
||||
[InlineData("unknownCommandName")]
|
||||
public void WhenNoCommandIsPassedItPrintsError(string commandName)
|
||||
{
|
||||
var cmd = new DotnetCommand()
|
||||
.ExecuteWithCapturedOutput($"list {commandName}");
|
||||
cmd.Should().Fail();
|
||||
cmd.StdErr.Should().Be("Required command was not provided.");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
@ -36,7 +56,7 @@ namespace Microsoft.DotNet.Cli.List.P2P.Tests
|
|||
.WithProject("one two three")
|
||||
.Execute("proj.csproj");
|
||||
cmd.ExitCode.Should().NotBe(0);
|
||||
cmd.StdErr.Should().Contain("Unrecognized command or argument");
|
||||
cmd.StdErr.Should().Be("Unrecognized command or argument 'two'");
|
||||
}
|
||||
|
||||
[Theory]
|
||||
|
@ -51,8 +71,8 @@ namespace Microsoft.DotNet.Cli.List.P2P.Tests
|
|||
.WithProject(projName)
|
||||
.Execute($"\"{setup.ValidRefCsprojPath}\"");
|
||||
cmd.ExitCode.Should().NotBe(0);
|
||||
cmd.StdErr.Should().Contain("Could not find");
|
||||
cmd.StdOut.Should().Contain(UsageText);
|
||||
cmd.StdErr.Should().Be($"Could not find project or directory `{projName}`.");
|
||||
cmd.StdOut.Should().Be(HelpText);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
@ -66,8 +86,8 @@ namespace Microsoft.DotNet.Cli.List.P2P.Tests
|
|||
.WithProject(projName)
|
||||
.Execute($"\"{setup.ValidRefCsprojPath}\"");
|
||||
cmd.ExitCode.Should().NotBe(0);
|
||||
cmd.StdErr.Should().Contain(" is invalid.");
|
||||
cmd.StdOut.Should().Contain(UsageText);
|
||||
cmd.StdErr.Should().Be("Project `Broken/Broken.csproj` is invalid.");
|
||||
cmd.StdOut.Should().Be(HelpText);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
@ -75,12 +95,13 @@ namespace Microsoft.DotNet.Cli.List.P2P.Tests
|
|||
{
|
||||
var setup = Setup();
|
||||
|
||||
var workingDir = Path.Combine(setup.TestRoot, "MoreThanOne");
|
||||
var cmd = new ListP2PsCommand()
|
||||
.WithWorkingDirectory(Path.Combine(setup.TestRoot, "MoreThanOne"))
|
||||
.WithWorkingDirectory(workingDir)
|
||||
.Execute($"\"{setup.ValidRefCsprojRelToOtherProjPath}\"");
|
||||
cmd.ExitCode.Should().NotBe(0);
|
||||
cmd.StdErr.Should().Contain("more than one");
|
||||
cmd.StdOut.Should().Contain(UsageText);
|
||||
cmd.StdErr.Should().Be($"Found more than one project in `{workingDir + Path.DirectorySeparatorChar}`. Please specify which one to use.");
|
||||
cmd.StdOut.Should().Be(HelpText);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
@ -92,8 +113,8 @@ namespace Microsoft.DotNet.Cli.List.P2P.Tests
|
|||
.WithWorkingDirectory(setup.TestRoot)
|
||||
.Execute($"\"{setup.ValidRefCsprojPath}\"");
|
||||
cmd.ExitCode.Should().NotBe(0);
|
||||
cmd.StdErr.Should().Contain("not find any");
|
||||
cmd.StdOut.Should().Contain(UsageText);
|
||||
cmd.StdErr.Should().Be($"Could not find any project in `{setup.TestRoot + Path.DirectorySeparatorChar}`.");
|
||||
cmd.StdOut.Should().Be(HelpText);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
@ -105,12 +126,16 @@ namespace Microsoft.DotNet.Cli.List.P2P.Tests
|
|||
.WithProject(lib.CsProjPath)
|
||||
.Execute();
|
||||
cmd.Should().Pass();
|
||||
cmd.StdOut.Should().Contain("There are no Project to Project references in project");
|
||||
cmd.StdOut.Should().Be($"There are no Project to Project references in project {lib.CsProjPath}. ;; Project to Project is the type of the item being requested (project, package, p2p) and {lib.CsProjPath} is the object operated on (a project file or a solution file). ");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ItPrintsSingleReference()
|
||||
{
|
||||
const string OutputText = @"Project reference(s)
|
||||
--------------------
|
||||
..\ItPrintsSingleReferenceref\ItPrintsSingleReferenceref.csproj";
|
||||
|
||||
var lib = NewLib("ItPrintsSingleReference", "lib");
|
||||
string ref1 = NewLib("ItPrintsSingleReference", "ref").CsProjPath;
|
||||
AddValidRef(ref1, lib);
|
||||
|
@ -119,13 +144,18 @@ namespace Microsoft.DotNet.Cli.List.P2P.Tests
|
|||
.WithProject(lib.CsProjPath)
|
||||
.Execute();
|
||||
cmd.Should().Pass();
|
||||
cmd.StdOut.Should().Contain("Project reference(s)");
|
||||
cmd.StdOut.Should().Contain(@"..\ItPrintsSingleReferenceref\ItPrintsSingleReferenceref.csproj");
|
||||
cmd.StdOut.Should().Be(OutputText);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ItPrintsMultipleReferences()
|
||||
{
|
||||
const string OutputText = @"Project reference(s)
|
||||
--------------------
|
||||
..\ItPrintsSingleReferenceref1\ItPrintsSingleReferenceref1.csproj
|
||||
..\ItPrintsSingleReferenceref2\ItPrintsSingleReferenceref2.csproj
|
||||
..\ItPrintsSingleReferenceref3\ItPrintsSingleReferenceref3.csproj";
|
||||
|
||||
var lib = NewLib("ItPrintsSingleReference", "lib");
|
||||
string ref1 = NewLib("ItPrintsSingleReference", "ref1").CsProjPath;
|
||||
string ref2 = NewLib("ItPrintsSingleReference", "ref2").CsProjPath;
|
||||
|
@ -139,10 +169,7 @@ namespace Microsoft.DotNet.Cli.List.P2P.Tests
|
|||
.WithProject(lib.CsProjPath)
|
||||
.Execute();
|
||||
cmd.Should().Pass();
|
||||
cmd.StdOut.Should().Contain("Project reference(s)");
|
||||
cmd.StdOut.Should().Contain(@"..\ItPrintsSingleReferenceref1\ItPrintsSingleReferenceref1.csproj");
|
||||
cmd.StdOut.Should().Contain(@"..\ItPrintsSingleReferenceref2\ItPrintsSingleReferenceref2.csproj");
|
||||
cmd.StdOut.Should().Contain(@"..\ItPrintsSingleReferenceref3\ItPrintsSingleReferenceref3.csproj");
|
||||
cmd.StdOut.Should().Be(OutputText);
|
||||
}
|
||||
|
||||
private TestSetup Setup([System.Runtime.CompilerServices.CallerMemberName] string callingMethod = nameof(Setup), string identifier = "")
|
||||
|
|
|
@ -31,7 +31,7 @@ Options:
|
|||
var cmd = new DotnetCommand()
|
||||
.ExecuteWithCapturedOutput($"list projects {helpArg}");
|
||||
cmd.Should().Pass();
|
||||
cmd.StdOut.Should().Contain(HelpText);
|
||||
cmd.StdOut.Should().Be(HelpText);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
|
@ -42,7 +42,7 @@ Options:
|
|||
var cmd = new DotnetCommand()
|
||||
.ExecuteWithCapturedOutput($"list {commandName}");
|
||||
cmd.Should().Fail();
|
||||
cmd.StdErr.Should().Contain("Required command was not provided.");
|
||||
cmd.StdErr.Should().Be("Required command was not provided.");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
@ -51,7 +51,7 @@ Options:
|
|||
var cmd = new DotnetCommand()
|
||||
.ExecuteWithCapturedOutput("list one.sln two.sln three.sln projects");
|
||||
cmd.Should().Fail();
|
||||
cmd.StdErr.Should().Contain("Unrecognized command or argument 'two.sln'");
|
||||
cmd.StdErr.Should().Be("Unrecognized command or argument 'two.sln'");
|
||||
}
|
||||
|
||||
[Theory]
|
||||
|
@ -65,8 +65,8 @@ Options:
|
|||
var cmd = new DotnetCommand()
|
||||
.ExecuteWithCapturedOutput($"list {solutionName} projects");
|
||||
cmd.Should().Fail();
|
||||
cmd.StdErr.Should().Contain($"Could not find solution or directory `{solutionName}`");
|
||||
cmd.StdOut.Should().Contain(HelpText);
|
||||
cmd.StdErr.Should().Be($"Could not find solution or directory `{solutionName}`.");
|
||||
cmd.StdOut.Should().Be(HelpText);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
@ -83,8 +83,8 @@ Options:
|
|||
.WithWorkingDirectory(projectDirectory)
|
||||
.ExecuteWithCapturedOutput("list InvalidSolution.sln projects");
|
||||
cmd.Should().Fail();
|
||||
cmd.StdErr.Should().Contain("Invalid solution `InvalidSolution.sln`");
|
||||
cmd.StdOut.Should().Contain(HelpText);
|
||||
cmd.StdErr.Should().Be("Invalid solution `InvalidSolution.sln`.");
|
||||
cmd.StdOut.Should().Be(HelpText);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
@ -102,8 +102,8 @@ Options:
|
|||
.WithWorkingDirectory(projectDirectory)
|
||||
.ExecuteWithCapturedOutput("list projects");
|
||||
cmd.Should().Fail();
|
||||
cmd.StdErr.Should().Contain($"Invalid solution `{solutionFullPath}`");
|
||||
cmd.StdOut.Should().Contain(HelpText);
|
||||
cmd.StdErr.Should().Be($"Invalid solution `{solutionFullPath}`.");
|
||||
cmd.StdOut.Should().Be(HelpText);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
@ -121,8 +121,8 @@ Options:
|
|||
.WithWorkingDirectory(solutionDir)
|
||||
.ExecuteWithCapturedOutput("list projects");
|
||||
cmd.Should().Fail();
|
||||
cmd.StdErr.Should().Contain($"Specified solution file {solutionDir + Path.DirectorySeparatorChar} does not exist, or there is no solution file in the directory");
|
||||
cmd.StdOut.Should().Contain(HelpText);
|
||||
cmd.StdErr.Should().Be($"Specified solution file {solutionDir + Path.DirectorySeparatorChar} does not exist, or there is no solution file in the directory.");
|
||||
cmd.StdOut.Should().Be(HelpText);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
@ -139,8 +139,8 @@ Options:
|
|||
.WithWorkingDirectory(projectDirectory)
|
||||
.ExecuteWithCapturedOutput("list projects");
|
||||
cmd.Should().Fail();
|
||||
cmd.StdErr.Should().Contain($"Found more than one solution file in {projectDirectory + Path.DirectorySeparatorChar}. Please specify which one to use.");
|
||||
cmd.StdOut.Should().Contain(HelpText);
|
||||
cmd.StdErr.Should().Be($"Found more than one solution file in {projectDirectory + Path.DirectorySeparatorChar}. Please specify which one to use.");
|
||||
cmd.StdOut.Should().Be(HelpText);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
@ -157,12 +157,17 @@ Options:
|
|||
.WithWorkingDirectory(projectDirectory)
|
||||
.ExecuteWithCapturedOutput("list projects");
|
||||
cmd.Should().Pass();
|
||||
cmd.StdOut.Should().Contain("No projects found in the solution.");
|
||||
cmd.StdOut.Should().Be("No projects found in the solution.");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void WhenProjectReferencesArePresentInTheSolutionItListsThem()
|
||||
{
|
||||
const string OutputText = @"Project reference(s)
|
||||
--------------------
|
||||
App\App.csproj
|
||||
Lib\Lib.csproj";
|
||||
|
||||
var projectDirectory = TestAssets
|
||||
.Get("TestAppWithSlnAndExistingCsprojReferences")
|
||||
.CreateInstance()
|
||||
|
@ -174,9 +179,7 @@ Options:
|
|||
.WithWorkingDirectory(projectDirectory)
|
||||
.ExecuteWithCapturedOutput("list projects");
|
||||
cmd.Should().Pass();
|
||||
cmd.StdOut.Should().Contain("Project reference(s)");
|
||||
cmd.StdOut.Should().Contain(@"App\App.csproj");
|
||||
cmd.StdOut.Should().Contain(@"Lib\Lib.csproj");
|
||||
cmd.StdOut.Should().Be(OutputText);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,6 +13,21 @@ namespace Microsoft.DotNet.Cli.Remove.P2P.Tests
|
|||
{
|
||||
public class GivenDotnetRemoveP2P : TestBase
|
||||
{
|
||||
private const string HelpText = @".NET Remove Project to Project (p2p) reference Command
|
||||
|
||||
Usage: dotnet remove <PROJECT_OR_SOLUTION> p2p [options] [args]
|
||||
|
||||
Arguments:
|
||||
<PROJECT_OR_SOLUTION> The project or solution to operation on. If a file is not specified, the current directory is searched.
|
||||
|
||||
Options:
|
||||
-h|--help Show help information
|
||||
-f|--framework <FRAMEWORK> Remove reference only when targetting a specific framework
|
||||
|
||||
Args:
|
||||
Project to project references to remove
|
||||
";
|
||||
|
||||
const string FrameworkNet451Arg = "-f net451";
|
||||
const string ConditionFrameworkNet451 = "== 'net451'";
|
||||
const string FrameworkNetCoreApp10Arg = "-f netcoreapp1.0";
|
||||
|
@ -103,7 +118,18 @@ namespace Microsoft.DotNet.Cli.Remove.P2P.Tests
|
|||
{
|
||||
var cmd = new RemoveP2PCommand().Execute(helpArg);
|
||||
cmd.Should().Pass();
|
||||
cmd.StdOut.Should().Contain("Usage");
|
||||
cmd.StdOut.Should().Be(HelpText);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("")]
|
||||
[InlineData("unknownCommandName")]
|
||||
public void WhenNoCommandIsPassedItPrintsError(string commandName)
|
||||
{
|
||||
var cmd = new DotnetCommand()
|
||||
.ExecuteWithCapturedOutput($"remove {commandName}");
|
||||
cmd.Should().Fail();
|
||||
cmd.StdErr.Should().Be("Required command was not provided.");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
@ -113,7 +139,8 @@ namespace Microsoft.DotNet.Cli.Remove.P2P.Tests
|
|||
.WithProject("one two three")
|
||||
.Execute("proj.csproj");
|
||||
cmd.ExitCode.Should().NotBe(0);
|
||||
cmd.StdErr.Should().Contain("Unrecognized command or argument");
|
||||
cmd.StdErr.Should().Be("Unrecognized command or argument 'two'");
|
||||
cmd.StdOut.Should().Be("Specify --help for a list of available options and commands.");
|
||||
}
|
||||
|
||||
[Theory]
|
||||
|
@ -128,8 +155,8 @@ namespace Microsoft.DotNet.Cli.Remove.P2P.Tests
|
|||
.WithProject(projName)
|
||||
.Execute($"\"{setup.ValidRefCsprojPath}\"");
|
||||
cmd.ExitCode.Should().NotBe(0);
|
||||
cmd.StdErr.Should().Contain("Could not find");
|
||||
cmd.StdOut.Should().Contain("Usage");
|
||||
cmd.StdErr.Should().Be($"Could not find project or directory `{projName}`.");
|
||||
cmd.StdOut.Should().Be(HelpText);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
@ -143,8 +170,8 @@ namespace Microsoft.DotNet.Cli.Remove.P2P.Tests
|
|||
.WithProject(projName)
|
||||
.Execute($"\"{setup.ValidRefCsprojPath}\"");
|
||||
cmd.ExitCode.Should().NotBe(0);
|
||||
cmd.StdErr.Should().Contain(" is invalid.");
|
||||
cmd.StdOut.Should().Contain("Usage");
|
||||
cmd.StdErr.Should().Be("Project `Broken/Broken.csproj` is invalid.");
|
||||
cmd.StdOut.Should().Be(HelpText);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
@ -152,12 +179,13 @@ namespace Microsoft.DotNet.Cli.Remove.P2P.Tests
|
|||
{
|
||||
var setup = Setup();
|
||||
|
||||
var workingDir = Path.Combine(setup.TestRoot, "MoreThanOne");
|
||||
var cmd = new RemoveP2PCommand()
|
||||
.WithWorkingDirectory(Path.Combine(setup.TestRoot, "MoreThanOne"))
|
||||
.WithWorkingDirectory(workingDir)
|
||||
.Execute($"\"{setup.ValidRefCsprojRelToOtherProjPath}\"");
|
||||
cmd.ExitCode.Should().NotBe(0);
|
||||
cmd.StdErr.Should().Contain("more than one");
|
||||
cmd.StdOut.Should().Contain("Usage");
|
||||
cmd.StdErr.Should().Be($"Found more than one project in `{workingDir + Path.DirectorySeparatorChar}`. Please specify which one to use.");
|
||||
cmd.StdOut.Should().Be(HelpText);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
@ -169,8 +197,8 @@ namespace Microsoft.DotNet.Cli.Remove.P2P.Tests
|
|||
.WithWorkingDirectory(setup.TestRoot)
|
||||
.Execute($"\"{setup.ValidRefCsprojPath}\"");
|
||||
cmd.ExitCode.Should().NotBe(0);
|
||||
cmd.StdErr.Should().Contain("not find any");
|
||||
cmd.StdOut.Should().Contain("Usage");
|
||||
cmd.StdErr.Should().Be($"Could not find any project in `{setup.TestRoot + Path.DirectorySeparatorChar}`.");
|
||||
cmd.StdOut.Should().Be(HelpText);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
@ -186,7 +214,7 @@ namespace Microsoft.DotNet.Cli.Remove.P2P.Tests
|
|||
.WithProject(lib.CsProjPath)
|
||||
.Execute($"\"{libref.CsProjPath}\"");
|
||||
cmd.Should().Pass();
|
||||
cmd.StdOut.Should().MatchRegex("(^|[\r\n])Project reference[^\r\n]*removed.($|[\r\n])");
|
||||
cmd.StdOut.Should().Be($"Project reference `{Path.Combine(TestSetup.ProjectName, "Lib", setup.LibCsprojName)}` removed.");
|
||||
var csproj = lib.CsProj();
|
||||
csproj.NumberOfItemGroupsWithoutCondition().Should().Be(noCondBefore - 1);
|
||||
csproj.NumberOfProjectReferencesWithIncludeContaining(libref.Name).Should().Be(0);
|
||||
|
@ -205,7 +233,7 @@ namespace Microsoft.DotNet.Cli.Remove.P2P.Tests
|
|||
.WithProject(lib.CsProjPath)
|
||||
.Execute($"{FrameworkNet451Arg} \"{libref.CsProjPath}\"");
|
||||
cmd.Should().Pass();
|
||||
cmd.StdOut.Should().MatchRegex("(^|[\r\n])Project reference[^\r\n]*removed.($|[\r\n])");
|
||||
cmd.StdOut.Should().Be($"Project reference `{Path.Combine(TestSetup.ProjectName, "Lib", setup.LibCsprojName)}` removed.");
|
||||
var csproj = lib.CsProj();
|
||||
csproj.NumberOfItemGroupsWithConditionContaining(ConditionFrameworkNet451).Should().Be(condBefore - 1);
|
||||
csproj.NumberOfProjectReferencesWithIncludeAndConditionContaining(libref.Name, ConditionFrameworkNet451).Should().Be(0);
|
||||
|
@ -225,8 +253,7 @@ namespace Microsoft.DotNet.Cli.Remove.P2P.Tests
|
|||
.WithProject(lib.CsProjPath)
|
||||
.Execute($"\"{libref.CsProjPath}\"");
|
||||
cmd.Should().Pass();
|
||||
cmd.StdOut.Should().MatchRegex("(^|[\r\n])Project reference[^\r\n]*removed.($|[\r\n])");
|
||||
cmd.StdOut.Should().NotContain(validref.Name);
|
||||
cmd.StdOut.Should().Be($"Project reference `{Path.Combine(TestSetup.ProjectName, "Lib", setup.LibCsprojName)}` removed.");
|
||||
var csproj = lib.CsProj();
|
||||
csproj.NumberOfItemGroupsWithoutCondition().Should().Be(noCondBefore);
|
||||
csproj.NumberOfProjectReferencesWithIncludeContaining(libref.Name).Should().Be(0);
|
||||
|
@ -245,7 +272,7 @@ namespace Microsoft.DotNet.Cli.Remove.P2P.Tests
|
|||
.WithProject(lib.CsProjPath)
|
||||
.Execute($"\"{libref.CsProjPath}\"");
|
||||
cmd.Should().Pass();
|
||||
cmd.StdOut.Should().Contain("could not be found");
|
||||
cmd.StdOut.Should().Be($"Project reference `{libref.CsProjPath}` could not be found.");
|
||||
lib.CsProjContent().Should().BeEquivalentTo(csprojContetntBefore);
|
||||
}
|
||||
|
||||
|
@ -262,7 +289,7 @@ namespace Microsoft.DotNet.Cli.Remove.P2P.Tests
|
|||
.WithProject(lib.CsProjPath)
|
||||
.Execute($"{FrameworkNet451Arg} \"{libref.CsProjPath}\"");
|
||||
cmd.Should().Pass();
|
||||
cmd.StdOut.Should().Contain("could not be found");
|
||||
cmd.StdOut.Should().Be($"Project reference `{libref.CsProjPath}` could not be found.");
|
||||
lib.CsProjContent().Should().BeEquivalentTo(csprojContetntBefore);
|
||||
}
|
||||
|
||||
|
@ -282,7 +309,7 @@ namespace Microsoft.DotNet.Cli.Remove.P2P.Tests
|
|||
.WithProject(lib.CsProjPath)
|
||||
.Execute($"\"{librefNoCond.CsProjPath}\"");
|
||||
cmd.Should().Pass();
|
||||
cmd.StdOut.Should().MatchRegex("(^|[\r\n])Project reference[^\r\n]*removed.($|[\r\n])");
|
||||
cmd.StdOut.Should().Be($"Project reference `{Path.Combine(TestSetup.ProjectName, "Lib", setup.LibCsprojName)}` removed.");
|
||||
var csproj = lib.CsProj();
|
||||
csproj.NumberOfItemGroupsWithoutCondition().Should().Be(noCondBefore - 1);
|
||||
csproj.NumberOfProjectReferencesWithIncludeContaining(librefNoCond.Name).Should().Be(0);
|
||||
|
@ -307,7 +334,7 @@ namespace Microsoft.DotNet.Cli.Remove.P2P.Tests
|
|||
.WithProject(lib.CsProjPath)
|
||||
.Execute($"{FrameworkNet451Arg} \"{librefCond.CsProjPath}\"");
|
||||
cmd.Should().Pass();
|
||||
cmd.StdOut.Should().MatchRegex("(^|[\r\n])Project reference[^\r\n]*removed.($|[\r\n])");
|
||||
cmd.StdOut.Should().Be($"Project reference `{Path.Combine(TestSetup.ProjectName, "Lib", setup.LibCsprojName)}` removed.");
|
||||
var csproj = lib.CsProj();
|
||||
csproj.NumberOfItemGroupsWithoutCondition().Should().Be(noCondBefore);
|
||||
csproj.NumberOfProjectReferencesWithIncludeContaining(librefNoCond.Name).Should().Be(1);
|
||||
|
@ -332,7 +359,7 @@ namespace Microsoft.DotNet.Cli.Remove.P2P.Tests
|
|||
.WithProject(lib.CsProjPath)
|
||||
.Execute($"{FrameworkNet451Arg} \"{librefCondNet451.CsProjPath}\"");
|
||||
cmd.Should().Pass();
|
||||
cmd.StdOut.Should().MatchRegex("(^|[\r\n])Project reference[^\r\n]*removed.($|[\r\n])");
|
||||
cmd.StdOut.Should().Be($"Project reference `{Path.Combine(TestSetup.ProjectName, "Lib", setup.LibCsprojName)}` removed.");
|
||||
var csproj = lib.CsProj();
|
||||
csproj.NumberOfItemGroupsWithConditionContaining(ConditionFrameworkNet451).Should().Be(condNet451Before - 1);
|
||||
csproj.NumberOfProjectReferencesWithIncludeAndConditionContaining(librefCondNet451.Name, ConditionFrameworkNet451).Should().Be(0);
|
||||
|
@ -348,13 +375,16 @@ namespace Microsoft.DotNet.Cli.Remove.P2P.Tests
|
|||
var proj = new ProjDir(Path.Combine(setup.TestRoot, "WithDoubledRef"));
|
||||
var libref = GetLibRef(setup);
|
||||
|
||||
string removedText = $@"Project reference `{setup.LibCsprojRelPath}` removed.
|
||||
Project reference `{setup.LibCsprojRelPath}` removed.";
|
||||
|
||||
int noCondBefore = proj.CsProj().NumberOfItemGroupsWithoutCondition();
|
||||
var cmd = new RemoveP2PCommand()
|
||||
.WithWorkingDirectory(setup.TestRoot)
|
||||
.WithProject(proj.CsProjPath)
|
||||
.Execute($"\"{libref.CsProjPath}\"");
|
||||
cmd.Should().Pass();
|
||||
cmd.StdOut.Should().MatchRegex("(^|[\r\n])Project reference[^\r\n]*removed.($|[\r\n])");
|
||||
cmd.StdOut.Should().Be(removedText);
|
||||
|
||||
var csproj = proj.CsProj();
|
||||
csproj.NumberOfItemGroupsWithoutCondition().Should().Be(noCondBefore - 1);
|
||||
|
@ -374,7 +404,7 @@ namespace Microsoft.DotNet.Cli.Remove.P2P.Tests
|
|||
.WithProject(lib.CsProjPath)
|
||||
.Execute($"\"{setup.ValidRefCsprojRelToOtherProjPath}\"");
|
||||
cmd.Should().Pass();
|
||||
cmd.StdOut.Should().MatchRegex("(^|[\r\n])Project reference[^\r\n]*removed.($|[\r\n])");
|
||||
cmd.StdOut.Should().Be($"Project reference `{setup.ValidRefCsprojRelToOtherProjPath}` removed.");
|
||||
var csproj = lib.CsProj();
|
||||
csproj.NumberOfItemGroupsWithoutCondition().Should().Be(noCondBefore - 1);
|
||||
csproj.NumberOfProjectReferencesWithIncludeContaining(libref.Name).Should().Be(0);
|
||||
|
@ -393,7 +423,7 @@ namespace Microsoft.DotNet.Cli.Remove.P2P.Tests
|
|||
.WithProject(lib.CsProjPath)
|
||||
.Execute($"\"{setup.ValidRefCsprojRelToOtherProjPath}\"");
|
||||
cmd.Should().Pass();
|
||||
cmd.StdOut.Should().MatchRegex("(^|[\r\n])Project reference[^\r\n]*removed.($|[\r\n])");
|
||||
cmd.StdOut.Should().Be($"Project reference `{setup.ValidRefCsprojRelToOtherProjPath}` removed.");
|
||||
var csproj = lib.CsProj();
|
||||
csproj.NumberOfItemGroupsWithoutCondition().Should().Be(noCondBefore - 1);
|
||||
csproj.NumberOfProjectReferencesWithIncludeContaining(libref.Name).Should().Be(0);
|
||||
|
@ -412,7 +442,7 @@ namespace Microsoft.DotNet.Cli.Remove.P2P.Tests
|
|||
.WithProject(lib.CsProjPath)
|
||||
.Execute($"\"{setup.ValidRefCsprojPath}\"");
|
||||
cmd.Should().Pass();
|
||||
cmd.StdOut.Should().MatchRegex("(^|[\r\n])Project reference[^\r\n]*removed.($|[\r\n])");
|
||||
cmd.StdOut.Should().Be($"Project reference `{setup.ValidRefCsprojRelToOtherProjPath}` removed.");
|
||||
var csproj = lib.CsProj();
|
||||
csproj.NumberOfItemGroupsWithoutCondition().Should().Be(noCondBefore - 1);
|
||||
csproj.NumberOfProjectReferencesWithIncludeContaining(libref.Name).Should().Be(0);
|
||||
|
@ -426,13 +456,16 @@ namespace Microsoft.DotNet.Cli.Remove.P2P.Tests
|
|||
var libref = AddLibRef(setup, lib);
|
||||
var validref = AddValidRef(setup, lib);
|
||||
|
||||
string outputText = $@"Project reference `{Path.Combine(TestSetup.ProjectName, "Lib", setup.LibCsprojName)}` removed.
|
||||
Project reference `{Path.Combine(TestSetup.ProjectName, setup.ValidRefCsprojRelPath)}` removed.";
|
||||
|
||||
int noCondBefore = lib.CsProj().NumberOfItemGroupsWithoutCondition();
|
||||
var cmd = new RemoveP2PCommand()
|
||||
.WithWorkingDirectory(setup.TestRoot)
|
||||
.WithProject(lib.CsProjPath)
|
||||
.Execute($"\"{libref.CsProjPath}\" \"{validref.CsProjPath}\"");
|
||||
cmd.Should().Pass();
|
||||
cmd.StdOut.Should().MatchRegex("(^|[\r\n])Project reference[^\r\n]*removed.($|[\r\n])");
|
||||
cmd.StdOut.Should().Be(outputText);
|
||||
var csproj = lib.CsProj();
|
||||
csproj.NumberOfItemGroupsWithoutCondition().Should().Be(noCondBefore - 1);
|
||||
csproj.NumberOfProjectReferencesWithIncludeContaining(libref.Name).Should().Be(0);
|
||||
|
@ -447,14 +480,16 @@ namespace Microsoft.DotNet.Cli.Remove.P2P.Tests
|
|||
var libref = GetLibRef(setup);
|
||||
var validref = AddValidRef(setup, lib);
|
||||
|
||||
string OutputText = $@"Project reference `{setup.LibCsprojPath}` could not be found.
|
||||
Project reference `{Path.Combine(TestSetup.ProjectName, setup.ValidRefCsprojRelPath)}` removed.";
|
||||
|
||||
int noCondBefore = lib.CsProj().NumberOfItemGroupsWithoutCondition();
|
||||
var cmd = new RemoveP2PCommand()
|
||||
.WithWorkingDirectory(setup.TestRoot)
|
||||
.WithProject(lib.CsProjPath)
|
||||
.Execute($"\"{libref.CsProjPath}\" \"{validref.CsProjPath}\"");
|
||||
cmd.Should().Pass();
|
||||
cmd.StdOut.Should().MatchRegex("(^|[\r\n])Project reference[^\r\n]*removed.($|[\r\n])");
|
||||
cmd.StdOut.Should().Contain("could not be found");
|
||||
cmd.StdOut.Should().Be(OutputText);
|
||||
var csproj = lib.CsProj();
|
||||
csproj.NumberOfItemGroupsWithoutCondition().Should().Be(noCondBefore - 1);
|
||||
csproj.NumberOfProjectReferencesWithIncludeContaining(validref.Name).Should().Be(0);
|
||||
|
|
280
test/dotnet-remove-proj.Tests/GivenDotnetRemoveProj.cs
Normal file
280
test/dotnet-remove-proj.Tests/GivenDotnetRemoveProj.cs
Normal file
|
@ -0,0 +1,280 @@
|
|||
// 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 FluentAssertions;
|
||||
using Microsoft.DotNet.Cli.Sln.Internal;
|
||||
using Microsoft.DotNet.Tools.Test.Utilities;
|
||||
using System;
|
||||
using System.IO;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.DotNet.Cli.Remove.P2P.Tests
|
||||
{
|
||||
public class GivenDotnetRemoveProj : TestBase
|
||||
{
|
||||
private const string HelpText = @".NET Remove Project from Solution Command
|
||||
|
||||
Usage: dotnet remove <PROJECT_OR_SOLUTION> project [options] [args]
|
||||
|
||||
Arguments:
|
||||
<PROJECT_OR_SOLUTION> The project or solution to operation on. If a file is not specified, the current directory is searched.
|
||||
|
||||
Options:
|
||||
-h|--help Show help information
|
||||
|
||||
Args:
|
||||
Projects to remove from a solution
|
||||
";
|
||||
|
||||
[Theory]
|
||||
[InlineData("--help")]
|
||||
[InlineData("-h")]
|
||||
public void WhenHelpOptionIsPassedItPrintsUsage(string helpArg)
|
||||
{
|
||||
var cmd = new DotnetCommand()
|
||||
.ExecuteWithCapturedOutput($"remove project {helpArg}");
|
||||
cmd.Should().Pass();
|
||||
cmd.StdOut.Should().Be(HelpText);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void WhenTooManyArgumentsArePassedItPrintsError()
|
||||
{
|
||||
var cmd = new DotnetCommand()
|
||||
.ExecuteWithCapturedOutput("remove one.sln two.sln three.sln project");
|
||||
cmd.Should().Fail();
|
||||
cmd.StdErr.Should().Be("Unrecognized command or argument 'two.sln'");
|
||||
cmd.StdOut.Should().Be("Specify --help for a list of available options and commands.");
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("")]
|
||||
[InlineData("unknownCommandName")]
|
||||
public void WhenNoCommandIsPassedItPrintsError(string commandName)
|
||||
{
|
||||
var cmd = new DotnetCommand()
|
||||
.ExecuteWithCapturedOutput($"remove {commandName}");
|
||||
cmd.Should().Fail();
|
||||
cmd.StdErr.Should().Be("Required command was not provided.");
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("idontexist.sln")]
|
||||
[InlineData("ihave?invalidcharacters")]
|
||||
[InlineData("ihaveinv@lidcharacters")]
|
||||
[InlineData("ihaveinvalid/characters")]
|
||||
[InlineData("ihaveinvalidchar\\acters")]
|
||||
public void WhenNonExistingSolutionIsPassedItPrintsErrorAndUsage(string solutionName)
|
||||
{
|
||||
var cmd = new DotnetCommand()
|
||||
.ExecuteWithCapturedOutput($"remove {solutionName} project p.csproj");
|
||||
cmd.Should().Fail();
|
||||
cmd.StdErr.Should().Be($"Could not find solution or directory `{solutionName}`.");
|
||||
cmd.StdOut.Should().Be(HelpText);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void WhenInvalidSolutionIsPassedItPrintsErrorAndUsage()
|
||||
{
|
||||
var projectDirectory = TestAssets
|
||||
.Get("InvalidSolution")
|
||||
.CreateInstance()
|
||||
.WithSourceFiles()
|
||||
.Root
|
||||
.FullName;
|
||||
|
||||
var projectToRemove = Path.Combine("Lib", "Lib.csproj");
|
||||
var cmd = new DotnetCommand()
|
||||
.WithWorkingDirectory(projectDirectory)
|
||||
.ExecuteWithCapturedOutput($"remove InvalidSolution.sln project {projectToRemove}");
|
||||
cmd.Should().Fail();
|
||||
cmd.StdErr.Should().Be("Invalid solution `InvalidSolution.sln`.");
|
||||
cmd.StdOut.Should().Be(HelpText);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void WhenInvalidSolutionIsFoundItPrintsErrorAndUsage()
|
||||
{
|
||||
var projectDirectory = TestAssets
|
||||
.Get("InvalidSolution")
|
||||
.CreateInstance()
|
||||
.WithSourceFiles()
|
||||
.Root
|
||||
.FullName;
|
||||
|
||||
var solutionPath = Path.Combine(projectDirectory, "InvalidSolution.sln");
|
||||
var projectToRemove = Path.Combine("Lib", "Lib.csproj");
|
||||
var cmd = new DotnetCommand()
|
||||
.WithWorkingDirectory(projectDirectory)
|
||||
.ExecuteWithCapturedOutput($"remove project {projectToRemove}");
|
||||
cmd.Should().Fail();
|
||||
cmd.StdErr.Should().Be($"Invalid solution `{solutionPath}`.");
|
||||
cmd.StdOut.Should().Be(HelpText);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void WhenNoProjectIsPassedItPrintsErrorAndUsage()
|
||||
{
|
||||
var projectDirectory = TestAssets
|
||||
.Get("TestAppWithSlnAndCsprojFiles")
|
||||
.CreateInstance()
|
||||
.WithSourceFiles()
|
||||
.Root
|
||||
.FullName;
|
||||
|
||||
var cmd = new DotnetCommand()
|
||||
.WithWorkingDirectory(projectDirectory)
|
||||
.ExecuteWithCapturedOutput(@"remove App.sln project");
|
||||
cmd.Should().Fail();
|
||||
cmd.StdErr.Should().Be("You must specify at least one project to remove.");
|
||||
cmd.StdOut.Should().Be(HelpText);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void WhenNoSolutionExistsInTheDirectoryItPrintsErrorAndUsage()
|
||||
{
|
||||
var projectDirectory = TestAssets
|
||||
.Get("TestAppWithSlnAndCsprojFiles")
|
||||
.CreateInstance()
|
||||
.WithSourceFiles()
|
||||
.Root
|
||||
.FullName;
|
||||
|
||||
var solutionPath = Path.Combine(projectDirectory, "App");
|
||||
var cmd = new DotnetCommand()
|
||||
.WithWorkingDirectory(solutionPath)
|
||||
.ExecuteWithCapturedOutput(@"remove project App.csproj");
|
||||
cmd.Should().Fail();
|
||||
cmd.StdErr.Should().Be($"Specified solution file {solutionPath + Path.DirectorySeparatorChar} does not exist, or there is no solution file in the directory.");
|
||||
cmd.StdOut.Should().Be(HelpText);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void WhenMoreThanOneSolutionExistsInTheDirectoryItPrintsErrorAndUsage()
|
||||
{
|
||||
var projectDirectory = TestAssets
|
||||
.Get("TestAppWithMultipleSlnFiles")
|
||||
.CreateInstance()
|
||||
.WithSourceFiles()
|
||||
.Root
|
||||
.FullName;
|
||||
|
||||
var projectToRemove = Path.Combine("Lib", "Lib.csproj");
|
||||
var cmd = new DotnetCommand()
|
||||
.WithWorkingDirectory(projectDirectory)
|
||||
.ExecuteWithCapturedOutput($"remove project {projectToRemove}");
|
||||
cmd.Should().Fail();
|
||||
cmd.StdErr.Should().Be($"Found more than one solution file in {projectDirectory + Path.DirectorySeparatorChar}. Please specify which one to use.");
|
||||
cmd.StdOut.Should().Be(HelpText);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void WhenPassedAReferenceNotInSlnItPrintsStatus()
|
||||
{
|
||||
var projectDirectory = TestAssets
|
||||
.Get("TestAppWithSlnAndExistingCsprojReferences")
|
||||
.CreateInstance()
|
||||
.WithSourceFiles()
|
||||
.Root
|
||||
.FullName;
|
||||
|
||||
var solutionPath = Path.Combine(projectDirectory, "App.sln");
|
||||
var contentBefore = File.ReadAllText(solutionPath);
|
||||
var cmd = new DotnetCommand()
|
||||
.WithWorkingDirectory(projectDirectory)
|
||||
.ExecuteWithCapturedOutput("remove project referenceDoesNotExistInSln.csproj");
|
||||
cmd.Should().Pass();
|
||||
cmd.StdOut.Should().Be("Project reference `referenceDoesNotExistInSln.csproj` could not be found.");
|
||||
File.ReadAllText(solutionPath)
|
||||
.Should().Be(contentBefore);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void WhenPassedAReferenceItRemovesTheReferenceButNotOtherReferences()
|
||||
{
|
||||
var projectDirectory = TestAssets
|
||||
.Get("TestAppWithSlnAndExistingCsprojReferences")
|
||||
.CreateInstance()
|
||||
.WithSourceFiles()
|
||||
.Root
|
||||
.FullName;
|
||||
|
||||
var solutionPath = Path.Combine(projectDirectory, "App.sln");
|
||||
SlnFile slnFile = SlnFile.Read(solutionPath);
|
||||
slnFile.Projects.Count.Should().Be(2);
|
||||
|
||||
var projectToRemove = Path.Combine("Lib", "Lib.csproj");
|
||||
var projectToRemoveNormalized = @"Lib\Lib.csproj";
|
||||
var cmd = new DotnetCommand()
|
||||
.WithWorkingDirectory(projectDirectory)
|
||||
.ExecuteWithCapturedOutput($"remove project {projectToRemove}");
|
||||
cmd.Should().Pass();
|
||||
cmd.StdOut.Should().Be($"Project reference `{projectToRemoveNormalized}` removed.");
|
||||
|
||||
slnFile = SlnFile.Read(solutionPath);
|
||||
slnFile.Projects.Count.Should().Be(1);
|
||||
slnFile.Projects[0].FilePath.Should().Be(@"App\App.csproj");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void WhenDuplicateReferencesArePresentItRemovesThemAll()
|
||||
{
|
||||
var projectDirectory = TestAssets
|
||||
.Get("TestAppWithSlnAndDuplicateProjectReferences")
|
||||
.CreateInstance()
|
||||
.WithSourceFiles()
|
||||
.Root
|
||||
.FullName;
|
||||
|
||||
var solutionPath = Path.Combine(projectDirectory, "App.sln");
|
||||
SlnFile slnFile = SlnFile.Read(solutionPath);
|
||||
slnFile.Projects.Count.Should().Be(3);
|
||||
|
||||
var projectToRemove = Path.Combine("Lib", "Lib.csproj");
|
||||
var projectToRemoveNormalized = @"Lib\Lib.csproj";
|
||||
var cmd = new DotnetCommand()
|
||||
.WithWorkingDirectory(projectDirectory)
|
||||
.ExecuteWithCapturedOutput($"remove project {projectToRemove}");
|
||||
cmd.Should().Pass();
|
||||
|
||||
string outputText = $@"Project reference `{projectToRemoveNormalized}` removed.
|
||||
Project reference `{projectToRemoveNormalized}` removed.";
|
||||
cmd.StdOut.Should().Be(outputText);
|
||||
|
||||
slnFile = SlnFile.Read(solutionPath);
|
||||
slnFile.Projects.Count.Should().Be(1);
|
||||
slnFile.Projects[0].FilePath.Should().Be(@"App\App.csproj");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void WhenPassedMultipleReferencesAndOneOfThemDoesNotExistItRemovesTheOneThatExists()
|
||||
{
|
||||
var projectDirectory = TestAssets
|
||||
.Get("TestAppWithSlnAndExistingCsprojReferences")
|
||||
.CreateInstance()
|
||||
.WithSourceFiles()
|
||||
.Root
|
||||
.FullName;
|
||||
|
||||
var solutionPath = Path.Combine(projectDirectory, "App.sln");
|
||||
SlnFile slnFile = SlnFile.Read(solutionPath);
|
||||
slnFile.Projects.Count.Should().Be(2);
|
||||
|
||||
var projectToRemove = Path.Combine("Lib", "Lib.csproj");
|
||||
var projectToRemoveNormalized = @"Lib\Lib.csproj";
|
||||
var cmd = new DotnetCommand()
|
||||
.WithWorkingDirectory(projectDirectory)
|
||||
.ExecuteWithCapturedOutput($"remove project idontexist.csproj {projectToRemove} idontexisteither.csproj");
|
||||
cmd.Should().Pass();
|
||||
|
||||
string outputText = $@"Project reference `idontexist.csproj` could not be found.
|
||||
Project reference `{projectToRemoveNormalized}` removed.
|
||||
Project reference `idontexisteither.csproj` could not be found.";
|
||||
cmd.StdOut.Should().Be(outputText);
|
||||
|
||||
slnFile = SlnFile.Read(solutionPath);
|
||||
slnFile.Projects.Count.Should().Be(1);
|
||||
slnFile.Projects[0].FilePath.Should().Be(@"App\App.csproj");
|
||||
}
|
||||
}
|
||||
}
|
1
test/dotnet-remove-proj.Tests/MSBuild.exe
Normal file
1
test/dotnet-remove-proj.Tests/MSBuild.exe
Normal file
|
@ -0,0 +1 @@
|
|||
https://github.com/Microsoft/msbuild/issues/927
|
1
test/dotnet-remove-proj.Tests/MSBuild.exe.config
Normal file
1
test/dotnet-remove-proj.Tests/MSBuild.exe.config
Normal file
|
@ -0,0 +1 @@
|
|||
https://github.com/Microsoft/msbuild/issues/927
|
|
@ -0,0 +1,44 @@
|
|||
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" />
|
||||
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp1.0</TargetFramework>
|
||||
<GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>
|
||||
<AssemblyName>dotnet-remove-proj.Tests</AssemblyName>
|
||||
<PackageTargetFallback Condition=" '$(TargetFramework)' == 'netcoreapp1.0' ">$(PackageTargetFallback);dotnet5.4;portable-net451+win8</PackageTargetFallback>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Include="**\*.cs" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Microsoft.DotNet.Tools.Tests.Utilities\Microsoft.DotNet.Tools.Tests.Utilities.csproj" />
|
||||
<ProjectReference Include="..\..\src\Microsoft.DotNet.Cli.Sln.Internal\Microsoft.DotNet.Cli.Sln.Internal.csproj" />
|
||||
<ProjectReference Include="..\..\src\Microsoft.DotNet.Cli.Utils\Microsoft.DotNet.Cli.Utils.csproj" />
|
||||
<ProjectReference Include="..\..\src\Microsoft.DotNet.InternalAbstractions\Microsoft.DotNet.InternalAbstractions.csproj" />
|
||||
<ProjectReference Include="..\..\src\Microsoft.DotNet.TestFramework\Microsoft.DotNet.TestFramework.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.NET.Sdk">
|
||||
<Version>$(CLI_NETSDK_Version)</Version>
|
||||
<PrivateAssets>All</PrivateAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk">
|
||||
<Version>15.0.0-preview-20161024-02</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="xunit.runner.visualstudio">
|
||||
<Version>2.2.0-beta4-build1194</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.NETCore.App">
|
||||
<Version>1.0.1</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="xunit">
|
||||
<Version>2.2.0-beta4-build3444</Version>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
</Project>
|
Loading…
Reference in a new issue