Skip to content

Commit 1e27202

Browse files
authored
Merge pull request #1 from MSLukeWest/MSLukeWest-NetCorePublishItemsOutputGroup
Adding NetCorePublishItemsOutputGroup to support VS installer project scenarios
2 parents 82cca88 + 087db91 commit 1e27202

File tree

4 files changed

+174
-0
lines changed

4 files changed

+174
-0
lines changed

src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.Publish.targets

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -841,6 +841,26 @@ Copyright (c) .NET Foundation. All rights reserved.
841841

842842
</Target>
843843

844+
<!--
845+
============================================================
846+
NetCorePublishItemsOutputGroup
847+
848+
Emit an output group containing all files that get published. This will be consumed by VS installer projects.
849+
============================================================
850+
-->
851+
<PropertyGroup>
852+
<NetCorePublishItemsOutputGroupDependsOn>
853+
$(NetCorePublishItemsOutputGroupDependsOn);
854+
ComputeFilesToPublish;
855+
</NetCorePublishItemsOutputGroupDependsOn>
856+
</PropertyGroup>
857+
858+
<Target Name="NetCorePublishItemsOutputGroup" DependsOnTargets="$(NetCorePublishItemsOutputGroupDependsOn)" Returns="@(NetCorePublishItemsOutputGroupOutputs)">
859+
<ItemGroup>
860+
<NetCorePublishItemsOutputGroupOutputs Include="@(ResolvedFileToPublish->'%(FullPath)')" TargetPath="%(ResolvedFileToPublish.RelativePath)" OutputGroup="NetCorePublishItemsOutputGroup" />
861+
</ItemGroup>
862+
</Target>
863+
844864
<!--
845865
This target exists for back-compat with Azure Functions SDK: https://github.com/dotnet/cli/issues/10363
846866
Because build copy-local now behaves the same as publish with respect to package dependency resolution,
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
using System.Collections.Generic;
2+
using System.IO;
3+
using FluentAssertions;
4+
using Microsoft.NET.TestFramework;
5+
using Microsoft.NET.TestFramework.Assertions;
6+
using Microsoft.NET.TestFramework.Commands;
7+
using Microsoft.NET.TestFramework.ProjectConstruction;
8+
using Xunit;
9+
using Xunit.Abstractions;
10+
11+
namespace Microsoft.NET.Publish.Tests
12+
{
13+
public class NetCorePublishItemsOutputGroupTests : SdkTest
14+
{
15+
public NetCorePublishItemsOutputGroupTests(ITestOutputHelper log) : base(log)
16+
{
17+
}
18+
19+
private static List<string> FrameworkAssemblies = new List<string>()
20+
{
21+
"api-ms-win-core-console-l1-1-0.dll",
22+
"System.Runtime.dll",
23+
"WindowsBase.dll",
24+
};
25+
26+
[CoreMSBuildOnlyFact]
27+
public void GroupPopulatedWithRid()
28+
{
29+
var testProject = this.SetupProject();
30+
var testAsset = _testAssetsManager.CreateTestProject(testProject);
31+
32+
var restoreCommand = new RestoreCommand(Log, testAsset.Path, testProject.Name);
33+
restoreCommand
34+
.Execute()
35+
.Should()
36+
.Pass();
37+
38+
var buildCommand = new BuildCommand(Log, testAsset.Path, testProject.Name);
39+
buildCommand
40+
.Execute("/p:RuntimeIdentifier=win-x86", "/t:NetCorePublishItemsOutputGroup")
41+
.Should()
42+
.Pass();
43+
44+
var testOutputDir = Path.Combine(testAsset.Path, testProject.Name, "TestOutput");
45+
Log.WriteLine("Contents of NetCorePublishItemsOutputGroup dumped to '{0}'.", testOutputDir);
46+
47+
// Check for the existence of a few specific files that should be in the directory where the
48+
// contents of NetCorePublishItemsOutputGroup were dumped to make sure it's getting populated.
49+
Assert.True(File.Exists(Path.Combine(testOutputDir, $"{testProject.Name}.exe")), $"Assembly {testProject.Name}.exe is present in the output group.");
50+
foreach (var assem in FrameworkAssemblies)
51+
{
52+
Assert.True(File.Exists(Path.Combine(testOutputDir, assem)), $"Assembly {assem} is present in the output group.");
53+
}
54+
}
55+
56+
[CoreMSBuildOnlyFact]
57+
public void GroupNotPopulatedWithoutRid()
58+
{
59+
var testProject = this.SetupProject();
60+
var testAsset = _testAssetsManager.CreateTestProject(testProject);
61+
62+
var restoreCommand = new RestoreCommand(Log, testAsset.Path, testProject.Name);
63+
restoreCommand
64+
.Execute()
65+
.Should()
66+
.Pass();
67+
68+
var buildCommand = new BuildCommand(Log, testAsset.Path, testProject.Name);
69+
buildCommand
70+
.Execute("/t:NetCorePublishItemsOutputGroup")
71+
.Should()
72+
.Pass();
73+
74+
var testOutputDir = Path.Combine(testAsset.Path, testProject.Name, "TestOutput");
75+
Log.WriteLine("Contents of NetCorePublishItemsOutputGroup dumped to '{0}'.", testOutputDir);
76+
77+
// Since no RID was specified the output group should only contain framework dependent output
78+
Assert.True(File.Exists(Path.Combine(testOutputDir, $"{testProject.Name}.exe")), $"Assembly {testProject.Name}.exe is present in the output group.");
79+
foreach (var assem in FrameworkAssemblies)
80+
{
81+
Assert.False(File.Exists(Path.Combine(testOutputDir, assem)), $"Assembly {assem} is not present in the output group.");
82+
}
83+
}
84+
85+
private TestProject SetupProject()
86+
{
87+
var testProject = new TestProject()
88+
{
89+
Name = "TestPublishOutputGroup",
90+
TargetFrameworks = "netcoreapp3.0",
91+
IsSdkProject = true,
92+
IsExe = true
93+
};
94+
95+
testProject.AdditionalProperties["RuntimeIdentifiers"] = "win-x86";
96+
97+
// Use a test-specific packages folder
98+
testProject.AdditionalProperties["RestorePackagesPath"] = @"$(MSBuildProjectDirectory)\..\pkg";
99+
100+
// Add a target that will dump the contents of the NetCorePublishItemsOutputGroup to
101+
// a test directory after building.
102+
testProject.CopyFilesTargets.Add(new CopyFilesTarget(
103+
"CopyNetCorePublishItemsOutputGroup",
104+
"NetCorePublishItemsOutputGroup",
105+
"@(NetCorePublishItemsOutputGroupOutputs)",
106+
"$(MSBuildProjectDirectory)\\TestOutput"));
107+
108+
return testProject;
109+
}
110+
}
111+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// Copyright (c) .NET Foundation and contributors. All rights reserved.
2+
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
3+
4+
namespace Microsoft.NET.TestFramework
5+
{
6+
/// <summary>
7+
/// Represents a target that will copy some set of files to a given location after some other target completes.
8+
/// Useful for verifying the contents of an output group in a test.
9+
/// </summary>
10+
public class CopyFilesTarget
11+
{
12+
public CopyFilesTarget(string targetName, string targetToRunAfter, string sourceFiles, string destination)
13+
{
14+
TargetName = targetName;
15+
TargetToRunAfter = targetToRunAfter;
16+
SourceFiles = sourceFiles;
17+
Destination = destination;
18+
}
19+
20+
public string TargetName { get; private set; }
21+
public string TargetToRunAfter { get; private set; }
22+
public string SourceFiles { get; private set; }
23+
public string Destination { get; private set; }
24+
}
25+
}

src/Tests/Microsoft.NET.TestFramework/ProjectConstruction/TestProject.cs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ public class TestProject
3636
public List<TestPackageReference> PackageReferences { get; } = new List<TestPackageReference>();
3737

3838
public List<TestPackageReference> DotNetCliToolReferences { get; } = new List<TestPackageReference>();
39+
40+
public List<CopyFilesTarget> CopyFilesTargets { get; } = new List<CopyFilesTarget>();
3941

4042
public Dictionary<string, string> SourceFiles { get; } = new Dictionary<string, string>();
4143

@@ -270,6 +272,22 @@ internal void Create(TestAsset targetTestAsset, string testProjectsSourceFolder)
270272
new XAttribute("Include", reference)));
271273
}
272274
}
275+
276+
if (this.CopyFilesTargets.Any())
277+
{
278+
foreach (var copyFilesTarget in CopyFilesTargets)
279+
{
280+
var target = new XElement(ns + "Target",
281+
new XAttribute("Name", copyFilesTarget.TargetName),
282+
new XAttribute("AfterTargets", copyFilesTarget.TargetToRunAfter));
283+
284+
target.Add(new XElement(ns + "Copy",
285+
new XAttribute("SourceFiles", copyFilesTarget.SourceFiles),
286+
new XAttribute("DestinationFolder", copyFilesTarget.Destination)));
287+
288+
projectXml.Root.Add(target);
289+
}
290+
}
273291

274292
using (var file = File.CreateText(targetProjectPath))
275293
{

0 commit comments

Comments
 (0)