diff --git a/.gitattributes b/.gitattributes index 50950c656..4422d1501 100644 --- a/.gitattributes +++ b/.gitattributes @@ -51,4 +51,5 @@ *.vbproj text=auto *.fsproj text=auto *.dbproj text=auto +*.xlf text=auto *.sln text=auto eol=crlf \ No newline at end of file diff --git a/TestAssets/NonRestoredTestProjects/DotnetAddP2PProjects/Empty/README b/TestAssets/NonRestoredTestProjects/DotnetAddP2PProjects/Empty/README new file mode 100644 index 000000000..439cfe9c7 --- /dev/null +++ b/TestAssets/NonRestoredTestProjects/DotnetAddP2PProjects/Empty/README @@ -0,0 +1,2 @@ +This directory is intentionally empty. + diff --git a/TestAssets/TestProjects/TestAppWithSlnAndCsprojFiles/Empty/README b/TestAssets/TestProjects/TestAppWithSlnAndCsprojFiles/Empty/README new file mode 100644 index 000000000..439cfe9c7 --- /dev/null +++ b/TestAssets/TestProjects/TestAppWithSlnAndCsprojFiles/Empty/README @@ -0,0 +1,2 @@ +This directory is intentionally empty. + diff --git a/TestAssets/TestProjects/TestAppWithSlnAndCsprojFiles/Multiple/First.csproj b/TestAssets/TestProjects/TestAppWithSlnAndCsprojFiles/Multiple/First.csproj new file mode 100644 index 000000000..9f5c4f4ab --- /dev/null +++ b/TestAssets/TestProjects/TestAppWithSlnAndCsprojFiles/Multiple/First.csproj @@ -0,0 +1,7 @@ + + + + netstandard2.0 + + + diff --git a/TestAssets/TestProjects/TestAppWithSlnAndCsprojFiles/Multiple/Second.csproj b/TestAssets/TestProjects/TestAppWithSlnAndCsprojFiles/Multiple/Second.csproj new file mode 100644 index 000000000..9f5c4f4ab --- /dev/null +++ b/TestAssets/TestProjects/TestAppWithSlnAndCsprojFiles/Multiple/Second.csproj @@ -0,0 +1,7 @@ + + + + netstandard2.0 + + + diff --git a/TestAssets/TestProjects/TestAppWithSlnAndCsprojToRemove/Empty/README b/TestAssets/TestProjects/TestAppWithSlnAndCsprojToRemove/Empty/README new file mode 100644 index 000000000..439cfe9c7 --- /dev/null +++ b/TestAssets/TestProjects/TestAppWithSlnAndCsprojToRemove/Empty/README @@ -0,0 +1,2 @@ +This directory is intentionally empty. + diff --git a/TestAssets/TestProjects/TestAppWithSlnAndCsprojToRemove/Multiple/First.csproj b/TestAssets/TestProjects/TestAppWithSlnAndCsprojToRemove/Multiple/First.csproj new file mode 100644 index 000000000..9f5c4f4ab --- /dev/null +++ b/TestAssets/TestProjects/TestAppWithSlnAndCsprojToRemove/Multiple/First.csproj @@ -0,0 +1,7 @@ + + + + netstandard2.0 + + + diff --git a/TestAssets/TestProjects/TestAppWithSlnAndCsprojToRemove/Multiple/Second.csproj b/TestAssets/TestProjects/TestAppWithSlnAndCsprojToRemove/Multiple/Second.csproj new file mode 100644 index 000000000..9f5c4f4ab --- /dev/null +++ b/TestAssets/TestProjects/TestAppWithSlnAndCsprojToRemove/Multiple/Second.csproj @@ -0,0 +1,7 @@ + + + + netstandard2.0 + + + diff --git a/src/Microsoft.DotNet.Cli.Utils/PathUtility.cs b/src/Microsoft.DotNet.Cli.Utils/PathUtility.cs index e0ad71840..32620e0d5 100644 --- a/src/Microsoft.DotNet.Cli.Utils/PathUtility.cs +++ b/src/Microsoft.DotNet.Cli.Utils/PathUtility.cs @@ -330,13 +330,14 @@ namespace Microsoft.DotNet.Tools.Common public static void EnsureAllPathsExist( IReadOnlyCollection paths, - string pathDoesNotExistLocalizedFormatString) + string pathDoesNotExistLocalizedFormatString, + bool allowDirectories = false) { var notExisting = new List(); foreach (var p in paths) { - if (!File.Exists(p)) + if (!File.Exists(p) && (!allowDirectories || !Directory.Exists(p))) { notExisting.Add(p); } diff --git a/src/dotnet/CommonLocalizableStrings.resx b/src/dotnet/CommonLocalizableStrings.resx index d165ca59e..e51b2a473 100644 --- a/src/dotnet/CommonLocalizableStrings.resx +++ b/src/dotnet/CommonLocalizableStrings.resx @@ -345,9 +345,6 @@ Specified solution file {0} does not exist, or there is no solution file in the directory. - - Reference {0} does not exist. - Reference `{0}` is invalid. @@ -384,6 +381,9 @@ Project `{0}` added to the solution. + + Project `{0}` removed from the solution. + Solution {0} already contains project {1}. diff --git a/src/dotnet/SlnFileExtensions.cs b/src/dotnet/SlnFileExtensions.cs index 789318476..84ce82b0d 100644 --- a/src/dotnet/SlnFileExtensions.cs +++ b/src/dotnet/SlnFileExtensions.cs @@ -221,7 +221,7 @@ namespace Microsoft.DotNet.Tools.Common if (projectsToRemove.Count == 0) { Reporter.Output.WriteLine(string.Format( - CommonLocalizableStrings.ProjectReferenceCouldNotBeFound, + CommonLocalizableStrings.ProjectNotFoundInTheSolution, projectPath)); } else @@ -244,7 +244,7 @@ namespace Microsoft.DotNet.Tools.Common slnFile.Projects.Remove(slnProject); Reporter.Output.WriteLine( - string.Format(CommonLocalizableStrings.ProjectReferenceRemoved, slnProject.FilePath)); + string.Format(CommonLocalizableStrings.ProjectRemovedFromTheSolution, slnProject.FilePath)); } foreach (var project in slnFile.Projects) diff --git a/src/dotnet/commands/dotnet-add/dotnet-add-reference/Program.cs b/src/dotnet/commands/dotnet-add/dotnet-add-reference/Program.cs index e79ebfc0c..31d1f716f 100644 --- a/src/dotnet/commands/dotnet-add/dotnet-add-reference/Program.cs +++ b/src/dotnet/commands/dotnet-add/dotnet-add-reference/Program.cs @@ -45,9 +45,9 @@ namespace Microsoft.DotNet.Tools.Add.ProjectToProjectReference var frameworkString = _appliedCommand.ValueOrDefault("framework"); - PathUtility.EnsureAllPathsExist(_appliedCommand.Arguments, CommonLocalizableStrings.ReferenceDoesNotExist); + PathUtility.EnsureAllPathsExist(_appliedCommand.Arguments, CommonLocalizableStrings.CouldNotFindProjectOrDirectory, true); List refs = _appliedCommand.Arguments - .Select((r) => MsbuildProject.FromFile(projects, r)) + .Select((r) => MsbuildProject.FromFileOrDirectory(projects, r)) .ToList(); if (frameworkString == null) @@ -90,9 +90,10 @@ namespace Microsoft.DotNet.Tools.Add.ProjectToProjectReference } } - var relativePathReferences = _appliedCommand.Arguments.Select((r) => - Path.GetRelativePath(msbuildProj.ProjectDirectory, Path.GetFullPath(r))) - .ToList(); + var relativePathReferences = refs.Select((r) => + Path.GetRelativePath( + msbuildProj.ProjectDirectory, + r.ProjectRootElement.FullPath)).ToList(); int numberOfAddedReferences = msbuildProj.AddProjectToProjectReferences( frameworkString, diff --git a/src/dotnet/commands/dotnet-remove/dotnet-remove-reference/Program.cs b/src/dotnet/commands/dotnet-remove/dotnet-remove-reference/Program.cs index e813dda3a..4f8fabb61 100644 --- a/src/dotnet/commands/dotnet-remove/dotnet-remove-reference/Program.cs +++ b/src/dotnet/commands/dotnet-remove/dotnet-remove-reference/Program.cs @@ -2,6 +2,7 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. using System; +using System.IO; using System.Linq; using Microsoft.Build.Evaluation; using Microsoft.DotNet.Cli; @@ -42,10 +43,22 @@ namespace Microsoft.DotNet.Tools.Remove.ProjectToProjectReference public override int Execute() { var msbuildProj = MsbuildProject.FromFileOrDirectory(new ProjectCollection(), _fileOrDirectory); + var references = _appliedCommand.Arguments.Select(p => { + var fullPath = Path.GetFullPath(p); + if (!Directory.Exists(fullPath)) + { + return p; + } + + return Path.GetRelativePath( + msbuildProj.ProjectRootElement.FullPath, + MsbuildProject.GetProjectFileFromDirectory(fullPath).FullName + ); + }); int numberOfRemovedReferences = msbuildProj.RemoveProjectToProjectReferences( _appliedCommand.ValueOrDefault("framework"), - _appliedCommand.Arguments); + references); if (numberOfRemovedReferences != 0) { diff --git a/src/dotnet/commands/dotnet-sln/add/Program.cs b/src/dotnet/commands/dotnet-sln/add/Program.cs index 9ce0a7d09..d49398ba1 100644 --- a/src/dotnet/commands/dotnet-sln/add/Program.cs +++ b/src/dotnet/commands/dotnet-sln/add/Program.cs @@ -40,11 +40,14 @@ namespace Microsoft.DotNet.Tools.Sln.Add throw new GracefulException(CommonLocalizableStrings.SpecifyAtLeastOneProjectToAdd); } - PathUtility.EnsureAllPathsExist(_appliedCommand.Arguments, CommonLocalizableStrings.ProjectDoesNotExist); + PathUtility.EnsureAllPathsExist(_appliedCommand.Arguments, CommonLocalizableStrings.CouldNotFindProjectOrDirectory, true); - var fullProjectPaths = _appliedCommand.Arguments - .Select(Path.GetFullPath) - .ToList(); + var fullProjectPaths = _appliedCommand.Arguments.Select(p => { + var fullPath = Path.GetFullPath(p); + return Directory.Exists(fullPath) ? + MsbuildProject.GetProjectFileFromDirectory(fullPath).FullName : + fullPath; + }).ToList(); var preAddProjectCount = slnFile.Projects.Count; diff --git a/src/dotnet/commands/dotnet-sln/remove/Program.cs b/src/dotnet/commands/dotnet-sln/remove/Program.cs index 973294c6e..4952b7c24 100644 --- a/src/dotnet/commands/dotnet-sln/remove/Program.cs +++ b/src/dotnet/commands/dotnet-sln/remove/Program.cs @@ -40,11 +40,16 @@ namespace Microsoft.DotNet.Tools.Sln.Remove { SlnFile slnFile = SlnFileFactory.CreateFromFileOrDirectory(_fileOrDirectory); - var relativeProjectPaths = _appliedCommand.Arguments.Select(p => - Path.GetRelativePath( - PathUtility.EnsureTrailingSlash(slnFile.BaseDirectory), - Path.GetFullPath(p))) - .ToList(); + var baseDirectory = PathUtility.EnsureTrailingSlash(slnFile.BaseDirectory); + var relativeProjectPaths = _appliedCommand.Arguments.Select(p => { + var fullPath = Path.GetFullPath(p); + return Path.GetRelativePath( + baseDirectory, + Directory.Exists(fullPath) ? + MsbuildProject.GetProjectFileFromDirectory(fullPath).FullName : + fullPath + ); + }); bool slnChanged = false; foreach (var path in relativeProjectPaths) diff --git a/src/dotnet/xlf/CommonLocalizableStrings.cs.xlf b/src/dotnet/xlf/CommonLocalizableStrings.cs.xlf index 56caa7e29..ccc70ef3d 100644 --- a/src/dotnet/xlf/CommonLocalizableStrings.cs.xlf +++ b/src/dotnet/xlf/CommonLocalizableStrings.cs.xlf @@ -97,11 +97,6 @@ Aplikace - - Reference {0} does not exist. - Odkaz na {0} neexistuje. - - Reference `{0}` added to the project. Odkaz na {0} byl přidán do projektu. @@ -674,6 +669,11 @@ Při spuštění příkazu neprovede implicitní obnovení. + + Project `{0}` removed from the solution. + Project `{0}` removed from the solution. + + \ No newline at end of file diff --git a/src/dotnet/xlf/CommonLocalizableStrings.de.xlf b/src/dotnet/xlf/CommonLocalizableStrings.de.xlf index b2c179985..ec92f7055 100644 --- a/src/dotnet/xlf/CommonLocalizableStrings.de.xlf +++ b/src/dotnet/xlf/CommonLocalizableStrings.de.xlf @@ -97,11 +97,6 @@ Anwendung - - Reference {0} does not exist. - Der Verweis "{0}" ist nicht vorhanden. - - Reference `{0}` added to the project. Der Verweis "{0}" wurde dem Projekt hinzugefügt. @@ -674,6 +669,11 @@ Führt beim Ausführen des Befehls keine implizite Wiederherstellung durch. + + Project `{0}` removed from the solution. + Project `{0}` removed from the solution. + + \ No newline at end of file diff --git a/src/dotnet/xlf/CommonLocalizableStrings.es.xlf b/src/dotnet/xlf/CommonLocalizableStrings.es.xlf index f1a9c6402..e00b791e1 100644 --- a/src/dotnet/xlf/CommonLocalizableStrings.es.xlf +++ b/src/dotnet/xlf/CommonLocalizableStrings.es.xlf @@ -97,11 +97,6 @@ Aplicación - - Reference {0} does not exist. - La referencia {0} no existe. - - Reference `{0}` added to the project. Se ha agregado la referencia "{0}" al proyecto. @@ -674,6 +669,11 @@ No realiza una restauración implícita al ejecutar el comando. + + Project `{0}` removed from the solution. + Project `{0}` removed from the solution. + + \ No newline at end of file diff --git a/src/dotnet/xlf/CommonLocalizableStrings.fr.xlf b/src/dotnet/xlf/CommonLocalizableStrings.fr.xlf index b33c6611e..cd9ba1cee 100644 --- a/src/dotnet/xlf/CommonLocalizableStrings.fr.xlf +++ b/src/dotnet/xlf/CommonLocalizableStrings.fr.xlf @@ -97,11 +97,6 @@ Application - - Reference {0} does not exist. - La référence {0} n'existe pas. - - Reference `{0}` added to the project. Référence '{0}' ajoutée au projet. @@ -674,6 +669,11 @@ Ne fait pas de restauration implicite durant l'exécution de la commande. + + Project `{0}` removed from the solution. + Project `{0}` removed from the solution. + + \ No newline at end of file diff --git a/src/dotnet/xlf/CommonLocalizableStrings.it.xlf b/src/dotnet/xlf/CommonLocalizableStrings.it.xlf index b1714f3e5..5ab33a95b 100644 --- a/src/dotnet/xlf/CommonLocalizableStrings.it.xlf +++ b/src/dotnet/xlf/CommonLocalizableStrings.it.xlf @@ -97,11 +97,6 @@ Applicazione - - Reference {0} does not exist. - Il riferimento {0} non esiste. - - Reference `{0}` added to the project. Il riferimento `{0}` è stato aggiunto al progetto. @@ -674,6 +669,11 @@ Non esegue un ripristino implicito durante l'esecuzione del comando. + + Project `{0}` removed from the solution. + Project `{0}` removed from the solution. + + \ No newline at end of file diff --git a/src/dotnet/xlf/CommonLocalizableStrings.ja.xlf b/src/dotnet/xlf/CommonLocalizableStrings.ja.xlf index f95dbf451..4d025f02b 100644 --- a/src/dotnet/xlf/CommonLocalizableStrings.ja.xlf +++ b/src/dotnet/xlf/CommonLocalizableStrings.ja.xlf @@ -97,11 +97,6 @@ アプリケーション - - Reference {0} does not exist. - 参照 {0} は存在しません。 - - Reference `{0}` added to the project. 参照 `{0}` がプロジェクトに追加されました。 @@ -674,6 +669,11 @@ コマンドを実行するときに暗黙的復元を行いません。 + + Project `{0}` removed from the solution. + Project `{0}` removed from the solution. + + \ No newline at end of file diff --git a/src/dotnet/xlf/CommonLocalizableStrings.ko.xlf b/src/dotnet/xlf/CommonLocalizableStrings.ko.xlf index 029bc8c0c..f9f9a96c0 100644 --- a/src/dotnet/xlf/CommonLocalizableStrings.ko.xlf +++ b/src/dotnet/xlf/CommonLocalizableStrings.ko.xlf @@ -97,11 +97,6 @@ 응용 프로그램 - - Reference {0} does not exist. - {0} 참조가 없습니다. - - Reference `{0}` added to the project. 프로젝트에 '{0}' 참조가 추가되었습니다. @@ -674,6 +669,11 @@ 명령을 실행할 때 암시적 복원을 수행하지 않습니다. + + Project `{0}` removed from the solution. + Project `{0}` removed from the solution. + + \ No newline at end of file diff --git a/src/dotnet/xlf/CommonLocalizableStrings.pl.xlf b/src/dotnet/xlf/CommonLocalizableStrings.pl.xlf index 1db654dd8..ca40ba7d5 100644 --- a/src/dotnet/xlf/CommonLocalizableStrings.pl.xlf +++ b/src/dotnet/xlf/CommonLocalizableStrings.pl.xlf @@ -97,11 +97,6 @@ Aplikacja - - Reference {0} does not exist. - Odwołanie {0} nie istnieje. - - Reference `{0}` added to the project. Do projektu zostało dodane odwołanie „{0}”. @@ -674,6 +669,11 @@ Nie wykonuje niejawnego przywracania podczas wykonywania polecenia. + + Project `{0}` removed from the solution. + Project `{0}` removed from the solution. + + \ No newline at end of file diff --git a/src/dotnet/xlf/CommonLocalizableStrings.pt-BR.xlf b/src/dotnet/xlf/CommonLocalizableStrings.pt-BR.xlf index 89cc1e55d..1fe5abd21 100644 --- a/src/dotnet/xlf/CommonLocalizableStrings.pt-BR.xlf +++ b/src/dotnet/xlf/CommonLocalizableStrings.pt-BR.xlf @@ -97,11 +97,6 @@ Aplicativo - - Reference {0} does not exist. - A referência {0} não existe. - - Reference `{0}` added to the project. A referência ‘{0}’ foi adicionada ao projeto. @@ -674,6 +669,11 @@ Não faz uma restauração implícita ao executar o comando. + + Project `{0}` removed from the solution. + Project `{0}` removed from the solution. + + \ No newline at end of file diff --git a/src/dotnet/xlf/CommonLocalizableStrings.ru.xlf b/src/dotnet/xlf/CommonLocalizableStrings.ru.xlf index a63e439a0..5f250b68d 100644 --- a/src/dotnet/xlf/CommonLocalizableStrings.ru.xlf +++ b/src/dotnet/xlf/CommonLocalizableStrings.ru.xlf @@ -97,11 +97,6 @@ Приложение - - Reference {0} does not exist. - Ссылка {0} не существует. - - Reference `{0}` added to the project. Ссылка "{0}" добавлена в проект. @@ -674,6 +669,11 @@ Не выполняет неявное восстановление при выполнении команды. + + Project `{0}` removed from the solution. + Project `{0}` removed from the solution. + + \ No newline at end of file diff --git a/src/dotnet/xlf/CommonLocalizableStrings.tr.xlf b/src/dotnet/xlf/CommonLocalizableStrings.tr.xlf index 6584fc018..7ddbad9b0 100644 --- a/src/dotnet/xlf/CommonLocalizableStrings.tr.xlf +++ b/src/dotnet/xlf/CommonLocalizableStrings.tr.xlf @@ -97,11 +97,6 @@ Uygulama - - Reference {0} does not exist. - {0} başvurusu yok. - - Reference `{0}` added to the project. `{0}` başvurusu projeye eklendi. @@ -674,6 +669,11 @@ Komut yürütülürken örtük geri yükleme gerçekleştirmez. + + Project `{0}` removed from the solution. + Project `{0}` removed from the solution. + + \ No newline at end of file diff --git a/src/dotnet/xlf/CommonLocalizableStrings.zh-Hans.xlf b/src/dotnet/xlf/CommonLocalizableStrings.zh-Hans.xlf index 2fdb31f54..c3bf2ce59 100644 --- a/src/dotnet/xlf/CommonLocalizableStrings.zh-Hans.xlf +++ b/src/dotnet/xlf/CommonLocalizableStrings.zh-Hans.xlf @@ -97,11 +97,6 @@ 应用程序 - - Reference {0} does not exist. - 引用 {0} 不存在。 - - Reference `{0}` added to the project. 已将引用“{0}”添加到项目。 @@ -674,6 +669,11 @@ 请勿在执行命令时进行隐式还原。 + + Project `{0}` removed from the solution. + Project `{0}` removed from the solution. + + \ No newline at end of file diff --git a/src/dotnet/xlf/CommonLocalizableStrings.zh-Hant.xlf b/src/dotnet/xlf/CommonLocalizableStrings.zh-Hant.xlf index 2e0845e40..4a6eedb67 100644 --- a/src/dotnet/xlf/CommonLocalizableStrings.zh-Hant.xlf +++ b/src/dotnet/xlf/CommonLocalizableStrings.zh-Hant.xlf @@ -97,11 +97,6 @@ 應用程式 - - Reference {0} does not exist. - 參考 {0} 不存在。 - - Reference `{0}` added to the project. 參考 `{0}` 已新增至專案。 @@ -674,6 +669,11 @@ 執行此命令時,請勿進行隱含還原。 + + Project `{0}` removed from the solution. + Project `{0}` removed from the solution. + + \ No newline at end of file diff --git a/test/dotnet-add-reference.Tests/GivenDotnetAddReference.cs b/test/dotnet-add-reference.Tests/GivenDotnetAddReference.cs index ba37b1e73..75269124f 100644 --- a/test/dotnet-add-reference.Tests/GivenDotnetAddReference.cs +++ b/test/dotnet-add-reference.Tests/GivenDotnetAddReference.cs @@ -559,7 +559,7 @@ Commands: .WithProject(lib.CsProjName) .Execute("\"IDoNotExist.csproj\""); cmd.Should().Fail(); - cmd.StdErr.Should().Be(string.Format(CommonLocalizableStrings.ReferenceDoesNotExist, "IDoNotExist.csproj")); + cmd.StdErr.Should().Be(string.Format(CommonLocalizableStrings.CouldNotFindProjectOrDirectory, "IDoNotExist.csproj")); lib.CsProjContent().Should().BeEquivalentTo(contentBefore); } @@ -575,7 +575,7 @@ Commands: .WithProject(lib.CsProjPath) .Execute($"\"{setup.ValidRefCsprojPath}\" \"IDoNotExist.csproj\""); cmd.Should().Fail(); - cmd.StdErr.Should().Be(string.Format(CommonLocalizableStrings.ReferenceDoesNotExist, "IDoNotExist.csproj")); + cmd.StdErr.Should().Be(string.Format(CommonLocalizableStrings.CouldNotFindProjectOrDirectory, "IDoNotExist.csproj")); lib.CsProjContent().Should().BeEquivalentTo(contentBefore); } @@ -693,5 +693,55 @@ Commands: cmd.StdErr.Should().MatchRegex(" - net45"); net45lib.CsProjContent().Should().BeEquivalentTo(csProjContent); } + + [Fact] + public void WhenDirectoryContainingProjectIsGivenReferenceIsAdded() + { + var setup = Setup(); + var lib = NewLibWithFrameworks(dir: setup.TestRoot); + + var result = new AddReferenceCommand() + .WithWorkingDirectory(setup.TestRoot) + .WithProject(lib.CsProjPath) + .Execute($"\"{Path.GetDirectoryName(setup.ValidRefCsprojPath)}\""); + + result.Should().Pass(); + result.StdOut.Should().Be(string.Format(CommonLocalizableStrings.ReferenceAddedToTheProject, @"ValidRef\ValidRef.csproj")); + result.StdErr.Should().BeEmpty(); + } + + [Fact] + public void WhenDirectoryContainsNoProjectsItCancelsWholeOperation() + { + var setup = Setup(); + var lib = NewLibWithFrameworks(dir: setup.TestRoot); + + var reference = "Empty"; + var result = new AddReferenceCommand() + .WithWorkingDirectory(setup.TestRoot) + .WithProject(lib.CsProjPath) + .Execute(reference); + + result.Should().Fail(); + result.StdOut.Should().BeVisuallyEquivalentToIfNotLocalized(HelpText); + result.StdErr.Should().Be(string.Format(CommonLocalizableStrings.CouldNotFindAnyProjectInDirectory, reference)); + } + + [Fact] + public void WhenDirectoryContainsMultipleProjectsItCancelsWholeOperation() + { + var setup = Setup(); + var lib = NewLibWithFrameworks(dir: setup.TestRoot); + + var reference = "MoreThanOne"; + var result = new AddReferenceCommand() + .WithWorkingDirectory(setup.TestRoot) + .WithProject(lib.CsProjPath) + .Execute(reference); + + result.Should().Fail(); + result.StdOut.Should().BeVisuallyEquivalentToIfNotLocalized(HelpText); + result.StdErr.Should().Be(string.Format(CommonLocalizableStrings.MoreThanOneProjectInDirectory, reference)); + } } } diff --git a/test/dotnet-remove-reference.Tests/GivenDotnetRemoveP2P.cs b/test/dotnet-remove-reference.Tests/GivenDotnetRemoveP2P.cs index 65da417b2..b557ff5df 100644 --- a/test/dotnet-remove-reference.Tests/GivenDotnetRemoveP2P.cs +++ b/test/dotnet-remove-reference.Tests/GivenDotnetRemoveP2P.cs @@ -506,5 +506,56 @@ Commands: csproj.NumberOfItemGroupsWithoutCondition().Should().Be(noCondBefore - 1); csproj.NumberOfProjectReferencesWithIncludeContaining(validref.Name).Should().Be(0); } + + [Fact] + public void WhenDirectoryContainingProjectIsGivenReferenceIsRemoved() + { + var setup = Setup(); + var lib = NewLibWithFrameworks(dir: setup.TestRoot); + var libref = AddLibRef(setup, lib); + + var result = new RemoveReferenceCommand() + .WithWorkingDirectory(setup.TestRoot) + .WithProject(lib.CsProjPath) + .Execute($"\"{libref.CsProjPath}\""); + + result.Should().Pass(); + result.StdOut.Should().Be(string.Format(CommonLocalizableStrings.ProjectReferenceRemoved, Path.Combine("Lib", setup.LibCsprojName))); + result.StdErr.Should().BeEmpty(); + } + + [Fact] + public void WhenDirectoryContainsNoProjectsItCancelsWholeOperation() + { + var setup = Setup(); + var lib = NewLibWithFrameworks(dir: setup.TestRoot); + + var reference = "Empty"; + var result = new RemoveReferenceCommand() + .WithWorkingDirectory(setup.TestRoot) + .WithProject(lib.CsProjPath) + .Execute(reference); + + result.Should().Fail(); + result.StdOut.Should().BeVisuallyEquivalentToIfNotLocalized(HelpText); + result.StdErr.Should().Be(string.Format(CommonLocalizableStrings.CouldNotFindAnyProjectInDirectory, Path.Combine(setup.TestRoot, reference))); + } + + [Fact] + public void WhenDirectoryContainsMultipleProjectsItCancelsWholeOperation() + { + var setup = Setup(); + var lib = NewLibWithFrameworks(dir: setup.TestRoot); + + var reference = "MoreThanOne"; + var result = new RemoveReferenceCommand() + .WithWorkingDirectory(setup.TestRoot) + .WithProject(lib.CsProjPath) + .Execute(reference); + + result.Should().Fail(); + result.StdOut.Should().BeVisuallyEquivalentToIfNotLocalized(HelpText); + result.StdErr.Should().Be(string.Format(CommonLocalizableStrings.MoreThanOneProjectInDirectory, Path.Combine(setup.TestRoot, reference))); + } } } diff --git a/test/dotnet-sln-add.Tests/GivenDotnetSlnAdd.cs b/test/dotnet-sln-add.Tests/GivenDotnetSlnAdd.cs index 3d245115f..13fe61606 100644 --- a/test/dotnet-sln-add.Tests/GivenDotnetSlnAdd.cs +++ b/test/dotnet-sln-add.Tests/GivenDotnetSlnAdd.cs @@ -359,6 +359,81 @@ EndGlobal .Should().BeVisuallyEquivalentTo(expectedSlnContents); } + [Fact] + public void WhenDirectoryContainingProjectIsGivenProjectIsAdded() + { + var projectDirectory = TestAssets + .Get("TestAppWithSlnAndCsprojFiles") + .CreateInstance() + .WithSourceFiles() + .Root + .FullName; + + var cmd = new DotnetCommand() + .WithWorkingDirectory(projectDirectory) + .ExecuteWithCapturedOutput("sln add Lib"); + cmd.Should().Pass(); + + var slnPath = Path.Combine(projectDirectory, "App.sln"); + var expectedSlnContents = GetExpectedSlnContents(slnPath, ExpectedSlnFileAfterAddingLibProj); + File.ReadAllText(slnPath) + .Should().BeVisuallyEquivalentTo(expectedSlnContents); + } + + [Fact] + public void WhenDirectoryContainsNoProjectsItCancelsWholeOperation() + { + var projectDirectory = TestAssets + .Get("TestAppWithSlnAndCsprojFiles") + .CreateInstance() + .WithSourceFiles() + .Root + .FullName; + + var slnFullPath = Path.Combine(projectDirectory, "App.sln"); + var contentBefore = File.ReadAllText(slnFullPath); + var directoryToAdd = "Empty"; + + var cmd = new DotnetCommand() + .WithWorkingDirectory(projectDirectory) + .ExecuteWithCapturedOutput($"sln add {directoryToAdd}"); + cmd.Should().Fail(); + cmd.StdErr.Should().Be( + string.Format( + CommonLocalizableStrings.CouldNotFindAnyProjectInDirectory, + Path.Combine(projectDirectory, directoryToAdd))); + + File.ReadAllText(slnFullPath) + .Should().BeVisuallyEquivalentTo(contentBefore); + } + + [Fact] + public void WhenDirectoryContainsMultipleProjectsItCancelsWholeOperation() + { + var projectDirectory = TestAssets + .Get("TestAppWithSlnAndCsprojFiles") + .CreateInstance() + .WithSourceFiles() + .Root + .FullName; + + var slnFullPath = Path.Combine(projectDirectory, "App.sln"); + var contentBefore = File.ReadAllText(slnFullPath); + var directoryToAdd = "Multiple"; + + var cmd = new DotnetCommand() + .WithWorkingDirectory(projectDirectory) + .ExecuteWithCapturedOutput($"sln add {directoryToAdd}"); + cmd.Should().Fail(); + cmd.StdErr.Should().Be( + string.Format( + CommonLocalizableStrings.MoreThanOneProjectInDirectory, + Path.Combine(projectDirectory, directoryToAdd))); + + File.ReadAllText(slnFullPath) + .Should().BeVisuallyEquivalentTo(contentBefore); + } + [Fact] public void WhenProjectDirectoryIsAddedSolutionFoldersAreNotCreated() { @@ -597,7 +672,7 @@ EndGlobal .WithWorkingDirectory(projectDirectory) .ExecuteWithCapturedOutput($"sln App.sln add {projectToAdd} idonotexist.csproj"); cmd.Should().Fail(); - cmd.StdErr.Should().Be(string.Format(CommonLocalizableStrings.ProjectDoesNotExist, "idonotexist.csproj")); + cmd.StdErr.Should().Be(string.Format(CommonLocalizableStrings.CouldNotFindProjectOrDirectory, "idonotexist.csproj")); File.ReadAllText(slnFullPath) .Should().BeVisuallyEquivalentTo(contentBefore); diff --git a/test/dotnet-sln-remove.Tests/GivenDotnetSlnRemove.cs b/test/dotnet-sln-remove.Tests/GivenDotnetSlnRemove.cs index 0b0b6a7e2..50c6f00e5 100644 --- a/test/dotnet-sln-remove.Tests/GivenDotnetSlnRemove.cs +++ b/test/dotnet-sln-remove.Tests/GivenDotnetSlnRemove.cs @@ -367,7 +367,7 @@ EndGlobal .WithWorkingDirectory(projectDirectory) .ExecuteWithCapturedOutput("sln remove referenceDoesNotExistInSln.csproj"); cmd.Should().Pass(); - cmd.StdOut.Should().Be(string.Format(CommonLocalizableStrings.ProjectReferenceCouldNotBeFound, "referenceDoesNotExistInSln.csproj")); + cmd.StdOut.Should().Be(string.Format(CommonLocalizableStrings.ProjectNotFoundInTheSolution, "referenceDoesNotExistInSln.csproj")); File.ReadAllText(solutionPath) .Should().BeVisuallyEquivalentTo(contentBefore); } @@ -391,7 +391,7 @@ EndGlobal .WithWorkingDirectory(projectDirectory) .ExecuteWithCapturedOutput($"sln remove {projectToRemove}"); cmd.Should().Pass(); - cmd.StdOut.Should().Be(string.Format(CommonLocalizableStrings.ProjectReferenceRemoved, projectToRemove)); + cmd.StdOut.Should().Be(string.Format(CommonLocalizableStrings.ProjectRemovedFromTheSolution, projectToRemove)); slnFile = SlnFile.Read(solutionPath); slnFile.Projects.Count.Should().Be(1); @@ -418,7 +418,7 @@ EndGlobal .ExecuteWithCapturedOutput($"sln remove {projectToRemove}"); cmd.Should().Pass(); - string outputText = string.Format(CommonLocalizableStrings.ProjectReferenceRemoved, projectToRemove); + string outputText = string.Format(CommonLocalizableStrings.ProjectRemovedFromTheSolution, projectToRemove); outputText += Environment.NewLine + outputText; cmd.StdOut.Should().BeVisuallyEquivalentTo(outputText); @@ -447,9 +447,9 @@ EndGlobal .ExecuteWithCapturedOutput($"sln remove idontexist.csproj {projectToRemove} idontexisteither.csproj"); cmd.Should().Pass(); - string outputText = $@"{string.Format(CommonLocalizableStrings.ProjectReferenceCouldNotBeFound, "idontexist.csproj")} -{string.Format(CommonLocalizableStrings.ProjectReferenceRemoved, projectToRemove)} -{string.Format(CommonLocalizableStrings.ProjectReferenceCouldNotBeFound, "idontexisteither.csproj")}"; + string outputText = $@"{string.Format(CommonLocalizableStrings.ProjectNotFoundInTheSolution, "idontexist.csproj")} +{string.Format(CommonLocalizableStrings.ProjectRemovedFromTheSolution, projectToRemove)} +{string.Format(CommonLocalizableStrings.ProjectNotFoundInTheSolution, "idontexisteither.csproj")}"; cmd.StdOut.Should().BeVisuallyEquivalentTo(outputText); @@ -482,6 +482,73 @@ EndGlobal .Should().BeVisuallyEquivalentTo(ExpectedSlnContentsAfterRemove); } + [Fact] + public void WhenDirectoryContainingProjectIsGivenProjectIsRemoved() + { + var projectDirectory = TestAssets + .Get("TestAppWithSlnAndCsprojToRemove") + .CreateInstance() + .WithSourceFiles() + .Root + .FullName; + + var solutionPath = Path.Combine(projectDirectory, "App.sln"); + SlnFile slnFile = SlnFile.Read(solutionPath); + slnFile.Projects.Count.Should().Be(2); + + var cmd = new DotnetCommand() + .WithWorkingDirectory(projectDirectory) + .ExecuteWithCapturedOutput("sln remove Lib"); + cmd.Should().Pass(); + + File.ReadAllText(solutionPath) + .Should().BeVisuallyEquivalentTo(ExpectedSlnContentsAfterRemove); + } + + [Fact] + public void WhenDirectoryContainsNoProjectsItCancelsWholeOperation() + { + var projectDirectory = TestAssets + .Get("TestAppWithSlnAndCsprojToRemove") + .CreateInstance() + .WithSourceFiles() + .Root + .FullName; + var directoryToRemove = "Empty"; + + var cmd = new DotnetCommand() + .WithWorkingDirectory(projectDirectory) + .ExecuteWithCapturedOutput($"sln remove {directoryToRemove}"); + cmd.Should().Fail(); + cmd.StdErr.Should().Be( + string.Format( + CommonLocalizableStrings.CouldNotFindAnyProjectInDirectory, + Path.Combine(projectDirectory, directoryToRemove))); + cmd.StdOut.Should().BeVisuallyEquivalentToIfNotLocalized(HelpText); + } + + [Fact] + public void WhenDirectoryContainsMultipleProjectsItCancelsWholeOperation() + { + var projectDirectory = TestAssets + .Get("TestAppWithSlnAndCsprojToRemove") + .CreateInstance() + .WithSourceFiles() + .Root + .FullName; + var directoryToRemove = "Multiple"; + + var cmd = new DotnetCommand() + .WithWorkingDirectory(projectDirectory) + .ExecuteWithCapturedOutput($"sln remove {directoryToRemove}"); + cmd.Should().Fail(); + cmd.StdErr.Should().Be( + string.Format( + CommonLocalizableStrings.MoreThanOneProjectInDirectory, + Path.Combine(projectDirectory, directoryToRemove))); + cmd.StdOut.Should().BeVisuallyEquivalentToIfNotLocalized(HelpText); + } + [Fact] public void WhenReferenceIsRemovedSlnBuilds() {