Skip to content

Commit

Permalink
Add support for static graph when project extension is not csproj, vb…
Browse files Browse the repository at this point in the history
…proj, or fsproj (#139)
  • Loading branch information
cdmihai authored and jeffkl committed Nov 19, 2019
1 parent 922c8d5 commit 38f7f90
Show file tree
Hide file tree
Showing 3 changed files with 157 additions and 39 deletions.
181 changes: 143 additions & 38 deletions src/NoTargets.UnitTests/NoTargetsTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,26 +3,154 @@
// Licensed under the MIT license.

using Microsoft.Build.Evaluation;
using Microsoft.Build.Execution;
using Microsoft.Build.Experimental.Graph;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities.ProjectCreation;
using Shouldly;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using UnitTest.Common;
using Xunit;

namespace Microsoft.Build.NoTargets.UnitTests
{
public class NoTargetsTests : MSBuildSdkTestBase
{
[Theory]
[InlineData(".csproj")]
[InlineData(".proj")]
public void SimpleBuild(string projectExtension)
{
ProjectCreator.Templates.NoTargetsProject(
path: GetTempFileWithExtension(projectExtension),
projectCollection: new ProjectCollection(
new Dictionary<string, string>
{
["DesignTimeBuild"] = "true"
}),
customAction: creator =>
{
creator.Target("TakeAction", afterTargets: "Build")
.TaskMessage("86F00AF59170450E9D687652D74A6394", MessageImportance.High);
})
.Property("GenerateDependencyFile", "false")
.Save()
.TryBuild("Build", out var result, out var buildOutput);

result.ShouldBeTrue(() => buildOutput.GetConsoleLog());

buildOutput.Messages.High.ShouldContain("86F00AF59170450E9D687652D74A6394");
}

[Theory]
[InlineData(".csproj")]
[InlineData(".proj")]
public void ProjectContainsStaticGraphImplementation(string projectExtension)
{
var noTargets = ProjectCreator.Templates.NoTargetsProject(
path: GetTempFileWithExtension(projectExtension),
projectCollection: new ProjectCollection(
new Dictionary<string, string>
{
["DesignTimeBuild"] = "true"
}),
customAction: creator =>
{
creator.Target("TakeAction", afterTargets: "Build")
.TaskMessage("86F00AF59170450E9D687652D74A6394", MessageImportance.High);
})
.Property("GenerateDependencyFile", "false")
.Save();

var projectReferenceTargets = noTargets.Project.GetItems("ProjectReferenceTargets");

TargetProtocolShouldContainValuesForTarget("Build");
TargetProtocolShouldContainValuesForTarget("Clean");
TargetProtocolShouldContainValuesForTarget("Rebuild");
TargetProtocolShouldContainValuesForTarget("Publish");

void TargetProtocolShouldContainValuesForTarget(string target)
{
var buildTargets =
projectReferenceTargets.Where(i => i.EvaluatedInclude.Equals(target, StringComparison.OrdinalIgnoreCase))
.Select(i => i.GetMetadata("Targets")?.EvaluatedValue)
.Where(t => !string.IsNullOrEmpty(t));

buildTargets.ShouldNotBeEmpty();
}
}

[Theory(Skip = "https://github.com/microsoft/MSBuildSdks/issues/138")]
[InlineData(".csproj")]
[InlineData(".proj")]
public void StaticGraphBuildsSucceed(string projectExtension)
{
using var collection = new ProjectCollection();

var sdkReference = ProjectCreator.Templates.SdkCsproj(
GetTempFileWithExtension(".csproj"),
projectCollection: collection).Save();

var legacyReference = ProjectCreator.Templates.LegacyCsproj(
GetTempFileWithExtension(".csproj"),
projectCollection: collection).Save();

var noTargets = ProjectCreator.Templates.NoTargetsProject(
path: GetTempFileWithExtension(projectExtension),
targetFramework: "net472",
projectCollection: collection,
customAction: creator =>
{
creator.ItemProjectReference(sdkReference.Project, referenceOutputAssembly: false);
creator.ItemProjectReference(legacyReference.Project, referenceOutputAssembly: false);
}).Save();

var root = ProjectCreator.Templates.SdkCsproj(
GetTempFileWithExtension(".csproj"),
projectCollection: collection,
targetFramework: "net472",
projectCreator: creator => { creator.ItemProjectReference(noTargets.Project, referenceOutputAssembly: false); }).Save();

root.TryBuild("Restore", out var result, out var buildOutput1);
result.ShouldBe(true);

using var buildManager = new BuildManager();

try
{
var buildOutput = BuildOutput.Create();
buildManager.BeginBuild(
new BuildParameters
{
Loggers = new[] { buildOutput },
IsolateProjects = true
});

var graphResult = buildManager.BuildRequest(
new GraphBuildRequestData(
new[] { new ProjectGraphEntryPoint(root.FullPath) },
new[] { "Build" }));

graphResult.OverallResult.ShouldBe(BuildResultCode.Success);
buildOutput.Succeeded.ShouldBe(true);
}
finally
{
buildManager.EndBuild();
}
}

[Fact]
public void EnableDefaultCompileItemsIsFalse()
{
ProjectCreator.Templates.NoTargetsProject(
path: GetTempFileWithExtension(".csproj"))
path: GetTempFileWithExtension(".csproj"))
.Property("GenerateDependencyFile", "false")
.Save()
.TryGetPropertyValue("EnableDefaultCompileItems", out string enableDefaultCompileItems);
.TryGetPropertyValue("EnableDefaultCompileItems", out var enableDefaultCompileItems);

enableDefaultCompileItems.ShouldBe("false");
}
Expand All @@ -31,10 +159,10 @@ public void EnableDefaultCompileItemsIsFalse()
public void EnableDefaultEmbeddedResourceItemsIsFalse()
{
ProjectCreator.Templates.NoTargetsProject(
path: GetTempFileWithExtension(".csproj"))
path: GetTempFileWithExtension(".csproj"))
.Property("GenerateDependencyFile", "false")
.Save()
.TryGetPropertyValue("EnableDefaultEmbeddedResourceItems", out string enableDefaultEmbeddedResourceItems);
.TryGetPropertyValue("EnableDefaultEmbeddedResourceItems", out var enableDefaultEmbeddedResourceItems);

enableDefaultEmbeddedResourceItems.ShouldBe("false");
}
Expand All @@ -43,72 +171,49 @@ public void EnableDefaultEmbeddedResourceItemsIsFalse()
public void IncludeBuildOutputIsFalseByDefault()
{
ProjectCreator.Templates.NoTargetsProject(
path: GetTempFileWithExtension(".csproj"))
path: GetTempFileWithExtension(".csproj"))
.Save()
.TryGetPropertyValue("IncludeBuildOutput", out string includeBuildOutput);
.TryGetPropertyValue("IncludeBuildOutput", out var includeBuildOutput);

includeBuildOutput.ShouldBe("false");
}

