Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
3 changes: 2 additions & 1 deletion src/Tasks/Common/ConflictResolution/ConflictItem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ internal enum ConflictItemType
Reference,
CopyLocal,
Runtime,
Platform
Platform,
Analyzer
}

internal interface IConflictItem
Expand Down
7 changes: 7 additions & 0 deletions src/Tasks/Common/ConflictResolution/FrameworkListReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,13 @@ private static IEnumerable<ConflictItem> LoadConflictItems(string frameworkListP
var ret = new List<ConflictItem>();
foreach (var file in frameworkList.Root.Elements("File"))
{
var type = file.Attribute("Type")?.Value;

if (type?.Equals("Analyzer", StringComparison.OrdinalIgnoreCase) ?? false)
{
continue;
}

var assemblyName = file.Attribute("AssemblyName")?.Value;
var assemblyVersionString = file.Attribute("Version")?.Value;

Expand Down
22 changes: 22 additions & 0 deletions src/Tasks/Common/ConflictResolution/ResolvePackageFileConflicts.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,15 @@ namespace Microsoft.NET.Build.Tasks.ConflictResolution
public class ResolvePackageFileConflicts : TaskWithAssemblyResolveHooks
{
private HashSet<ITaskItem> referenceConflicts = new HashSet<ITaskItem>();
private HashSet<ITaskItem> analyzerConflicts = new HashSet<ITaskItem>();
private HashSet<ITaskItem> copyLocalConflicts = new HashSet<ITaskItem>();
private HashSet<ConflictItem> compilePlatformWinners = new HashSet<ConflictItem>();
private HashSet<ConflictItem> allConflicts = new HashSet<ConflictItem>();

public ITaskItem[] References { get; set; }

public ITaskItem[] Analyzers { get; set; }

public ITaskItem[] ReferenceCopyLocalPaths { get; set; }

public ITaskItem[] OtherRuntimeItems { get; set; }
Expand Down Expand Up @@ -46,6 +49,10 @@ public class ResolvePackageFileConflicts : TaskWithAssemblyResolveHooks
[Output]
public ITaskItem[] ReferencesWithoutConflicts { get; set; }

[Output]
public ITaskItem[] AnalyzersWithoutConflicts { get; set; }


[Output]
public ITaskItem[] ReferenceCopyLocalPathsWithoutConflicts { get; set; }

Expand Down Expand Up @@ -90,6 +97,14 @@ protected override void ExecuteCore()
// Remove platform items which won a conflict with a reference but subsequently lost to something else
compilePlatformWinners.ExceptWith(allConflicts);

// resolve analyzer conflicts
var analyzerItems = GetConflictTaskItems(Analyzers, ConflictItemType.Analyzer).ToArray();

using (var analyzerConflictScope = new ConflictResolver<ConflictItem>(packageRanks, packageOverrides, log))
{
analyzerConflictScope.ResolveConflicts(analyzerItems, ci => ci.FileName, HandleAnalyzerConflict);
}

// resolve conflicts that clash in output
IEnumerable<ConflictItem> copyLocalItems;
IEnumerable<ConflictItem> otherRuntimeItems;
Expand Down Expand Up @@ -140,6 +155,7 @@ protected override void ExecuteCore()
}

ReferencesWithoutConflicts = RemoveConflicts(References, referenceConflicts);
AnalyzersWithoutConflicts = RemoveConflicts(Analyzers, analyzerConflicts);
ReferenceCopyLocalPathsWithoutConflicts = RemoveConflicts(ReferenceCopyLocalPaths, copyLocalConflicts);
Conflicts = CreateConflictTaskItems(allConflicts);

Expand Down Expand Up @@ -233,6 +249,12 @@ private void HandleCompileConflict(ConflictItem winner, ConflictItem loser)
allConflicts.Add(loser);
}

private void HandleAnalyzerConflict(ConflictItem winner, ConflictItem loser)
{
analyzerConflicts.Add(loser.OriginalItem);
allConflicts.Add(loser);
}

private void HandleRuntimeConflict(ConflictItem winner, ConflictItem loser)
{
if (loser.ItemType == ConflictItemType.Reference)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,23 @@ public void Given_ResolvedTargetingPacks_with_valid_PATH_in_PlatformManifest_It_
})
};

