Skip to content

Commit ee5fec9

Browse files
authored
Keep the whole NoWarn list, and each target framework once (#826)
Directory.Build.props declared NoWarn twice. The second declaration replaced the first rather than adding to it, so CS0649, NU1608 and NU1109 were suppressed nowhere - and with TreatWarningsAsErrors on, the next unassigned field would have failed the build rather than warned in it. One list now, with everything both had. DiffEngine.csproj also listed net9.0 and net10.0 in both of its TargetFrameworks lines. MSBuild collapses that, so it built the same set, but the file said something it did not mean. Neither shows up in a build, which is why the two rules are asserted in a test instead.
1 parent c2e33e2 commit ee5fec9

3 files changed

Lines changed: 67 additions & 4 deletions

File tree

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
/// <summary>
2+
/// Two things about the build files that a build cannot tell anyone. A second property of the same
3+
/// name replaces the first rather than adding to it, and a target framework listed twice is
4+
/// collapsed, so both mistakes build clean and say nothing.
5+
/// </summary>
6+
public class BuildFileTests
7+
{
8+
/// <summary>
9+
/// There were two, so only the later list was in force and CS0649, NU1608 and NU1109 were
10+
/// suppressed nowhere - which under TreatWarningsAsErrors is a build failure waiting for the
11+
/// first unassigned field.
12+
/// </summary>
13+
[Test]
14+
public async Task NoWarn_is_declared_once()
15+
{
16+
var props = await File.ReadAllTextAsync(Path.Combine(Source(), "Directory.Build.props"));
17+
18+
var declarations = props.Split(["<NoWarn>"], StringSplitOptions.None).Length - 1;
19+
20+
await Assert.That(declarations).IsEqualTo(1);
21+
}
22+
23+
[Test]
24+
public async Task No_target_framework_is_listed_twice()
25+
{
26+
var project = await File.ReadAllTextAsync(Path.Combine(Source(), "DiffEngine", "DiffEngine.csproj"));
27+
28+
var listed = project
29+
.Split('\n')
30+
.Where(_ => _.Contains("<TargetFrameworks"))
31+
.SelectMany(_ => _[(_.IndexOf('>') + 1)..^"</TargetFrameworks>".Length].Split(';'))
32+
.Where(_ => _.StartsWith("net", StringComparison.Ordinal))
33+
.ToList();
34+
35+
await Assert.That(listed).IsNotEmpty();
36+
await Assert.That(listed.Distinct()).IsEquivalentTo(listed);
37+
}
38+
39+
/// <summary>
40+
/// The src directory, found by walking up from the test output rather than by counting
41+
/// directories, which differs per target framework and configuration.
42+
/// </summary>
43+
static string Source()
44+
{
45+
var directory = new DirectoryInfo(AppContext.BaseDirectory);
46+
while (directory != null)
47+
{
48+
if (File.Exists(Path.Combine(directory.FullName, "Directory.Build.props")))
49+
{
50+
return directory.FullName;
51+
}
52+
53+
directory = directory.Parent;
54+
}
55+
56+
throw new("Could not find Directory.Build.props above the test output.");
57+
}
58+
}

src/DiffEngine/DiffEngine.csproj

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
<Project Sdk="Microsoft.NET.Sdk">
22
<PropertyGroup>
3-
<TargetFrameworks Condition=" '$(OS)' == 'Windows_NT'">net462;net472;net48;net9.0;net10.0</TargetFrameworks>
4-
<TargetFrameworks>$(TargetFrameworks);net6.0;net7.0;net8.0;net9.0;net10.0</TargetFrameworks>
3+
<TargetFrameworks>net6.0;net7.0;net8.0;net9.0;net10.0</TargetFrameworks>
4+
<!-- The .NET Framework legs, which only Windows can build -->
5+
<TargetFrameworks Condition=" '$(OS)' == 'Windows_NT'">net462;net472;net48;$(TargetFrameworks)</TargetFrameworks>
56
<AllowUnsafeBlocks Condition="$([MSBuild]::IsTargetFrameworkCompatible('$(TargetFramework)', 'net7.0'))">true</AllowUnsafeBlocks>
67
<IsAotCompatible Condition="$([MSBuild]::IsTargetFrameworkCompatible('$(TargetFramework)', 'net7.0'))">true</IsAotCompatible>
78
</PropertyGroup>

src/Directory.Build.props

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
<?xml version="1.0" encoding="utf-8"?>
22
<Project>
33
<PropertyGroup>
4-
<NoWarn>CS1591;CS0649;NU1608;NU1109</NoWarn>
54
<Version>20.0.0-beta.30</Version>
65
<AssemblyVersion>1.0.0</AssemblyVersion>
76
<PackageTags>Testing, Snapshot, Diff, Compare</PackageTags>
@@ -14,7 +13,12 @@
1413
<CheckEolTargetFramework>false</CheckEolTargetFramework>
1514
<SuppressTfmSupportBuildWarnings>true</SuppressTfmSupportBuildWarnings>
1615
<ResolveAssemblyReferencesSilent>true</ResolveAssemblyReferencesSilent>
17-
<NoWarn>CA1416;CS1591</NoWarn>
16+
<!--
17+
One NoWarn, because a second property of the same name replaces the first rather than adding to
18+
it. There were two, so CS0649, NU1608 and NU1109 were not suppressed at all - and with
19+
TreatWarningsAsErrors below they would have failed a build rather than warned in one.
20+
-->
21+
<NoWarn>CS1591;CS0649;NU1608;NU1109;CA1416</NoWarn>
1822
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
1923
<EnforceCodeStyleInBuild>true</EnforceCodeStyleInBuild>
2024
<SuppressNETCoreSdkPreviewMessage>true</SuppressNETCoreSdkPreviewMessage>

0 commit comments

Comments
 (0)