-
Notifications
You must be signed in to change notification settings - Fork 1.1k
/
Copy pathFrameworkListReader.cs
109 lines (88 loc) · 4.3 KB
/
FrameworkListReader.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System.Globalization;
using System.Reflection;
using Microsoft.Build.Framework;
namespace Microsoft.NET.Build.Tasks.ConflictResolution
{
class FrameworkListReader
{
private IBuildEngine4 _buildEngine;
public FrameworkListReader(IBuildEngine4 buildEngine)
{
_buildEngine = buildEngine;
}
public IEnumerable<ConflictItem> GetConflictItems(string frameworkListPath, Logger log)
{
if (frameworkListPath == null)
{
throw new ArgumentNullException(nameof(frameworkListPath));
}
if (!Path.IsPathRooted(frameworkListPath))
{
throw new BuildErrorException(Strings.FrameworkListPathNotRooted, frameworkListPath);
}
// Need to include assembly name in the key here, since both Microsoft.NET.Build.Tasks and Microsoft.NET.Build.Extensions.Tasks share this code,
// but can't share the types of the ConflictItem objects.
string? assemblyName = typeof(FrameworkListReader).GetTypeInfo().Assembly.FullName;
string objectKey = $"{assemblyName}:{nameof(FrameworkListReader)}:{frameworkListPath}";
IEnumerable<ConflictItem> result;
object existingConflictItems = _buildEngine.GetRegisteredTaskObject(objectKey, RegisteredTaskObjectLifetime.AppDomain);
if (existingConflictItems == null)
{
result = LoadConflictItems(frameworkListPath, log);
_buildEngine.RegisterTaskObject(objectKey, result, RegisteredTaskObjectLifetime.AppDomain, true);
}
else
{
result = (IEnumerable<ConflictItem>)existingConflictItems;
}
return result;
}
private static IEnumerable<ConflictItem> LoadConflictItems(string frameworkListPath, Logger log)
{
if (!File.Exists(frameworkListPath))
{
// This is not an error, as we get both the root target framework directory as well as the Facades folder passed in as TargetFrameworkDirectories.
// Only the root will have a RedistList\FrameworkList.xml in it
return Enumerable.Empty<ConflictItem>();
}
var frameworkList = XDocument.Load(frameworkListPath);
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;
if (string.IsNullOrEmpty(assemblyName))
{
string errorMessage = string.Format(CultureInfo.CurrentCulture, Strings.ErrorParsingFrameworkListInvalidValue,
frameworkListPath,
"AssemblyName",
assemblyName);
log.LogError(errorMessage);
return Enumerable.Empty<ConflictItem>();
}
Version? assemblyVersion;
if (string.IsNullOrEmpty(assemblyVersionString) || !Version.TryParse(assemblyVersionString, out assemblyVersion))
{
string errorMessage = string.Format(CultureInfo.CurrentCulture, Strings.ErrorParsingFrameworkListInvalidValue,
frameworkListPath,
"Version",
assemblyVersionString);
log.LogError(errorMessage);
return Enumerable.Empty<ConflictItem>();
}
ret.Add(new ConflictItem(assemblyName + ".dll",
packageId: "TargetingPack",
assemblyVersion: assemblyVersion,
fileVersion: null));
}
return ret;
}
}
}