task.ProjectLanguage = "C#";

task.Execute().Should().BeTrue();

task.ReferencesToAdd[0].ItemSpec.Should().Be(Path.Combine(mockPackageDirectory, "lib/Microsoft.Windows.SDK.NET.dll"));
task.PlatformManifests[0].ItemSpec.Should().Be(Path.Combine(mockPackageDirectory, $"data{Path.DirectorySeparatorChar}PlatformManifest.txt"));
task.AnalyzersToAdd.Length.Should().Be(2);
task.AnalyzersToAdd[0].ItemSpec.Should().Be(Path.Combine(mockPackageDirectory, "analyzers/dotnet/anyAnalyzer.dll"));
task.AnalyzersToAdd[1].ItemSpec.Should().Be(Path.Combine(mockPackageDirectory, "analyzers/dotnet/cs/csAnalyzer.dll"));
}

private readonly string _frameworkList =
"<FileList Name=\"cswinrt .NET Core 5.0\"> <File Type=\"Managed\" Path=\"lib/Microsoft.Windows.SDK.NET.dll\" PublicKeyToken=\"null\" AssemblyName=\"Microsoft.Windows.SDK.NET\" AssemblyVersion=\"10.0.18362.3\" FileVersion=\"10.0.18362.3\" /></FileList>";
@"<FileList Name=""cswinrt .NET Core 5.0"">
<File Type=""Managed"" Path=""lib/Microsoft.Windows.SDK.NET.dll"" PublicKeyToken=""null"" AssemblyName=""Microsoft.Windows.SDK.NET"" AssemblyVersion=""10.0.18362.3"" FileVersion=""10.0.18362.3"" />
<File Type=""Analyzer"" Path=""analyzers/dotnet/anyAnalyzer.dll"" PublicKeyToken=""null"" AssemblyName=""anyAnalyzer"" AssemblyVersion=""10.0.18362.3"" FileVersion=""10.0.18362.3"" />
<File Type=""Analyzer"" Language=""cs"" Path=""analyzers/dotnet/cs/csAnalyzer.dll"" PublicKeyToken=""null"" AssemblyName=""csAnalyzer"" AssemblyVersion=""10.0.18362.3"" FileVersion=""10.0.18362.3"" />
<File Type=""Analyzer"" Language=""vb"" Path=""analyzers/dotnet/vb/vbAnalyzer.dll"" PublicKeyToken=""null"" AssemblyName=""vbAnalyzer"" AssemblyVersion=""10.0.18362.3"" FileVersion=""10.0.18362.3"" />
</FileList>";
}
}
58 changes: 45 additions & 13 deletions src/Tasks/Microsoft.NET.Build.Tasks/ResolveTargetingPackAssets.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,14 @@ public class ResolveTargetingPackAssets : TaskBase

public string NetCoreTargetingPackRoot { get; set; }

public string ProjectLanguage { get; set; }

[Output]
public ITaskItem[] ReferencesToAdd { get; set; }

[Output]
public ITaskItem[] AnalyzersToAdd { get; set; }

[Output]
public ITaskItem[] PlatformManifests { get; set; }

