From 1d1c4b06dde9d5332b09c63fa9c0bdafbff645ad Mon Sep 17 00:00:00 2001 From: Eduardo Villalpando Mello Date: Wed, 30 Oct 2024 11:57:17 -0700 Subject: [PATCH 01/60] [IMP] sln-list: Support for slnx Refactor code Refactor code Add translations Fix typo Fix issues with --solution-folders Standarize error messages and tests Fix solution folder formatting Nit: Address pr comments --- .../dotnet/commands/dotnet-sln/LocalizableStrings.resx | 4 ++-- src/Cli/dotnet/commands/dotnet-sln/list/Program.cs | 1 + .../commands/dotnet-sln/xlf/LocalizableStrings.cs.xlf | 8 ++++---- .../commands/dotnet-sln/xlf/LocalizableStrings.de.xlf | 8 ++++---- .../commands/dotnet-sln/xlf/LocalizableStrings.es.xlf | 8 ++++---- .../commands/dotnet-sln/xlf/LocalizableStrings.fr.xlf | 8 ++++---- .../commands/dotnet-sln/xlf/LocalizableStrings.it.xlf | 8 ++++---- .../commands/dotnet-sln/xlf/LocalizableStrings.ja.xlf | 8 ++++---- .../commands/dotnet-sln/xlf/LocalizableStrings.ko.xlf | 8 ++++---- .../commands/dotnet-sln/xlf/LocalizableStrings.pl.xlf | 8 ++++---- .../commands/dotnet-sln/xlf/LocalizableStrings.pt-BR.xlf | 8 ++++---- .../commands/dotnet-sln/xlf/LocalizableStrings.ru.xlf | 8 ++++---- .../commands/dotnet-sln/xlf/LocalizableStrings.tr.xlf | 8 ++++---- .../dotnet-sln/xlf/LocalizableStrings.zh-Hans.xlf | 8 ++++---- .../dotnet-sln/xlf/LocalizableStrings.zh-Hant.xlf | 8 ++++---- 15 files changed, 55 insertions(+), 54 deletions(-) diff --git a/src/Cli/dotnet/commands/dotnet-sln/LocalizableStrings.resx b/src/Cli/dotnet/commands/dotnet-sln/LocalizableStrings.resx index 4748d3d4504b..9e4647d556fa 100644 --- a/src/Cli/dotnet/commands/dotnet-sln/LocalizableStrings.resx +++ b/src/Cli/dotnet/commands/dotnet-sln/LocalizableStrings.resx @@ -184,9 +184,9 @@ .slnx file {0} generated. - Only .sln files can be migrated to .slnx format. + Cannot migrate .slnx file. - Could not read solution file {0}. Supported files are .sln and .slnx valid solutions. + Could not find serializer for file {0}. \ No newline at end of file diff --git a/src/Cli/dotnet/commands/dotnet-sln/list/Program.cs b/src/Cli/dotnet/commands/dotnet-sln/list/Program.cs index 99b948207011..9dfb1f5f6f71 100644 --- a/src/Cli/dotnet/commands/dotnet-sln/list/Program.cs +++ b/src/Cli/dotnet/commands/dotnet-sln/list/Program.cs @@ -39,6 +39,7 @@ public override int Execute() private async Task ListAllProjectsAsync(string solutionFileFullPath, CancellationToken cancellationToken) { + Guid solutionFolderGuid = new Guid(ProjectTypeGuids.SolutionFolderGuid); ISolutionSerializer serializer = SlnCommandParser.GetSolutionSerializer(solutionFileFullPath); SolutionModel solution = await serializer.OpenAsync(solutionFileFullPath, cancellationToken); string[] paths; diff --git a/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.cs.xlf b/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.cs.xlf index f5b32233e7d0..4bab05e710d3 100644 --- a/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.cs.xlf +++ b/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.cs.xlf @@ -28,8 +28,8 @@ - Only .sln files can be migrated to .slnx format. - Only .sln files can be migrated to .slnx format. + Cannot migrate .slnx file. + Cannot migrate .slnx file. @@ -68,8 +68,8 @@ - Could not read solution file {0}. Supported files are .sln and .slnx valid solutions. - Could not read solution file {0}. Supported files are .sln and .slnx valid solutions. + Could not find serializer for file {0}. + Could not find serializer for file {0}. diff --git a/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.de.xlf b/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.de.xlf index f8eb231f7950..d5f7d7054d71 100644 --- a/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.de.xlf +++ b/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.de.xlf @@ -28,8 +28,8 @@ - Only .sln files can be migrated to .slnx format. - Only .sln files can be migrated to .slnx format. + Cannot migrate .slnx file. + Cannot migrate .slnx file. @@ -68,8 +68,8 @@ - Could not read solution file {0}. Supported files are .sln and .slnx valid solutions. - Could not read solution file {0}. Supported files are .sln and .slnx valid solutions. + Could not find serializer for file {0}. + Could not find serializer for file {0}. diff --git a/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.es.xlf b/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.es.xlf index 6ed23a5e39fe..c36ef1717c81 100644 --- a/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.es.xlf +++ b/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.es.xlf @@ -28,8 +28,8 @@ - Only .sln files can be migrated to .slnx format. - Only .sln files can be migrated to .slnx format. + Cannot migrate .slnx file. + Cannot migrate .slnx file. @@ -68,8 +68,8 @@ - Could not read solution file {0}. Supported files are .sln and .slnx valid solutions. - Could not read solution file {0}. Supported files are .sln and .slnx valid solutions. + Could not find serializer for file {0}. + Could not find serializer for file {0}. diff --git a/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.fr.xlf b/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.fr.xlf index b1d8c5880aff..66cd0437b80d 100644 --- a/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.fr.xlf +++ b/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.fr.xlf @@ -28,8 +28,8 @@ - Only .sln files can be migrated to .slnx format. - Only .sln files can be migrated to .slnx format. + Cannot migrate .slnx file. + Cannot migrate .slnx file. @@ -68,8 +68,8 @@ - Could not read solution file {0}. Supported files are .sln and .slnx valid solutions. - Could not read solution file {0}. Supported files are .sln and .slnx valid solutions. + Could not find serializer for file {0}. + Could not find serializer for file {0}. diff --git a/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.it.xlf b/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.it.xlf index 989a4f33844e..63a4dca3e966 100644 --- a/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.it.xlf +++ b/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.it.xlf @@ -28,8 +28,8 @@ - Only .sln files can be migrated to .slnx format. - Only .sln files can be migrated to .slnx format. + Cannot migrate .slnx file. + Cannot migrate .slnx file. @@ -68,8 +68,8 @@ - Could not read solution file {0}. Supported files are .sln and .slnx valid solutions. - Could not read solution file {0}. Supported files are .sln and .slnx valid solutions. + Could not find serializer for file {0}. + Could not find serializer for file {0}. diff --git a/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.ja.xlf b/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.ja.xlf index 2683028f11aa..fa49b36f3c7c 100644 --- a/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.ja.xlf +++ b/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.ja.xlf @@ -28,8 +28,8 @@ - Only .sln files can be migrated to .slnx format. - Only .sln files can be migrated to .slnx format. + Cannot migrate .slnx file. + Cannot migrate .slnx file. @@ -68,8 +68,8 @@ - Could not read solution file {0}. Supported files are .sln and .slnx valid solutions. - Could not read solution file {0}. Supported files are .sln and .slnx valid solutions. + Could not find serializer for file {0}. + Could not find serializer for file {0}. diff --git a/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.ko.xlf b/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.ko.xlf index 895400338f29..ec6fcef3b737 100644 --- a/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.ko.xlf +++ b/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.ko.xlf @@ -28,8 +28,8 @@ - Only .sln files can be migrated to .slnx format. - Only .sln files can be migrated to .slnx format. + Cannot migrate .slnx file. + Cannot migrate .slnx file. @@ -68,8 +68,8 @@ - Could not read solution file {0}. Supported files are .sln and .slnx valid solutions. - Could not read solution file {0}. Supported files are .sln and .slnx valid solutions. + Could not find serializer for file {0}. + Could not find serializer for file {0}. diff --git a/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.pl.xlf b/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.pl.xlf index e384d5d00475..601ff500d1cc 100644 --- a/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.pl.xlf +++ b/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.pl.xlf @@ -28,8 +28,8 @@ - Only .sln files can be migrated to .slnx format. - Only .sln files can be migrated to .slnx format. + Cannot migrate .slnx file. + Cannot migrate .slnx file. @@ -68,8 +68,8 @@ - Could not read solution file {0}. Supported files are .sln and .slnx valid solutions. - Could not read solution file {0}. Supported files are .sln and .slnx valid solutions. + Could not find serializer for file {0}. + Could not find serializer for file {0}. diff --git a/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.pt-BR.xlf b/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.pt-BR.xlf index ba4d879b8340..6d941b650f1e 100644 --- a/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.pt-BR.xlf +++ b/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.pt-BR.xlf @@ -28,8 +28,8 @@ - Only .sln files can be migrated to .slnx format. - Only .sln files can be migrated to .slnx format. + Cannot migrate .slnx file. + Cannot migrate .slnx file. @@ -68,8 +68,8 @@ - Could not read solution file {0}. Supported files are .sln and .slnx valid solutions. - Could not read solution file {0}. Supported files are .sln and .slnx valid solutions. + Could not find serializer for file {0}. + Could not find serializer for file {0}. diff --git a/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.ru.xlf b/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.ru.xlf index c5dfbd52a60c..6960662f0eed 100644 --- a/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.ru.xlf +++ b/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.ru.xlf @@ -28,8 +28,8 @@ - Only .sln files can be migrated to .slnx format. - Only .sln files can be migrated to .slnx format. + Cannot migrate .slnx file. + Cannot migrate .slnx file. @@ -68,8 +68,8 @@ - Could not read solution file {0}. Supported files are .sln and .slnx valid solutions. - Could not read solution file {0}. Supported files are .sln and .slnx valid solutions. + Could not find serializer for file {0}. + Could not find serializer for file {0}. diff --git a/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.tr.xlf b/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.tr.xlf index fea7bcc4ea34..a705f8605a87 100644 --- a/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.tr.xlf +++ b/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.tr.xlf @@ -28,8 +28,8 @@ - Only .sln files can be migrated to .slnx format. - Only .sln files can be migrated to .slnx format. + Cannot migrate .slnx file. + Cannot migrate .slnx file. @@ -68,8 +68,8 @@ - Could not read solution file {0}. Supported files are .sln and .slnx valid solutions. - Could not read solution file {0}. Supported files are .sln and .slnx valid solutions. + Could not find serializer for file {0}. + Could not find serializer for file {0}. diff --git a/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.zh-Hans.xlf b/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.zh-Hans.xlf index 82241d2d4a6a..533a67153faf 100644 --- a/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.zh-Hans.xlf +++ b/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.zh-Hans.xlf @@ -28,8 +28,8 @@ - Only .sln files can be migrated to .slnx format. - Only .sln files can be migrated to .slnx format. + Cannot migrate .slnx file. + Cannot migrate .slnx file. @@ -68,8 +68,8 @@ - Could not read solution file {0}. Supported files are .sln and .slnx valid solutions. - Could not read solution file {0}. Supported files are .sln and .slnx valid solutions. + Could not find serializer for file {0}. + Could not find serializer for file {0}. diff --git a/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.zh-Hant.xlf b/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.zh-Hant.xlf index 5b061ec4f5f2..fcf5d583a1ba 100644 --- a/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.zh-Hant.xlf +++ b/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.zh-Hant.xlf @@ -28,8 +28,8 @@ - Only .sln files can be migrated to .slnx format. - Only .sln files can be migrated to .slnx format. + Cannot migrate .slnx file. + Cannot migrate .slnx file. @@ -68,8 +68,8 @@ - Could not read solution file {0}. Supported files are .sln and .slnx valid solutions. - Could not read solution file {0}. Supported files are .sln and .slnx valid solutions. + Could not find serializer for file {0}. + Could not find serializer for file {0}. From bdff950c523ff98c4d4963d9f125c88bbfae4f2b Mon Sep 17 00:00:00 2001 From: Eduardo Villalpando Mello Date: Thu, 31 Oct 2024 15:23:18 -0700 Subject: [PATCH 02/60] sln-add: Support for slnx --- .../dotnet/commands/dotnet-sln/add/Program.cs | 69 +++++++++---------- 1 file changed, 31 insertions(+), 38 deletions(-) diff --git a/src/Cli/dotnet/commands/dotnet-sln/add/Program.cs b/src/Cli/dotnet/commands/dotnet-sln/add/Program.cs index ded4c5fc3968..6bc9672a8580 100644 --- a/src/Cli/dotnet/commands/dotnet-sln/add/Program.cs +++ b/src/Cli/dotnet/commands/dotnet-sln/add/Program.cs @@ -6,6 +6,8 @@ using Microsoft.DotNet.Cli.Sln.Internal; using Microsoft.DotNet.Cli.Utils; using Microsoft.DotNet.Tools.Common; +using Microsoft.VisualStudio.SolutionPersistence; +using Microsoft.VisualStudio.SolutionPersistence.Model; namespace Microsoft.DotNet.Tools.Sln.Add { @@ -14,18 +16,18 @@ internal class AddProjectToSolutionCommand : CommandBase private readonly string _fileOrDirectory; private readonly bool _inRoot; private readonly IList _relativeRootSolutionFolders; - private readonly IReadOnlyCollection _arguments; + private readonly IReadOnlyCollection _projects; public AddProjectToSolutionCommand(ParseResult parseResult) : base(parseResult) { _fileOrDirectory = parseResult.GetValue(SlnCommandParser.SlnArgument); - _arguments = parseResult.GetValue(SlnAddParser.ProjectPathArgument)?.ToArray() ?? (IReadOnlyCollection)Array.Empty(); + _projects = parseResult.GetValue(SlnAddParser.ProjectPathArgument)?.ToArray() ?? (IReadOnlyCollection)Array.Empty(); _inRoot = parseResult.GetValue(SlnAddParser.InRootOption); string relativeRoot = parseResult.GetValue(SlnAddParser.SolutionFolderOption); - SlnArgumentValidator.ParseAndValidateArguments(_fileOrDirectory, _arguments, SlnArgumentValidator.CommandType.Add, _inRoot, relativeRoot); + SlnArgumentValidator.ParseAndValidateArguments(_fileOrDirectory, _projects, SlnArgumentValidator.CommandType.Add, _inRoot, relativeRoot); bool hasRelativeRoot = !string.IsNullOrEmpty(relativeRoot); @@ -42,40 +44,41 @@ public AddProjectToSolutionCommand(ParseResult parseResult) : base(parseResult) public override int Execute() { - SlnFile slnFile = SlnFileFactory.CreateFromFileOrDirectory(_fileOrDirectory); + var solutionFileFullPath = SlnCommandParser.GetSlnFileFullPath(_fileOrDirectory); - var arguments = (_parseResult.GetValue>(SlnAddParser.ProjectPathArgument) ?? Array.Empty()).ToList().AsReadOnly(); - if (arguments.Count == 0) + if (_projects.Count == 0) { throw new GracefulException(CommonLocalizableStrings.SpecifyAtLeastOneProjectToAdd); } - - PathUtility.EnsureAllPathsExist(arguments, CommonLocalizableStrings.CouldNotFindProjectOrDirectory, true); - - var fullProjectPaths = _arguments.Select(p => + PathUtility.EnsureAllPathsExist(_projects, CommonLocalizableStrings.CouldNotFindProjectOrDirectory, true); + var fullProjectPaths = _projects.Select(project => { - var fullPath = Path.GetFullPath(p); - return Directory.Exists(fullPath) ? - MsbuildProject.GetProjectFileFromDirectory(fullPath).FullName : - fullPath; - }).ToList(); + var fullPath = Path.GetFullPath(project); + return Directory.Exists(fullPath) ? MsbuildProject.GetProjectFileFromDirectory(fullPath).FullName : fullPath; + }).ToArray(); - var preAddProjectCount = slnFile.Projects.Count; - - foreach (var fullProjectPath in fullProjectPaths) + try { - // Identify the intended solution folders - var solutionFolders = DetermineSolutionFolder(slnFile, fullProjectPath); - - slnFile.AddProject(fullProjectPath, solutionFolders); + AddProjectsToSolutionAsync(solutionFileFullPath, fullProjectPaths, CancellationToken.None).Wait(); + return 0; } - - if (slnFile.Projects.Count > preAddProjectCount) + catch (Exception ex) { - slnFile.Write(); + throw new GracefulException("TODO: Handle exception", ex); } + } - return 0; + private async Task AddProjectsToSolutionAsync(string solutionFileFullPath, string[] projectPaths, CancellationToken cancellationToken) + { + ISolutionSerializer serializer = SlnCommandParser.GetSolutionSerializer(solutionFileFullPath); + SolutionModel solution = await serializer.OpenAsync(solutionFileFullPath, cancellationToken); + foreach (var projectPath in projectPaths) + { + // TODO: Handle solution folder + // var solutionFolder = string.Join(Path.DirectorySeparatorChar, GetSolutionFoldersFromProjectPath(Path.GetRelativePath(solutionFileFullPath, projectPath))); + solution.AddProject(Path.GetRelativePath(Path.GetDirectoryName(solutionFileFullPath), projectPath), null, null); + } + await serializer.SaveAsync(solutionFileFullPath, solution, cancellationToken); } private static IList GetSolutionFoldersFromProjectPath(string projectFilePath) @@ -91,11 +94,11 @@ private static IList GetSolutionFoldersFromProjectPath(string projectFil projectFilePath = projectFilePath.Substring(currentDirString.Length); } - var projectDirectoryPath = TrimProject(projectFilePath); + var projectDirectoryPath = Path.GetDirectoryName(projectFilePath); if (string.IsNullOrEmpty(projectDirectoryPath)) return solutionFolders; - var solutionFoldersPath = TrimProjectDirectory(projectDirectoryPath); + var solutionFoldersPath = Path.GetDirectoryName(projectDirectoryPath); if (string.IsNullOrEmpty(solutionFoldersPath)) return solutionFolders; @@ -130,15 +133,5 @@ private static bool IsPathInTreeRootedAtSolutionDirectory(string path) { return !path.StartsWith(".."); } - - private static string TrimProject(string path) - { - return Path.GetDirectoryName(path); - } - - private static string TrimProjectDirectory(string path) - { - return Path.GetDirectoryName(path); - } } } From 01b3031288492e5d7944fbc299b3769b7a50f440 Mon Sep 17 00:00:00 2001 From: Eduardo Villalpando Mello Date: Fri, 1 Nov 2024 10:19:42 -0700 Subject: [PATCH 03/60] Handle solution folders --- .../dotnet/commands/dotnet-sln/add/Program.cs | 80 +++---------------- 1 file changed, 11 insertions(+), 69 deletions(-) diff --git a/src/Cli/dotnet/commands/dotnet-sln/add/Program.cs b/src/Cli/dotnet/commands/dotnet-sln/add/Program.cs index 6bc9672a8580..7bf92d3e0ce1 100644 --- a/src/Cli/dotnet/commands/dotnet-sln/add/Program.cs +++ b/src/Cli/dotnet/commands/dotnet-sln/add/Program.cs @@ -15,8 +15,8 @@ internal class AddProjectToSolutionCommand : CommandBase { private readonly string _fileOrDirectory; private readonly bool _inRoot; - private readonly IList _relativeRootSolutionFolders; private readonly IReadOnlyCollection _projects; + private readonly string? _solutionFolderPath; public AddProjectToSolutionCommand(ParseResult parseResult) : base(parseResult) { @@ -25,21 +25,9 @@ public AddProjectToSolutionCommand(ParseResult parseResult) : base(parseResult) _projects = parseResult.GetValue(SlnAddParser.ProjectPathArgument)?.ToArray() ?? (IReadOnlyCollection)Array.Empty(); _inRoot = parseResult.GetValue(SlnAddParser.InRootOption); - string relativeRoot = parseResult.GetValue(SlnAddParser.SolutionFolderOption); + _solutionFolderPath = parseResult.GetValue(SlnAddParser.SolutionFolderOption); - SlnArgumentValidator.ParseAndValidateArguments(_fileOrDirectory, _projects, SlnArgumentValidator.CommandType.Add, _inRoot, relativeRoot); - - bool hasRelativeRoot = !string.IsNullOrEmpty(relativeRoot); - - if (hasRelativeRoot) - { - relativeRoot = PathUtility.GetPathWithDirectorySeparator(relativeRoot); - _relativeRootSolutionFolders = relativeRoot.Split(Path.DirectorySeparatorChar, StringSplitOptions.RemoveEmptyEntries); - } - else - { - _relativeRootSolutionFolders = null; - } + SlnArgumentValidator.ParseAndValidateArguments(_fileOrDirectory, _projects, SlnArgumentValidator.CommandType.Add, _inRoot, _solutionFolderPath); } public override int Execute() @@ -64,7 +52,7 @@ public override int Execute() } catch (Exception ex) { - throw new GracefulException("TODO: Handle exception", ex); + throw new GracefulException(ex.Message, ex); } } @@ -72,66 +60,20 @@ private async Task AddProjectsToSolutionAsync(string solutionFileFullPath, strin { ISolutionSerializer serializer = SlnCommandParser.GetSolutionSerializer(solutionFileFullPath); SolutionModel solution = await serializer.OpenAsync(solutionFileFullPath, cancellationToken); + SolutionFolderModel solutionFolder = (!_inRoot && _solutionFolderPath != null) + ? solution.AddFolder(GetSolutionFolderPathWithForwardSlashes()) + : null; foreach (var projectPath in projectPaths) { - // TODO: Handle solution folder - // var solutionFolder = string.Join(Path.DirectorySeparatorChar, GetSolutionFoldersFromProjectPath(Path.GetRelativePath(solutionFileFullPath, projectPath))); - solution.AddProject(Path.GetRelativePath(Path.GetDirectoryName(solutionFileFullPath), projectPath), null, null); + solution.AddProject(Path.GetRelativePath(Path.GetDirectoryName(solutionFileFullPath), projectPath), null, solutionFolder); } await serializer.SaveAsync(solutionFileFullPath, solution, cancellationToken); } - private static IList GetSolutionFoldersFromProjectPath(string projectFilePath) - { - var solutionFolders = new List(); - - if (!IsPathInTreeRootedAtSolutionDirectory(projectFilePath)) - return solutionFolders; - - var currentDirString = $".{Path.DirectorySeparatorChar}"; - if (projectFilePath.StartsWith(currentDirString)) - { - projectFilePath = projectFilePath.Substring(currentDirString.Length); - } - - var projectDirectoryPath = Path.GetDirectoryName(projectFilePath); - if (string.IsNullOrEmpty(projectDirectoryPath)) - return solutionFolders; - - var solutionFoldersPath = Path.GetDirectoryName(projectDirectoryPath); - if (string.IsNullOrEmpty(solutionFoldersPath)) - return solutionFolders; - - solutionFolders.AddRange(solutionFoldersPath.Split(Path.DirectorySeparatorChar)); - - return solutionFolders; - } - - private IList DetermineSolutionFolder(SlnFile slnFile, string fullProjectPath) - { - if (_inRoot) - { - // The user requested all projects go to the root folder - return null; - } - - if (_relativeRootSolutionFolders != null) - { - // The user has specified an explicit root - return _relativeRootSolutionFolders; - } - - // We determine the root for each individual project - var relativeProjectPath = Path.GetRelativePath( - PathUtility.EnsureTrailingSlash(slnFile.BaseDirectory), - fullProjectPath); - - return GetSolutionFoldersFromProjectPath(relativeProjectPath); - } - - private static bool IsPathInTreeRootedAtSolutionDirectory(string path) + private string GetSolutionFolderPathWithForwardSlashes() { - return !path.StartsWith(".."); + // SolutionModel::AddFolder expects path to have leading, trailing and inner forward slashes + return PathUtility.EnsureTrailingForwardSlash( PathUtility.GetPathWithForwardSlashes(Path.Join("/", _solutionFolderPath)) ); } } } From 277a1d746758526717e1bb0972417439d88982a2 Mon Sep 17 00:00:00 2001 From: Eduardo Villalpando Mello Date: Fri, 1 Nov 2024 13:39:43 -0700 Subject: [PATCH 04/60] Fix tests --- src/Cli/dotnet/commands/dotnet-sln/add/Program.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Cli/dotnet/commands/dotnet-sln/add/Program.cs b/src/Cli/dotnet/commands/dotnet-sln/add/Program.cs index 7bf92d3e0ce1..6af286284a3f 100644 --- a/src/Cli/dotnet/commands/dotnet-sln/add/Program.cs +++ b/src/Cli/dotnet/commands/dotnet-sln/add/Program.cs @@ -66,6 +66,9 @@ private async Task AddProjectsToSolutionAsync(string solutionFileFullPath, strin foreach (var projectPath in projectPaths) { solution.AddProject(Path.GetRelativePath(Path.GetDirectoryName(solutionFileFullPath), projectPath), null, solutionFolder); + Reporter.Output.WriteLine( + CommonLocalizableStrings.ProjectAddedToTheSolution, + Path.GetRelativePath(Path.GetDirectoryName(solutionFileFullPath), projectPath)); } await serializer.SaveAsync(solutionFileFullPath, solution, cancellationToken); } From 5e6e3ffcd4baac3d625b0a9156c642cc272fb472 Mon Sep 17 00:00:00 2001 From: Eduardo Villalpando Mello Date: Fri, 1 Nov 2024 15:11:10 -0700 Subject: [PATCH 05/60] Fix UTF8 BOM tests --- src/Cli/dotnet/commands/dotnet-sln/add/Program.cs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/Cli/dotnet/commands/dotnet-sln/add/Program.cs b/src/Cli/dotnet/commands/dotnet-sln/add/Program.cs index 6af286284a3f..8f5e2bbe9f1e 100644 --- a/src/Cli/dotnet/commands/dotnet-sln/add/Program.cs +++ b/src/Cli/dotnet/commands/dotnet-sln/add/Program.cs @@ -8,6 +8,7 @@ using Microsoft.DotNet.Tools.Common; using Microsoft.VisualStudio.SolutionPersistence; using Microsoft.VisualStudio.SolutionPersistence.Model; +using Microsoft.VisualStudio.SolutionPersistence.Serializer.SlnV12; namespace Microsoft.DotNet.Tools.Sln.Add { @@ -60,6 +61,14 @@ private async Task AddProjectsToSolutionAsync(string solutionFileFullPath, strin { ISolutionSerializer serializer = SlnCommandParser.GetSolutionSerializer(solutionFileFullPath); SolutionModel solution = await serializer.OpenAsync(solutionFileFullPath, cancellationToken); + // set UTF8 BOM encoding for .sln + if (serializer is ISolutionSerializer v12Serializer) + { + solution.SerializerExtension = v12Serializer.CreateModelExtension(new() + { + Encoding = new UTF8Encoding(encoderShouldEmitUTF8Identifier: true) + }); + } SolutionFolderModel solutionFolder = (!_inRoot && _solutionFolderPath != null) ? solution.AddFolder(GetSolutionFolderPathWithForwardSlashes()) : null; From b4ac6a4b1d83ffcacf01eacd13acecb9d9d66b23 Mon Sep 17 00:00:00 2001 From: Eduardo Villalpando Mello Date: Fri, 1 Nov 2024 16:39:49 -0700 Subject: [PATCH 06/60] Catch errors --- src/Cli/dotnet/commands/dotnet-sln/add/Program.cs | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/Cli/dotnet/commands/dotnet-sln/add/Program.cs b/src/Cli/dotnet/commands/dotnet-sln/add/Program.cs index 8f5e2bbe9f1e..1d102b681780 100644 --- a/src/Cli/dotnet/commands/dotnet-sln/add/Program.cs +++ b/src/Cli/dotnet/commands/dotnet-sln/add/Program.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.CommandLine; +using System.Text.RegularExpressions; using Microsoft.DotNet.Cli; using Microsoft.DotNet.Cli.Sln.Internal; using Microsoft.DotNet.Cli.Utils; @@ -53,6 +54,15 @@ public override int Execute() } catch (Exception ex) { + // TODO: Have better error matching + // Using string comparison as keys are not exposed + if (Regex.Match(ex.Message, @"Duplicate item '.*' of type 'Project'.").Success) + { + Reporter.Output.WriteLine( + string.Format(CommonLocalizableStrings.SolutionAlreadyContainsProject)); + // We treat this as a successful command + return 0; + } throw new GracefulException(ex.Message, ex); } } @@ -85,7 +95,7 @@ private async Task AddProjectsToSolutionAsync(string solutionFileFullPath, strin private string GetSolutionFolderPathWithForwardSlashes() { // SolutionModel::AddFolder expects path to have leading, trailing and inner forward slashes - return PathUtility.EnsureTrailingForwardSlash( PathUtility.GetPathWithForwardSlashes(Path.Join("/", _solutionFolderPath)) ); + return PathUtility.EnsureTrailingForwardSlash( PathUtility.GetPathWithForwardSlashes(Path.Join(" / ", _solutionFolderPath)) ); } } } From 3f967f75bb5fc0da338fcc099cab8728da2e2e8c Mon Sep 17 00:00:00 2001 From: Eduardo Villalpando Mello Date: Mon, 4 Nov 2024 09:53:31 -0800 Subject: [PATCH 07/60] Fix additional tests --- .../dotnet/commands/dotnet-sln/add/Program.cs | 33 +++++++++++-------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/src/Cli/dotnet/commands/dotnet-sln/add/Program.cs b/src/Cli/dotnet/commands/dotnet-sln/add/Program.cs index 1d102b681780..bd0f7e1db11f 100644 --- a/src/Cli/dotnet/commands/dotnet-sln/add/Program.cs +++ b/src/Cli/dotnet/commands/dotnet-sln/add/Program.cs @@ -46,7 +46,6 @@ public override int Execute() var fullPath = Path.GetFullPath(project); return Directory.Exists(fullPath) ? MsbuildProject.GetProjectFileFromDirectory(fullPath).FullName : fullPath; }).ToArray(); - try { AddProjectsToSolutionAsync(solutionFileFullPath, fullProjectPaths, CancellationToken.None).Wait(); @@ -54,15 +53,6 @@ public override int Execute() } catch (Exception ex) { - // TODO: Have better error matching - // Using string comparison as keys are not exposed - if (Regex.Match(ex.Message, @"Duplicate item '.*' of type 'Project'.").Success) - { - Reporter.Output.WriteLine( - string.Format(CommonLocalizableStrings.SolutionAlreadyContainsProject)); - // We treat this as a successful command - return 0; - } throw new GracefulException(ex.Message, ex); } } @@ -84,10 +74,25 @@ private async Task AddProjectsToSolutionAsync(string solutionFileFullPath, strin : null; foreach (var projectPath in projectPaths) { - solution.AddProject(Path.GetRelativePath(Path.GetDirectoryName(solutionFileFullPath), projectPath), null, solutionFolder); - Reporter.Output.WriteLine( - CommonLocalizableStrings.ProjectAddedToTheSolution, - Path.GetRelativePath(Path.GetDirectoryName(solutionFileFullPath), projectPath)); + // Get full project path + var relativePath = Path.GetRelativePath(Path.GetDirectoryName(solutionFileFullPath), projectPath); + try + { + solution.AddProject(relativePath, null, solutionFolder); + Reporter.Output.WriteLine(CommonLocalizableStrings.ProjectAddedToTheSolution, relativePath); + } + catch (Exception ex) + { + if (Regex.Match(ex.Message, @"Project name '.*' already exists in the solution folder\.").Success || Regex.Match(ex.Message, @"Duplicate item '.*' of type 'Project'\.").Success) + { + Reporter.Output.WriteLine( + string.Format(CommonLocalizableStrings.SolutionAlreadyContainsProject, solutionFileFullPath, relativePath)); + } + else + { + throw new GracefulException(ex.Message, ex); + } + } } await serializer.SaveAsync(solutionFileFullPath, solution, cancellationToken); } From 3d52972b848691326531241ba46b9326c52c2102 Mon Sep 17 00:00:00 2001 From: Eduardo Villalpando Mello Date: Mon, 4 Nov 2024 15:57:30 -0800 Subject: [PATCH 08/60] Fix additional tests --- src/Cli/dotnet/commands/dotnet-sln/add/Program.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Cli/dotnet/commands/dotnet-sln/add/Program.cs b/src/Cli/dotnet/commands/dotnet-sln/add/Program.cs index bd0f7e1db11f..798e1920066a 100644 --- a/src/Cli/dotnet/commands/dotnet-sln/add/Program.cs +++ b/src/Cli/dotnet/commands/dotnet-sln/add/Program.cs @@ -53,6 +53,10 @@ public override int Execute() } catch (Exception ex) { + if (ex is SolutionException || ex.InnerException is SolutionException) + { + throw new GracefulException(CommonLocalizableStrings.InvalidSolutionFormatString, solutionFileFullPath, ex.Message); + } throw new GracefulException(ex.Message, ex); } } From de95e6dce4e23c635aa6b58dc7c2bc12d5d8dca3 Mon Sep 17 00:00:00 2001 From: Eduardo Villalpando Mello Date: Tue, 5 Nov 2024 12:50:34 -0800 Subject: [PATCH 09/60] Fix additional issues --- sdk.slnx | 332 ++++++++++++++++++ .../ProjectTypeGuids.cs | 1 + .../dotnet/commands/dotnet-sln/add/Program.cs | 21 +- test/dotnet-sln.Tests/GivenDotnetSlnAdd.cs | 4 +- 4 files changed, 354 insertions(+), 4 deletions(-) create mode 100644 sdk.slnx diff --git a/sdk.slnx b/sdk.slnx new file mode 100644 index 000000000000..cbd4594cef46 --- /dev/null +++ b/sdk.slnx @@ -0,0 +1,332 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Cli/Microsoft.DotNet.Cli.Sln.Internal/ProjectTypeGuids.cs b/src/Cli/Microsoft.DotNet.Cli.Sln.Internal/ProjectTypeGuids.cs index 5db6beb30ed7..772028ed2a34 100644 --- a/src/Cli/Microsoft.DotNet.Cli.Sln.Internal/ProjectTypeGuids.cs +++ b/src/Cli/Microsoft.DotNet.Cli.Sln.Internal/ProjectTypeGuids.cs @@ -10,5 +10,6 @@ public static class ProjectTypeGuids public const string VBProjectTypeGuid = "{F184B08F-C81C-45F6-A57F-5ABD9991F28F}"; public const string SolutionFolderGuid = "{2150E333-8FDC-42A3-9474-1A3956D46DE8}"; public const string SharedProjectGuid = "{D954291E-2A0B-460D-934E-DC6B0785DB48}"; + public const string UnknownProjectGuid = "{130159A9-F047-44B3-88CF-0CF7F02ED50F}"; } } diff --git a/src/Cli/dotnet/commands/dotnet-sln/add/Program.cs b/src/Cli/dotnet/commands/dotnet-sln/add/Program.cs index 798e1920066a..d8754720a360 100644 --- a/src/Cli/dotnet/commands/dotnet-sln/add/Program.cs +++ b/src/Cli/dotnet/commands/dotnet-sln/add/Program.cs @@ -79,14 +79,15 @@ private async Task AddProjectsToSolutionAsync(string solutionFileFullPath, strin foreach (var projectPath in projectPaths) { // Get full project path - var relativePath = Path.GetRelativePath(Path.GetDirectoryName(solutionFileFullPath), projectPath); + var relativePath = Path.GetRelativePath(Path.GetDirectoryName(solutionFileFullPath), projectPath); try { - solution.AddProject(relativePath, null, solutionFolder); + AddProjectToSolutionWithDefaultType(solution, relativePath, solutionFolder); Reporter.Output.WriteLine(CommonLocalizableStrings.ProjectAddedToTheSolution, relativePath); } catch (Exception ex) { + // TODO: Update with error codes from vs-solutionpersistence if (Regex.Match(ex.Message, @"Project name '.*' already exists in the solution folder\.").Success || Regex.Match(ex.Message, @"Duplicate item '.*' of type 'Project'\.").Success) { Reporter.Output.WriteLine( @@ -106,5 +107,21 @@ private string GetSolutionFolderPathWithForwardSlashes() // SolutionModel::AddFolder expects path to have leading, trailing and inner forward slashes return PathUtility.EnsureTrailingForwardSlash( PathUtility.GetPathWithForwardSlashes(Path.Join(" / ", _solutionFolderPath)) ); } + + private void AddProjectToSolutionWithDefaultType(SolutionModel solution, string relativePath, SolutionFolderModel solutionFolder) + { + try + { + solution.AddProject(relativePath, null, solutionFolder); + } + catch (ArgumentException ex) + { + // TODO: Update with error codes from vs-solutionpersistence + if (ex.Message == "ProjectType '' not found. (Parameter 'projectTypeName')") + { + solution.AddProject(relativePath, ProjectTypeGuids.UnknownProjectGuid, solutionFolder); + } + } + } } } diff --git a/test/dotnet-sln.Tests/GivenDotnetSlnAdd.cs b/test/dotnet-sln.Tests/GivenDotnetSlnAdd.cs index 8c13d746f746..272b3c850c31 100644 --- a/test/dotnet-sln.Tests/GivenDotnetSlnAdd.cs +++ b/test/dotnet-sln.Tests/GivenDotnetSlnAdd.cs @@ -484,7 +484,7 @@ public void WhenInvalidSolutionIsPassedItPrintsErrorAndUsage(string solutionComm .WithWorkingDirectory(projectDirectory) .Execute(solutionCommand, "InvalidSolution.sln", "add", projectToAdd); cmd.Should().Fail(); - cmd.StdErr.Should().Be(string.Format(CommonLocalizableStrings.InvalidSolutionFormatString, "InvalidSolution.sln", LocalizableStrings.FileHeaderMissingError)); + cmd.StdErr.Should().Contain(string.Format(CommonLocalizableStrings.InvalidSolutionFormatString, "InvalidSolution.sln", "").TrimEnd(".")); cmd.StdOut.Should().BeVisuallyEquivalentToIfNotLocalized(""); } @@ -504,7 +504,7 @@ public void WhenInvalidSolutionIsFoundAddPrintsErrorAndUsage(string solutionComm .WithWorkingDirectory(projectDirectory) .Execute(solutionCommand, "add", projectToAdd); cmd.Should().Fail(); - cmd.StdErr.Should().Be(string.Format(CommonLocalizableStrings.InvalidSolutionFormatString, solutionPath, LocalizableStrings.FileHeaderMissingError)); + cmd.StdErr.Should().Contain(string.Format(CommonLocalizableStrings.InvalidSolutionFormatString, solutionPath, "").TrimEnd(".")); cmd.StdOut.Should().BeVisuallyEquivalentToIfNotLocalized(""); } From a090ad4b83a9a66e67d649462cba225ea7039885 Mon Sep 17 00:00:00 2001 From: Eduardo Villalpando Mello Date: Tue, 5 Nov 2024 12:56:52 -0800 Subject: [PATCH 10/60] Remove sdk.slnx file --- sdk.slnx | 332 ------------------------------------------------------- 1 file changed, 332 deletions(-) delete mode 100644 sdk.slnx diff --git a/sdk.slnx b/sdk.slnx deleted file mode 100644 index cbd4594cef46..000000000000 --- a/sdk.slnx +++ /dev/null @@ -1,332 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - From c03cad73b3f796ddb56fa2ea9d237f583df4672e Mon Sep 17 00:00:00 2001 From: Eduardo Villalpando Mello Date: Wed, 6 Nov 2024 09:18:40 -0800 Subject: [PATCH 11/60] Fix additional tests --- .../dotnet/commands/dotnet-sln/add/Program.cs | 28 ++++--------------- test/dotnet-sln.Tests/GivenDotnetSlnAdd.cs | 4 +-- 2 files changed, 8 insertions(+), 24 deletions(-) diff --git a/src/Cli/dotnet/commands/dotnet-sln/add/Program.cs b/src/Cli/dotnet/commands/dotnet-sln/add/Program.cs index d8754720a360..08a3d876262d 100644 --- a/src/Cli/dotnet/commands/dotnet-sln/add/Program.cs +++ b/src/Cli/dotnet/commands/dotnet-sln/add/Program.cs @@ -82,21 +82,21 @@ private async Task AddProjectsToSolutionAsync(string solutionFileFullPath, strin var relativePath = Path.GetRelativePath(Path.GetDirectoryName(solutionFileFullPath), projectPath); try { - AddProjectToSolutionWithDefaultType(solution, relativePath, solutionFolder); + solution.AddProject(relativePath, null, solutionFolder); Reporter.Output.WriteLine(CommonLocalizableStrings.ProjectAddedToTheSolution, relativePath); } catch (Exception ex) { // TODO: Update with error codes from vs-solutionpersistence + // Duplicate project if (Regex.Match(ex.Message, @"Project name '.*' already exists in the solution folder\.").Success || Regex.Match(ex.Message, @"Duplicate item '.*' of type 'Project'\.").Success) { Reporter.Output.WriteLine( string.Format(CommonLocalizableStrings.SolutionAlreadyContainsProject, solutionFileFullPath, relativePath)); + continue; } - else - { - throw new GracefulException(ex.Message, ex); - } + // Invalid project + throw new GracefulException(ex.Message, ex); } } await serializer.SaveAsync(solutionFileFullPath, solution, cancellationToken); @@ -105,23 +105,7 @@ private async Task AddProjectsToSolutionAsync(string solutionFileFullPath, strin private string GetSolutionFolderPathWithForwardSlashes() { // SolutionModel::AddFolder expects path to have leading, trailing and inner forward slashes - return PathUtility.EnsureTrailingForwardSlash( PathUtility.GetPathWithForwardSlashes(Path.Join(" / ", _solutionFolderPath)) ); - } - - private void AddProjectToSolutionWithDefaultType(SolutionModel solution, string relativePath, SolutionFolderModel solutionFolder) - { - try - { - solution.AddProject(relativePath, null, solutionFolder); - } - catch (ArgumentException ex) - { - // TODO: Update with error codes from vs-solutionpersistence - if (ex.Message == "ProjectType '' not found. (Parameter 'projectTypeName')") - { - solution.AddProject(relativePath, ProjectTypeGuids.UnknownProjectGuid, solutionFolder); - } - } + return PathUtility.EnsureTrailingForwardSlash( PathUtility.GetPathWithForwardSlashes(Path.Join("/", _solutionFolderPath)) ); } } } diff --git a/test/dotnet-sln.Tests/GivenDotnetSlnAdd.cs b/test/dotnet-sln.Tests/GivenDotnetSlnAdd.cs index 272b3c850c31..a2daf11fbc4a 100644 --- a/test/dotnet-sln.Tests/GivenDotnetSlnAdd.cs +++ b/test/dotnet-sln.Tests/GivenDotnetSlnAdd.cs @@ -484,7 +484,7 @@ public void WhenInvalidSolutionIsPassedItPrintsErrorAndUsage(string solutionComm .WithWorkingDirectory(projectDirectory) .Execute(solutionCommand, "InvalidSolution.sln", "add", projectToAdd); cmd.Should().Fail(); - cmd.StdErr.Should().Contain(string.Format(CommonLocalizableStrings.InvalidSolutionFormatString, "InvalidSolution.sln", "").TrimEnd(".")); + cmd.StdErr.Should().Match(string.Format(CommonLocalizableStrings.InvalidSolutionFormatString, Path.Combine(projectDirectory, "InvalidSolution.sln"), "*")); cmd.StdOut.Should().BeVisuallyEquivalentToIfNotLocalized(""); } @@ -504,7 +504,7 @@ public void WhenInvalidSolutionIsFoundAddPrintsErrorAndUsage(string solutionComm .WithWorkingDirectory(projectDirectory) .Execute(solutionCommand, "add", projectToAdd); cmd.Should().Fail(); - cmd.StdErr.Should().Contain(string.Format(CommonLocalizableStrings.InvalidSolutionFormatString, solutionPath, "").TrimEnd(".")); + cmd.StdErr.Should().Match(string.Format(CommonLocalizableStrings.InvalidSolutionFormatString, solutionPath, "*")); cmd.StdOut.Should().BeVisuallyEquivalentToIfNotLocalized(""); } From 90f4248bfcab6c505212dcf0ba9ee139384a62f4 Mon Sep 17 00:00:00 2001 From: Eduardo Villalpando Mello Date: Wed, 6 Nov 2024 09:55:17 -0800 Subject: [PATCH 12/60] Fix additional tests --- .../dotnet/commands/dotnet-sln/add/Program.cs | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/Cli/dotnet/commands/dotnet-sln/add/Program.cs b/src/Cli/dotnet/commands/dotnet-sln/add/Program.cs index 08a3d876262d..17a0e0266d62 100644 --- a/src/Cli/dotnet/commands/dotnet-sln/add/Program.cs +++ b/src/Cli/dotnet/commands/dotnet-sln/add/Program.cs @@ -82,7 +82,7 @@ private async Task AddProjectsToSolutionAsync(string solutionFileFullPath, strin var relativePath = Path.GetRelativePath(Path.GetDirectoryName(solutionFileFullPath), projectPath); try { - solution.AddProject(relativePath, null, solutionFolder); + AddProjectWithDefaultGuid(solution, relativePath, solutionFolder); Reporter.Output.WriteLine(CommonLocalizableStrings.ProjectAddedToTheSolution, relativePath); } catch (Exception ex) @@ -107,5 +107,20 @@ private string GetSolutionFolderPathWithForwardSlashes() // SolutionModel::AddFolder expects path to have leading, trailing and inner forward slashes return PathUtility.EnsureTrailingForwardSlash( PathUtility.GetPathWithForwardSlashes(Path.Join("/", _solutionFolderPath)) ); } + + private void AddProjectWithDefaultGuid(SolutionModel solution, string relativePath, SolutionFolderModel solutionFolder) + { + try + { + solution.AddProject(relativePath, null, solutionFolder); + } + catch (ArgumentException ex) + { + if (ex.Message == "ProjectType '' not found. (Parameter 'projectTypeName')") + { + solution.AddProject(relativePath, "130159A9-F047-44B3-88CF-0CF7F02ED50F", solutionFolder); + } + } + } } } From 492997985f9fa48afd4aa068cf94661161b80bcb Mon Sep 17 00:00:00 2001 From: Eduardo Villalpando Mello Date: Wed, 6 Nov 2024 13:26:12 -0800 Subject: [PATCH 13/60] Fix additional tests --- src/Cli/dotnet/commands/dotnet-sln/add/Program.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/Cli/dotnet/commands/dotnet-sln/add/Program.cs b/src/Cli/dotnet/commands/dotnet-sln/add/Program.cs index 17a0e0266d62..970312440c91 100644 --- a/src/Cli/dotnet/commands/dotnet-sln/add/Program.cs +++ b/src/Cli/dotnet/commands/dotnet-sln/add/Program.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.CommandLine; +using System.Linq.Expressions; using System.Text.RegularExpressions; using Microsoft.DotNet.Cli; using Microsoft.DotNet.Cli.Sln.Internal; @@ -105,7 +106,7 @@ private async Task AddProjectsToSolutionAsync(string solutionFileFullPath, strin private string GetSolutionFolderPathWithForwardSlashes() { // SolutionModel::AddFolder expects path to have leading, trailing and inner forward slashes - return PathUtility.EnsureTrailingForwardSlash( PathUtility.GetPathWithForwardSlashes(Path.Join("/", _solutionFolderPath)) ); + return "/" + string.Join("/", PathUtility.GetPathWithDirectorySeparator(_solutionFolderPath).Split(Path.DirectorySeparatorChar, StringSplitOptions.RemoveEmptyEntries)) + "/"; } private void AddProjectWithDefaultGuid(SolutionModel solution, string relativePath, SolutionFolderModel solutionFolder) @@ -116,10 +117,15 @@ private void AddProjectWithDefaultGuid(SolutionModel solution, string relativePa } catch (ArgumentException ex) { + // TODO: Update with error codes from vs-solutionpersistence if (ex.Message == "ProjectType '' not found. (Parameter 'projectTypeName')") { solution.AddProject(relativePath, "130159A9-F047-44B3-88CF-0CF7F02ED50F", solutionFolder); } + else + { + throw new ArgumentException(ex.Message, ex.ParamName, ex.InnerException); + } } } } From f88c3ebd56dab19c9ed54cacac932551741e9605 Mon Sep 17 00:00:00 2001 From: Eduardo Villalpando Mello Date: Wed, 6 Nov 2024 15:58:50 -0800 Subject: [PATCH 14/60] Fix duplicate project tests --- .../dotnet/commands/dotnet-sln/add/Program.cs | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/src/Cli/dotnet/commands/dotnet-sln/add/Program.cs b/src/Cli/dotnet/commands/dotnet-sln/add/Program.cs index 970312440c91..f5a328e9d242 100644 --- a/src/Cli/dotnet/commands/dotnet-sln/add/Program.cs +++ b/src/Cli/dotnet/commands/dotnet-sln/add/Program.cs @@ -86,18 +86,17 @@ private async Task AddProjectsToSolutionAsync(string solutionFileFullPath, strin AddProjectWithDefaultGuid(solution, relativePath, solutionFolder); Reporter.Output.WriteLine(CommonLocalizableStrings.ProjectAddedToTheSolution, relativePath); } - catch (Exception ex) + catch (ArgumentException ex) { - // TODO: Update with error codes from vs-solutionpersistence - // Duplicate project - if (Regex.Match(ex.Message, @"Project name '.*' already exists in the solution folder\.").Success || Regex.Match(ex.Message, @"Duplicate item '.*' of type 'Project'\.").Success) + // TODO: There are some cases where the project is not found but it already exists on the solution. So it is useful to check the error message. Will remove on future commit. + if (solution.FindProject(relativePath) != null || Regex.Match(ex.Message, @"Project name '.*' already exists in the solution folder\.").Success) { - Reporter.Output.WriteLine( - string.Format(CommonLocalizableStrings.SolutionAlreadyContainsProject, solutionFileFullPath, relativePath)); - continue; + Reporter.Output.WriteLine(CommonLocalizableStrings.SolutionAlreadyContainsProject, solutionFileFullPath, relativePath); + } + else + { + throw new ArgumentException(ex.Message, ex.ParamName, ex.InnerException); } - // Invalid project - throw new GracefulException(ex.Message, ex); } } await serializer.SaveAsync(solutionFileFullPath, solution, cancellationToken); From a900dc3fda103962151ef3f5ab9eabbfbd972a86 Mon Sep 17 00:00:00 2001 From: Eduardo Villalpando Mello Date: Thu, 7 Nov 2024 13:09:42 -0800 Subject: [PATCH 15/60] Fix tests --- .../ProjectTypeGuids.cs | 4 +--- src/Cli/dotnet/commands/dotnet-sln/add/Program.cs | 9 +++++---- src/Cli/dotnet/commands/dotnet-sln/list/Program.cs | 1 - 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/src/Cli/Microsoft.DotNet.Cli.Sln.Internal/ProjectTypeGuids.cs b/src/Cli/Microsoft.DotNet.Cli.Sln.Internal/ProjectTypeGuids.cs index 772028ed2a34..9f69dd7bc7aa 100644 --- a/src/Cli/Microsoft.DotNet.Cli.Sln.Internal/ProjectTypeGuids.cs +++ b/src/Cli/Microsoft.DotNet.Cli.Sln.Internal/ProjectTypeGuids.cs @@ -9,7 +9,5 @@ public static class ProjectTypeGuids public const string FSharpProjectTypeGuid = "{F2A71F9B-5D33-465A-A702-920D77279786}"; public const string VBProjectTypeGuid = "{F184B08F-C81C-45F6-A57F-5ABD9991F28F}"; public const string SolutionFolderGuid = "{2150E333-8FDC-42A3-9474-1A3956D46DE8}"; - public const string SharedProjectGuid = "{D954291E-2A0B-460D-934E-DC6B0785DB48}"; - public const string UnknownProjectGuid = "{130159A9-F047-44B3-88CF-0CF7F02ED50F}"; - } + public const string SharedProjectGuid = "{D954291E-2A0B-460D-934E-DC6B0785DB48}" } } diff --git a/src/Cli/dotnet/commands/dotnet-sln/add/Program.cs b/src/Cli/dotnet/commands/dotnet-sln/add/Program.cs index f5a328e9d242..490e588918d4 100644 --- a/src/Cli/dotnet/commands/dotnet-sln/add/Program.cs +++ b/src/Cli/dotnet/commands/dotnet-sln/add/Program.cs @@ -74,7 +74,7 @@ private async Task AddProjectsToSolutionAsync(string solutionFileFullPath, strin Encoding = new UTF8Encoding(encoderShouldEmitUTF8Identifier: true) }); } - SolutionFolderModel solutionFolder = (!_inRoot && _solutionFolderPath != null) + SolutionFolderModel? solutionFolder = (!_inRoot && _solutionFolderPath != null) ? solution.AddFolder(GetSolutionFolderPathWithForwardSlashes()) : null; foreach (var projectPath in projectPaths) @@ -89,13 +89,14 @@ private async Task AddProjectsToSolutionAsync(string solutionFileFullPath, strin catch (ArgumentException ex) { // TODO: There are some cases where the project is not found but it already exists on the solution. So it is useful to check the error message. Will remove on future commit. - if (solution.FindProject(relativePath) != null || Regex.Match(ex.Message, @"Project name '.*' already exists in the solution folder\.").Success) + if (solution.SolutionProjects.Any((p) => + string.Equals(p.FilePath, relativePath, StringComparison.OrdinalIgnoreCase))) { Reporter.Output.WriteLine(CommonLocalizableStrings.SolutionAlreadyContainsProject, solutionFileFullPath, relativePath); } else { - throw new ArgumentException(ex.Message, ex.ParamName, ex.InnerException); + throw; } } } @@ -123,7 +124,7 @@ private void AddProjectWithDefaultGuid(SolutionModel solution, string relativePa } else { - throw new ArgumentException(ex.Message, ex.ParamName, ex.InnerException); + throw; } } } diff --git a/src/Cli/dotnet/commands/dotnet-sln/list/Program.cs b/src/Cli/dotnet/commands/dotnet-sln/list/Program.cs index 9dfb1f5f6f71..99b948207011 100644 --- a/src/Cli/dotnet/commands/dotnet-sln/list/Program.cs +++ b/src/Cli/dotnet/commands/dotnet-sln/list/Program.cs @@ -39,7 +39,6 @@ public override int Execute() private async Task ListAllProjectsAsync(string solutionFileFullPath, CancellationToken cancellationToken) { - Guid solutionFolderGuid = new Guid(ProjectTypeGuids.SolutionFolderGuid); ISolutionSerializer serializer = SlnCommandParser.GetSolutionSerializer(solutionFileFullPath); SolutionModel solution = await serializer.OpenAsync(solutionFileFullPath, cancellationToken); string[] paths; From c394d75ff9983845c9578f6391a5318793259f28 Mon Sep 17 00:00:00 2001 From: Eduardo Villalpando Mello Date: Thu, 7 Nov 2024 14:13:19 -0800 Subject: [PATCH 16/60] 108/133 tests passing --- .../ProjectTypeGuids.cs | 3 ++- src/Cli/dotnet/commands/dotnet-sln/add/Program.cs | 12 ++++++++++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/Cli/Microsoft.DotNet.Cli.Sln.Internal/ProjectTypeGuids.cs b/src/Cli/Microsoft.DotNet.Cli.Sln.Internal/ProjectTypeGuids.cs index 9f69dd7bc7aa..5db6beb30ed7 100644 --- a/src/Cli/Microsoft.DotNet.Cli.Sln.Internal/ProjectTypeGuids.cs +++ b/src/Cli/Microsoft.DotNet.Cli.Sln.Internal/ProjectTypeGuids.cs @@ -9,5 +9,6 @@ public static class ProjectTypeGuids public const string FSharpProjectTypeGuid = "{F2A71F9B-5D33-465A-A702-920D77279786}"; public const string VBProjectTypeGuid = "{F184B08F-C81C-45F6-A57F-5ABD9991F28F}"; public const string SolutionFolderGuid = "{2150E333-8FDC-42A3-9474-1A3956D46DE8}"; - public const string SharedProjectGuid = "{D954291E-2A0B-460D-934E-DC6B0785DB48}" } + public const string SharedProjectGuid = "{D954291E-2A0B-460D-934E-DC6B0785DB48}"; + } } diff --git a/src/Cli/dotnet/commands/dotnet-sln/add/Program.cs b/src/Cli/dotnet/commands/dotnet-sln/add/Program.cs index 490e588918d4..cb45e343bfa3 100644 --- a/src/Cli/dotnet/commands/dotnet-sln/add/Program.cs +++ b/src/Cli/dotnet/commands/dotnet-sln/add/Program.cs @@ -4,6 +4,8 @@ using System.CommandLine; using System.Linq.Expressions; using System.Text.RegularExpressions; +using Microsoft.Build.Construction; +using Microsoft.Build.Exceptions; using Microsoft.DotNet.Cli; using Microsoft.DotNet.Cli.Sln.Internal; using Microsoft.DotNet.Cli.Utils; @@ -83,14 +85,20 @@ private async Task AddProjectsToSolutionAsync(string solutionFileFullPath, strin var relativePath = Path.GetRelativePath(Path.GetDirectoryName(solutionFileFullPath), projectPath); try { + // Try to open the project to see if it is valid + ProjectRootElement p = ProjectRootElement.Open(projectPath); AddProjectWithDefaultGuid(solution, relativePath, solutionFolder); Reporter.Output.WriteLine(CommonLocalizableStrings.ProjectAddedToTheSolution, relativePath); } + catch (InvalidProjectFileException ex) + { + Reporter.Error.WriteLine(string.Format( + CommonLocalizableStrings.InvalidProjectWithExceptionMessage, projectPath, ex.Message)); + } catch (ArgumentException ex) { // TODO: There are some cases where the project is not found but it already exists on the solution. So it is useful to check the error message. Will remove on future commit. - if (solution.SolutionProjects.Any((p) => - string.Equals(p.FilePath, relativePath, StringComparison.OrdinalIgnoreCase))) + if (solution.FindProject(relativePath) != null || Regex.Match(ex.Message, @"Project name '.*' already exists in the solution folder.").Success) { Reporter.Output.WriteLine(CommonLocalizableStrings.SolutionAlreadyContainsProject, solutionFileFullPath, relativePath); } From c8e5996479ef56af85ea6bd72723ed5e08ea7813 Mon Sep 17 00:00:00 2001 From: Eduardo Villalpando Mello Date: Thu, 7 Nov 2024 16:14:07 -0800 Subject: [PATCH 17/60] Work on tests --- src/Cli/dotnet/commands/dotnet-sln/add/Program.cs | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/Cli/dotnet/commands/dotnet-sln/add/Program.cs b/src/Cli/dotnet/commands/dotnet-sln/add/Program.cs index cb45e343bfa3..f28676438719 100644 --- a/src/Cli/dotnet/commands/dotnet-sln/add/Program.cs +++ b/src/Cli/dotnet/commands/dotnet-sln/add/Program.cs @@ -108,6 +108,11 @@ private async Task AddProjectsToSolutionAsync(string solutionFileFullPath, strin } } } + solution.DistillProjectConfigurations(); + foreach (var solutionPropertyBag in SlnV12Extensions.GetSlnProperties(solution)) + { + solution.AddSlnProperties(solutionPropertyBag); + } await serializer.SaveAsync(solutionFileFullPath, solution, cancellationToken); } @@ -119,22 +124,27 @@ private string GetSolutionFolderPathWithForwardSlashes() private void AddProjectWithDefaultGuid(SolutionModel solution, string relativePath, SolutionFolderModel solutionFolder) { + SolutionProjectModel project; try { - solution.AddProject(relativePath, null, solutionFolder); + project = solution.AddProject(relativePath, null, solutionFolder); } catch (ArgumentException ex) { // TODO: Update with error codes from vs-solutionpersistence if (ex.Message == "ProjectType '' not found. (Parameter 'projectTypeName')") { - solution.AddProject(relativePath, "130159A9-F047-44B3-88CF-0CF7F02ED50F", solutionFolder); + project = solution.AddProject(relativePath, "130159A9-F047-44B3-88CF-0CF7F02ED50F", solutionFolder); } else { throw; } } + foreach (var solutionPropertyBag in SlnV12Extensions.GetSlnProperties(project)) + { + solution.AddSlnProperties(solutionPropertyBag); + } } } } From 039e694c9973ccbbb132eae398c4841c7ce3c94e Mon Sep 17 00:00:00 2001 From: Eduardo Villalpando Mello Date: Fri, 8 Nov 2024 08:46:50 -0800 Subject: [PATCH 18/60] Nit --- src/Cli/dotnet/commands/dotnet-sln/add/Program.cs | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/src/Cli/dotnet/commands/dotnet-sln/add/Program.cs b/src/Cli/dotnet/commands/dotnet-sln/add/Program.cs index f28676438719..cab758d3f190 100644 --- a/src/Cli/dotnet/commands/dotnet-sln/add/Program.cs +++ b/src/Cli/dotnet/commands/dotnet-sln/add/Program.cs @@ -48,7 +48,7 @@ public override int Execute() { var fullPath = Path.GetFullPath(project); return Directory.Exists(fullPath) ? MsbuildProject.GetProjectFileFromDirectory(fullPath).FullName : fullPath; - }).ToArray(); + }); try { AddProjectsToSolutionAsync(solutionFileFullPath, fullProjectPaths, CancellationToken.None).Wait(); @@ -64,7 +64,7 @@ public override int Execute() } } - private async Task AddProjectsToSolutionAsync(string solutionFileFullPath, string[] projectPaths, CancellationToken cancellationToken) + private async Task AddProjectsToSolutionAsync(string solutionFileFullPath, IEnumerable projectPaths, CancellationToken cancellationToken) { ISolutionSerializer serializer = SlnCommandParser.GetSolutionSerializer(solutionFileFullPath); SolutionModel solution = await serializer.OpenAsync(solutionFileFullPath, cancellationToken); @@ -109,10 +109,6 @@ private async Task AddProjectsToSolutionAsync(string solutionFileFullPath, strin } } solution.DistillProjectConfigurations(); - foreach (var solutionPropertyBag in SlnV12Extensions.GetSlnProperties(solution)) - { - solution.AddSlnProperties(solutionPropertyBag); - } await serializer.SaveAsync(solutionFileFullPath, solution, cancellationToken); } @@ -141,10 +137,6 @@ private void AddProjectWithDefaultGuid(SolutionModel solution, string relativePa throw; } } - foreach (var solutionPropertyBag in SlnV12Extensions.GetSlnProperties(project)) - { - solution.AddSlnProperties(solutionPropertyBag); - } } } } From cef4d22e50301f0c46b44b24e781e68ba446cf61 Mon Sep 17 00:00:00 2001 From: Eduardo Villalpando Mello Date: Fri, 8 Nov 2024 10:21:40 -0800 Subject: [PATCH 19/60] Refactored code to fix guid tests --- .../dotnet/commands/dotnet-sln/add/Program.cs | 32 +++++++++++-------- test/dotnet-sln.Tests/GivenDotnetSlnAdd.cs | 2 +- 2 files changed, 19 insertions(+), 15 deletions(-) diff --git a/src/Cli/dotnet/commands/dotnet-sln/add/Program.cs b/src/Cli/dotnet/commands/dotnet-sln/add/Program.cs index cab758d3f190..bfa14079eb8f 100644 --- a/src/Cli/dotnet/commands/dotnet-sln/add/Program.cs +++ b/src/Cli/dotnet/commands/dotnet-sln/add/Program.cs @@ -44,22 +44,26 @@ public override int Execute() throw new GracefulException(CommonLocalizableStrings.SpecifyAtLeastOneProjectToAdd); } PathUtility.EnsureAllPathsExist(_projects, CommonLocalizableStrings.CouldNotFindProjectOrDirectory, true); - var fullProjectPaths = _projects.Select(project => - { - var fullPath = Path.GetFullPath(project); - return Directory.Exists(fullPath) ? MsbuildProject.GetProjectFileFromDirectory(fullPath).FullName : fullPath; - }); try { + var fullProjectPaths = _projects.Select(project => + { + var fullPath = Path.GetFullPath(project); + return Directory.Exists(fullPath) ? MsbuildProject.GetProjectFileFromDirectory(fullPath).FullName : fullPath; + }); AddProjectsToSolutionAsync(solutionFileFullPath, fullProjectPaths, CancellationToken.None).Wait(); return 0; } + catch (GracefulException) + { + throw; + } + catch (SolutionException ex) + { + throw new GracefulException(CommonLocalizableStrings.InvalidSolutionFormatString, solutionFileFullPath, ex.Message); + } catch (Exception ex) { - if (ex is SolutionException || ex.InnerException is SolutionException) - { - throw new GracefulException(CommonLocalizableStrings.InvalidSolutionFormatString, solutionFileFullPath, ex.Message); - } throw new GracefulException(ex.Message, ex); } } @@ -86,8 +90,8 @@ private async Task AddProjectsToSolutionAsync(string solutionFileFullPath, IEnum try { // Try to open the project to see if it is valid - ProjectRootElement p = ProjectRootElement.Open(projectPath); - AddProjectWithDefaultGuid(solution, relativePath, solutionFolder); + ProjectRootElement project = ProjectRootElement.Open(projectPath); + AddProjectWithDefaultGuid(solution, relativePath, solutionFolder, project.GetProjectTypeGuid()); Reporter.Output.WriteLine(CommonLocalizableStrings.ProjectAddedToTheSolution, relativePath); } catch (InvalidProjectFileException ex) @@ -118,19 +122,19 @@ private string GetSolutionFolderPathWithForwardSlashes() return "/" + string.Join("/", PathUtility.GetPathWithDirectorySeparator(_solutionFolderPath).Split(Path.DirectorySeparatorChar, StringSplitOptions.RemoveEmptyEntries)) + "/"; } - private void AddProjectWithDefaultGuid(SolutionModel solution, string relativePath, SolutionFolderModel solutionFolder) + private void AddProjectWithDefaultGuid(SolutionModel solution, string relativePath, SolutionFolderModel solutionFolder, string guid) { SolutionProjectModel project; try { - project = solution.AddProject(relativePath, null, solutionFolder); + solution.AddProject(relativePath, guid, solutionFolder); } catch (ArgumentException ex) { // TODO: Update with error codes from vs-solutionpersistence if (ex.Message == "ProjectType '' not found. (Parameter 'projectTypeName')") { - project = solution.AddProject(relativePath, "130159A9-F047-44B3-88CF-0CF7F02ED50F", solutionFolder); + solution.AddProject(relativePath, "130159A9-F047-44B3-88CF-0CF7F02ED50F", solutionFolder); } else { diff --git a/test/dotnet-sln.Tests/GivenDotnetSlnAdd.cs b/test/dotnet-sln.Tests/GivenDotnetSlnAdd.cs index a2daf11fbc4a..3df43abc47e8 100644 --- a/test/dotnet-sln.Tests/GivenDotnetSlnAdd.cs +++ b/test/dotnet-sln.Tests/GivenDotnetSlnAdd.cs @@ -733,7 +733,7 @@ public void WhenDirectoryContainsMultipleProjectsItCancelsWholeOperation(string .WithWorkingDirectory(projectDirectory) .Execute(solutionCommand, "add", directoryToAdd); cmd.Should().Fail(); - cmd.StdErr.Should().Be( + cmd.StdErr.Should().Contain( string.Format( CommonLocalizableStrings.MoreThanOneProjectInDirectory, Path.Combine(projectDirectory, directoryToAdd))); From 51294e972ae1872c2373002fce6b7790ff8b73a0 Mon Sep 17 00:00:00 2001 From: Eduardo Villalpando Mello Date: Fri, 8 Nov 2024 10:27:14 -0800 Subject: [PATCH 20/60] Fix tests --- test/dotnet-sln.Tests/GivenDotnetSlnAdd.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/dotnet-sln.Tests/GivenDotnetSlnAdd.cs b/test/dotnet-sln.Tests/GivenDotnetSlnAdd.cs index 3df43abc47e8..cf1c02a0ae72 100644 --- a/test/dotnet-sln.Tests/GivenDotnetSlnAdd.cs +++ b/test/dotnet-sln.Tests/GivenDotnetSlnAdd.cs @@ -706,7 +706,7 @@ public void WhenDirectoryContainsNoProjectsItCancelsWholeOperation(string soluti .WithWorkingDirectory(projectDirectory) .Execute(solutionCommand, "add", directoryToAdd); cmd.Should().Fail(); - cmd.StdErr.Should().Be( + cmd.StdErr.Should().Contain( string.Format( CommonLocalizableStrings.CouldNotFindAnyProjectInDirectory, Path.Combine(projectDirectory, directoryToAdd))); From 6aee57543087bf08ee8a81c460b125a5849518d6 Mon Sep 17 00:00:00 2001 From: Eduardo Villalpando Mello Date: Fri, 8 Nov 2024 14:10:21 -0800 Subject: [PATCH 21/60] Fix some config tests --- .../dotnet/commands/dotnet-sln/add/Program.cs | 25 ++++++++--- test/dotnet-sln.Tests/GivenDotnetSlnAdd.cs | 44 +++++++++---------- 2 files changed, 42 insertions(+), 27 deletions(-) diff --git a/src/Cli/dotnet/commands/dotnet-sln/add/Program.cs b/src/Cli/dotnet/commands/dotnet-sln/add/Program.cs index bfa14079eb8f..1024a97bd1a4 100644 --- a/src/Cli/dotnet/commands/dotnet-sln/add/Program.cs +++ b/src/Cli/dotnet/commands/dotnet-sln/add/Program.cs @@ -58,12 +58,12 @@ public override int Execute() { throw; } - catch (SolutionException ex) - { - throw new GracefulException(CommonLocalizableStrings.InvalidSolutionFormatString, solutionFileFullPath, ex.Message); - } catch (Exception ex) { + if (ex is SolutionException || ex.InnerException is SolutionException) + { + throw new GracefulException(CommonLocalizableStrings.InvalidSolutionFormatString, solutionFileFullPath, ex.Message); + } throw new GracefulException(ex.Message, ex); } } @@ -112,10 +112,25 @@ private async Task AddProjectsToSolutionAsync(string solutionFileFullPath, IEnum } } } - solution.DistillProjectConfigurations(); + AddDefaultProjectConfigurations(solution); await serializer.SaveAsync(solutionFileFullPath, solution, cancellationToken); } + private void AddDefaultProjectConfigurations(SolutionModel solution) + { + string[] defaultConfigurationPlatforms = { "Any CPU", "x86", "x64" }; + foreach (var platform in defaultConfigurationPlatforms) + { + solution.AddPlatform(platform); + } + string[] defaultConfigurationBuildTypes = { "Debug", "Release" }; + foreach (var buildType in defaultConfigurationBuildTypes) + { + solution.AddBuildType(buildType); + } + solution.DistillProjectConfigurations(); + } + private string GetSolutionFolderPathWithForwardSlashes() { // SolutionModel::AddFolder expects path to have leading, trailing and inner forward slashes diff --git a/test/dotnet-sln.Tests/GivenDotnetSlnAdd.cs b/test/dotnet-sln.Tests/GivenDotnetSlnAdd.cs index cf1c02a0ae72..7eaff331cdea 100644 --- a/test/dotnet-sln.Tests/GivenDotnetSlnAdd.cs +++ b/test/dotnet-sln.Tests/GivenDotnetSlnAdd.cs @@ -262,7 +262,7 @@ public GivenDotnetSlnAdd(ITestOutputHelper log) : base(log) # Visual Studio 15 VisualStudioVersion = 15.0.26006.2 MinimumVisualStudioVersion = 10.0.40219.1 -Project(""{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}"") = ""ProjectWithAdditionalConfigs"", ""ProjectWithAdditionalConfigs\ProjectWithAdditionalConfigs.csproj"", ""{A302325B-D680-4C0E-8680-7AE283981624}"" +Project(""{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}"") = ""ProjectWithAdditionalConfigs"", ""ProjectWithAdditionalConfigs\ProjectWithAdditionalConfigs.csproj"", ""{B3EDC824-7B36-5688-363C-38F5E302E800}"" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -276,29 +276,29 @@ public GivenDotnetSlnAdd(ITestOutputHelper log) : base(log) Foo Bar|x64 = Foo Bar|x64 Foo Bar|x86 = Foo Bar|x86 EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {A302325B-D680-4C0E-8680-7AE283981624}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {A302325B-D680-4C0E-8680-7AE283981624}.Debug|Any CPU.Build.0 = Debug|Any CPU - {A302325B-D680-4C0E-8680-7AE283981624}.Debug|x64.ActiveCfg = Debug|x64 - {A302325B-D680-4C0E-8680-7AE283981624}.Debug|x64.Build.0 = Debug|x64 - {A302325B-D680-4C0E-8680-7AE283981624}.Debug|x86.ActiveCfg = Debug|x86 - {A302325B-D680-4C0E-8680-7AE283981624}.Debug|x86.Build.0 = Debug|x86 - {A302325B-D680-4C0E-8680-7AE283981624}.Release|Any CPU.ActiveCfg = Release|Any CPU - {A302325B-D680-4C0E-8680-7AE283981624}.Release|Any CPU.Build.0 = Release|Any CPU - {A302325B-D680-4C0E-8680-7AE283981624}.Release|x64.ActiveCfg = Release|x64 - {A302325B-D680-4C0E-8680-7AE283981624}.Release|x64.Build.0 = Release|x64 - {A302325B-D680-4C0E-8680-7AE283981624}.Release|x86.ActiveCfg = Release|x86 - {A302325B-D680-4C0E-8680-7AE283981624}.Release|x86.Build.0 = Release|x86 - {A302325B-D680-4C0E-8680-7AE283981624}.Foo Bar|Any CPU.ActiveCfg = FooBar|Any CPU - {A302325B-D680-4C0E-8680-7AE283981624}.Foo Bar|Any CPU.Build.0 = FooBar|Any CPU - {A302325B-D680-4C0E-8680-7AE283981624}.Foo Bar|x64.ActiveCfg = FooBar|x64 - {A302325B-D680-4C0E-8680-7AE283981624}.Foo Bar|x64.Build.0 = FooBar|x64 - {A302325B-D680-4C0E-8680-7AE283981624}.Foo Bar|x86.ActiveCfg = FooBar|x86 - {A302325B-D680-4C0E-8680-7AE283981624}.Foo Bar|x86.Build.0 = FooBar|x86 + {B3EDC824-7B36-5688-363C-38F5E302E800}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B3EDC824-7B36-5688-363C-38F5E302E800}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B3EDC824-7B36-5688-363C-38F5E302E800}.Debug|x64.ActiveCfg = Debug|x64 + {B3EDC824-7B36-5688-363C-38F5E302E800}.Debug|x64.Build.0 = Debug|x64 + {B3EDC824-7B36-5688-363C-38F5E302E800}.Debug|x86.ActiveCfg = Debug|x86 + {B3EDC824-7B36-5688-363C-38F5E302E800}.Debug|x86.Build.0 = Debug|x86 + {B3EDC824-7B36-5688-363C-38F5E302E800}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B3EDC824-7B36-5688-363C-38F5E302E800}.Release|Any CPU.Build.0 = Release|Any CPU + {B3EDC824-7B36-5688-363C-38F5E302E800}.Release|x64.ActiveCfg = Release|x64 + {B3EDC824-7B36-5688-363C-38F5E302E800}.Release|x64.Build.0 = Release|x64 + {B3EDC824-7B36-5688-363C-38F5E302E800}.Release|x86.ActiveCfg = Release|x86 + {B3EDC824-7B36-5688-363C-38F5E302E800}.Release|x86.Build.0 = Release|x86 + {B3EDC824-7B36-5688-363C-38F5E302E800}.Foo Bar|Any CPU.ActiveCfg = FooBar|Any CPU + {B3EDC824-7B36-5688-363C-38F5E302E800}.Foo Bar|Any CPU.Build.0 = FooBar|Any CPU + {B3EDC824-7B36-5688-363C-38F5E302E800}.Foo Bar|x64.ActiveCfg = FooBar|x64 + {B3EDC824-7B36-5688-363C-38F5E302E800}.Foo Bar|x64.Build.0 = FooBar|x64 + {B3EDC824-7B36-5688-363C-38F5E302E800}.Foo Bar|x86.ActiveCfg = FooBar|x86 + {B3EDC824-7B36-5688-363C-38F5E302E800}.Foo Bar|x86.Build.0 = FooBar|x86 EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection EndGlobal "; From e1681582ec51238e18cdf71d3184291c9e0a5a55 Mon Sep 17 00:00:00 2001 From: Eduardo Villalpando Mello Date: Fri, 8 Nov 2024 15:14:23 -0800 Subject: [PATCH 22/60] Revert guid detection --- src/Cli/dotnet/commands/dotnet-sln/add/Program.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Cli/dotnet/commands/dotnet-sln/add/Program.cs b/src/Cli/dotnet/commands/dotnet-sln/add/Program.cs index 1024a97bd1a4..3cca5a0153d0 100644 --- a/src/Cli/dotnet/commands/dotnet-sln/add/Program.cs +++ b/src/Cli/dotnet/commands/dotnet-sln/add/Program.cs @@ -90,8 +90,8 @@ private async Task AddProjectsToSolutionAsync(string solutionFileFullPath, IEnum try { // Try to open the project to see if it is valid - ProjectRootElement project = ProjectRootElement.Open(projectPath); - AddProjectWithDefaultGuid(solution, relativePath, solutionFolder, project.GetProjectTypeGuid()); + ProjectRootElement.Open(projectPath); + AddProjectWithDefaultGuid(solution, relativePath, solutionFolder); Reporter.Output.WriteLine(CommonLocalizableStrings.ProjectAddedToTheSolution, relativePath); } catch (InvalidProjectFileException ex) @@ -137,12 +137,12 @@ private string GetSolutionFolderPathWithForwardSlashes() return "/" + string.Join("/", PathUtility.GetPathWithDirectorySeparator(_solutionFolderPath).Split(Path.DirectorySeparatorChar, StringSplitOptions.RemoveEmptyEntries)) + "/"; } - private void AddProjectWithDefaultGuid(SolutionModel solution, string relativePath, SolutionFolderModel solutionFolder, string guid) + private void AddProjectWithDefaultGuid(SolutionModel solution, string relativePath, SolutionFolderModel solutionFolder) { SolutionProjectModel project; try { - solution.AddProject(relativePath, guid, solutionFolder); + solution.AddProject(relativePath, null, solutionFolder); } catch (ArgumentException ex) { From 07343f93902a9a510c2e3bbb5223a4d92fddcb50 Mon Sep 17 00:00:00 2001 From: Eduardo Villalpando Mello Date: Mon, 11 Nov 2024 13:27:45 -0800 Subject: [PATCH 23/60] Update tests guids and translations --- .../dotnet-sln/LocalizableStrings.resx | 2 +- .../dotnet/commands/dotnet-sln/add/Program.cs | 4 +- test/dotnet-sln.Tests/GivenDotnetSlnAdd.cs | 72 +++++++++---------- 3 files changed, 39 insertions(+), 39 deletions(-) diff --git a/src/Cli/dotnet/commands/dotnet-sln/LocalizableStrings.resx b/src/Cli/dotnet/commands/dotnet-sln/LocalizableStrings.resx index 9e4647d556fa..85144374a79c 100644 --- a/src/Cli/dotnet/commands/dotnet-sln/LocalizableStrings.resx +++ b/src/Cli/dotnet/commands/dotnet-sln/LocalizableStrings.resx @@ -187,6 +187,6 @@ Cannot migrate .slnx file. - Could not find serializer for file {0}. + Could not read solution file {0}. Supported files are .sln and .slnx valid solutions. \ No newline at end of file diff --git a/src/Cli/dotnet/commands/dotnet-sln/add/Program.cs b/src/Cli/dotnet/commands/dotnet-sln/add/Program.cs index 3cca5a0153d0..f825e288fb27 100644 --- a/src/Cli/dotnet/commands/dotnet-sln/add/Program.cs +++ b/src/Cli/dotnet/commands/dotnet-sln/add/Program.cs @@ -142,14 +142,14 @@ private void AddProjectWithDefaultGuid(SolutionModel solution, string relativePa SolutionProjectModel project; try { - solution.AddProject(relativePath, null, solutionFolder); + project = solution.AddProject(relativePath, null, solutionFolder); } catch (ArgumentException ex) { // TODO: Update with error codes from vs-solutionpersistence if (ex.Message == "ProjectType '' not found. (Parameter 'projectTypeName')") { - solution.AddProject(relativePath, "130159A9-F047-44B3-88CF-0CF7F02ED50F", solutionFolder); + project = solution.AddProject(relativePath, "130159A9-F047-44B3-88CF-0CF7F02ED50F", solutionFolder); } else { diff --git a/test/dotnet-sln.Tests/GivenDotnetSlnAdd.cs b/test/dotnet-sln.Tests/GivenDotnetSlnAdd.cs index 7eaff331cdea..10ebd346bad7 100644 --- a/test/dotnet-sln.Tests/GivenDotnetSlnAdd.cs +++ b/test/dotnet-sln.Tests/GivenDotnetSlnAdd.cs @@ -172,7 +172,7 @@ public GivenDotnetSlnAdd(ITestOutputHelper log) : base(log) # Visual Studio 15 VisualStudioVersion = 15.0.26006.2 MinimumVisualStudioVersion = 10.0.40219.1 -Project(""{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}"") = ""ProjectWithoutMatchingConfigs"", ""ProjectWithoutMatchingConfigs\ProjectWithoutMatchingConfigs.csproj"", ""{C49B64DE-4401-4825-8A88-10DCB5950E57}"" +Project(""{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}"") = ""ProjectWithoutMatchingConfigs"", ""ProjectWithoutMatchingConfigs\ProjectWithoutMatchingConfigs.csproj"", ""{D75411E5-21DC-0537-8C05-E1E6A920613E}"" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -186,29 +186,29 @@ public GivenDotnetSlnAdd(ITestOutputHelper log) : base(log) Foo Bar|x64 = Foo Bar|x64 Foo Bar|x86 = Foo Bar|x86 EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {D75411E5-21DC-0537-8C05-E1E6A920613E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D75411E5-21DC-0537-8C05-E1E6A920613E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D75411E5-21DC-0537-8C05-E1E6A920613E}.Debug|x64.ActiveCfg = Debug|Any CPU + {D75411E5-21DC-0537-8C05-E1E6A920613E}.Debug|x64.Build.0 = Debug|Any CPU + {D75411E5-21DC-0537-8C05-E1E6A920613E}.Debug|x86.ActiveCfg = Debug|Any CPU + {D75411E5-21DC-0537-8C05-E1E6A920613E}.Debug|x86.Build.0 = Debug|Any CPU + {D75411E5-21DC-0537-8C05-E1E6A920613E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D75411E5-21DC-0537-8C05-E1E6A920613E}.Release|Any CPU.Build.0 = Release|Any CPU + {D75411E5-21DC-0537-8C05-E1E6A920613E}.Release|x64.ActiveCfg = Release|Any CPU + {D75411E5-21DC-0537-8C05-E1E6A920613E}.Release|x64.Build.0 = Release|Any CPU + {D75411E5-21DC-0537-8C05-E1E6A920613E}.Release|x86.ActiveCfg = Release|Any CPU + {D75411E5-21DC-0537-8C05-E1E6A920613E}.Release|x86.Build.0 = Release|Any CPU + {D75411E5-21DC-0537-8C05-E1E6A920613E}.Foo Bar|Any CPU.ActiveCfg = Debug|Any CPU + {D75411E5-21DC-0537-8C05-E1E6A920613E}.Foo Bar|Any CPU.Build.0 = Debug|Any CPU + {D75411E5-21DC-0537-8C05-E1E6A920613E}.Foo Bar|x64.ActiveCfg = Debug|Any CPU + {D75411E5-21DC-0537-8C05-E1E6A920613E}.Foo Bar|x64.Build.0 = Debug|Any CPU + {D75411E5-21DC-0537-8C05-E1E6A920613E}.Foo Bar|x86.ActiveCfg = Debug|Any CPU + {D75411E5-21DC-0537-8C05-E1E6A920613E}.Foo Bar|x86.Build.0 = Debug|Any CPU + EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {C49B64DE-4401-4825-8A88-10DCB5950E57}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {C49B64DE-4401-4825-8A88-10DCB5950E57}.Debug|Any CPU.Build.0 = Debug|Any CPU - {C49B64DE-4401-4825-8A88-10DCB5950E57}.Debug|x64.ActiveCfg = Debug|Any CPU - {C49B64DE-4401-4825-8A88-10DCB5950E57}.Debug|x64.Build.0 = Debug|Any CPU - {C49B64DE-4401-4825-8A88-10DCB5950E57}.Debug|x86.ActiveCfg = Debug|Any CPU - {C49B64DE-4401-4825-8A88-10DCB5950E57}.Debug|x86.Build.0 = Debug|Any CPU - {C49B64DE-4401-4825-8A88-10DCB5950E57}.Release|Any CPU.ActiveCfg = Release|Any CPU - {C49B64DE-4401-4825-8A88-10DCB5950E57}.Release|Any CPU.Build.0 = Release|Any CPU - {C49B64DE-4401-4825-8A88-10DCB5950E57}.Release|x64.ActiveCfg = Release|Any CPU - {C49B64DE-4401-4825-8A88-10DCB5950E57}.Release|x64.Build.0 = Release|Any CPU - {C49B64DE-4401-4825-8A88-10DCB5950E57}.Release|x86.ActiveCfg = Release|Any CPU - {C49B64DE-4401-4825-8A88-10DCB5950E57}.Release|x86.Build.0 = Release|Any CPU - {C49B64DE-4401-4825-8A88-10DCB5950E57}.Foo Bar|Any CPU.ActiveCfg = Debug|Any CPU - {C49B64DE-4401-4825-8A88-10DCB5950E57}.Foo Bar|Any CPU.Build.0 = Debug|Any CPU - {C49B64DE-4401-4825-8A88-10DCB5950E57}.Foo Bar|x64.ActiveCfg = Debug|Any CPU - {C49B64DE-4401-4825-8A88-10DCB5950E57}.Foo Bar|x64.Build.0 = Debug|Any CPU - {C49B64DE-4401-4825-8A88-10DCB5950E57}.Foo Bar|x86.ActiveCfg = Debug|Any CPU - {C49B64DE-4401-4825-8A88-10DCB5950E57}.Foo Bar|x86.Build.0 = Debug|Any CPU - EndGlobalSection EndGlobal "; @@ -309,7 +309,7 @@ public GivenDotnetSlnAdd(ITestOutputHelper log) : base(log) MinimumVisualStudioVersion = 10.0.40219.1 Project(""{9A19103F-16F7-4668-BE54-9A1E7A4F7556}"") = ""App"", ""App.csproj"", ""{7072A694-548F-4CAE-A58F-12D257D5F486}"" EndProject -Project(""{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}"") = ""Lib"", ""src\Lib\Lib.csproj"", ""{84A45D44-B677-492D-A6DA-B3A71135AB8E}"" +Project(""{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}"") = ""Lib"", ""src\Lib\Lib.csproj"", ""{8C318457-B2F6-5F74-188F-CC8D5F235C4A}"" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -333,18 +333,18 @@ public GivenDotnetSlnAdd(ITestOutputHelper log) : base(log) {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 - {84A45D44-B677-492D-A6DA-B3A71135AB8E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {84A45D44-B677-492D-A6DA-B3A71135AB8E}.Debug|Any CPU.Build.0 = Debug|Any CPU - {84A45D44-B677-492D-A6DA-B3A71135AB8E}.Debug|x64.ActiveCfg = Debug|Any CPU - {84A45D44-B677-492D-A6DA-B3A71135AB8E}.Debug|x64.Build.0 = Debug|Any CPU - {84A45D44-B677-492D-A6DA-B3A71135AB8E}.Debug|x86.ActiveCfg = Debug|Any CPU - {84A45D44-B677-492D-A6DA-B3A71135AB8E}.Debug|x86.Build.0 = Debug|Any CPU - {84A45D44-B677-492D-A6DA-B3A71135AB8E}.Release|Any CPU.ActiveCfg = Release|Any CPU - {84A45D44-B677-492D-A6DA-B3A71135AB8E}.Release|Any CPU.Build.0 = Release|Any CPU - {84A45D44-B677-492D-A6DA-B3A71135AB8E}.Release|x64.ActiveCfg = Release|Any CPU - {84A45D44-B677-492D-A6DA-B3A71135AB8E}.Release|x64.Build.0 = Release|Any CPU - {84A45D44-B677-492D-A6DA-B3A71135AB8E}.Release|x86.ActiveCfg = Release|Any CPU - {84A45D44-B677-492D-A6DA-B3A71135AB8E}.Release|x86.Build.0 = Release|Any CPU + {8C318457-B2F6-5F74-188F-CC8D5F235C4A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8C318457-B2F6-5F74-188F-CC8D5F235C4A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8C318457-B2F6-5F74-188F-CC8D5F235C4A}.Debug|x64.ActiveCfg = Debug|Any CPU + {8C318457-B2F6-5F74-188F-CC8D5F235C4A}.Debug|x64.Build.0 = Debug|Any CPU + {8C318457-B2F6-5F74-188F-CC8D5F235C4A}.Debug|x86.ActiveCfg = Debug|Any CPU + {8C318457-B2F6-5F74-188F-CC8D5F235C4A}.Debug|x86.Build.0 = Debug|Any CPU + {8C318457-B2F6-5F74-188F-CC8D5F235C4A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8C318457-B2F6-5F74-188F-CC8D5F235C4A}.Release|Any CPU.Build.0 = Release|Any CPU + {8C318457-B2F6-5F74-188F-CC8D5F235C4A}.Release|x64.ActiveCfg = Release|Any CPU + {8C318457-B2F6-5F74-188F-CC8D5F235C4A}.Release|x64.Build.0 = Release|Any CPU + {8C318457-B2F6-5F74-188F-CC8D5F235C4A}.Release|x86.ActiveCfg = Release|Any CPU + {8C318457-B2F6-5F74-188F-CC8D5F235C4A}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -830,10 +830,10 @@ public void WhenSolutionFolderExistsItDoesNotGetAdded(string solutionCommand, st [Theory] [InlineData("sln", "TestAppWithSlnAndCsprojFiles", ExpectedSlnFileAfterAddingLibProj, "")] - [InlineData("sln", "TestAppWithSlnAndCsprojProjectGuidFiles", ExpectedSlnFileAfterAddingLibProj, "{84A45D44-B677-492D-A6DA-B3A71135AB8E}")] + [InlineData("sln", "TestAppWithSlnAndCsprojProjectGuidFiles", ExpectedSlnFileAfterAddingLibProj, "{97594868-6D78-0274-047F-2FC3453194BE}")] [InlineData("sln", "TestAppWithEmptySln", ExpectedSlnFileAfterAddingLibProjToEmptySln, "")] [InlineData("solution", "TestAppWithSlnAndCsprojFiles", ExpectedSlnFileAfterAddingLibProj, "")] - [InlineData("solution", "TestAppWithSlnAndCsprojProjectGuidFiles", ExpectedSlnFileAfterAddingLibProj, "{84A45D44-B677-492D-A6DA-B3A71135AB8E}")] + [InlineData("solution", "TestAppWithSlnAndCsprojProjectGuidFiles", ExpectedSlnFileAfterAddingLibProj, "{97594868-6D78-0274-047F-2FC3453194BE}")] [InlineData("solution", "TestAppWithEmptySln", ExpectedSlnFileAfterAddingLibProjToEmptySln, "")] public void WhenValidProjectIsPassedBuildConfigsAreAdded( string solutionCommand, From af2917ac8e5fa5880bbf80d34fbf8378bd04072f Mon Sep 17 00:00:00 2001 From: Eduardo Villalpando Mello Date: Mon, 11 Nov 2024 13:34:29 -0800 Subject: [PATCH 24/60] Update translations (build) --- .../dotnet/commands/dotnet-sln/xlf/LocalizableStrings.cs.xlf | 4 ++-- .../dotnet/commands/dotnet-sln/xlf/LocalizableStrings.de.xlf | 4 ++-- .../dotnet/commands/dotnet-sln/xlf/LocalizableStrings.es.xlf | 4 ++-- .../dotnet/commands/dotnet-sln/xlf/LocalizableStrings.fr.xlf | 4 ++-- .../dotnet/commands/dotnet-sln/xlf/LocalizableStrings.it.xlf | 4 ++-- .../dotnet/commands/dotnet-sln/xlf/LocalizableStrings.ja.xlf | 4 ++-- .../dotnet/commands/dotnet-sln/xlf/LocalizableStrings.ko.xlf | 4 ++-- .../dotnet/commands/dotnet-sln/xlf/LocalizableStrings.pl.xlf | 4 ++-- .../commands/dotnet-sln/xlf/LocalizableStrings.pt-BR.xlf | 4 ++-- .../dotnet/commands/dotnet-sln/xlf/LocalizableStrings.ru.xlf | 4 ++-- .../dotnet/commands/dotnet-sln/xlf/LocalizableStrings.tr.xlf | 4 ++-- .../commands/dotnet-sln/xlf/LocalizableStrings.zh-Hans.xlf | 4 ++-- .../commands/dotnet-sln/xlf/LocalizableStrings.zh-Hant.xlf | 4 ++-- 13 files changed, 26 insertions(+), 26 deletions(-) diff --git a/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.cs.xlf b/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.cs.xlf index 4bab05e710d3..452eb1f1acba 100644 --- a/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.cs.xlf +++ b/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.cs.xlf @@ -68,8 +68,8 @@ - Could not find serializer for file {0}. - Could not find serializer for file {0}. + Could not read solution file {0}. Supported files are .sln and .slnx valid solutions. + Could not read solution file {0}. Supported files are .sln and .slnx valid solutions. diff --git a/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.de.xlf b/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.de.xlf index d5f7d7054d71..357e6e4a41e0 100644 --- a/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.de.xlf +++ b/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.de.xlf @@ -68,8 +68,8 @@ - Could not find serializer for file {0}. - Could not find serializer for file {0}. + Could not read solution file {0}. Supported files are .sln and .slnx valid solutions. + Could not read solution file {0}. Supported files are .sln and .slnx valid solutions. diff --git a/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.es.xlf b/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.es.xlf index c36ef1717c81..5bf6ad671c05 100644 --- a/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.es.xlf +++ b/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.es.xlf @@ -68,8 +68,8 @@ - Could not find serializer for file {0}. - Could not find serializer for file {0}. + Could not read solution file {0}. Supported files are .sln and .slnx valid solutions. + Could not read solution file {0}. Supported files are .sln and .slnx valid solutions. diff --git a/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.fr.xlf b/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.fr.xlf index 66cd0437b80d..36ca5556f161 100644 --- a/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.fr.xlf +++ b/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.fr.xlf @@ -68,8 +68,8 @@ - Could not find serializer for file {0}. - Could not find serializer for file {0}. + Could not read solution file {0}. Supported files are .sln and .slnx valid solutions. + Could not read solution file {0}. Supported files are .sln and .slnx valid solutions. diff --git a/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.it.xlf b/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.it.xlf index 63a4dca3e966..40ec30e1a3c6 100644 --- a/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.it.xlf +++ b/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.it.xlf @@ -68,8 +68,8 @@ - Could not find serializer for file {0}. - Could not find serializer for file {0}. + Could not read solution file {0}. Supported files are .sln and .slnx valid solutions. + Could not read solution file {0}. Supported files are .sln and .slnx valid solutions. diff --git a/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.ja.xlf b/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.ja.xlf index fa49b36f3c7c..274d0d2c9ea1 100644 --- a/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.ja.xlf +++ b/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.ja.xlf @@ -68,8 +68,8 @@ - Could not find serializer for file {0}. - Could not find serializer for file {0}. + Could not read solution file {0}. Supported files are .sln and .slnx valid solutions. + Could not read solution file {0}. Supported files are .sln and .slnx valid solutions. diff --git a/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.ko.xlf b/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.ko.xlf index ec6fcef3b737..66387fe59115 100644 --- a/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.ko.xlf +++ b/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.ko.xlf @@ -68,8 +68,8 @@ - Could not find serializer for file {0}. - Could not find serializer for file {0}. + Could not read solution file {0}. Supported files are .sln and .slnx valid solutions. + Could not read solution file {0}. Supported files are .sln and .slnx valid solutions. diff --git a/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.pl.xlf b/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.pl.xlf index 601ff500d1cc..9e1723fa511e 100644 --- a/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.pl.xlf +++ b/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.pl.xlf @@ -68,8 +68,8 @@ - Could not find serializer for file {0}. - Could not find serializer for file {0}. + Could not read solution file {0}. Supported files are .sln and .slnx valid solutions. + Could not read solution file {0}. Supported files are .sln and .slnx valid solutions. diff --git a/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.pt-BR.xlf b/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.pt-BR.xlf index 6d941b650f1e..876164d9cdb5 100644 --- a/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.pt-BR.xlf +++ b/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.pt-BR.xlf @@ -68,8 +68,8 @@ - Could not find serializer for file {0}. - Could not find serializer for file {0}. + Could not read solution file {0}. Supported files are .sln and .slnx valid solutions. + Could not read solution file {0}. Supported files are .sln and .slnx valid solutions. diff --git a/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.ru.xlf b/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.ru.xlf index 6960662f0eed..24c105f6a548 100644 --- a/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.ru.xlf +++ b/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.ru.xlf @@ -68,8 +68,8 @@ - Could not find serializer for file {0}. - Could not find serializer for file {0}. + Could not read solution file {0}. Supported files are .sln and .slnx valid solutions. + Could not read solution file {0}. Supported files are .sln and .slnx valid solutions. diff --git a/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.tr.xlf b/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.tr.xlf index a705f8605a87..4a29464dd1f5 100644 --- a/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.tr.xlf +++ b/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.tr.xlf @@ -68,8 +68,8 @@ - Could not find serializer for file {0}. - Could not find serializer for file {0}. + Could not read solution file {0}. Supported files are .sln and .slnx valid solutions. + Could not read solution file {0}. Supported files are .sln and .slnx valid solutions. diff --git a/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.zh-Hans.xlf b/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.zh-Hans.xlf index 533a67153faf..688f7b8723ee 100644 --- a/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.zh-Hans.xlf +++ b/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.zh-Hans.xlf @@ -68,8 +68,8 @@ - Could not find serializer for file {0}. - Could not find serializer for file {0}. + Could not read solution file {0}. Supported files are .sln and .slnx valid solutions. + Could not read solution file {0}. Supported files are .sln and .slnx valid solutions. diff --git a/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.zh-Hant.xlf b/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.zh-Hant.xlf index fcf5d583a1ba..4184b0f2118e 100644 --- a/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.zh-Hant.xlf +++ b/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.zh-Hant.xlf @@ -68,8 +68,8 @@ - Could not find serializer for file {0}. - Could not find serializer for file {0}. + Could not read solution file {0}. Supported files are .sln and .slnx valid solutions. + Could not read solution file {0}. Supported files are .sln and .slnx valid solutions. From 6d8c3fe7515652eb709e174a3e42664c34984685 Mon Sep 17 00:00:00 2001 From: Eduardo Villalpando Mello Date: Mon, 11 Nov 2024 15:41:26 -0800 Subject: [PATCH 25/60] Fix additional tests --- src/Cli/dotnet/commands/dotnet-sln/add/Program.cs | 7 ++++++- test/dotnet-sln.Tests/GivenDotnetSlnAdd.cs | 3 +++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/Cli/dotnet/commands/dotnet-sln/add/Program.cs b/src/Cli/dotnet/commands/dotnet-sln/add/Program.cs index f825e288fb27..8b6c331c62bf 100644 --- a/src/Cli/dotnet/commands/dotnet-sln/add/Program.cs +++ b/src/Cli/dotnet/commands/dotnet-sln/add/Program.cs @@ -118,7 +118,7 @@ private async Task AddProjectsToSolutionAsync(string solutionFileFullPath, IEnum private void AddDefaultProjectConfigurations(SolutionModel solution) { - string[] defaultConfigurationPlatforms = { "Any CPU", "x86", "x64" }; + string[] defaultConfigurationPlatforms = { "Any CPU", "x64", "x86" }; foreach (var platform in defaultConfigurationPlatforms) { solution.AddPlatform(platform); @@ -128,6 +128,11 @@ private void AddDefaultProjectConfigurations(SolutionModel solution) { solution.AddBuildType(buildType); } + if (solution.SolutionProjects.Count > 1) + { + // https://stackoverflow.com/a/14714485 + solution.RemoveProperties("HideSolutionNode"); + } solution.DistillProjectConfigurations(); } diff --git a/test/dotnet-sln.Tests/GivenDotnetSlnAdd.cs b/test/dotnet-sln.Tests/GivenDotnetSlnAdd.cs index 10ebd346bad7..f31c9afc5d52 100644 --- a/test/dotnet-sln.Tests/GivenDotnetSlnAdd.cs +++ b/test/dotnet-sln.Tests/GivenDotnetSlnAdd.cs @@ -109,6 +109,9 @@ public GivenDotnetSlnAdd(ITestOutputHelper log) : base(log) __LIB_PROJECT_GUID__.Release|x86.ActiveCfg = Release|Any CPU __LIB_PROJECT_GUID__.Release|x86.Build.0 = Release|Any CPU EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection EndGlobal "; From b19588008608e0db82b52b7c6939f5c8e2dcf388 Mon Sep 17 00:00:00 2001 From: Eduardo Villalpando Mello Date: Mon, 11 Nov 2024 16:39:43 -0800 Subject: [PATCH 26/60] Fix issues from pr --- src/Cli/dotnet/commands/dotnet-sln/LocalizableStrings.resx | 2 +- src/Cli/dotnet/commands/dotnet-sln/add/Program.cs | 1 - .../dotnet/commands/dotnet-sln/xlf/LocalizableStrings.cs.xlf | 4 ++-- .../dotnet/commands/dotnet-sln/xlf/LocalizableStrings.de.xlf | 4 ++-- .../dotnet/commands/dotnet-sln/xlf/LocalizableStrings.es.xlf | 4 ++-- .../dotnet/commands/dotnet-sln/xlf/LocalizableStrings.fr.xlf | 4 ++-- .../dotnet/commands/dotnet-sln/xlf/LocalizableStrings.it.xlf | 4 ++-- .../dotnet/commands/dotnet-sln/xlf/LocalizableStrings.ja.xlf | 4 ++-- .../dotnet/commands/dotnet-sln/xlf/LocalizableStrings.ko.xlf | 4 ++-- .../dotnet/commands/dotnet-sln/xlf/LocalizableStrings.pl.xlf | 4 ++-- .../commands/dotnet-sln/xlf/LocalizableStrings.pt-BR.xlf | 4 ++-- .../dotnet/commands/dotnet-sln/xlf/LocalizableStrings.ru.xlf | 4 ++-- .../dotnet/commands/dotnet-sln/xlf/LocalizableStrings.tr.xlf | 4 ++-- .../commands/dotnet-sln/xlf/LocalizableStrings.zh-Hans.xlf | 4 ++-- .../commands/dotnet-sln/xlf/LocalizableStrings.zh-Hant.xlf | 4 ++-- 15 files changed, 27 insertions(+), 28 deletions(-) diff --git a/src/Cli/dotnet/commands/dotnet-sln/LocalizableStrings.resx b/src/Cli/dotnet/commands/dotnet-sln/LocalizableStrings.resx index 85144374a79c..4748d3d4504b 100644 --- a/src/Cli/dotnet/commands/dotnet-sln/LocalizableStrings.resx +++ b/src/Cli/dotnet/commands/dotnet-sln/LocalizableStrings.resx @@ -184,7 +184,7 @@ .slnx file {0} generated. - Cannot migrate .slnx file. + Only .sln files can be migrated to .slnx format. Could not read solution file {0}. Supported files are .sln and .slnx valid solutions. diff --git a/src/Cli/dotnet/commands/dotnet-sln/add/Program.cs b/src/Cli/dotnet/commands/dotnet-sln/add/Program.cs index 8b6c331c62bf..a513b0306bf0 100644 --- a/src/Cli/dotnet/commands/dotnet-sln/add/Program.cs +++ b/src/Cli/dotnet/commands/dotnet-sln/add/Program.cs @@ -2,7 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.CommandLine; -using System.Linq.Expressions; using System.Text.RegularExpressions; using Microsoft.Build.Construction; using Microsoft.Build.Exceptions; diff --git a/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.cs.xlf b/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.cs.xlf index 452eb1f1acba..f5b32233e7d0 100644 --- a/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.cs.xlf +++ b/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.cs.xlf @@ -28,8 +28,8 @@ - Cannot migrate .slnx file. - Cannot migrate .slnx file. + Only .sln files can be migrated to .slnx format. + Only .sln files can be migrated to .slnx format. diff --git a/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.de.xlf b/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.de.xlf index 357e6e4a41e0..f8eb231f7950 100644 --- a/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.de.xlf +++ b/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.de.xlf @@ -28,8 +28,8 @@ - Cannot migrate .slnx file. - Cannot migrate .slnx file. + Only .sln files can be migrated to .slnx format. + Only .sln files can be migrated to .slnx format. diff --git a/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.es.xlf b/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.es.xlf index 5bf6ad671c05..6ed23a5e39fe 100644 --- a/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.es.xlf +++ b/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.es.xlf @@ -28,8 +28,8 @@ - Cannot migrate .slnx file. - Cannot migrate .slnx file. + Only .sln files can be migrated to .slnx format. + Only .sln files can be migrated to .slnx format. diff --git a/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.fr.xlf b/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.fr.xlf index 36ca5556f161..b1d8c5880aff 100644 --- a/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.fr.xlf +++ b/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.fr.xlf @@ -28,8 +28,8 @@ - Cannot migrate .slnx file. - Cannot migrate .slnx file. + Only .sln files can be migrated to .slnx format. + Only .sln files can be migrated to .slnx format. diff --git a/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.it.xlf b/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.it.xlf index 40ec30e1a3c6..989a4f33844e 100644 --- a/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.it.xlf +++ b/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.it.xlf @@ -28,8 +28,8 @@ - Cannot migrate .slnx file. - Cannot migrate .slnx file. + Only .sln files can be migrated to .slnx format. + Only .sln files can be migrated to .slnx format. diff --git a/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.ja.xlf b/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.ja.xlf index 274d0d2c9ea1..2683028f11aa 100644 --- a/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.ja.xlf +++ b/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.ja.xlf @@ -28,8 +28,8 @@ - Cannot migrate .slnx file. - Cannot migrate .slnx file. + Only .sln files can be migrated to .slnx format. + Only .sln files can be migrated to .slnx format. diff --git a/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.ko.xlf b/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.ko.xlf index 66387fe59115..895400338f29 100644 --- a/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.ko.xlf +++ b/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.ko.xlf @@ -28,8 +28,8 @@ - Cannot migrate .slnx file. - Cannot migrate .slnx file. + Only .sln files can be migrated to .slnx format. + Only .sln files can be migrated to .slnx format. diff --git a/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.pl.xlf b/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.pl.xlf index 9e1723fa511e..e384d5d00475 100644 --- a/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.pl.xlf +++ b/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.pl.xlf @@ -28,8 +28,8 @@ - Cannot migrate .slnx file. - Cannot migrate .slnx file. + Only .sln files can be migrated to .slnx format. + Only .sln files can be migrated to .slnx format. diff --git a/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.pt-BR.xlf b/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.pt-BR.xlf index 876164d9cdb5..ba4d879b8340 100644 --- a/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.pt-BR.xlf +++ b/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.pt-BR.xlf @@ -28,8 +28,8 @@ - Cannot migrate .slnx file. - Cannot migrate .slnx file. + Only .sln files can be migrated to .slnx format. + Only .sln files can be migrated to .slnx format. diff --git a/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.ru.xlf b/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.ru.xlf index 24c105f6a548..c5dfbd52a60c 100644 --- a/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.ru.xlf +++ b/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.ru.xlf @@ -28,8 +28,8 @@ - Cannot migrate .slnx file. - Cannot migrate .slnx file. + Only .sln files can be migrated to .slnx format. + Only .sln files can be migrated to .slnx format. diff --git a/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.tr.xlf b/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.tr.xlf index 4a29464dd1f5..fea7bcc4ea34 100644 --- a/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.tr.xlf +++ b/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.tr.xlf @@ -28,8 +28,8 @@ - Cannot migrate .slnx file. - Cannot migrate .slnx file. + Only .sln files can be migrated to .slnx format. + Only .sln files can be migrated to .slnx format. diff --git a/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.zh-Hans.xlf b/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.zh-Hans.xlf index 688f7b8723ee..82241d2d4a6a 100644 --- a/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.zh-Hans.xlf +++ b/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.zh-Hans.xlf @@ -28,8 +28,8 @@ - Cannot migrate .slnx file. - Cannot migrate .slnx file. + Only .sln files can be migrated to .slnx format. + Only .sln files can be migrated to .slnx format. diff --git a/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.zh-Hant.xlf b/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.zh-Hant.xlf index 4184b0f2118e..5b061ec4f5f2 100644 --- a/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.zh-Hant.xlf +++ b/src/Cli/dotnet/commands/dotnet-sln/xlf/LocalizableStrings.zh-Hant.xlf @@ -28,8 +28,8 @@ - Cannot migrate .slnx file. - Cannot migrate .slnx file. + Only .sln files can be migrated to .slnx format. + Only .sln files can be migrated to .slnx format. From 93775e81592788108a915bdfaa6c6b4f7bb1e640 Mon Sep 17 00:00:00 2001 From: Eduardo Villalpando Mello Date: Tue, 12 Nov 2024 15:08:10 -0800 Subject: [PATCH 27/60] Solve solution folder tests --- .../dotnet/commands/dotnet-sln/add/Program.cs | 28 ++++++++++++++----- test/dotnet-sln.Tests/GivenDotnetSlnAdd.cs | 4 +-- 2 files changed, 23 insertions(+), 9 deletions(-) diff --git a/src/Cli/dotnet/commands/dotnet-sln/add/Program.cs b/src/Cli/dotnet/commands/dotnet-sln/add/Program.cs index a513b0306bf0..843d41e7563c 100644 --- a/src/Cli/dotnet/commands/dotnet-sln/add/Program.cs +++ b/src/Cli/dotnet/commands/dotnet-sln/add/Program.cs @@ -22,6 +22,11 @@ internal class AddProjectToSolutionCommand : CommandBase private readonly IReadOnlyCollection _projects; private readonly string? _solutionFolderPath; + private static string GetSolutionFolderPathWithForwardSlashes(string path) + { + // SolutionModel::AddFolder expects path to have leading, trailing and inner forward slashes + return "/" + string.Join("/", PathUtility.GetPathWithDirectorySeparator(path).Split(Path.DirectorySeparatorChar, StringSplitOptions.RemoveEmptyEntries)) + "/"; + } public AddProjectToSolutionCommand(ParseResult parseResult) : base(parseResult) { _fileOrDirectory = parseResult.GetValue(SlnCommandParser.SlnArgument); @@ -80,7 +85,7 @@ private async Task AddProjectsToSolutionAsync(string solutionFileFullPath, IEnum }); } SolutionFolderModel? solutionFolder = (!_inRoot && _solutionFolderPath != null) - ? solution.AddFolder(GetSolutionFolderPathWithForwardSlashes()) + ? solution.AddFolder(GetSolutionFolderPathWithForwardSlashes(_solutionFolderPath)) : null; foreach (var projectPath in projectPaths) { @@ -135,12 +140,6 @@ private void AddDefaultProjectConfigurations(SolutionModel solution) solution.DistillProjectConfigurations(); } - private string GetSolutionFolderPathWithForwardSlashes() - { - // SolutionModel::AddFolder expects path to have leading, trailing and inner forward slashes - return "/" + string.Join("/", PathUtility.GetPathWithDirectorySeparator(_solutionFolderPath).Split(Path.DirectorySeparatorChar, StringSplitOptions.RemoveEmptyEntries)) + "/"; - } - private void AddProjectWithDefaultGuid(SolutionModel solution, string relativePath, SolutionFolderModel solutionFolder) { SolutionProjectModel project; @@ -160,6 +159,21 @@ private void AddProjectWithDefaultGuid(SolutionModel solution, string relativePa throw; } } + // Generate local solution folder + if (solutionFolder is null) + { + var relativePathDirectory = Path.GetDirectoryName(relativePath); + if (relativePathDirectory != null) + { + SolutionFolderModel relativeSolutionFolder = solution.AddFolder(GetSolutionFolderPathWithForwardSlashes(relativePathDirectory)); + project.MoveToFolder(relativeSolutionFolder); + // Avoid duplicate folder/project names + if (project.Parent is not null && project.Parent.ActualDisplayName == project.ActualDisplayName) + { + solution.RemoveFolder(project.Parent); + } + } + } } } } diff --git a/test/dotnet-sln.Tests/GivenDotnetSlnAdd.cs b/test/dotnet-sln.Tests/GivenDotnetSlnAdd.cs index f31c9afc5d52..1a9d65c66b76 100644 --- a/test/dotnet-sln.Tests/GivenDotnetSlnAdd.cs +++ b/test/dotnet-sln.Tests/GivenDotnetSlnAdd.cs @@ -122,10 +122,10 @@ public GivenDotnetSlnAdd(ITestOutputHelper log) : base(log) MinimumVisualStudioVersion = 10.0.40219.1 Project(""{9A19103F-16F7-4668-BE54-9A1E7A4F7556}"") = ""App"", ""App.csproj"", ""{7072A694-548F-4CAE-A58F-12D257D5F486}"" EndProject -Project(""{2150E333-8FDC-42A3-9474-1A3956D46DE8}"") = ""src"", ""src"", ""__SRC_FOLDER_GUID__"" -EndProject Project(""{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}"") = ""Lib"", ""src\Lib\Lib.csproj"", ""__LIB_PROJECT_GUID__"" EndProject +Project(""{2150E333-8FDC-42A3-9474-1A3956D46DE8}"") = ""src"", ""src"", ""__SRC_FOLDER_GUID__"" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU From 3195e02592cd0b025374eb4fbb4b6b7840f56cba Mon Sep 17 00:00:00 2001 From: Eduardo Villalpando Mello Date: Tue, 12 Nov 2024 15:31:26 -0800 Subject: [PATCH 28/60] Fix additional tests --- src/Cli/dotnet/commands/dotnet-sln/add/Program.cs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/Cli/dotnet/commands/dotnet-sln/add/Program.cs b/src/Cli/dotnet/commands/dotnet-sln/add/Program.cs index 843d41e7563c..f11575ef31cb 100644 --- a/src/Cli/dotnet/commands/dotnet-sln/add/Program.cs +++ b/src/Cli/dotnet/commands/dotnet-sln/add/Program.cs @@ -89,12 +89,10 @@ private async Task AddProjectsToSolutionAsync(string solutionFileFullPath, IEnum : null; foreach (var projectPath in projectPaths) { - // Get full project path var relativePath = Path.GetRelativePath(Path.GetDirectoryName(solutionFileFullPath), projectPath); try { - // Try to open the project to see if it is valid - ProjectRootElement.Open(projectPath); + ProjectRootElement.Open(projectPath); // Try to open the project to see if it is valid AddProjectWithDefaultGuid(solution, relativePath, solutionFolder); Reporter.Output.WriteLine(CommonLocalizableStrings.ProjectAddedToTheSolution, relativePath); } @@ -105,7 +103,8 @@ private async Task AddProjectsToSolutionAsync(string solutionFileFullPath, IEnum } catch (ArgumentException ex) { - // TODO: There are some cases where the project is not found but it already exists on the solution. So it is useful to check the error message. Will remove on future commit. + // TODO: There are some cases where the project is not found but it already exists on the solution. So it is useful to check the error message. Will remove on future commit. + // TODO: Update with error codes from vs-solutionpersistence if (solution.FindProject(relativePath) != null || Regex.Match(ex.Message, @"Project name '.*' already exists in the solution folder.").Success) { Reporter.Output.WriteLine(CommonLocalizableStrings.SolutionAlreadyContainsProject, solutionFileFullPath, relativePath); @@ -163,7 +162,7 @@ private void AddProjectWithDefaultGuid(SolutionModel solution, string relativePa if (solutionFolder is null) { var relativePathDirectory = Path.GetDirectoryName(relativePath); - if (relativePathDirectory != null) + if (relativePathDirectory != null && !_inRoot) { SolutionFolderModel relativeSolutionFolder = solution.AddFolder(GetSolutionFolderPathWithForwardSlashes(relativePathDirectory)); project.MoveToFolder(relativeSolutionFolder); From 8975dbcff01b022248c8fd46f4ae4a3f68a56782 Mon Sep 17 00:00:00 2001 From: Eduardo Villalpando Mello Date: Tue, 12 Nov 2024 16:37:41 -0800 Subject: [PATCH 29/60] Refactor code --- .../dotnet/commands/dotnet-sln/add/Program.cs | 30 +++++++++++-------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/src/Cli/dotnet/commands/dotnet-sln/add/Program.cs b/src/Cli/dotnet/commands/dotnet-sln/add/Program.cs index f11575ef31cb..2159e7372e7c 100644 --- a/src/Cli/dotnet/commands/dotnet-sln/add/Program.cs +++ b/src/Cli/dotnet/commands/dotnet-sln/add/Program.cs @@ -31,7 +31,7 @@ public AddProjectToSolutionCommand(ParseResult parseResult) : base(parseResult) { _fileOrDirectory = parseResult.GetValue(SlnCommandParser.SlnArgument); - _projects = parseResult.GetValue(SlnAddParser.ProjectPathArgument)?.ToArray() ?? (IReadOnlyCollection)Array.Empty(); + _projects = (IReadOnlyCollection)(parseResult.GetValue(SlnAddParser.ProjectPathArgument) ?? []); _inRoot = parseResult.GetValue(SlnAddParser.InRootOption); _solutionFolderPath = parseResult.GetValue(SlnAddParser.SolutionFolderOption); @@ -41,16 +41,15 @@ public AddProjectToSolutionCommand(ParseResult parseResult) : base(parseResult) public override int Execute() { - var solutionFileFullPath = SlnCommandParser.GetSlnFileFullPath(_fileOrDirectory); - + string solutionFileFullPath = SlnCommandParser.GetSlnFileFullPath(_fileOrDirectory); if (_projects.Count == 0) { throw new GracefulException(CommonLocalizableStrings.SpecifyAtLeastOneProjectToAdd); } - PathUtility.EnsureAllPathsExist(_projects, CommonLocalizableStrings.CouldNotFindProjectOrDirectory, true); try { - var fullProjectPaths = _projects.Select(project => + PathUtility.EnsureAllPathsExist(_projects, CommonLocalizableStrings.CouldNotFindProjectOrDirectory, true); + IEnumerable fullProjectPaths = _projects.Select(project => { var fullPath = Path.GetFullPath(project); return Directory.Exists(fullPath) ? MsbuildProject.GetProjectFileFromDirectory(fullPath).FullName : fullPath; @@ -89,17 +88,17 @@ private async Task AddProjectsToSolutionAsync(string solutionFileFullPath, IEnum : null; foreach (var projectPath in projectPaths) { - var relativePath = Path.GetRelativePath(Path.GetDirectoryName(solutionFileFullPath), projectPath); + SolutionProjectModel? project = null; + string relativePath = Path.GetRelativePath(Path.GetDirectoryName(solutionFileFullPath), projectPath); try { ProjectRootElement.Open(projectPath); // Try to open the project to see if it is valid - AddProjectWithDefaultGuid(solution, relativePath, solutionFolder); + project = AddProjectWithDefaultGuid(solution, relativePath, solutionFolder); Reporter.Output.WriteLine(CommonLocalizableStrings.ProjectAddedToTheSolution, relativePath); } catch (InvalidProjectFileException ex) { - Reporter.Error.WriteLine(string.Format( - CommonLocalizableStrings.InvalidProjectWithExceptionMessage, projectPath, ex.Message)); + Reporter.Error.WriteLine(string.Format(CommonLocalizableStrings.InvalidProjectWithExceptionMessage, projectPath, ex.Message)); } catch (ArgumentException ex) { @@ -107,6 +106,10 @@ private async Task AddProjectsToSolutionAsync(string solutionFileFullPath, IEnum // TODO: Update with error codes from vs-solutionpersistence if (solution.FindProject(relativePath) != null || Regex.Match(ex.Message, @"Project name '.*' already exists in the solution folder.").Success) { + if (project is not null && project.Parent is not null) + { + throw new GracefulException(CommonLocalizableStrings.SolutionAlreadyContainsProject, solutionFileFullPath, relativePath, ex.Message); + } Reporter.Output.WriteLine(CommonLocalizableStrings.SolutionAlreadyContainsProject, solutionFileFullPath, relativePath); } else @@ -139,7 +142,7 @@ private void AddDefaultProjectConfigurations(SolutionModel solution) solution.DistillProjectConfigurations(); } - private void AddProjectWithDefaultGuid(SolutionModel solution, string relativePath, SolutionFolderModel solutionFolder) + private SolutionProjectModel AddProjectWithDefaultGuid(SolutionModel solution, string relativePath, SolutionFolderModel solutionFolder) { SolutionProjectModel project; try @@ -158,11 +161,11 @@ private void AddProjectWithDefaultGuid(SolutionModel solution, string relativePa throw; } } - // Generate local solution folder - if (solutionFolder is null) + // Generate intermediate solution folders + if (solutionFolder is null && !_inRoot) { var relativePathDirectory = Path.GetDirectoryName(relativePath); - if (relativePathDirectory != null && !_inRoot) + if (relativePathDirectory != null) { SolutionFolderModel relativeSolutionFolder = solution.AddFolder(GetSolutionFolderPathWithForwardSlashes(relativePathDirectory)); project.MoveToFolder(relativeSolutionFolder); @@ -173,6 +176,7 @@ private void AddProjectWithDefaultGuid(SolutionModel solution, string relativePa } } } + return project; } } } From 2e9b5ea56c0e5789fd244232233e793c4c67a87e Mon Sep 17 00:00:00 2001 From: Eduardo Villalpando Mello Date: Tue, 12 Nov 2024 16:41:11 -0800 Subject: [PATCH 30/60] Update tests --- src/Cli/dotnet/commands/dotnet-sln/add/Program.cs | 9 ++------- test/dotnet-sln.Tests/GivenDotnetSlnAdd.cs | 7 +++---- 2 files changed, 5 insertions(+), 11 deletions(-) diff --git a/src/Cli/dotnet/commands/dotnet-sln/add/Program.cs b/src/Cli/dotnet/commands/dotnet-sln/add/Program.cs index 2159e7372e7c..945ee62e7ba0 100644 --- a/src/Cli/dotnet/commands/dotnet-sln/add/Program.cs +++ b/src/Cli/dotnet/commands/dotnet-sln/add/Program.cs @@ -88,12 +88,11 @@ private async Task AddProjectsToSolutionAsync(string solutionFileFullPath, IEnum : null; foreach (var projectPath in projectPaths) { - SolutionProjectModel? project = null; string relativePath = Path.GetRelativePath(Path.GetDirectoryName(solutionFileFullPath), projectPath); try { ProjectRootElement.Open(projectPath); // Try to open the project to see if it is valid - project = AddProjectWithDefaultGuid(solution, relativePath, solutionFolder); + AddProjectWithDefaultGuid(solution, relativePath, solutionFolder); Reporter.Output.WriteLine(CommonLocalizableStrings.ProjectAddedToTheSolution, relativePath); } catch (InvalidProjectFileException ex) @@ -106,11 +105,7 @@ private async Task AddProjectsToSolutionAsync(string solutionFileFullPath, IEnum // TODO: Update with error codes from vs-solutionpersistence if (solution.FindProject(relativePath) != null || Regex.Match(ex.Message, @"Project name '.*' already exists in the solution folder.").Success) { - if (project is not null && project.Parent is not null) - { - throw new GracefulException(CommonLocalizableStrings.SolutionAlreadyContainsProject, solutionFileFullPath, relativePath, ex.Message); - } - Reporter.Output.WriteLine(CommonLocalizableStrings.SolutionAlreadyContainsProject, solutionFileFullPath, relativePath); + throw new GracefulException(CommonLocalizableStrings.SolutionAlreadyContainsProject, solutionFileFullPath, relativePath, ex.Message); } else { diff --git a/test/dotnet-sln.Tests/GivenDotnetSlnAdd.cs b/test/dotnet-sln.Tests/GivenDotnetSlnAdd.cs index 1a9d65c66b76..a2951f7fbedf 100644 --- a/test/dotnet-sln.Tests/GivenDotnetSlnAdd.cs +++ b/test/dotnet-sln.Tests/GivenDotnetSlnAdd.cs @@ -1008,9 +1008,8 @@ public void WhenSolutionAlreadyContainsProjectItDoesntDuplicate(string solutionC var cmd = new DotnetCommand(Log) .WithWorkingDirectory(projectDirectory) .Execute(solutionCommand, "App.sln", "add", projectToAdd); - cmd.Should().Pass(); - cmd.StdOut.Should().Be(string.Format(CommonLocalizableStrings.SolutionAlreadyContainsProject, solutionPath, projectToAdd)); - cmd.StdErr.Should().BeEmpty(); + cmd.Should().Fail(); + cmd.StdErr.Should().Be(string.Format(CommonLocalizableStrings.SolutionAlreadyContainsProject, solutionPath, projectToAdd)); } [Theory] @@ -1099,7 +1098,7 @@ public void WhenPassedAProjectItAddsCorrectProjectTypeGuid( nonSolutionFolderProjects.Single().TypeGuid.Should().Be(expectedTypeGuid); } - [Theory] + [Theory(Skip = "https://github.com/dotnet/sdk/pull/44570#issuecomment-2472029173")] [InlineData("sln")] [InlineData("solution")] public void WhenPassedAProjectWithoutATypeGuidItErrors(string solutionCommand) From 76a2f1dad2ef93085f577901599c3225093fcb34 Mon Sep 17 00:00:00 2001 From: Eduardo Villalpando Mello Date: Wed, 13 Nov 2024 09:43:50 -0800 Subject: [PATCH 31/60] Fix tests Most tests are now fixed. The rest are still pending due to design considerations and coordination with vs-solutionpersistence team --- src/Cli/dotnet/commands/dotnet-sln/add/Program.cs | 2 +- test/dotnet-sln.Tests/GivenDotnetSlnAdd.cs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Cli/dotnet/commands/dotnet-sln/add/Program.cs b/src/Cli/dotnet/commands/dotnet-sln/add/Program.cs index 945ee62e7ba0..dd80eb5376c4 100644 --- a/src/Cli/dotnet/commands/dotnet-sln/add/Program.cs +++ b/src/Cli/dotnet/commands/dotnet-sln/add/Program.cs @@ -105,7 +105,7 @@ private async Task AddProjectsToSolutionAsync(string solutionFileFullPath, IEnum // TODO: Update with error codes from vs-solutionpersistence if (solution.FindProject(relativePath) != null || Regex.Match(ex.Message, @"Project name '.*' already exists in the solution folder.").Success) { - throw new GracefulException(CommonLocalizableStrings.SolutionAlreadyContainsProject, solutionFileFullPath, relativePath, ex.Message); + Reporter.Output.WriteLine(CommonLocalizableStrings.SolutionAlreadyContainsProject, solutionFileFullPath, relativePath); } else { diff --git a/test/dotnet-sln.Tests/GivenDotnetSlnAdd.cs b/test/dotnet-sln.Tests/GivenDotnetSlnAdd.cs index a2951f7fbedf..a082aa10d33f 100644 --- a/test/dotnet-sln.Tests/GivenDotnetSlnAdd.cs +++ b/test/dotnet-sln.Tests/GivenDotnetSlnAdd.cs @@ -1008,8 +1008,8 @@ public void WhenSolutionAlreadyContainsProjectItDoesntDuplicate(string solutionC var cmd = new DotnetCommand(Log) .WithWorkingDirectory(projectDirectory) .Execute(solutionCommand, "App.sln", "add", projectToAdd); - cmd.Should().Fail(); - cmd.StdErr.Should().Be(string.Format(CommonLocalizableStrings.SolutionAlreadyContainsProject, solutionPath, projectToAdd)); + cmd.Should().Pass(); + cmd.StdOut.Should().Be(string.Format(CommonLocalizableStrings.SolutionAlreadyContainsProject, solutionPath, projectToAdd)); } [Theory] From 60d434c3b4a9d57db51932ce0b97102858b2ebca Mon Sep 17 00:00:00 2001 From: Eduardo Villalpando Mello Date: Tue, 19 Nov 2024 11:03:59 -0800 Subject: [PATCH 32/60] Fix WhenProjectWithAdditionalConfigurationsIsAddedSolutionDoesNotMapThem --- src/Cli/dotnet/commands/dotnet-sln/add/Program.cs | 15 ++++++++++++++- test/dotnet-sln.Tests/GivenDotnetSlnAdd.cs | 2 +- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/src/Cli/dotnet/commands/dotnet-sln/add/Program.cs b/src/Cli/dotnet/commands/dotnet-sln/add/Program.cs index dd80eb5376c4..a5813bfc13a2 100644 --- a/src/Cli/dotnet/commands/dotnet-sln/add/Program.cs +++ b/src/Cli/dotnet/commands/dotnet-sln/add/Program.cs @@ -5,6 +5,7 @@ using System.Text.RegularExpressions; using Microsoft.Build.Construction; using Microsoft.Build.Exceptions; +using Microsoft.Build.Execution; using Microsoft.DotNet.Cli; using Microsoft.DotNet.Cli.Sln.Internal; using Microsoft.DotNet.Cli.Utils; @@ -91,7 +92,6 @@ private async Task AddProjectsToSolutionAsync(string solutionFileFullPath, IEnum string relativePath = Path.GetRelativePath(Path.GetDirectoryName(solutionFileFullPath), projectPath); try { - ProjectRootElement.Open(projectPath); // Try to open the project to see if it is valid AddProjectWithDefaultGuid(solution, relativePath, solutionFolder); Reporter.Output.WriteLine(CommonLocalizableStrings.ProjectAddedToTheSolution, relativePath); } @@ -139,6 +139,8 @@ private void AddDefaultProjectConfigurations(SolutionModel solution) private SolutionProjectModel AddProjectWithDefaultGuid(SolutionModel solution, string relativePath, SolutionFolderModel solutionFolder) { + // Open project instance + ProjectRootElement projectRootElement = ProjectRootElement.Open(relativePath); SolutionProjectModel project; try { @@ -171,7 +173,18 @@ private SolutionProjectModel AddProjectWithDefaultGuid(SolutionModel solution, s } } } + // Generate configurations and platforms + ProjectInstance projectInstance = new ProjectInstance(projectRootElement); + foreach (var buildType in projectInstance.GetConfigurations()) + { + project.AddProjectConfigurationRule(new ConfigurationRule(BuildDimension.BuildType, buildType, "*", buildType)); + } + foreach (var platform in projectInstance.GetPlatforms()) + { + project.AddProjectConfigurationRule(new ConfigurationRule(BuildDimension.Platform, "*", platform, platform)); + } return project; + } } } diff --git a/test/dotnet-sln.Tests/GivenDotnetSlnAdd.cs b/test/dotnet-sln.Tests/GivenDotnetSlnAdd.cs index a082aa10d33f..f14442a4fa27 100644 --- a/test/dotnet-sln.Tests/GivenDotnetSlnAdd.cs +++ b/test/dotnet-sln.Tests/GivenDotnetSlnAdd.cs @@ -639,7 +639,7 @@ public void WhenNestedProjectIsAddedSolutionFoldersAreCreatedBuild(string soluti } - [Theory] + [Theory(Skip = "Having projects with the same name in different paths is allowed.")] [InlineData("sln")] [InlineData("solution")] public void WhenNestedDuplicateProjectIsAddedToASolutionFolder(string solutionCommand) From f79ddf34e199d7b1461f33ac144737899b27d09c Mon Sep 17 00:00:00 2001 From: Eduardo Villalpando Mello Date: Tue, 19 Nov 2024 15:57:43 -0800 Subject: [PATCH 33/60] Revert changed project guids Guids are now read from project info --- .../dotnet/commands/dotnet-sln/add/Program.cs | 11 ++- test/dotnet-sln.Tests/GivenDotnetSlnAdd.cs | 76 +++++++++---------- 2 files changed, 47 insertions(+), 40 deletions(-) diff --git a/src/Cli/dotnet/commands/dotnet-sln/add/Program.cs b/src/Cli/dotnet/commands/dotnet-sln/add/Program.cs index a5813bfc13a2..de32047a2722 100644 --- a/src/Cli/dotnet/commands/dotnet-sln/add/Program.cs +++ b/src/Cli/dotnet/commands/dotnet-sln/add/Program.cs @@ -134,6 +134,7 @@ private void AddDefaultProjectConfigurations(SolutionModel solution) // https://stackoverflow.com/a/14714485 solution.RemoveProperties("HideSolutionNode"); } + // TODO: Remove (https://github.com/microsoft/vs-solutionpersistence/pull/78/files) solution.DistillProjectConfigurations(); } @@ -173,11 +174,17 @@ private SolutionProjectModel AddProjectWithDefaultGuid(SolutionModel solution, s } } } - // Generate configurations and platforms + // Add settings based on existing project instance ProjectInstance projectInstance = new ProjectInstance(projectRootElement); + string projectInstanceId = projectInstance.GetProjectId(); + if (!string.IsNullOrEmpty(projectInstanceId)) + { + project.Id = new Guid(projectInstance.GetProjectId()); + } foreach (var buildType in projectInstance.GetConfigurations()) { - project.AddProjectConfigurationRule(new ConfigurationRule(BuildDimension.BuildType, buildType, "*", buildType)); + var buildTypeWithoutWhitespaces = buildType.TakeWhile(c => !char.IsWhiteSpace(c)).ToString(); + project.AddProjectConfigurationRule(new ConfigurationRule(BuildDimension.BuildType, buildTypeWithoutWhitespaces, "*", buildTypeWithoutWhitespaces)); } foreach (var platform in projectInstance.GetPlatforms()) { diff --git a/test/dotnet-sln.Tests/GivenDotnetSlnAdd.cs b/test/dotnet-sln.Tests/GivenDotnetSlnAdd.cs index f14442a4fa27..33c8184de82a 100644 --- a/test/dotnet-sln.Tests/GivenDotnetSlnAdd.cs +++ b/test/dotnet-sln.Tests/GivenDotnetSlnAdd.cs @@ -175,7 +175,7 @@ public GivenDotnetSlnAdd(ITestOutputHelper log) : base(log) # Visual Studio 15 VisualStudioVersion = 15.0.26006.2 MinimumVisualStudioVersion = 10.0.40219.1 -Project(""{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}"") = ""ProjectWithoutMatchingConfigs"", ""ProjectWithoutMatchingConfigs\ProjectWithoutMatchingConfigs.csproj"", ""{D75411E5-21DC-0537-8C05-E1E6A920613E}"" +Project(""{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}"") = ""ProjectWithoutMatchingConfigs"", ""ProjectWithoutMatchingConfigs\ProjectWithoutMatchingConfigs.csproj"", ""{C49B64DE-4401-4825-8A88-10DCB5950E57}"" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -190,24 +190,24 @@ public GivenDotnetSlnAdd(ITestOutputHelper log) : base(log) Foo Bar|x86 = Foo Bar|x86 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {D75411E5-21DC-0537-8C05-E1E6A920613E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {D75411E5-21DC-0537-8C05-E1E6A920613E}.Debug|Any CPU.Build.0 = Debug|Any CPU - {D75411E5-21DC-0537-8C05-E1E6A920613E}.Debug|x64.ActiveCfg = Debug|Any CPU - {D75411E5-21DC-0537-8C05-E1E6A920613E}.Debug|x64.Build.0 = Debug|Any CPU - {D75411E5-21DC-0537-8C05-E1E6A920613E}.Debug|x86.ActiveCfg = Debug|Any CPU - {D75411E5-21DC-0537-8C05-E1E6A920613E}.Debug|x86.Build.0 = Debug|Any CPU - {D75411E5-21DC-0537-8C05-E1E6A920613E}.Release|Any CPU.ActiveCfg = Release|Any CPU - {D75411E5-21DC-0537-8C05-E1E6A920613E}.Release|Any CPU.Build.0 = Release|Any CPU - {D75411E5-21DC-0537-8C05-E1E6A920613E}.Release|x64.ActiveCfg = Release|Any CPU - {D75411E5-21DC-0537-8C05-E1E6A920613E}.Release|x64.Build.0 = Release|Any CPU - {D75411E5-21DC-0537-8C05-E1E6A920613E}.Release|x86.ActiveCfg = Release|Any CPU - {D75411E5-21DC-0537-8C05-E1E6A920613E}.Release|x86.Build.0 = Release|Any CPU - {D75411E5-21DC-0537-8C05-E1E6A920613E}.Foo Bar|Any CPU.ActiveCfg = Debug|Any CPU - {D75411E5-21DC-0537-8C05-E1E6A920613E}.Foo Bar|Any CPU.Build.0 = Debug|Any CPU - {D75411E5-21DC-0537-8C05-E1E6A920613E}.Foo Bar|x64.ActiveCfg = Debug|Any CPU - {D75411E5-21DC-0537-8C05-E1E6A920613E}.Foo Bar|x64.Build.0 = Debug|Any CPU - {D75411E5-21DC-0537-8C05-E1E6A920613E}.Foo Bar|x86.ActiveCfg = Debug|Any CPU - {D75411E5-21DC-0537-8C05-E1E6A920613E}.Foo Bar|x86.Build.0 = Debug|Any CPU + {C49B64DE-4401-4825-8A88-10DCB5950E57}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C49B64DE-4401-4825-8A88-10DCB5950E57}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C49B64DE-4401-4825-8A88-10DCB5950E57}.Debug|x64.ActiveCfg = Debug|Any CPU + {C49B64DE-4401-4825-8A88-10DCB5950E57}.Debug|x64.Build.0 = Debug|Any CPU + {C49B64DE-4401-4825-8A88-10DCB5950E57}.Debug|x86.ActiveCfg = Debug|Any CPU + {C49B64DE-4401-4825-8A88-10DCB5950E57}.Debug|x86.Build.0 = Debug|Any CPU + {C49B64DE-4401-4825-8A88-10DCB5950E57}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C49B64DE-4401-4825-8A88-10DCB5950E57}.Release|Any CPU.Build.0 = Release|Any CPU + {C49B64DE-4401-4825-8A88-10DCB5950E57}.Release|x64.ActiveCfg = Release|Any CPU + {C49B64DE-4401-4825-8A88-10DCB5950E57}.Release|x64.Build.0 = Release|Any CPU + {C49B64DE-4401-4825-8A88-10DCB5950E57}.Release|x86.ActiveCfg = Release|Any CPU + {C49B64DE-4401-4825-8A88-10DCB5950E57}.Release|x86.Build.0 = Release|Any CPU + {C49B64DE-4401-4825-8A88-10DCB5950E57}.Foo Bar|Any CPU.ActiveCfg = Debug|Any CPU + {C49B64DE-4401-4825-8A88-10DCB5950E57}.Foo Bar|Any CPU.Build.0 = Debug|Any CPU + {C49B64DE-4401-4825-8A88-10DCB5950E57}.Foo Bar|x64.ActiveCfg = Debug|Any CPU + {C49B64DE-4401-4825-8A88-10DCB5950E57}.Foo Bar|x64.Build.0 = Debug|Any CPU + {C49B64DE-4401-4825-8A88-10DCB5950E57}.Foo Bar|x86.ActiveCfg = Debug|Any CPU + {C49B64DE-4401-4825-8A88-10DCB5950E57}.Foo Bar|x86.Build.0 = Debug|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -265,7 +265,7 @@ public GivenDotnetSlnAdd(ITestOutputHelper log) : base(log) # Visual Studio 15 VisualStudioVersion = 15.0.26006.2 MinimumVisualStudioVersion = 10.0.40219.1 -Project(""{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}"") = ""ProjectWithAdditionalConfigs"", ""ProjectWithAdditionalConfigs\ProjectWithAdditionalConfigs.csproj"", ""{B3EDC824-7B36-5688-363C-38F5E302E800}"" +Project(""{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}"") = ""ProjectWithAdditionalConfigs"", ""ProjectWithAdditionalConfigs\ProjectWithAdditionalConfigs.csproj"", ""{A302325B-D680-4C0E-8680-7AE283981624}"" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -280,24 +280,24 @@ public GivenDotnetSlnAdd(ITestOutputHelper log) : base(log) Foo Bar|x86 = Foo Bar|x86 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {B3EDC824-7B36-5688-363C-38F5E302E800}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {B3EDC824-7B36-5688-363C-38F5E302E800}.Debug|Any CPU.Build.0 = Debug|Any CPU - {B3EDC824-7B36-5688-363C-38F5E302E800}.Debug|x64.ActiveCfg = Debug|x64 - {B3EDC824-7B36-5688-363C-38F5E302E800}.Debug|x64.Build.0 = Debug|x64 - {B3EDC824-7B36-5688-363C-38F5E302E800}.Debug|x86.ActiveCfg = Debug|x86 - {B3EDC824-7B36-5688-363C-38F5E302E800}.Debug|x86.Build.0 = Debug|x86 - {B3EDC824-7B36-5688-363C-38F5E302E800}.Release|Any CPU.ActiveCfg = Release|Any CPU - {B3EDC824-7B36-5688-363C-38F5E302E800}.Release|Any CPU.Build.0 = Release|Any CPU - {B3EDC824-7B36-5688-363C-38F5E302E800}.Release|x64.ActiveCfg = Release|x64 - {B3EDC824-7B36-5688-363C-38F5E302E800}.Release|x64.Build.0 = Release|x64 - {B3EDC824-7B36-5688-363C-38F5E302E800}.Release|x86.ActiveCfg = Release|x86 - {B3EDC824-7B36-5688-363C-38F5E302E800}.Release|x86.Build.0 = Release|x86 - {B3EDC824-7B36-5688-363C-38F5E302E800}.Foo Bar|Any CPU.ActiveCfg = FooBar|Any CPU - {B3EDC824-7B36-5688-363C-38F5E302E800}.Foo Bar|Any CPU.Build.0 = FooBar|Any CPU - {B3EDC824-7B36-5688-363C-38F5E302E800}.Foo Bar|x64.ActiveCfg = FooBar|x64 - {B3EDC824-7B36-5688-363C-38F5E302E800}.Foo Bar|x64.Build.0 = FooBar|x64 - {B3EDC824-7B36-5688-363C-38F5E302E800}.Foo Bar|x86.ActiveCfg = FooBar|x86 - {B3EDC824-7B36-5688-363C-38F5E302E800}.Foo Bar|x86.Build.0 = FooBar|x86 + {A302325B-D680-4C0E-8680-7AE283981624}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A302325B-D680-4C0E-8680-7AE283981624}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A302325B-D680-4C0E-8680-7AE283981624}.Debug|x64.ActiveCfg = Debug|x64 + {A302325B-D680-4C0E-8680-7AE283981624}.Debug|x64.Build.0 = Debug|x64 + {A302325B-D680-4C0E-8680-7AE283981624}.Debug|x86.ActiveCfg = Debug|x86 + {A302325B-D680-4C0E-8680-7AE283981624}.Debug|x86.Build.0 = Debug|x86 + {A302325B-D680-4C0E-8680-7AE283981624}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A302325B-D680-4C0E-8680-7AE283981624}.Release|Any CPU.Build.0 = Release|Any CPU + {A302325B-D680-4C0E-8680-7AE283981624}.Release|x64.ActiveCfg = Release|x64 + {A302325B-D680-4C0E-8680-7AE283981624}.Release|x64.Build.0 = Release|x64 + {A302325B-D680-4C0E-8680-7AE283981624}.Release|x86.ActiveCfg = Release|x86 + {A302325B-D680-4C0E-8680-7AE283981624}.Release|x86.Build.0 = Release|x86 + {A302325B-D680-4C0E-8680-7AE283981624}.Foo Bar|Any CPU.ActiveCfg = FooBar|Any CPU + {A302325B-D680-4C0E-8680-7AE283981624}.Foo Bar|Any CPU.Build.0 = FooBar|Any CPU + {A302325B-D680-4C0E-8680-7AE283981624}.Foo Bar|x64.ActiveCfg = FooBar|x64 + {A302325B-D680-4C0E-8680-7AE283981624}.Foo Bar|x64.Build.0 = FooBar|x64 + {A302325B-D680-4C0E-8680-7AE283981624}.Foo Bar|x86.ActiveCfg = FooBar|x86 + {A302325B-D680-4C0E-8680-7AE283981624}.Foo Bar|x86.Build.0 = FooBar|x86 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE From d90d9dfe120e1641ec492a0309ab548cf38b5b75 Mon Sep 17 00:00:00 2001 From: Eduardo Villalpando Mello Date: Tue, 19 Nov 2024 16:05:19 -0800 Subject: [PATCH 34/60] Revert changed project guids Guids are now read from project info --- test/dotnet-sln.Tests/GivenDotnetSlnAdd.cs | 30 +++++++++++----------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/test/dotnet-sln.Tests/GivenDotnetSlnAdd.cs b/test/dotnet-sln.Tests/GivenDotnetSlnAdd.cs index 33c8184de82a..97ccc41cc765 100644 --- a/test/dotnet-sln.Tests/GivenDotnetSlnAdd.cs +++ b/test/dotnet-sln.Tests/GivenDotnetSlnAdd.cs @@ -312,7 +312,7 @@ public GivenDotnetSlnAdd(ITestOutputHelper log) : base(log) MinimumVisualStudioVersion = 10.0.40219.1 Project(""{9A19103F-16F7-4668-BE54-9A1E7A4F7556}"") = ""App"", ""App.csproj"", ""{7072A694-548F-4CAE-A58F-12D257D5F486}"" EndProject -Project(""{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}"") = ""Lib"", ""src\Lib\Lib.csproj"", ""{8C318457-B2F6-5F74-188F-CC8D5F235C4A}"" +Project(""{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}"") = ""Lib"", ""src\Lib\Lib.csproj"", ""{84A45D44-B677-492D-A6DA-B3A71135AB8E}"" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -336,18 +336,18 @@ public GivenDotnetSlnAdd(ITestOutputHelper log) : base(log) {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 - {8C318457-B2F6-5F74-188F-CC8D5F235C4A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {8C318457-B2F6-5F74-188F-CC8D5F235C4A}.Debug|Any CPU.Build.0 = Debug|Any CPU - {8C318457-B2F6-5F74-188F-CC8D5F235C4A}.Debug|x64.ActiveCfg = Debug|Any CPU - {8C318457-B2F6-5F74-188F-CC8D5F235C4A}.Debug|x64.Build.0 = Debug|Any CPU - {8C318457-B2F6-5F74-188F-CC8D5F235C4A}.Debug|x86.ActiveCfg = Debug|Any CPU - {8C318457-B2F6-5F74-188F-CC8D5F235C4A}.Debug|x86.Build.0 = Debug|Any CPU - {8C318457-B2F6-5F74-188F-CC8D5F235C4A}.Release|Any CPU.ActiveCfg = Release|Any CPU - {8C318457-B2F6-5F74-188F-CC8D5F235C4A}.Release|Any CPU.Build.0 = Release|Any CPU - {8C318457-B2F6-5F74-188F-CC8D5F235C4A}.Release|x64.ActiveCfg = Release|Any CPU - {8C318457-B2F6-5F74-188F-CC8D5F235C4A}.Release|x64.Build.0 = Release|Any CPU - {8C318457-B2F6-5F74-188F-CC8D5F235C4A}.Release|x86.ActiveCfg = Release|Any CPU - {8C318457-B2F6-5F74-188F-CC8D5F235C4A}.Release|x86.Build.0 = Release|Any CPU + {84A45D44-B677-492D-A6DA-B3A71135AB8E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {84A45D44-B677-492D-A6DA-B3A71135AB8E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {84A45D44-B677-492D-A6DA-B3A71135AB8E}.Debug|x64.ActiveCfg = Debug|Any CPU + {84A45D44-B677-492D-A6DA-B3A71135AB8E}.Debug|x64.Build.0 = Debug|Any CPU + {84A45D44-B677-492D-A6DA-B3A71135AB8E}.Debug|x86.ActiveCfg = Debug|Any CPU + {84A45D44-B677-492D-A6DA-B3A71135AB8E}.Debug|x86.Build.0 = Debug|Any CPU + {84A45D44-B677-492D-A6DA-B3A71135AB8E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {84A45D44-B677-492D-A6DA-B3A71135AB8E}.Release|Any CPU.Build.0 = Release|Any CPU + {84A45D44-B677-492D-A6DA-B3A71135AB8E}.Release|x64.ActiveCfg = Release|Any CPU + {84A45D44-B677-492D-A6DA-B3A71135AB8E}.Release|x64.Build.0 = Release|Any CPU + {84A45D44-B677-492D-A6DA-B3A71135AB8E}.Release|x86.ActiveCfg = Release|Any CPU + {84A45D44-B677-492D-A6DA-B3A71135AB8E}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -833,10 +833,10 @@ public void WhenSolutionFolderExistsItDoesNotGetAdded(string solutionCommand, st [Theory] [InlineData("sln", "TestAppWithSlnAndCsprojFiles", ExpectedSlnFileAfterAddingLibProj, "")] - [InlineData("sln", "TestAppWithSlnAndCsprojProjectGuidFiles", ExpectedSlnFileAfterAddingLibProj, "{97594868-6D78-0274-047F-2FC3453194BE}")] + [InlineData("sln", "TestAppWithSlnAndCsprojProjectGuidFiles", ExpectedSlnFileAfterAddingLibProj, "{84A45D44-B677-492D-A6DA-B3A71135AB8E}")] [InlineData("sln", "TestAppWithEmptySln", ExpectedSlnFileAfterAddingLibProjToEmptySln, "")] [InlineData("solution", "TestAppWithSlnAndCsprojFiles", ExpectedSlnFileAfterAddingLibProj, "")] - [InlineData("solution", "TestAppWithSlnAndCsprojProjectGuidFiles", ExpectedSlnFileAfterAddingLibProj, "{97594868-6D78-0274-047F-2FC3453194BE}")] + [InlineData("solution", "TestAppWithSlnAndCsprojProjectGuidFiles", ExpectedSlnFileAfterAddingLibProj, "{84A45D44-B677-492D-A6DA-B3A71135AB8E}")] [InlineData("solution", "TestAppWithEmptySln", ExpectedSlnFileAfterAddingLibProjToEmptySln, "")] public void WhenValidProjectIsPassedBuildConfigsAreAdded( string solutionCommand, From 63c1fdaeb508a02b66ce513feaadb432af93a377 Mon Sep 17 00:00:00 2001 From: Eduardo Villalpando Mello Date: Wed, 20 Nov 2024 16:01:11 -0800 Subject: [PATCH 35/60] Fix project config tests --- .../dotnet/commands/dotnet-sln/add/Program.cs | 38 ++++++++++++------- test/dotnet-sln.Tests/GivenDotnetSlnAdd.cs | 6 +-- 2 files changed, 28 insertions(+), 16 deletions(-) diff --git a/src/Cli/dotnet/commands/dotnet-sln/add/Program.cs b/src/Cli/dotnet/commands/dotnet-sln/add/Program.cs index de32047a2722..7cf61129f727 100644 --- a/src/Cli/dotnet/commands/dotnet-sln/add/Program.cs +++ b/src/Cli/dotnet/commands/dotnet-sln/add/Program.cs @@ -84,6 +84,9 @@ private async Task AddProjectsToSolutionAsync(string solutionFileFullPath, IEnum Encoding = new UTF8Encoding(encoderShouldEmitUTF8Identifier: true) }); } + + AddDefaultProjectConfigurations(solution); + SolutionFolderModel? solutionFolder = (!_inRoot && _solutionFolderPath != null) ? solution.AddFolder(GetSolutionFolderPathWithForwardSlashes(_solutionFolderPath)) : null; @@ -113,7 +116,13 @@ private async Task AddProjectsToSolutionAsync(string solutionFileFullPath, IEnum } } } - AddDefaultProjectConfigurations(solution); + if (solution.SolutionProjects.Count > 1) + { + // https://stackoverflow.com/a/14714485 + solution.RemoveProperties("HideSolutionNode"); + } + // TODO: Remove (https://github.com/microsoft/vs-solutionpersistence/pull/78/files) + solution.DistillProjectConfigurations(); await serializer.SaveAsync(solutionFileFullPath, solution, cancellationToken); } @@ -129,13 +138,7 @@ private void AddDefaultProjectConfigurations(SolutionModel solution) { solution.AddBuildType(buildType); } - if (solution.SolutionProjects.Count > 1) - { - // https://stackoverflow.com/a/14714485 - solution.RemoveProperties("HideSolutionNode"); - } - // TODO: Remove (https://github.com/microsoft/vs-solutionpersistence/pull/78/files) - solution.DistillProjectConfigurations(); + } private SolutionProjectModel AddProjectWithDefaultGuid(SolutionModel solution, string relativePath, SolutionFolderModel solutionFolder) @@ -181,15 +184,24 @@ private SolutionProjectModel AddProjectWithDefaultGuid(SolutionModel solution, s { project.Id = new Guid(projectInstance.GetProjectId()); } - foreach (var buildType in projectInstance.GetConfigurations()) + + var projectInstanceConfigurations = projectInstance.GetConfigurations(); + var projectInstancePlatforms = projectInstance.GetPlatforms(); + + foreach (var platform in projectInstancePlatforms) { - var buildTypeWithoutWhitespaces = buildType.TakeWhile(c => !char.IsWhiteSpace(c)).ToString(); - project.AddProjectConfigurationRule(new ConfigurationRule(BuildDimension.BuildType, buildTypeWithoutWhitespaces, "*", buildTypeWithoutWhitespaces)); + var solutionPlatform = solution.Platforms.FirstOrDefault( + x => x.Replace(" ", string.Empty) == platform.Replace(" ", string.Empty), "Any CPU"); + project.AddProjectConfigurationRule(new ConfigurationRule(BuildDimension.Platform, "*", solutionPlatform, platform)); } - foreach (var platform in projectInstance.GetPlatforms()) + + foreach (var buildType in projectInstanceConfigurations) { - project.AddProjectConfigurationRule(new ConfigurationRule(BuildDimension.Platform, "*", platform, platform)); + var solutionBuildType = solution.BuildTypes.FirstOrDefault( + x => x.Replace(" ", string.Empty) == buildType.Replace(" ", string.Empty), solution.BuildTypes.FirstOrDefault("Debug")); + project.AddProjectConfigurationRule(new ConfigurationRule(BuildDimension.BuildType, solutionBuildType, "*", buildType)); } + return project; } diff --git a/test/dotnet-sln.Tests/GivenDotnetSlnAdd.cs b/test/dotnet-sln.Tests/GivenDotnetSlnAdd.cs index 97ccc41cc765..9fdccda9b0b5 100644 --- a/test/dotnet-sln.Tests/GivenDotnetSlnAdd.cs +++ b/test/dotnet-sln.Tests/GivenDotnetSlnAdd.cs @@ -234,9 +234,6 @@ public GivenDotnetSlnAdd(ITestOutputHelper log) : base(log) Foo Bar|x64 = Foo Bar|x64 Foo Bar|x86 = Foo Bar|x86 EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {C9601CA2-DB64-4FB6-B463-368C7764BF0D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {C9601CA2-DB64-4FB6-B463-368C7764BF0D}.Debug|Any CPU.Build.0 = Debug|Any CPU @@ -257,6 +254,9 @@ public GivenDotnetSlnAdd(ITestOutputHelper log) : base(log) {C9601CA2-DB64-4FB6-B463-368C7764BF0D}.Foo Bar|x86.ActiveCfg = FooBar|x86 {C9601CA2-DB64-4FB6-B463-368C7764BF0D}.Foo Bar|x86.Build.0 = FooBar|x86 EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection EndGlobal "; From 6f0cc412b0bea9d233a6d505b54f0015a09a1761 Mon Sep 17 00:00:00 2001 From: Eduardo Villalpando Mello Date: Wed, 20 Nov 2024 16:16:18 -0800 Subject: [PATCH 36/60] Fix tests --- src/Cli/dotnet/commands/dotnet-sln/add/Program.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Cli/dotnet/commands/dotnet-sln/add/Program.cs b/src/Cli/dotnet/commands/dotnet-sln/add/Program.cs index 7cf61129f727..581f6d15762b 100644 --- a/src/Cli/dotnet/commands/dotnet-sln/add/Program.cs +++ b/src/Cli/dotnet/commands/dotnet-sln/add/Program.cs @@ -192,14 +192,14 @@ private SolutionProjectModel AddProjectWithDefaultGuid(SolutionModel solution, s { var solutionPlatform = solution.Platforms.FirstOrDefault( x => x.Replace(" ", string.Empty) == platform.Replace(" ", string.Empty), "Any CPU"); - project.AddProjectConfigurationRule(new ConfigurationRule(BuildDimension.Platform, "*", solutionPlatform, platform)); + project.AddProjectConfigurationRule(new ConfigurationRule(BuildDimension.Platform, "*", platform, solutionPlatform)); } foreach (var buildType in projectInstanceConfigurations) { var solutionBuildType = solution.BuildTypes.FirstOrDefault( x => x.Replace(" ", string.Empty) == buildType.Replace(" ", string.Empty), solution.BuildTypes.FirstOrDefault("Debug")); - project.AddProjectConfigurationRule(new ConfigurationRule(BuildDimension.BuildType, solutionBuildType, "*", buildType)); + project.AddProjectConfigurationRule(new ConfigurationRule(BuildDimension.BuildType, buildType, "*", solutionBuildType)); } return project; From 7cf1a3707bdb8d0f680320a802639bdea5bffe98 Mon Sep 17 00:00:00 2001 From: Eduardo Villalpando Mello Date: Thu, 21 Nov 2024 11:11:23 -0800 Subject: [PATCH 37/60] Fix all tests + Update vs-solutionpersistence --- Directory.Packages.props | 6 +- .../dotnet/commands/dotnet-sln/add/Program.cs | 98 ++++++++----------- test/dotnet-sln.Tests/GivenDotnetSlnAdd.cs | 2 +- 3 files changed, 42 insertions(+), 64 deletions(-) diff --git a/Directory.Packages.props b/Directory.Packages.props index d25580eda3a1..09516e18a456 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -4,7 +4,6 @@ $(NoWarn);NU1507 - @@ -67,7 +66,7 @@ - + @@ -123,7 +122,6 @@ - $(NoWarn);NU1507 + @@ -124,6 +125,7 @@ +