Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 14 additions & 2 deletions src/Package/build/ReferenceTrimmer.targets
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,21 @@
<ItemGroup>
<!-- https://github.com/dotnet/roslyn/blob/main/docs/analyzers/Using%20Additional%20Files.md#in-a-project-file -->
<AdditionalFiles Include="$(_ReferenceTrimmerDeclaredReferencesFile)" />
<EmbedInBinlog Include="$(_ReferenceTrimmerDeclaredReferencesFile)" />
<FileWrites Include="$(_ReferenceTrimmerDeclaredReferencesFile)" />
<FileWrites Include="$(_ReferenceTrimmerUsedReferencesFile)" Condition="'$(EnableReferenceTrimmerDiagnostics)'=='true'" />
<FileWrites Include="$(_ReferenceTrimmerUnusedReferencesFile)" Condition="'$(EnableReferenceTrimmerDiagnostics)'=='true'" />
</ItemGroup>
</Target>

<Target Name="_EmbedReferenceTrimmerDiagnosticsInBinlog"
AfterTargets="CoreCompile"
Condition="'$(EnableReferenceTrimmer)' != 'false' and '$(EnableReferenceTrimmerDiagnostics)' == 'true'">
<ItemGroup Condition="Exists('$(_ReferenceTrimmerUsedReferencesFile)')">
<EmbedInBinlog Include="$(_ReferenceTrimmerUsedReferencesFile)" />
<FileWrites Include="$(_ReferenceTrimmerUsedReferencesFile)" />
</ItemGroup>
<ItemGroup Condition="Exists('$(_ReferenceTrimmerUnusedReferencesFile)')">
<EmbedInBinlog Include="$(_ReferenceTrimmerUnusedReferencesFile)" />
<FileWrites Include="$(_ReferenceTrimmerUnusedReferencesFile)" />
</ItemGroup>
</Target>
</Project>
47 changes: 47 additions & 0 deletions src/Tasks/CollectDeclaredReferencesTask.cs
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ public override bool Execute()
// Ignore implicitly defined references (references which are SDK-provided)
if (reference.GetMetadata("IsImplicitlyDefined").Equals("true", StringComparison.OrdinalIgnoreCase))
{
Log.LogMessage(MessageImportance.Low, "Skipping Reference '{0}' because it is implicitly defined (SDK-provided)", reference.ItemSpec);
continue;
}

Expand All @@ -79,18 +80,21 @@ public override bool Execute()
// so the resulting reference would be unavoidable.
if (targetFrameworkAssemblies.Contains(reference.ItemSpec))
{
Log.LogMessage(MessageImportance.Low, "Skipping Reference '{0}' because it is a target framework assembly", reference.ItemSpec);
continue;
}

// Ignore references from packages. Those as handled later.
if (reference.GetMetadata("NuGetPackageId").Length != 0)
{
// Logs will be emitted for these references when processing the PackageReferences
continue;
}

// Ignore suppressions
if (IsSuppressed(reference, "RT0001"))
{
Log.LogMessage(MessageImportance.Low, "Skipping Reference '{0}' because it is suppressed via NoWarn=\"RT0001\" or <TreatAsUsed>", reference.ItemSpec);
continue;
}

Expand All @@ -117,6 +121,7 @@ public override bool Execute()
{
if (referencePath.StartsWith(NuGetPackageRoot, StringComparison.OrdinalIgnoreCase))
{
Log.LogMessage(MessageImportance.Low, "Skipping Reference '{0}' because its resolved path '{1}' is under the NuGet package root (likely added by a package's props/targets)", referenceSpec, referencePath);
continue;
}
}
Expand All @@ -127,6 +132,10 @@ public override bool Execute()
}
}
}
else
{
Log.LogMessage(MessageImportance.Low, "No References to process");
}

if (ProjectReferences != null)
{
Expand All @@ -135,6 +144,7 @@ public override bool Execute()
// Ignore suppressions
if (IsSuppressed(projectReference, "RT0002"))
{
Log.LogMessage(MessageImportance.Low, "Skipping ProjectReference '{0}' because it is suppressed via NoWarn=\"RT0002\" or <TreatAsUsed>", projectReference.ItemSpec);
continue;
}

Expand All @@ -154,6 +164,10 @@ public override bool Execute()
declaredReferences.Add(new DeclaredReference(projectReferenceAssemblyPath, DeclaredReferenceKind.ProjectReference, referenceProjectFile));
}
}
else
{
Log.LogMessage(MessageImportance.Low, "No ProjectReferences to process");
}

if (PackageReferences != null)
{
Expand All @@ -163,17 +177,24 @@ public override bool Execute()
// Ignore suppressions
if (IsSuppressed(packageReference, "RT0003"))
{
Log.LogMessage(MessageImportance.Low, "Skipping PackageReference '{0}' because it is suppressed via NoWarn=\"RT0003\" or <TreatAsUsed>", packageReference.ItemSpec);
continue;
}

if (!packageInfos.TryGetValue(packageReference.ItemSpec, out PackageInfo packageInfo))
{
// These are likely Analyzers, tools, etc.
Log.LogMessage(MessageImportance.Low, "Skipping PackageReference '{0}' because it has no compile-time assemblies (likely an Analyzer, tool, or content-only package)", packageReference.ItemSpec);
continue;
}

if (packageInfo.BuildFiles.Count > 0)
{
Log.LogMessage(MessageImportance.Low, "Skipping PackageReference '{0}' because it has build {1} file(s):", packageReference.ItemSpec, packageInfo.BuildFiles.Count);
foreach (string buildFile in packageInfo.BuildFiles)
{
Log.LogMessage(MessageImportance.Low, " Build file: '{0}'", buildFile);
}
continue;
}

Expand All @@ -183,10 +204,15 @@ public override bool Execute()
}
}
}
else
{
Log.LogMessage(MessageImportance.Low, "No PackageReferences to process");
}

