Skip to content

Commit 568b376

Browse files
committed
Add support for Microsoft.Build.NoTargets SDK
This allows using that SDK for packaging projects if desired. This change allows referencing such projects from other packaging projects, and also from regular Microsoft.NET.Sdk projects too.
1 parent 5595774 commit 568b376

File tree

5 files changed

+182
-14
lines changed

5 files changed

+182
-14
lines changed
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<!--
2+
***********************************************************************************************
3+
NuGetizer.Authoring.NoTargets.props
4+
5+
WARNING: DO NOT MODIFY this file unless you are knowledgeable about MSBuild and have
6+
created a backup copy. Incorrect changes to this file will make it
7+
impossible to load or build your projects from the command-line or the IDE.
8+
9+
Copyright (c) .NET Foundation. All rights reserved.
10+
***********************************************************************************************
11+
-->
12+
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
13+
<PropertyGroup>
14+
<CustomAfterNoTargets>$(MSBuildThisFileDirectory)NuGetizer.Authoring.NoTargets.targets</CustomAfterNoTargets>
15+
</PropertyGroup>
16+
</Project>
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<!--
2+
***********************************************************************************************
3+
NuGetizer.Authoring.NoTargets.targets
4+
5+
WARNING: DO NOT MODIFY this file unless you are knowledgeable about MSBuild and have
6+
created a backup copy. Incorrect changes to this file will make it
7+
impossible to load or build your projects from the command-line or the IDE.
8+
9+
Copyright (c) .NET Foundation. All rights reserved.
10+
***********************************************************************************************
11+
-->
12+
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
13+
14+
<!--NOTE: the NoTargets SDK overwrites this target with a blank one, breaking the P2P reference
15+
for NuGetizer. We bring it back to allow this again. -->
16+
<Target Name="GetTargetPathWithTargetPlatformMoniker"
17+
BeforeTargets="GetTargetPath"
18+
DependsOnTargets="$(GetTargetPathWithTargetPlatformMonikerDependsOn)"
19+
Returns="@(TargetPathWithTargetPlatformMoniker)">
20+
<ItemGroup>
21+
<TargetPathWithTargetPlatformMoniker Include="$(TargetPath)">
22+
<TargetPlatformMoniker>$(TargetPlatformMoniker)</TargetPlatformMoniker>
23+
<TargetPlatformIdentifier>$(TargetPlatformIdentifier)</TargetPlatformIdentifier>
24+
<TargetFrameworkIdentifier>$(TargetFrameworkIdentifier)</TargetFrameworkIdentifier>
25+
<TargetFrameworkVersion>$(TargetFrameworkVersion.TrimStart('vV'))</TargetFrameworkVersion>
26+
</TargetPathWithTargetPlatformMoniker>
27+
</ItemGroup>
28+
</Target>
29+
30+
</Project>

src/NuGetizer.Tasks/NuGetizer.Authoring.props

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,4 +54,6 @@ Copyright (c) .NET Foundation. All rights reserved.
5454
<BuildProjectReferences Condition="'$(BuildProjectReferences)' == ''">true</BuildProjectReferences>
5555
</PropertyGroup>
5656

57+
<Import Project="NuGetizer.Authoring.NoTargets.props" Condition="'$(UsingMicrosoftNoTargetsSdk)' == 'true'"/>
58+
5759
</Project>

