Skip to content

Commit 3f84e45

Browse files
authored
Improve source-built cache conflict warning (#878)
Try to find where the conflicting package came from and include the path in the message. For example, this identifies that Microsoft.NETCore.Targets in the tarball build is being used from prebuilt/source-built. Before this change, it would incorrectly suggest the package was restored from the internet. Add source-build infrastructure MSBuild binlogging for better diagnosis.
1 parent 8e33312 commit 3f84e45

File tree

4 files changed

+72
-14
lines changed

4 files changed

+72
-14
lines changed

build.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,5 +26,5 @@ SDKPATH="$CLIPATH/sdk/$SDK_VERSION"
2626

2727
set -x
2828

29-
$CLIPATH/dotnet $SDKPATH/MSBuild.dll $SCRIPT_ROOT/build.proj /flp:v=diag /clp:v=m "$@"
29+
$CLIPATH/dotnet $SDKPATH/MSBuild.dll $SCRIPT_ROOT/build.proj /bl /flp:v=diag /clp:v=m "$@"
3030

repos/dir.targets

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -189,8 +189,15 @@
189189
<Output TaskParameter="PackageInfoItems" ItemName="_PreviouslySourceBuiltPackageInfos" />
190190
</ReadNuGetPackageInfos>
191191

192+
<ItemGroup>
193+
<_KnownOriginPackagePaths Include="$(PrebuiltSourceBuiltPackagesPath)*.nupkg" />
194+
<_KnownOriginPackagePaths Include="$(PrebuiltPackagesPath)*.nupkg" />
195+
<_KnownOriginPackagePaths Include="$(ReferencePackagesDir)*.nupkg" />
196+
</ItemGroup>
197+
192198
<GetSourceBuiltNupkgCacheConflicts SourceBuiltPackageInfos="@(_PreviouslySourceBuiltPackageInfos)"
193-
PackageCacheDir="$(PackagesDir)">
199+
PackageCacheDir="$(PackagesDir)"
200+
KnownOriginPackagePaths="@(_KnownOriginPackagePaths)">
194201
<Output TaskParameter="ConflictingPackageInfos" ItemName="ConflictingPackageInfos" />
195202
</GetSourceBuiltNupkgCacheConflicts>
196203
</Target>
@@ -213,7 +220,8 @@
213220
<WriteUsageReports DataFile="$(_ReportDataFile)"
214221
OutputDirectory="$(_ReportDir)" />
215222

216-
<Warning Text="Detected package id/version(s) in the cache that were source-built, but contents don't match. They were probably downloaded. See $(_ReportDir) for usage details. @(ConflictingPackageInfos->'%(PackageId) %(PackageVersion)', ', ')" />
223+
<Warning Text="Detected packages in the cache that should be source-built, but contents don't match. See $(_ReportDir) for usage details:" />
224+
<Warning Text="%(ConflictingPackageInfos.PackageId)/%(ConflictingPackageInfos.PackageVersion) : %(ConflictingPackageInfos.WarningMessage)" />
217225
</Target>
218226

219227
<Target Name="CreateRestoreSourceProps"

support/tarball/build.sh

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ export NUGET_PACKAGES="$SCRIPT_ROOT/packages/"
1414
MSBUILD_ARGUMENTS=("/p:OfflineBuild=true" "/flp:v=detailed")
1515

1616
echo "Rebuild reference assemblies"
17-
$CLI_ROOT/dotnet $CLI_ROOT/sdk/$CLI_VERSION/MSBuild.dll $SCRIPT_ROOT/tools-local/init-build.proj /t:BuildReferenceAssemblies ${MSBUILD_ARGUMENTS[@]} "$@"
17+
$CLI_ROOT/dotnet $CLI_ROOT/sdk/$CLI_VERSION/MSBuild.dll /bl:initBuildReferenceAssemblies.binlog $SCRIPT_ROOT/tools-local/init-build.proj /t:BuildReferenceAssemblies ${MSBUILD_ARGUMENTS[@]} "$@"
1818

1919
echo "Expanding BuildTools dependencies into packages directory..."
2020
# init-tools tries to copy from its script directory to Tools, which in this case is a copy to
@@ -38,5 +38,5 @@ REF_PACKAGE_SOURCE="$SCRIPT_ROOT/reference-packages/packages"
3838
exit 1
3939
)
4040