if (OutputFile is not null)
{
new DeclaredReferences(declaredReferences).SaveToFile(OutputFile);
Log.LogMessage(MessageImportance.Low, "Saved {0} declared references to '{1}'", declaredReferences.Count, OutputFile);
}
}
finally
Expand All @@ -201,14 +227,17 @@ private Dictionary<string, PackageInfo> GetPackageInfos()
{
var packageInfoBuilders = new Dictionary<string, PackageInfoBuilder>(StringComparer.OrdinalIgnoreCase);

Log.LogMessage(MessageImportance.Low, "Loading lock file from '{0}'", ProjectAssetsFile);
var lockFile = LockFileUtilities.GetLockFile(ProjectAssetsFile, NullLogger.Instance);
var packageFolders = lockFile.PackageFolders.Select(item => item.Path).ToList();
Log.LogMessage(MessageImportance.Low, "Package folders: {0}", string.Join("; ", packageFolders));

LockFileTarget? nugetTarget = null;
if (!string.IsNullOrEmpty(TargetFrameworkMoniker))
{
var nugetFramework = NuGetFramework.ParseComponents(TargetFrameworkMoniker!, TargetPlatformMoniker);
nugetTarget = lockFile.GetTarget(nugetFramework, RuntimeIdentifier);
Log.LogMessage(MessageImportance.Low, "Resolved NuGet target framework: '{0}'", nugetFramework);
}

List<LockFileTargetLibrary> nugetLibraries;
Expand All @@ -217,10 +246,12 @@ private Dictionary<string, PackageInfo> GetPackageInfos()
nugetLibraries = nugetTarget.Libraries
.Where(nugetLibrary => string.Equals(nugetLibrary.Type, "Package", StringComparison.OrdinalIgnoreCase))
.ToList();
Log.LogMessage(MessageImportance.Low, "Found {0} NuGet package library(ies) in lock file target", nugetLibraries.Count);
}
else
{
nugetLibraries = new List<LockFileTargetLibrary>();
Log.LogMessage(MessageImportance.Low, "No NuGet target libraries found in lock file");
}

// Compute the hierarchy of packages.
Expand Down Expand Up @@ -268,6 +299,7 @@ private Dictionary<string, PackageInfo> GetPackageInfos()
{
// This can happen if the project has a stale lock file.
// Just ignore it as NuGet itself will likely error.
Log.LogMessage(MessageImportance.Low, "Package '{0}' could not be found in any package folder (stale lock file?). Skipping.", nugetLibrary.Name);
continue;
}

Expand All @@ -289,6 +321,14 @@ private Dictionary<string, PackageInfo> GetPackageInfos()
.Select(path => Path.Combine(nugetLibraryAbsolutePath, path))
.ToList();

if (packageToIgnoreBuildFiles.Contains(nugetLibrary.Name) && nugetLibrary.Build.Count > 0)
{
Log.LogMessage(MessageImportance.Low, "Package '{0}' has {1} build file(s) but they are ignored via IgnorePackageBuildFiles", nugetLibrary.Name, nugetLibrary.Build.Count);
}

Log.LogMessage(MessageImportance.Low, "Package '{0}' v{1}: {2} compile-time assembly(ies), {3} build file(s)",
nugetLibrary.Name, nugetLibrary.Version, nugetLibraryAssemblies.Count, buildFiles.Count);

// Add this package's assets, if there are any
if (nugetLibraryAssemblies.Count > 0 || buildFiles.Count > 0)
{
Expand Down Expand Up @@ -344,11 +384,13 @@ private HashSet<string> GetTargetFrameworkAssemblyNames()
// See: https://github.com/dotnet/sdk/blob/main/src/Tasks/Common/ConflictResolution/FrameworkListReader.cs
if (TargetFrameworkDirectories != null)
{
Log.LogMessage(MessageImportance.Low, "Scanning {0} TargetFrameworkDirectory(ies) for framework assemblies", TargetFrameworkDirectories.Length);
foreach (ITaskItem targetFrameworkDirectory in TargetFrameworkDirectories)
{
string frameworkListPath = Path.Combine(targetFrameworkDirectory.ItemSpec, "RedistList", "FrameworkList.xml");
if (!File.Exists(frameworkListPath))
{
Log.LogMessage(MessageImportance.Low, "FrameworkList.xml not found at '{0}'", frameworkListPath);
continue;
}

Expand Down Expand Up @@ -388,8 +430,13 @@ private HashSet<string> GetTargetFrameworkAssemblyNames()
string nugetProjectModelFile = Path.Combine(Path.GetDirectoryName(NuGetRestoreTargets)!, assemblyName.Name + ".dll");
if (File.Exists(nugetProjectModelFile))
{
Log.LogMessage(MessageImportance.Low, "Resolved assembly '{0}' from '{1}'", assemblyName.Name, nugetProjectModelFile);
return Assembly.LoadFrom(nugetProjectModelFile);
}
else
{
Log.LogMessage(MessageImportance.Low, "Could not resolve assembly '{0}' - file not found at '{1}'", assemblyName.Name, nugetProjectModelFile);
}
}

return null;
Expand Down