src/NuGetizer.Tests/Builder.NuGetizer.cs

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
using Microsoft.Build.Execution;
1212
using Microsoft.Build.Framework;
1313
using Microsoft.Build.Logging.StructuredLogger;
14+
using NuGet.ProjectManagement;
1415
using Xunit;
1516
using Xunit.Abstractions;
1617
using Xunit.Sdk;
@@ -21,7 +22,20 @@
2122
static partial class Builder
2223
{
2324
public static TargetResult BuildProject(
24-
string projectContent = null,
25+
string projectContent,
26+
string target = "GetPackageContents",
27+
ITestOutputHelper output = null,
28+
LoggerVerbosity? verbosity = null,
29+
params (string name, string contents)[] files)
30+
{
31+
return BuildProjects(
32+
target: target,
33+
output: output,
34+
verbosity: verbosity,
35+
files: new[] { ("scenario.csproj", projectContent) }.Concat(files).ToArray());
36+
}
37+
38+
public static TargetResult BuildProjects(
2539
string target = "GetPackageContents",
2640
ITestOutputHelper output = null,
2741
LoggerVerbosity? verbosity = null,
@@ -31,22 +45,17 @@ public static TargetResult BuildProject(
3145

3246
// Combination of last write time for the test assembly + contents of the projects.
3347
var hash = Base62.Encode(Math.Abs(BitConverter.ToInt64(
34-
sha.ComputeHash(Encoding.UTF8.GetBytes(projectContent + string.Join("|", files.Select(f => f.contents)))), 0)));
48+
sha.ComputeHash(Encoding.UTF8.GetBytes(string.Join("|", files.Select(f => f.contents)))), 0)));
3549

3650
var scenarioName = hash;
3751
var scenarioDir = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Scenarios", scenarioName);
3852
Directory.CreateDirectory(scenarioDir);
39-
var doc = XDocument.Parse(projectContent);
40-
doc.Root.AddFirst(XElement
41-
.Parse("<Import Project='$([MSBuild]::GetPathOfFileAbove(Scenario.props, $(MSBuildThisFileDirectory)))' />"));
42-
43-
doc.Save(Path.Combine(scenarioDir, "scenario.csproj"));
4453