[Fact]
public void ProjectsCanDependOnNoTargetsProjects()
{
ProjectCreator project1 = ProjectCreator.Templates.LegacyCsproj(
path: Path.Combine(TestRootPath, "project1", "project1.csproj"))
var project1 = ProjectCreator.Templates.LegacyCsproj(
Path.Combine(TestRootPath, "project1", "project1.csproj"))
.Save();

ProjectCreator project2 = ProjectCreator.Templates.NoTargetsProject(
path: Path.Combine(TestRootPath, "project2", "project2.csproj"))
var project2 = ProjectCreator.Templates.NoTargetsProject(
path: Path.Combine(TestRootPath, "project2", "project2.csproj"))
.Property("DesignTimeBuild", "true")
.Property("GenerateDependencyFile", "false")
.Target("_GetProjectReferenceTargetFrameworkProperties")
.ItemProjectReference(project1)
.Save();

ProjectCreator project3 = ProjectCreator.Templates.NoTargetsProject(
path: Path.Combine(TestRootPath, "project3", "project3.csproj"))
var project3 = ProjectCreator.Templates.NoTargetsProject(
path: Path.Combine(TestRootPath, "project3", "project3.csproj"))
.Property("DesignTimeBuild", "true")
.Property("GenerateDependencyFile", "false")
.ItemProjectReference(project2)
.Target("_GetProjectReferenceTargetFrameworkProperties")
.Save();

project3.TryBuild(out bool result, out BuildOutput buildOutput);
project3.TryBuild(out var result, out var buildOutput);

result.ShouldBeTrue(buildOutput.GetConsoleLog());
}

