-
Notifications
You must be signed in to change notification settings - Fork 1.1k
/
MergeConfigurationProperties.cs
130 lines (108 loc) · 6.8 KB
/
MergeConfigurationProperties.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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System.Text.RegularExpressions;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
namespace Microsoft.AspNetCore.StaticWebAssets.Tasks
{
public class MergeConfigurationProperties : Task
{
[Required]
public ITaskItem[] CandidateConfigurations { get; set; }
[Required]
public ITaskItem[] ProjectReferences { get; set; }
[Output]
public ITaskItem[] ProjectConfigurations { get; set; }
public override bool Execute()
{
try
{
ProjectConfigurations = new TaskItem[CandidateConfigurations.Length];
for (var i = 0; i < CandidateConfigurations.Length; i++)
{
var configuration = CandidateConfigurations[i];
var foundProjectReference = FindMatchingProject(configuration);
if (foundProjectReference == null)
{
Log.LogError(
"Unable to find a project reference for project configuration item '{0}'",
configuration.ItemSpec);
return false;
}
var entry = new TaskItem(configuration.ItemSpec, new Dictionary<string, string>
{
["Version"] = configuration.GetMetadata(nameof(StaticWebAssetsManifest.ReferencedProjectConfiguration.Version)),
["Source"] = configuration.GetMetadata(nameof(StaticWebAssetsManifest.ReferencedProjectConfiguration.Source)),
["GetBuildAssetsTargets"] = configuration.GetMetadata(nameof(StaticWebAssetsManifest.ReferencedProjectConfiguration.GetBuildAssetsTargets)),
["AdditionalBuildProperties"] = configuration.GetMetadata(nameof(StaticWebAssetsManifest.ReferencedProjectConfiguration.AdditionalBuildProperties)),
["AdditionalBuildPropertiesToRemove"] = configuration.GetMetadata(nameof(StaticWebAssetsManifest.ReferencedProjectConfiguration.AdditionalBuildPropertiesToRemove)),
["GetPublishAssetsTargets"] = configuration.GetMetadata(nameof(StaticWebAssetsManifest.ReferencedProjectConfiguration.GetPublishAssetsTargets)),
["AdditionalPublishProperties"] = configuration.GetMetadata(nameof(StaticWebAssetsManifest.ReferencedProjectConfiguration.AdditionalPublishProperties)),
["AdditionalPublishPropertiesToRemove"] = configuration.GetMetadata(nameof(StaticWebAssetsManifest.ReferencedProjectConfiguration.AdditionalPublishPropertiesToRemove)),
});
var additionalBuildProperties = string.Join(
";", configuration.GetMetadata("AdditionalBuildProperties"),
foundProjectReference.GetMetadata("SetConfiguration"),
foundProjectReference.GetMetadata("SetPlatform"),
foundProjectReference.GetMetadata("SetTargetFramework"));
CleanupMetadata(entry, "AdditionalBuildProperties", additionalBuildProperties);
var buildPropertiesToRemove = string.Join(
";", configuration.GetMetadata("AdditionalBuildPropertiesToRemove"),
foundProjectReference.GetMetadata("GlobalPropertiesToRemove"),
foundProjectReference.GetMetadata("UndefineProperties"));
CleanupMetadata(entry, "AdditionalBuildPropertiesToRemove", buildPropertiesToRemove);
var additionalPublishProperties = string.Join(
";", configuration.GetMetadata("AdditionalPublishProperties"),
foundProjectReference.GetMetadata("SetConfiguration"),
foundProjectReference.GetMetadata("SetPlatform"),
foundProjectReference.GetMetadata("SetTargetFramework"));
CleanupMetadata(entry, "AdditionalPublishProperties", additionalPublishProperties);
var publishPropertiesToRemove = string.Join(
";", configuration.GetMetadata("AdditionalPublishPropertiesToRemove"),
foundProjectReference.GetMetadata("GlobalPropertiesToRemove"),
foundProjectReference.GetMetadata("UndefineProperties"));
CleanupMetadata(entry, "AdditionalPublishPropertiesToRemove", publishPropertiesToRemove);
ProjectConfigurations[i] = entry;
}
}
catch (Exception ex)
{
Log.LogErrorFromException(ex, showStackTrace: true, showDetail: true, file: null);
}
return !Log.HasLoggedErrors;
static void CleanupMetadata(TaskItem entry, string metadataName, string metadataValue)
{
metadataValue = Regex.Replace(metadataValue, ";{2,}", ";");
metadataValue = metadataValue.Trim(';');
entry.SetMetadata(metadataName, metadataValue);
}
}
private ITaskItem FindMatchingProject(ITaskItem configuration)
{
for (var j = 0; j < ProjectReferences.Length; j++)
{
var projectReference = ProjectReferences[j];
var referenceMetadata = projectReference.GetMetadata("MSBuildSourceProjectFile");
// All project references should define MSBuildSourceProjectFile but in the ASP.NET Core some special (malformed) references do not.
// We can be more lenient here and fallback to the project reference ItemSpec if not present.
referenceMetadata = !string.IsNullOrEmpty(referenceMetadata) ? referenceMetadata : projectReference.ItemSpec;
var configurationFullPath = configuration.GetMetadata("FullPath");
var projectReferenceFullPath = Path.GetFullPath(referenceMetadata);
var matchPath = string.Equals(
configurationFullPath,
projectReferenceFullPath,
OSPath.PathComparison);
if (matchPath)
{
Log.LogMessage(MessageImportance.Low, "Found project reference '{0}' for configuration item '{1}'.", configurationFullPath, projectReferenceFullPath);
return projectReference;
}
else
{
Log.LogMessage(MessageImportance.Low, "Rejected project reference '{0}' for configuration item '{1}' because paths don't match.", configurationFullPath, projectReferenceFullPath);
}
}
return null;
}
}
}