Skip to content
This repository has been archived by the owner on Oct 4, 2021. It is now read-only.

Commit

Permalink
Merge pull request #5119 from mono/backport-pr-5114-to-release-7.6
Browse files Browse the repository at this point in the history
[release-7.6] [Core] Allow loading of SDK style projects without TargetFramework
  • Loading branch information
slluis committed Jun 21, 2018
2 parents a9afbb4 + c5654eb commit 9743981
Show file tree
Hide file tree
Showing 12 changed files with 188 additions and 11 deletions.
Expand Up @@ -368,6 +368,28 @@ public void WriteProject_TargetFrameworkVersionChanged_TargetFrameworkUpdated ()
Assert.AreEqual ("netcoreapp1.1", savedFramework);
}

[Test]
public void WriteProject_TargetFrameworkVersionChangedThenChangedBackAgain_OriginalTargetFrameworkUsedInProject ()
{
CreateMSBuildProject (
"<Project Sdk=\"Microsoft.NET.Sdk\">\r\n" +
" <PropertyGroup>\r\n" +
" <OutputType>Exe</OutputType>\r\n" +
" <TargetFramework>netcoreapp1.0</TargetFramework>\r\n" +
" </PropertyGroup>\r\n" +
"</Project>");
msbuildProject.Evaluate ();
ReadProject ();
project.Sdk = "Microsoft.NET.Sdk";

WriteProject (".NETCoreApp,Version=v1.1");
WriteProject (".NETCoreApp,Version=v1.0");

string savedFramework = msbuildProject.GetGlobalPropertyGroup ()
.GetValue ("TargetFramework");
Assert.AreEqual ("netcoreapp1.0", savedFramework);
}

[Test]
public void WriteProject_NetStandardTargetFrameworkVersionChanged_TargetFrameworkUpdated ()
{
Expand Down
Expand Up @@ -338,5 +338,35 @@ public async Task DotNetCoreProject_DefaultBuildActions ()
File.WriteAllText (fileName, string.Empty);
Assert.AreEqual ("None", project.GetDefaultBuildAction (fileName));
}

[Test]
public async Task ConsoleProjectNoMainPropertyGroup_ChangeToLibraryAndSaveProject_OutputTypeSavedInProject ()
{
string solutionFileName = Util.GetSampleProject ("DotNetCoreNoMainPropertyGroup", "DotNetCoreNoMainPropertyGroup.sln");
solution = (Solution) await Services.ProjectService.ReadWorkspaceItem (Util.GetMonitor (), solutionFileName);
var project = solution.GetAllDotNetProjects ().Single ();

// Original project does not have OutputType.
var globalPropertyGroup = project.MSBuildProject.GetGlobalPropertyGroup ();
Assert.IsFalse (globalPropertyGroup.HasProperty ("OutputType"));
Assert.AreEqual (CompileTarget.Exe, project.CompileTarget);

string outputTypeEvaluatedValue = project.MSBuildProject.EvaluatedProperties.GetValue ("OutputType");
Assert.AreEqual ("Exe", outputTypeEvaluatedValue);

project.CompileTarget = CompileTarget.Library;
await project.SaveAsync (Util.GetMonitor ());

// Reload project.
solution.Dispose ();
solution = (Solution) await Services.ProjectService.ReadWorkspaceItem (Util.GetMonitor (), solutionFileName);
project = solution.GetAllDotNetProjects ().Single ();

globalPropertyGroup = project.MSBuildProject.GetGlobalPropertyGroup ();

string outputTypeProperty = globalPropertyGroup.GetValue ("OutputType");
Assert.AreEqual ("Library", outputTypeProperty);
Assert.AreEqual (CompileTarget.Library, project.CompileTarget);
}
}
}
Expand Up @@ -96,7 +96,7 @@ public void WriteProject (MSBuildProject project, TargetFrameworkMoniker framewo
globalPropertyGroup.RemoveProperty ("TargetFrameworkVersion");

if (!IsOutputTypeDefined)
globalPropertyGroup.RemoveProperty ("OutputType");
RemoveOutputTypeIfHasDefaultValue (project, globalPropertyGroup);

RemoveMSBuildProjectNameDerivedProperties (globalPropertyGroup);

Expand All @@ -117,6 +117,16 @@ public void WriteProject (MSBuildProject project, TargetFrameworkMoniker framewo
}
}

