forked from dotnet/sdk
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
sln-add: Support for slnx (dotnet#44570)
- Loading branch information
Showing
40 changed files
with
1,214 additions
and
787 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,144 +1,180 @@ | ||
// Licensed to the .NET Foundation under one or more agreements. | ||
// The .NET Foundation licenses this file to you under the MIT license. | ||
|
||
using System; | ||
using System.CommandLine; | ||
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; | ||
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 | ||
{ | ||
internal class AddProjectToSolutionCommand : CommandBase | ||
{ | ||
private static string[] _defaultPlatforms = new[] { "Any CPU", "x64", "x86" }; | ||
private static string[] _defaultBuildTypes = new[] { "Debug", "Release" }; | ||
private readonly string _fileOrDirectory; | ||
private readonly bool _inRoot; | ||
private readonly IList<string> _relativeRootSolutionFolders; | ||
private readonly IReadOnlyCollection<string> _arguments; | ||
private readonly IReadOnlyCollection<string> _projects; | ||
private readonly string? _solutionFolderPath; | ||
|
||
private static string GetSolutionFolderPathWithForwardSlashes(string path) | ||
{ | ||
// SolutionModel::AddFolder expects paths to have leading, trailing and inner forward slashes | ||
// https://github.com/microsoft/vs-solutionpersistence/blob/87ee8ea069662d55c336a9bd68fe4851d0384fa5/src/Microsoft.VisualStudio.SolutionPersistence/Model/SolutionModel.cs#L171C1-L172C1 | ||
return "/" + string.Join("/", PathUtility.GetPathWithDirectorySeparator(path).Split(Path.DirectorySeparatorChar, StringSplitOptions.RemoveEmptyEntries)) + "/"; | ||
} | ||
|
||
public AddProjectToSolutionCommand(ParseResult parseResult) : base(parseResult) | ||
{ | ||
_fileOrDirectory = parseResult.GetValue(SlnCommandParser.SlnArgument); | ||
|
||
_arguments = parseResult.GetValue(SlnAddParser.ProjectPathArgument)?.ToArray() ?? (IReadOnlyCollection<string>)Array.Empty<string>(); | ||
|
||
_projects = (IReadOnlyCollection<string>)(parseResult.GetValue(SlnAddParser.ProjectPathArgument) ?? []); | ||
_inRoot = parseResult.GetValue(SlnAddParser.InRootOption); | ||
string relativeRoot = parseResult.GetValue(SlnAddParser.SolutionFolderOption); | ||
|
||
SlnArgumentValidator.ParseAndValidateArguments(_fileOrDirectory, _arguments, 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; | ||
} | ||
_solutionFolderPath = parseResult.GetValue(SlnAddParser.SolutionFolderOption); | ||
SlnArgumentValidator.ParseAndValidateArguments(_fileOrDirectory, _projects, SlnArgumentValidator.CommandType.Add, _inRoot, _solutionFolderPath); | ||
} | ||
|
||
public override int Execute() | ||
{ | ||
SlnFile slnFile = SlnFileFactory.CreateFromFileOrDirectory(_fileOrDirectory); | ||
|
||
var arguments = (_parseResult.GetValue<IEnumerable<string>>(SlnAddParser.ProjectPathArgument) ?? Array.Empty<string>()).ToList().AsReadOnly(); | ||
if (arguments.Count == 0) | ||
if (_projects.Count == 0) | ||
{ | ||
throw new GracefulException(CommonLocalizableStrings.SpecifyAtLeastOneProjectToAdd); | ||
} | ||
string solutionFileFullPath = SlnCommandParser.GetSlnFileFullPath(_fileOrDirectory); | ||
|
||
PathUtility.EnsureAllPathsExist(arguments, CommonLocalizableStrings.CouldNotFindProjectOrDirectory, true); | ||
|
||
var fullProjectPaths = _arguments.Select(p => | ||
{ | ||
var fullPath = Path.GetFullPath(p); | ||
return Directory.Exists(fullPath) ? | ||
MsbuildProject.GetProjectFileFromDirectory(fullPath).FullName : | ||
fullPath; | ||
}).ToList(); | ||
|
||
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); | ||
PathUtility.EnsureAllPathsExist(_projects, CommonLocalizableStrings.CouldNotFindProjectOrDirectory, true); | ||
IEnumerable<string> fullProjectPaths = _projects.Select(project => | ||
{ | ||
var fullPath = Path.GetFullPath(project); | ||
return Directory.Exists(fullPath) ? MsbuildProject.GetProjectFileFromDirectory(fullPath).FullName : fullPath; | ||
}); | ||
AddProjectsToSolutionAsync(solutionFileFullPath, fullProjectPaths, CancellationToken.None).GetAwaiter().GetResult(); | ||
return 0; | ||
} | ||
|
||
if (slnFile.Projects.Count > preAddProjectCount) | ||
catch (Exception ex) when (ex is not GracefulException) | ||
{ | ||
slnFile.Write(); | ||
{ | ||
if (ex is SolutionException || ex.InnerException is SolutionException) | ||
{ | ||
throw new GracefulException(CommonLocalizableStrings.InvalidSolutionFormatString, solutionFileFullPath, ex.Message); | ||
} | ||
throw new GracefulException(ex.Message, ex); | ||
} | ||
} | ||
|
||
return 0; | ||
} | ||
|
||
private static IList<string> GetSolutionFoldersFromProjectPath(string projectFilePath) | ||
private async Task AddProjectsToSolutionAsync(string solutionFileFullPath, IEnumerable<string> projectPaths, CancellationToken cancellationToken) | ||
{ | ||
var solutionFolders = new List<string>(); | ||
|
||
if (!IsPathInTreeRootedAtSolutionDirectory(projectFilePath)) | ||
return solutionFolders; | ||
|
||
var currentDirString = $".{Path.DirectorySeparatorChar}"; | ||
if (projectFilePath.StartsWith(currentDirString)) | ||
ISolutionSerializer serializer = SlnCommandParser.GetSolutionSerializer(solutionFileFullPath); | ||
SolutionModel solution = await serializer.OpenAsync(solutionFileFullPath, cancellationToken); | ||
// set UTF8 BOM encoding for .sln | ||
if (serializer is ISolutionSerializer<SlnV12SerializerSettings> v12Serializer) | ||
{ | ||
projectFilePath = projectFilePath.Substring(currentDirString.Length); | ||
solution.SerializerExtension = v12Serializer.CreateModelExtension(new() | ||
{ | ||
Encoding = new UTF8Encoding(encoderShouldEmitUTF8Identifier: true) | ||
}); | ||
} | ||
// Set default configurations and platforms for sln file | ||
foreach (var platform in _defaultPlatforms) | ||
{ | ||
solution.AddPlatform(platform); | ||
} | ||
foreach (var buildType in _defaultBuildTypes) | ||
{ | ||
solution.AddBuildType(buildType); | ||
} | ||
|
||
var projectDirectoryPath = TrimProject(projectFilePath); | ||
if (string.IsNullOrEmpty(projectDirectoryPath)) | ||
return solutionFolders; | ||
|
||
var solutionFoldersPath = TrimProjectDirectory(projectDirectoryPath); | ||
if (string.IsNullOrEmpty(solutionFoldersPath)) | ||
return solutionFolders; | ||
|
||
solutionFolders.AddRange(solutionFoldersPath.Split(Path.DirectorySeparatorChar)); | ||
SolutionFolderModel? solutionFolder = (!_inRoot && !string.IsNullOrEmpty(_solutionFolderPath)) | ||
? solution.AddFolder(GetSolutionFolderPathWithForwardSlashes(_solutionFolderPath)) | ||
: null; | ||
|
||
return solutionFolders; | ||
foreach (var projectPath in projectPaths) | ||
{ | ||
string relativePath = Path.GetRelativePath(Path.GetDirectoryName(solutionFileFullPath), projectPath); | ||
// Add fallback solution folder | ||
string relativeSolutionFolder = Path.GetDirectoryName(relativePath); | ||
if (!_inRoot && solutionFolder is null && !string.IsNullOrEmpty(relativeSolutionFolder)) | ||
{ | ||
if (relativeSolutionFolder.Split(Path.DirectorySeparatorChar).LastOrDefault() == Path.GetFileNameWithoutExtension(relativePath)) | ||
{ | ||
relativeSolutionFolder = Path.Combine(relativeSolutionFolder.Split(Path.DirectorySeparatorChar).SkipLast(1).ToArray()); | ||
} | ||
if (!string.IsNullOrEmpty(relativeSolutionFolder)) | ||
{ | ||
solutionFolder = solution.AddFolder(GetSolutionFolderPathWithForwardSlashes(relativeSolutionFolder)); | ||
} | ||
} | ||
|
||
try | ||
{ | ||
AddProject(solution, relativePath, projectPath, solutionFolder); | ||
} | ||
catch (InvalidProjectFileException ex) | ||
{ | ||
Reporter.Error.WriteLine(string.Format(CommonLocalizableStrings.InvalidProjectWithExceptionMessage, projectPath, ex.Message)); | ||
} | ||
catch (SolutionArgumentException ex) when (solution.FindProject(relativePath) != null || ex.Type == SolutionErrorType.DuplicateProjectName) | ||
{ | ||
Reporter.Output.WriteLine(CommonLocalizableStrings.SolutionAlreadyContainsProject, solutionFileFullPath, relativePath); | ||
} | ||
} | ||
await serializer.SaveAsync(solutionFileFullPath, solution, cancellationToken); | ||
} | ||
|
||
private IList<string> DetermineSolutionFolder(SlnFile slnFile, string fullProjectPath) | ||
private void AddProject(SolutionModel solution, string solutionRelativeProjectPath, string fullPath, SolutionFolderModel? solutionFolder) | ||
{ | ||
if (_inRoot) | ||
// Open project instance to see if it is a valid project | ||
ProjectRootElement projectRootElement = ProjectRootElement.Open(fullPath); | ||
SolutionProjectModel project; | ||
try | ||
{ | ||
// The user requested all projects go to the root folder | ||
return null; | ||
project = solution.AddProject(solutionRelativeProjectPath, null, solutionFolder); | ||
} | ||
|
||
if (_relativeRootSolutionFolders != null) | ||
catch (SolutionArgumentException ex) when (ex.ParamName == "projectTypeName") | ||
{ | ||
// The user has specified an explicit root | ||
return _relativeRootSolutionFolders; | ||
// If guid is not identified by vs-solutionpersistence, check in project element itself | ||
var guid = projectRootElement.GetProjectTypeGuid(); | ||
if (string.IsNullOrEmpty(guid)) | ||
{ | ||
Reporter.Error.WriteLine(CommonLocalizableStrings.UnsupportedProjectType, fullPath); | ||
return; | ||
} | ||
project = solution.AddProject(solutionRelativeProjectPath, guid, solutionFolder); | ||
} | ||
// Add settings based on existing project instance | ||
ProjectInstance projectInstance = new ProjectInstance(projectRootElement); | ||
string projectInstanceId = projectInstance.GetProjectId(); | ||
if (!string.IsNullOrEmpty(projectInstanceId)) | ||
{ | ||
project.Id = new Guid(projectInstanceId); | ||
} | ||
|
||
// 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) | ||
{ | ||
return !path.StartsWith(".."); | ||
} | ||
var projectInstanceBuildTypes = projectInstance.GetConfigurations(); | ||
var projectInstancePlatforms = projectInstance.GetPlatforms(); | ||
|
||
private static string TrimProject(string path) | ||
{ | ||
return Path.GetDirectoryName(path); | ||
} | ||
foreach (var solutionPlatform in solution.Platforms) | ||
{ | ||
var projectPlatform = projectInstancePlatforms.FirstOrDefault( | ||
platform => platform.Replace(" ", string.Empty) == solutionPlatform.Replace(" ", string.Empty), projectInstancePlatforms.FirstOrDefault()); | ||
project.AddProjectConfigurationRule(new ConfigurationRule(BuildDimension.Platform, "*", solutionPlatform, projectPlatform)); | ||
} | ||
|
||
private static string TrimProjectDirectory(string path) | ||
{ | ||
return Path.GetDirectoryName(path); | ||
foreach (var solutionBuildType in solution.BuildTypes) | ||
{ | ||
var projectBuildType = projectInstanceBuildTypes.FirstOrDefault( | ||
buildType => buildType.Replace(" ", string.Empty) == solutionBuildType.Replace(" ", string.Empty), projectInstanceBuildTypes.FirstOrDefault()); | ||
project.AddProjectConfigurationRule(new ConfigurationRule(BuildDimension.BuildType, solutionBuildType, "*", projectBuildType)); | ||
} | ||
Reporter.Output.WriteLine(CommonLocalizableStrings.ProjectAddedToTheSolution, solutionRelativeProjectPath); | ||
} | ||
} | ||
} |
2 changes: 2 additions & 0 deletions
2
test/TestAssets/TestProjects/InvalidSolution/InvalidSolution.slnx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
<invalid> | ||
</invalid> |
1 change: 1 addition & 0 deletions
1
test/TestAssets/TestProjects/InvalidSolution/Sln/InvalidSolution.sln
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
This is a test of an invalid solution. |
2 changes: 2 additions & 0 deletions
2
test/TestAssets/TestProjects/InvalidSolution/Slnx/InvalidSolution.slnx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
<invalid> | ||
</invalid> |
7 changes: 7 additions & 0 deletions
7
test/TestAssets/TestProjects/SlnFileWithNoProjectReferencesAndUnknownProjectType/App.slnx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
<Solution> | ||
<Configurations> | ||
<Platform Name="Any CPU" /> | ||
<Platform Name="x64" /> | ||
<Platform Name="x86" /> | ||
</Configurations> | ||
</Solution> |
47 changes: 47 additions & 0 deletions
47
test/TestAssets/TestProjects/SolutionFilesTemplates/ExpectedSlnFileAfterAddingLibProj.sln
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
Microsoft Visual Studio Solution File, Format Version 12.00 | ||
# Visual Studio 15 | ||
VisualStudioVersion = 15.0.26006.2 | ||
MinimumVisualStudioVersion = 10.0.40219.1 | ||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "App", "App\App.csproj", "{7072A694-548F-4CAE-A58F-12D257D5F486}" | ||
EndProject | ||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Lib", "Lib\Lib.csproj", "__LIB_PROJECT_GUID__" | ||
EndProject | ||
Global | ||
GlobalSection(SolutionConfigurationPlatforms) = preSolution | ||
Debug|Any CPU = Debug|Any CPU | ||
Debug|x64 = Debug|x64 | ||
Debug|x86 = Debug|x86 | ||
Release|Any CPU = Release|Any CPU | ||
Release|x64 = Release|x64 | ||
Release|x86 = Release|x86 | ||
EndGlobalSection | ||
GlobalSection(ProjectConfigurationPlatforms) = postSolution | ||
{7072A694-548F-4CAE-A58F-12D257D5F486}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | ||
{7072A694-548F-4CAE-A58F-12D257D5F486}.Debug|Any CPU.Build.0 = Debug|Any CPU | ||
{7072A694-548F-4CAE-A58F-12D257D5F486}.Debug|x64.ActiveCfg = Debug|x64 | ||
{7072A694-548F-4CAE-A58F-12D257D5F486}.Debug|x64.Build.0 = Debug|x64 | ||
{7072A694-548F-4CAE-A58F-12D257D5F486}.Debug|x86.ActiveCfg = Debug|x86 | ||
{7072A694-548F-4CAE-A58F-12D257D5F486}.Debug|x86.Build.0 = Debug|x86 | ||
{7072A694-548F-4CAE-A58F-12D257D5F486}.Release|Any CPU.ActiveCfg = Release|Any CPU | ||
{7072A694-548F-4CAE-A58F-12D257D5F486}.Release|Any CPU.Build.0 = Release|Any CPU | ||
{7072A694-548F-4CAE-A58F-12D257D5F486}.Release|x64.ActiveCfg = Release|x64 | ||
{7072A694-548F-4CAE-A58F-12D257D5F486}.Release|x64.Build.0 = Release|x64 | ||
{7072A694-548F-4CAE-A58F-12D257D5F486}.Release|x86.ActiveCfg = Release|x86 | ||
{7072A694-548F-4CAE-A58F-12D257D5F486}.Release|x86.Build.0 = Release|x86 | ||
__LIB_PROJECT_GUID__.Debug|Any CPU.ActiveCfg = Debug|Any CPU | ||
__LIB_PROJECT_GUID__.Debug|Any CPU.Build.0 = Debug|Any CPU | ||
__LIB_PROJECT_GUID__.Debug|x64.ActiveCfg = Debug|Any CPU | ||
__LIB_PROJECT_GUID__.Debug|x64.Build.0 = Debug|Any CPU | ||
__LIB_PROJECT_GUID__.Debug|x86.ActiveCfg = Debug|Any CPU | ||
__LIB_PROJECT_GUID__.Debug|x86.Build.0 = Debug|Any CPU | ||
__LIB_PROJECT_GUID__.Release|Any CPU.ActiveCfg = Release|Any CPU | ||
__LIB_PROJECT_GUID__.Release|Any CPU.Build.0 = Release|Any CPU | ||
__LIB_PROJECT_GUID__.Release|x64.ActiveCfg = Release|Any CPU | ||
__LIB_PROJECT_GUID__.Release|x64.Build.0 = Release|Any CPU | ||
__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 |
12 changes: 12 additions & 0 deletions
12
test/TestAssets/TestProjects/SolutionFilesTemplates/ExpectedSlnFileAfterAddingLibProj.slnx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
<Solution> | ||
<Configurations> | ||
<Platform Name="Any CPU" /> | ||
<Platform Name="x64" /> | ||
<Platform Name="x86" /> | ||
</Configurations> | ||
<Project Path="App/App.csproj"> | ||
<Platform Solution="*|x64" Project="x64" /> | ||
<Platform Solution="*|x86" Project="x86" /> | ||
</Project> | ||
<Project Path="Lib/Lib.csproj" Id="__LIB_PROJECT_GUID__"/> | ||
</Solution> |
33 changes: 33 additions & 0 deletions
33
...ssets/TestProjects/SolutionFilesTemplates/ExpectedSlnFileAfterAddingLibProjToEmptySln.sln
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
Microsoft Visual Studio Solution File, Format Version 12.00 | ||
# Visual Studio 15 | ||
VisualStudioVersion = 15.0.26006.2 | ||
MinimumVisualStudioVersion = 10.0.40219.1 | ||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Lib", "Lib\Lib.csproj", "__LIB_PROJECT_GUID__" | ||
EndProject | ||
Global | ||
GlobalSection(SolutionConfigurationPlatforms) = preSolution | ||
Debug|Any CPU = Debug|Any CPU | ||
Debug|x64 = Debug|x64 | ||
Debug|x86 = Debug|x86 | ||
Release|Any CPU = Release|Any CPU | ||
Release|x64 = Release|x64 | ||
Release|x86 = Release|x86 | ||
EndGlobalSection | ||
GlobalSection(ProjectConfigurationPlatforms) = postSolution | ||
__LIB_PROJECT_GUID__.Debug|Any CPU.ActiveCfg = Debug|Any CPU | ||
__LIB_PROJECT_GUID__.Debug|Any CPU.Build.0 = Debug|Any CPU | ||
__LIB_PROJECT_GUID__.Debug|x64.ActiveCfg = Debug|Any CPU | ||
__LIB_PROJECT_GUID__.Debug|x64.Build.0 = Debug|Any CPU | ||
__LIB_PROJECT_GUID__.Debug|x86.ActiveCfg = Debug|Any CPU | ||
__LIB_PROJECT_GUID__.Debug|x86.Build.0 = Debug|Any CPU | ||
__LIB_PROJECT_GUID__.Release|Any CPU.ActiveCfg = Release|Any CPU | ||
__LIB_PROJECT_GUID__.Release|Any CPU.Build.0 = Release|Any CPU | ||
__LIB_PROJECT_GUID__.Release|x64.ActiveCfg = Release|Any CPU | ||
__LIB_PROJECT_GUID__.Release|x64.Build.0 = Release|Any CPU | ||
__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 |
8 changes: 8 additions & 0 deletions
8
...sets/TestProjects/SolutionFilesTemplates/ExpectedSlnFileAfterAddingLibProjToEmptySln.slnx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
<Solution> | ||
<Configurations> | ||
<Platform Name="Any CPU" /> | ||
<Platform Name="x64" /> | ||
<Platform Name="x86" /> | ||
</Configurations> | ||
<Project Path="Lib/Lib.csproj" Id="__LIB_PROJECT_GUID__" /> | ||
</Solution> |
Oops, something went wrong.