[Fact]
public void SimpleBuild()
{
ProjectCreator.Templates.NoTargetsProject(
path: GetTempFileWithExtension(".csproj"),
projectCollection: new ProjectCollection(new Dictionary<string, string>
{
["DesignTimeBuild"] = "true"
}),
customAction: creator =>
{
creator.Target("TakeAction", afterTargets: "Build")
.TaskMessage("86F00AF59170450E9D687652D74A6394", MessageImportance.High);
})
.Property("GenerateDependencyFile", "false")
.Save()
.TryBuild("Build", out bool result, out BuildOutput buildOutput);

result.ShouldBeTrue(() => buildOutput.GetConsoleLog());

buildOutput.Messages.High.ShouldContain("86F00AF59170450E9D687652D74A6394");
}

[Fact]
public void UsingMicrosoftNoTargetsSdkValueSet()
{
ProjectCreator.Templates.NoTargetsProject(
path: GetTempFileWithExtension(".csproj"))
.TryGetPropertyValue("UsingMicrosoftNoTargetsSdk", out string propertyValue);
.TryGetPropertyValue("UsingMicrosoftNoTargetsSdk", out var propertyValue);

propertyValue.ShouldBe("true");
}
}
}
}
7 changes: 7 additions & 0 deletions src/NoTargets/Sdk/Sdk.props
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,13 @@
<MSBuildAllProjects Condition="'$(MSBuildToolsVersion)' != 'Current'">$(MSBuildAllProjects);$(MsBuildThisFileFullPath)</MSBuildAllProjects>
</PropertyGroup>

<PropertyGroup>
<!-- Copy logic to know if managed targets got imported: https://github.com/dotnet/sdk/blob/49002c14cf91ecd08e79d6184dbd4716c005b509/src/Tasks/Microsoft.NET.Build.Tasks/sdk/Sdk.targets#L25-L27 -->
<ManagedLanguageTargetsGotImported Condition="'$(MSBuildProjectExtension)' == '.csproj'">true</ManagedLanguageTargetsGotImported>
<ManagedLanguageTargetsGotImported Condition="'$(MSBuildProjectExtension)' == '.vbproj'">true</ManagedLanguageTargetsGotImported>
<ManagedLanguageTargetsGotImported Condition="'$(MSBuildProjectExtension)' == '.fsproj'">true</ManagedLanguageTargetsGotImported>
</PropertyGroup>

<Import Project="$(CustomBeforeNoTargetsProps)" Condition=" '$(CustomBeforeNoTargetsProps)' != '' And Exists('$(CustomBeforeNoTargetsProps)') " />

<PropertyGroup>
Expand Down
8 changes: 7 additions & 1 deletion src/NoTargets/Sdk/Sdk.targets
Original file line number Diff line number Diff line change
Expand Up @@ -70,5 +70,11 @@
<Target Name="GetTargetPathWithTargetPlatformMoniker" />

<Import Project="$(CustomAfterNoTargets)" Condition="'$(CustomAfterNoTargets)' != '' and Exists('$(CustomAfterNoTargets)')" />


<!--
Microsoft.Managed.Targets is imported by the managed language target files, but most of the msbuild tasks are actually in Microsoft.Common.Currentversion.targets.
So import it when the managed targets do not get imported.
-->
<Import Project="$(MSBuildToolsPath)\Microsoft.Managed.targets" Condition="'$(ManagedLanguageTargetsGotImported)' != 'true'"/>

</Project>

0 comments on commit 38f7f90

Please sign in to comment.