static void RemoveOutputTypeIfHasDefaultValue (MSBuildProject project, MSBuildPropertyGroup globalPropertyGroup)
{
string outputType = project.EvaluatedProperties.GetValue ("OutputType");
if (string.IsNullOrEmpty (outputType)) {
globalPropertyGroup.RemoveProperty ("OutputType");
} else {
globalPropertyGroup.RemovePropertyIfHasDefaultValue ("OutputType", outputType);
}
}

void RemoveMSBuildProjectNameDerivedProperties (MSBuildPropertyGroup globalPropertyGroup)
{
string msbuildProjectName = globalPropertyGroup.ParentProject.FileName.FileNameWithoutExtension;
Expand Down Expand Up @@ -154,6 +164,7 @@ void UpdateTargetFramework (MSBuildProject project, TargetFrameworkMoniker frame
else
targetFrameworks[0] = shortFrameworkName;

targetFrameworkMoniker = framework;
project.UpdateTargetFrameworks (targetFrameworks);
}

Expand Down
Expand Up @@ -480,7 +480,7 @@ public MSBuildProjectInstance CreateInstance ()
internal MSBuildProjectInstanceInfo LoadNativeInstance (bool evaluateItems)
{
lock (readLock) {
var supportsMSBuild = UseMSBuildEngine && GetGlobalPropertyGroup ().GetValue ("UseMSBuildEngine", true);
var supportsMSBuild = UseMSBuildEngine && (GetGlobalPropertyGroup ()?.GetValue ("UseMSBuildEngine", true) ?? true);

if (engineManager == null) {
engineManager = new MSBuildEngineManager ();
Expand Down Expand Up @@ -573,19 +573,25 @@ public string ToolsVersion

public string [] ProjectTypeGuids
{
get { return GetGlobalPropertyGroup ().GetValue ("ProjectTypeGuids", "").Split (new [] { ';' }, StringSplitOptions.RemoveEmptyEntries).Select (t => t.Trim ()).ToArray (); }
set { GetGlobalPropertyGroup ().SetValue ("ProjectTypeGuids", string.Join (";", value), preserveExistingCase: true); }
get {
var propertyGroup = GetGlobalPropertyGroup ();
if (propertyGroup == null)
return Array.Empty<string> ();
return propertyGroup.GetValue ("ProjectTypeGuids", "").Split (new [] { ';' }, StringSplitOptions.RemoveEmptyEntries).Select (t => t.Trim ()).ToArray ();
}
set { GetOrCreateGlobalPropertyGroup ().SetValue ("ProjectTypeGuids", string.Join (";", value), preserveExistingCase: true); }
}

public bool AddProjectTypeGuid (string guid)
{
var guids = GetGlobalPropertyGroup ().GetValue ("ProjectTypeGuids", "").Trim ();
var propertyGroup = GetOrCreateGlobalPropertyGroup ();
var guids = propertyGroup.GetValue ("ProjectTypeGuids", "").Trim ();
if (guids.IndexOf (guid, StringComparison.OrdinalIgnoreCase) == -1) {
if (!string.IsNullOrEmpty (guids))
guids += ";" + guid;
else
guids = guid;
GetGlobalPropertyGroup ().SetValue ("ProjectTypeGuids", guids, preserveExistingCase: true);
propertyGroup.SetValue ("ProjectTypeGuids", guids, preserveExistingCase: true);
return true;
}
return false;
Expand Down Expand Up @@ -707,6 +713,17 @@ public MSBuildPropertyGroup GetGlobalPropertyGroup ()
return PropertyGroups.FirstOrDefault (g => g.Condition.Length == 0);
}

internal MSBuildPropertyGroup GetOrCreateGlobalPropertyGroup ()
{
var group = GetGlobalPropertyGroup ();
if (group == null) {
group = AddNewPropertyGroup (false);
// Ensure empty property group is not added on saving if it has no child properties.
group.SkipSerializationOnNoChildren = true;
}
return group;
}

public MSBuildPropertyGroup CreatePropertyGroup ()
{
return new MSBuildPropertyGroup ();
Expand Down
Expand Up @@ -463,6 +463,17 @@ public void SetPropertyOrder (params string[] propertyNames)
i++;
}
}

internal bool SkipSerializationOnNoChildren { get; set; } = false;

internal override bool SkipSerialization {
get {
if (SkipSerializationOnNoChildren)
return !GetChildren ().Any (c => !c.SkipSerialization);

return base.SkipSerialization;
}
}
}

public interface IMSBuildPropertyGroupEvaluated: IReadOnlyPropertySet
Expand Down
Expand Up @@ -199,10 +199,7 @@ protected override void OnInitialize ()
/// </summary>
void InitBeforeProjectExtensionLoad ()
{
var ggroup = sourceProject.GetGlobalPropertyGroup ();
// Avoid crash if there is not global group
if (ggroup == null)
ggroup = sourceProject.AddNewPropertyGroup (false);
var ggroup = sourceProject.GetOrCreateGlobalPropertyGroup ();

// Load the evaluated properties
InitMainGroupProperties (ggroup);
Expand Down Expand Up @@ -1425,7 +1422,7 @@ static string[] GetTargetFrameworks (MSBuildProject project)
return null;

var propertyGroup = project.GetGlobalPropertyGroup ();
string propertyValue = propertyGroup.GetValue ("TargetFramework", null);
string propertyValue = propertyGroup?.GetValue ("TargetFramework", null);
if (propertyValue != null)
return null;

Expand Down
Expand Up @@ -478,5 +478,29 @@ public async Task ReevaluateXamarinFormsVersion24PackageReference ()
Assert.AreEqual (xamlFile, xamlCSharpFile.DependsOnFile);
}
}

[Test]
public async Task DotNetCoreNoMainPropertyGroup ()
{
FilePath solFile = Util.GetSampleProject ("DotNetCoreNoMainPropertyGroup", "DotNetCoreNoMainPropertyGroup.sln");

using (var sol = (Solution)await Services.ProjectService.ReadWorkspaceItem (Util.GetMonitor (), solFile)) {
var p = (Project)sol.Items [0];
Assert.AreEqual ("DotNetCoreNoMainPropertyGroup", p.Name);

var process = Process.Start ("msbuild", $"/t:Restore \"{solFile}\"");
Assert.IsTrue (process.WaitForExit (120000), "Timeout restoring NuGet packages.");
Assert.AreEqual (0, process.ExitCode);

await p.ReevaluateProject (Util.GetMonitor ());

string projectXml = File.ReadAllText (p.FileName);
await p.SaveAsync (Util.GetMonitor ());

// Project xml should not be changed.
string savedProjectXml = File.ReadAllText (p.FileName);
Assert.AreEqual (projectXml, savedProjectXml);
}
}
}
}
Expand Up @@ -1569,6 +1569,34 @@ public void AddIncludeItemBeforeUpdateItemOfSameKind ()
p.Dispose ();
}