41-
$CLI_ROOT/dotnet $CLI_ROOT/sdk/$CLI_VERSION/MSBuild.dll $SCRIPT_ROOT/tools-local/init-build.proj /t:WriteDynamicPropsToStaticPropsFiles /p:GeneratingStaticPropertiesFile=true ${MSBUILD_ARGUMENTS[@]} "$@"
42-
$CLI_ROOT/dotnet $CLI_ROOT/sdk/$CLI_VERSION/MSBuild.dll $SCRIPT_ROOT/build.proj ${MSBUILD_ARGUMENTS[@]} "$@"
41+
$CLI_ROOT/dotnet $CLI_ROOT/sdk/$CLI_VERSION/MSBuild.dll /bl:initWriteDynamicPropsToStaticPropsFiles.binlog $SCRIPT_ROOT/tools-local/init-build.proj /t:WriteDynamicPropsToStaticPropsFiles /p:GeneratingStaticPropertiesFile=true ${MSBUILD_ARGUMENTS[@]} "$@"
42+
$CLI_ROOT/dotnet $CLI_ROOT/sdk/$CLI_VERSION/MSBuild.dll /bl:build.binlog $SCRIPT_ROOT/build.proj ${MSBUILD_ARGUMENTS[@]} "$@"

tools-local/tasks/Microsoft.DotNet.SourceBuild.Tasks/GetSourceBuiltNupkgCacheConflicts.cs

Lines changed: 58 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
using Microsoft.Build.Framework;
66
using Microsoft.Build.Utilities;
7+
using NuGet.Packaging.Core;
8+
using NuGet.Versioning;
79
using System;
810
using System.IO;
911
using System.Linq;
@@ -40,13 +42,33 @@ public class GetSourceBuiltNupkgCacheConflicts : Task
4042
[Required]
4143
public string PackageCacheDir { get; set; }
4244

45+
/// <summary>
46+
/// Paths to packages to compare against when conflicts are detected. Knowing where the
47+
/// package in the cache came from can help diagnose a conflict. For example, is it from
48+
/// prebuilt/source-built? Or does the build not have the nupkg anywhere else, and
49+
/// therefore it most likely came from the internet?
50+
/// </summary>
51+
public string[] KnownOriginPackagePaths { get; set; }
52+
4353
[Output]
4454
public ITaskItem[] ConflictingPackageInfos { get; set; }
4555

4656
public override bool Execute()
4757
{
4858
DateTime startTime = DateTime.Now;
4959

60+
var knownNupkgs = new Lazy<ILookup<PackageIdentity, string>>(() =>
61+
{
62+
Log.LogMessage(
63+
MessageImportance.Low,
64+
$"Reading all {nameof(KnownOriginPackagePaths)} package identities to search " +
65+
"for conflicting package origin...");
66+
67+
return KnownOriginPackagePaths.NullAsEmpty().ToLookup(
68+
ReadNuGetPackageInfos.ReadIdentity,
69+
path => path);
70+
});
71+
5072
ConflictingPackageInfos = SourceBuiltPackageInfos
5173
.Where(item =>
5274
{
@@ -72,22 +94,50 @@ public override bool Execute()
7294
MessageImportance.Low,
7395
$"Package id/version found in package cache, verifying: {id} {version}");
7496

75-
bool identical = File.ReadAllBytes(sourceBuiltPath)
76-
.SequenceEqual(File.ReadAllBytes(packageCachePath));
97+
byte[] packageCacheBytes = File.ReadAllBytes(packageCachePath);
7798

78-
if (!identical)
99+
if (packageCacheBytes.SequenceEqual(File.ReadAllBytes(sourceBuiltPath)))
79100
{
80101
Log.LogMessage(
81102
MessageImportance.Low,
82-
"BAD: Source-built nupkg is not byte-for-byte identical " +
83-
$"to nupkg in cache: {id} {version}");
84-
return true;
103+
$"OK: Package in cache is identical to source-built: {id} {version}");
104+
return false;
85105
}
86106

87107
Log.LogMessage(
88108
MessageImportance.Low,
89-
$"OK: Package in cache is identical to source-built: {id} {version}");
90-
return false;
109+
"BAD: Source-built nupkg is not byte-for-byte identical " +
110+
$"to nupkg in cache: {id} {version}");
111+
112+
var ident = new PackageIdentity(id, NuGetVersion.Parse(version));
113+
114+
string message = null;
115+
116+
foreach (string knownNupkg in knownNupkgs.Value[ident])
117+
{
118+
if (packageCacheBytes.SequenceEqual(File.ReadAllBytes(knownNupkg)))
119+
{
120+
Log.LogMessage(
121+
MessageImportance.Low,
122+
$"Found identity match with identical contents: {knownNupkg}");
123+
124+
message = (message ?? "Nupkg found at") + $" '{knownNupkg}'";
125+
}
126+
else
127+
{
128+
Log.LogMessage(
129+
MessageImportance.Low,
130+
$"Package identity match, but contents differ: {knownNupkg}");
131+
}
132+
}
133+
134+
item.SetMetadata(
135+
"WarningMessage",
136+
message ??
137+
"Origin nupkg not found in build directory. It may have been " +
138+
"downloaded by NuGet restore.");
139+
140+
return true;
91141
})
92142
.ToArray();
93143

0 commit comments

Comments
 (0)