Expand All @@ -48,6 +53,7 @@ public ResolveTargetingPackAssets()
protected override void ExecuteCore()
{
List<TaskItem> referencesToAdd = new List<TaskItem>();
List<TaskItem> analyzersToAdd = new List<TaskItem>();
List<TaskItem> platformManifests = new List<TaskItem>();
PackageConflictPreferredPackages = string.Empty;
List<TaskItem> packageConflictOverrides = new List<TaskItem>();
Expand Down Expand Up @@ -123,8 +129,8 @@ protected override void ExecuteCore()

string frameworkListPath = Path.Combine(targetingPackDataPath, "FrameworkList.xml");

AddReferencesFromFrameworkList(frameworkListPath, targetingPackRoot, targetingPackDllFolder,
targetingPack, referencesToAdd);
AddItemsFromFrameworkList(frameworkListPath, targetingPackRoot, targetingPackDllFolder,
targetingPack, referencesToAdd, analyzersToAdd);

if (File.Exists(platformManifestPath))
{
Expand All @@ -148,7 +154,10 @@ protected override void ExecuteCore()

// Filter out duplicate references (which can happen when referencing two different profiles that overlap)
List<TaskItem> deduplicatedReferences = DeduplicateItems(referencesToAdd);
ReferencesToAdd = deduplicatedReferences.Distinct() .ToArray();
ReferencesToAdd = deduplicatedReferences.Distinct().ToArray();

List<TaskItem> deduplicatedAnalyzers = DeduplicateItems(analyzersToAdd);
AnalyzersToAdd = deduplicatedAnalyzers.Distinct().ToArray();

PlatformManifests = platformManifests.ToArray();
PackageConflictOverrides = packageConflictOverrides.ToArray();
Expand Down Expand Up @@ -184,7 +193,7 @@ private void AddNetStandardTargetingPackAssets(ITaskItem targetingPack, string t

foreach (var dll in Directory.GetFiles(targetingPackAssetPath, "*.dll"))
{
var reference = CreateReferenceItem(dll, targetingPack);
var reference = CreateItem(dll, targetingPack);

if (!Path.GetFileName(dll).Equals("netstandard.dll", StringComparison.OrdinalIgnoreCase))
{
Expand All @@ -195,9 +204,9 @@ private void AddNetStandardTargetingPackAssets(ITaskItem targetingPack, string t
}
}

private void AddReferencesFromFrameworkList(string frameworkListPath, string targetingPackRoot,
private void AddItemsFromFrameworkList(string frameworkListPath, string targetingPackRoot,
string targetingPackDllFolder,
ITaskItem targetingPack, List<TaskItem> referenceItems)
ITaskItem targetingPack, List<TaskItem> referenceItems, List<TaskItem> analyzerItems)
{
XDocument frameworkListDoc = XDocument.Load(frameworkListPath);

Expand Down Expand Up @@ -234,17 +243,40 @@ private void AddReferencesFromFrameworkList(string frameworkListPath, string tar
continue;
}

string dllPath = usePathElementsInFrameworkListAsFallBack ?
string itemType = fileElement.Attribute("Type")?.Value;
bool isAnalzer = itemType?.Equals("Analyzer", StringComparison.OrdinalIgnoreCase) ?? false;
Comment thread
ericstj marked this conversation as resolved.
Outdated

string dllPath = usePathElementsInFrameworkListAsFallBack || isAnalzer ?
Path.Combine(targetingPackRoot, fileElement.Attribute("Path").Value) :
GetDllPathViaAssemblyName(targetingPackDllFolder, fileElement);

var referenceItem = CreateReferenceItem(dllPath, targetingPack);
var item = CreateItem(dllPath, targetingPack);

referenceItem.SetMetadata("AssemblyVersion", fileElement.Attribute("AssemblyVersion").Value);
referenceItem.SetMetadata("FileVersion", fileElement.Attribute("FileVersion").Value);
referenceItem.SetMetadata("PublicKeyToken", fileElement.Attribute("PublicKeyToken").Value);
item.SetMetadata("AssemblyVersion", fileElement.Attribute("AssemblyVersion").Value);
item.SetMetadata("FileVersion", fileElement.Attribute("FileVersion").Value);
item.SetMetadata("PublicKeyToken", fileElement.Attribute("PublicKeyToken").Value);

if (isAnalzer)
{
string itemLanguage = fileElement.Attribute("Language")?.Value;

if (itemLanguage != null)
{
// expect cs instead of C#, fs rather than F# per NuGet conventions
string projectLanguage = ProjectLanguage?.Replace('#', 's');

referenceItems.Add(referenceItem);
if (projectLanguage == null || !projectLanguage.Equals(itemLanguage, StringComparison.OrdinalIgnoreCase))
{
continue;
}
}

analyzerItems.Add(item);
}
else
{
referenceItems.Add(item);
}
}
}

Expand Down Expand Up @@ -279,7 +311,7 @@ private static string GetDllPathViaAssemblyName(string targetingPackDllFolder, X
return dllPath;
}

private TaskItem CreateReferenceItem(string dll, ITaskItem targetingPack)
private TaskItem CreateItem(string dll, ITaskItem targetingPack)
{
var reference = new TaskItem(dll);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,15 @@ Copyright (c) .NET Foundation. All rights reserved.
</ItemGroup>

<ResolvePackageFileConflicts References="@(Reference)"
Analyzers="@(Analyzer)"
ReferenceCopyLocalPaths="@(ReferenceCopyLocalPaths)"
OtherRuntimeItems="@(_RuntimeAssetsForConflictResolution)"
PlatformManifests="@(PackageConflictPlatformManifests)"
TargetFrameworkDirectories="$(TargetFrameworkDirectory)"
PackageOverrides="@(PackageConflictOverrides)"
PreferredPackages="$(PackageConflictPreferredPackages)">
<Output TaskParameter="ReferencesWithoutConflicts" ItemName="_ReferencesWithoutConflicts" />
<Output TaskParameter="AnalyzersWithoutConflicts" ItemName="_AnalyzersWithoutConflicts" />
<Output TaskParameter="ReferenceCopyLocalPathsWithoutConflicts" ItemName="_ReferenceCopyLocalPathsWithoutConflicts" />
<Output TaskParameter="Conflicts" ItemName="_ConflictPackageFiles" />
</ResolvePackageFileConflicts>
Expand All @@ -56,6 +58,8 @@ Copyright (c) .NET Foundation. All rights reserved.
<ItemGroup>
<Reference Remove="@(Reference)" />
<Reference Include="@(_ReferencesWithoutConflicts)" />
<Analyzer Remove="@(Analyzer)" />
<Analyzer Include="@(_AnalyzersWithoutConflicts)" />
<ReferenceCopyLocalPaths Remove="@(ReferenceCopyLocalPaths)" />
<ReferenceCopyLocalPaths Include="@(_ReferenceCopyLocalPathsWithoutConflicts)" />
</ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -326,12 +326,14 @@ Copyright (c) .NET Foundation. All rights reserved.
</PropertyGroup>

<ResolveTargetingPackAssets FrameworkReferences="@(FrameworkReference)"
ProjectLanguage="$(Language)"
ResolvedTargetingPacks="@(ResolvedTargetingPack)"
RuntimeFrameworks="@(RuntimeFramework)"
GenerateErrorForMissingTargetingPacks="$(GenerateErrorForMissingTargetingPacks)"
NuGetRestoreSupported="$(_NuGetRestoreSupported)"
NetCoreTargetingPackRoot="$(NetCoreTargetingPackRoot)">
<Output TaskParameter="ReferencesToAdd" ItemName="Reference" />
<Output TaskParameter="AnalyzersToAdd" Condition="'$(DisableFrameworkReferenceAnalyzers)' != 'true'" ItemName="Analyzer" />
Comment thread
ericstj marked this conversation as resolved.
<Output TaskParameter="PlatformManifests" ItemName="PlatformManifestsFromTargetingPacks" />
<Output TaskParameter="PackageConflictPreferredPackages" PropertyName="PackageConflictPreferredPackages" />
<Output TaskParameter="PackageConflictOverrides" ItemName="PackageConflictOverrides" />
Expand Down