forked from dotnet/sdk
-
Notifications
You must be signed in to change notification settings - Fork 0
/
ApplyImplicitVersions.cs
98 lines (75 loc) · 4.14 KB
/
ApplyImplicitVersions.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
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using Microsoft.Build.Framework;
namespace Microsoft.NET.Build.Tasks
{
public sealed class ApplyImplicitVersions : TaskBase
{
public string TargetFrameworkVersion { get; set; }
public bool TargetLatestRuntimePatch { get; set; }
public ITaskItem[] PackageReferences { get; set; } = Array.Empty<ITaskItem>();
public ITaskItem[] ImplicitPackageReferenceVersions { get; set; } = Array.Empty<ITaskItem>();
[Output]
public ITaskItem[] PackageReferencesToUpdate { get; private set; }
// This task runs both before restore and build, so if it logged warnings directly they could show up
// twice when building with implicit restore. So instead we generate the warnings here, and keep them
// in an item where they'll be logged in a target that runs before build, but not before restore.
[Output]
public string[] SdkBuildWarnings { get; private set; }
protected override void ExecuteCore()
{
List<string> buildWarnings = new();
var packageReferencesToUpdate = new List<ITaskItem>();
var implicitVersionTable = GetApplicableImplicitVersionTable();
foreach (var packageReference in PackageReferences)
{
ImplicitPackageReferenceVersion implicitVersion;
if (implicitVersionTable.TryGetValue(packageReference.ItemSpec, out implicitVersion))
{
string versionOnPackageReference = packageReference.GetMetadata(MetadataKeys.Version);
if (string.IsNullOrEmpty(versionOnPackageReference))
{
packageReference.SetMetadata(MetadataKeys.Version,
TargetLatestRuntimePatch ? implicitVersion.LatestVersion : implicitVersion.DefaultVersion);
packageReference.SetMetadata(MetadataKeys.IsImplicitlyDefined, "true");
packageReferencesToUpdate.Add(packageReference);
}
else if (!(packageReference.GetBooleanMetadata(MetadataKeys.AllowExplicitVersion) ?? false))
{
// NETSDK1071: A PackageReference to '{0}' specified a Version of `{1}`. Specifying the version of this package is not recommended. For more information, see https://aka.ms/sdkimplicitrefs
buildWarnings.Add(string.Format(Strings.PackageReferenceVersionNotRecommended, packageReference.ItemSpec, versionOnPackageReference));
}
}
}
PackageReferencesToUpdate = packageReferencesToUpdate.ToArray();
SdkBuildWarnings = buildWarnings.ToArray();
}
private Dictionary<string, ImplicitPackageReferenceVersion> GetApplicableImplicitVersionTable()
{
var result = new Dictionary<string, ImplicitPackageReferenceVersion>();
foreach (var item in ImplicitPackageReferenceVersions)
{
var implicitPackageReferenceVersion = new ImplicitPackageReferenceVersion(item);
if (implicitPackageReferenceVersion.TargetFrameworkVersion == TargetFrameworkVersion)
{
result.Add(implicitPackageReferenceVersion.Name, implicitPackageReferenceVersion);
}
}
return result;
}
private sealed class ImplicitPackageReferenceVersion
{
private ITaskItem _item;
public ImplicitPackageReferenceVersion(ITaskItem item)
{
_item = item;
}
// The name / Package ID
public string Name => _item.ItemSpec;
// The target framework version that this item applies to
public string TargetFrameworkVersion => _item.GetMetadata("TargetFrameworkVersion");
public string DefaultVersion => _item.GetMetadata("DefaultVersion");
public string LatestVersion => _item.GetMetadata("LatestVersion");
}
}
}