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 #5114 from mono/dotnetcore-no-main-property-group-…
Browse files Browse the repository at this point in the history
…project

[Core] Allow loading of SDK style projects without TargetFramework
  • Loading branch information
slluis authored Jun 21, 2018
2 parents 77fdbbd + 0af96b3 commit 5526ce3
Show file tree
Hide file tree
Showing 12 changed files with 188 additions and 11 deletions.
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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);
}
}
}
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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 override string Namespace {

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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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);
}
}
}
}
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<Project>
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.0</TargetFramework>
</PropertyGroup>
</Project>
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<Project Sdk="Microsoft.NET.Sdk">
</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using System;

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

0 comments on commit 5526ce3

Please sign in to comment.