4554
foreach (var file in files)
4655
{
4756
try
4857
{
49-
doc = XDocument.Parse(file.contents);
58+
var doc = XDocument.Parse(file.contents);
5059
doc.Root.AddFirst(XElement
5160
.Parse("<Import Project='$([MSBuild]::GetPathOfFileAbove(Scenario.props, $(MSBuildThisFileDirectory)))' />"));
5261

@@ -56,14 +65,15 @@ public static TargetResult BuildProject(
5665
{
5766
File.WriteAllText(Path.Combine(scenarioDir, file.name), file.contents);
5867
}
59-
6068
}
6169

70+
var main = files.First().name;
71+
6272
using (var disable = OpenBuildLogAttribute.Disable())
63-
BuildScenario(scenarioName, projectName: "scenario", target: "Restore", output: output, verbosity: verbosity)
73+
BuildScenario(scenarioName, projectName: main, target: "Restore", output: output, verbosity: verbosity)
6474
.AssertSuccess(output);
6575

66-
return BuildScenario(scenarioName, projectName: "scenario", target: target, output: output, verbosity: verbosity);
76+
return BuildScenario(scenarioName, projectName: main, target: target, output: output, verbosity: verbosity);
6777
}
6878

6979
public static TargetResult BuildScenario(
@@ -75,22 +85,24 @@ public static TargetResult BuildScenario(
7585
LoggerVerbosity? verbosity = null)
7686
{
7787
var scenarioDir = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Scenarios", scenarioName);
88+
if (projectName != null && !Path.HasExtension(projectName))
89+
projectName = projectName + ".csproj";
7890

7991
if (projectName == null)
8092
{
8193
projectName = scenarioName;
8294
if (scenarioName.StartsWith("given", StringComparison.OrdinalIgnoreCase))
8395
projectName = string.Join("_", scenarioName.Split('_').Skip(2));
8496
}
85-
else if (!File.Exists(Path.Combine(scenarioDir, $"{projectName}.csproj")))
97+
else if (!File.Exists(Path.Combine(scenarioDir, projectName)))
8698
{
8799
throw new FileNotFoundException($"Project '{projectName}' was not found under scenario path '{scenarioDir}'.", projectName);
88100
}
89101

90102
string projectOrSolution;
91103

92-
if (File.Exists(Path.Combine(scenarioDir, $"{projectName}.csproj")))
93-
projectOrSolution = Path.Combine(scenarioDir, $"{projectName}.csproj");
104+
if (File.Exists(Path.Combine(scenarioDir, projectName)))
105+
projectOrSolution = Path.Combine(scenarioDir, projectName);
94106
else
95107
projectOrSolution = Directory.EnumerateFiles(scenarioDir, "*.*proj").FirstOrDefault();
96108

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
using Xunit;
2+
using Xunit.Abstractions;
3+
4+
namespace NuGetizer
5+
{
6+
public class given_a_notargets_sdk_project
7+
{
8+
ITestOutputHelper output;
9+
10+
public given_a_notargets_sdk_project(ITestOutputHelper output) => this.output = output;
11+
12+
[Fact]
13+
public void cam_reference_packaging_project()
14+
{
15+
var result = Builder.BuildProjects(
16+
"GetPackageContents", output, null,
17+
("main.msbuildproj", @"
18+
<Project Sdk='Microsoft.Build.NoTargets/2.0.1'>
19+
<PropertyGroup>
20+
<PackageId>Foo</PackageId>
21+
<TargetFramework>netstandard2.0</TargetFramework>
22+
</PropertyGroup>
23+
<ItemGroup>
24+
<PackageReference Include='Newtonsoft.Json' Version='12.0.3' />
25+
<ProjectReference Include='other.msbuildproj' />
26+
</ItemGroup>
27+
</Project>"),
28+
("other.msbuildproj", @"
29+
<Project Sdk='Microsoft.Build.NoTargets/2.0.1'>
30+
<PropertyGroup>
31+
<PackageId>Bar</PackageId>
32+
<TargetFramework>netstandard2.0</TargetFramework>
33+
</PropertyGroup>
34+
<ItemGroup>
35+
<PackageReference Include='Castle.Core' Version='4.4.1' />
36+
</ItemGroup>
37+
</Project>"));
38+
39+
result.AssertSuccess(output);
40+
Assert.Contains(result.Items, item => item.Matches(new
41+
{
42+
Identity = "Foo",
43+
PackFolder = PackFolderKind.Metadata
44+
}));
45+
Assert.Contains(result.Items, item => item.Matches(new
46+
{
47+
Identity = "Newtonsoft.Json",
48+
PackFolder = PackFolderKind.Dependency
49+
}));
50+
Assert.Contains(result.Items, item => item.Matches(new
51+
{
52+
Identity = "Bar",
53+
PackFolder = PackFolderKind.Dependency
54+
}));
55+
Assert.DoesNotContain(result.Items, item => item.Matches(new
56+
{
57+
Identity = "Castle.Core",
58+
PackageId = "Foo",
59+
PackFolder = PackFolderKind.Dependency
60+
}));
61+
}
62+
63+
[Fact]
64+
public void cam_be_referenced()
65+
{
66+
var result = Builder.BuildProjects(
67+
"GetPackageContents", output, null,
68+
("main.csproj", @"
69+
<Project Sdk='Microsoft.NET.Sdk'>
70+
<PropertyGroup>
71+
<PackageId>Foo</PackageId>
72+
<TargetFramework>netstandard2.0</TargetFramework>
73+
</PropertyGroup>
74+
<ItemGroup>
75+
<ProjectReference Include='other.msbuildproj' />
76+
</ItemGroup>
77+
</Project>"),
78+
("other.msbuildproj", @"
79+
<Project Sdk='Microsoft.Build.NoTargets/2.0.1'>
80+
<PropertyGroup>
81+
<PackageId>Bar</PackageId>
82+
<TargetFramework>netstandard2.0</TargetFramework>
83+
</PropertyGroup>
84+
<ItemGroup>
85+
<PackageReference Include='Castle.Core' Version='4.4.1' />
86+
</ItemGroup>
87+
</Project>"));
88+
89+
result.AssertSuccess(output);
90+
Assert.Contains(result.Items, item => item.Matches(new
91+
{
92+
Identity = "Foo",
93+
PackFolder = PackFolderKind.Metadata
94+
}));
95+
Assert.Contains(result.Items, item => item.Matches(new
96+
{
97+
Identity = "Bar",
98+
PackFolder = PackFolderKind.Dependency
99+
}));
100+
Assert.DoesNotContain(result.Items, item => item.Matches(new
101+
{
102+
Identity = "Castle.Core",
103+
PackageId = "Foo",
104+
PackFolder = PackFolderKind.Dependency
105+
}));
106+
}
107+
}
108+
}

0 commit comments

Comments
 (0)