[Test]
public void ProjectHasNoMainPropertyGroup_AddRemoveProjectTypeGuid ()
{
string projectXml =
"<Project Sdk=\"Microsoft.NET.Sdk\">\r\n" +
"</Project>";

var p = new MSBuildProject ();
p.LoadXml (projectXml);

var projectTypeGuids = new string[] { "{test}" };
p.ProjectTypeGuids = projectTypeGuids;
Assert.AreEqual (projectTypeGuids, p.ProjectTypeGuids);

// Reload to ensure GlobalPropertyGroups is not available.
p.LoadXml (projectXml);

p.AddProjectTypeGuid ("{test}");
Assert.AreEqual (projectTypeGuids, p.ProjectTypeGuids);

// Reload to ensure GlobalPropertyGroups is not available.
p.LoadXml (projectXml);

p.AddProjectTypeGuid ("{test}");

p.Dispose ();
}

[Test]
public void GlobalPropertyProvider ()
{
Expand Down
@@ -0,0 +1,6 @@
<Project>
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.0</TargetFramework>
</PropertyGroup>
</Project>
@@ -0,0 +1,17 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2012
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DotNetCoreNoMainPropertyGroup", "DotNetCoreNoMainPropertyGroup\DotNetCoreNoMainPropertyGroup.csproj", "{32587BAB-C960-47D9-B952-FEFA8E55D76B}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{32587BAB-C960-47D9-B952-FEFA8E55D76B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{32587BAB-C960-47D9-B952-FEFA8E55D76B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{32587BAB-C960-47D9-B952-FEFA8E55D76B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{32587BAB-C960-47D9-B952-FEFA8E55D76B}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
EndGlobal
@@ -0,0 +1,2 @@
<Project Sdk="Microsoft.NET.Sdk">
</Project>
@@ -0,0 +1,12 @@
using System;

namespace DotNetCoreNoMainPropertyGroup
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello World!");
}
}
}

0 comments on commit 9743981

Please sign in to comment.