summaryrefslogtreecommitdiff
path: root/src/wix/WixToolset.BuildTasks/UpdateProjectReferenceMetadata.cs
diff options
context:
space:
mode:
Diffstat (limited to 'src/wix/WixToolset.BuildTasks/UpdateProjectReferenceMetadata.cs')
-rw-r--r--src/wix/WixToolset.BuildTasks/UpdateProjectReferenceMetadata.cs127
1 files changed, 114 insertions, 13 deletions
diff --git a/src/wix/WixToolset.BuildTasks/UpdateProjectReferenceMetadata.cs b/src/wix/WixToolset.BuildTasks/UpdateProjectReferenceMetadata.cs
index 4de948ba..c1ef45bc 100644
--- a/src/wix/WixToolset.BuildTasks/UpdateProjectReferenceMetadata.cs
+++ b/src/wix/WixToolset.BuildTasks/UpdateProjectReferenceMetadata.cs
@@ -5,6 +5,7 @@ namespace WixToolset.BuildTasks
5 using System; 5 using System;
6 using System.Collections.Generic; 6 using System.Collections.Generic;
7 using System.IO; 7 using System.IO;
8 using System.Linq;
8 using Microsoft.Build.Framework; 9 using Microsoft.Build.Framework;
9 using Microsoft.Build.Utilities; 10 using Microsoft.Build.Utilities;
10 11
@@ -13,6 +14,8 @@ namespace WixToolset.BuildTasks
13 /// </summary> 14 /// </summary>
14 public class UpdateProjectReferenceMetadata : Task 15 public class UpdateProjectReferenceMetadata : Task
15 { 16 {
17 private static readonly char[] TargetFrameworksSplitter = new char[] { ',', ';' };
18
16 /// <summary> 19 /// <summary>
17 /// The list of project references that exist. 20 /// The list of project references that exist.
18 /// </summary> 21 /// </summary>
@@ -26,40 +29,101 @@ namespace WixToolset.BuildTasks
26 public ITaskItem[] UpdatedProjectReferences { get; private set; } 29 public ITaskItem[] UpdatedProjectReferences { get; private set; }
27 30
28 /// <summary> 31 /// <summary>
29 /// Finds all project references requesting publishing and updates them to publish instead of build. 32 /// Finds all project references requesting publishing and updates them to publish instead of build and
33 /// sets target framework if requested.
30 /// </summary> 34 /// </summary>
31 /// <returns>True upon completion of the task execution.</returns> 35 /// <returns>True upon completion of the task execution.</returns>
32 public override bool Execute() 36 public override bool Execute()
33 { 37 {
34 var publishProjectReferences = new List<ITaskItem>(); 38 var updatedProjectReferences = new List<ITaskItem>();
35 var intermediateFolder = Path.GetFullPath(this.IntermediateFolder); 39 var intermediateFolder = Path.GetFullPath(this.IntermediateFolder);
36 40
37 foreach (var projectReference in this.ProjectReferences) 41 foreach (var projectReference in this.ProjectReferences)
38 { 42 {
39 var publish = projectReference.GetMetadata("Publish"); 43 var additionalProjectReferences = new List<ITaskItem>();
40 var publishDir = projectReference.GetMetadata("PublishDir"); 44
45 var updatedProjectReference = this.TrySetTargetFrameworksOnProjectReference(projectReference, additionalProjectReferences);
41 46
42 if (publish.Equals("true", StringComparison.OrdinalIgnoreCase) || 47 if (this.TryAddPublishPropertiesToProjectReference(projectReference, intermediateFolder))
43 (String.IsNullOrWhiteSpace(publish) && !String.IsNullOrWhiteSpace(publishDir)))
44 { 48 {
45 publishDir = String.IsNullOrWhiteSpace(publishDir) ? this.CalculatePublishDirFromProjectReference(projectReference, intermediateFolder) : Path.GetFullPath(publishDir); 49 foreach (var additionalProjectReference in additionalProjectReferences)
50 {
51 this.TryAddPublishPropertiesToProjectReference(additionalProjectReference, intermediateFolder);
52 }
46 53
47 this.AddPublishPropertiesToProjectReference(projectReference, publishDir); 54 updatedProjectReference = true;
55 }
48 56
49 publishProjectReferences.Add(projectReference); 57 if (updatedProjectReference)
58 {
59 updatedProjectReferences.Add(projectReference);
50 } 60 }
61
62 updatedProjectReferences.AddRange(additionalProjectReferences);
51 } 63 }
52 64
53 this.UpdatedProjectReferences = publishProjectReferences.ToArray(); 65 this.UpdatedProjectReferences = updatedProjectReferences.ToArray();
54 66
55 return true; 67 return true;
56 } 68 }
57 69
58 private string CalculatePublishDirFromProjectReference(ITaskItem projectReference, string intermediateFolder) 70 private bool TryAddPublishPropertiesToProjectReference(ITaskItem projectReference, string intermediateFolder)
59 { 71 {
60 var publishDir = Path.Combine("publish", Path.GetFileNameWithoutExtension(projectReference.ItemSpec)); 72 var publish = projectReference.GetMetadata("Publish");
73 var publishDir = projectReference.GetMetadata("PublishDir");
61 74
62 return Path.Combine(intermediateFolder, publishDir); 75 if (publish.Equals("true", StringComparison.OrdinalIgnoreCase) ||
76 (String.IsNullOrWhiteSpace(publish) && !String.IsNullOrWhiteSpace(publishDir)))
77 {
78 if (String.IsNullOrWhiteSpace(publishDir))
79 {
80 publishDir = CalculatePublishDirFromProjectReference(projectReference, intermediateFolder);
81 }
82
83 publishDir = AppendTargetFrameworkFromProjectReference(projectReference, publishDir);
84
85 publishDir = Path.GetFullPath(publishDir);
86
87 this.AddPublishPropertiesToProjectReference(projectReference, publishDir);
88
89 return true;
90 }
91
92 return false;
93 }
94
95 private bool TrySetTargetFrameworksOnProjectReference(ITaskItem projectReference, List<ITaskItem> additionalProjectReferences)
96 {
97 var setTargetFramework = projectReference.GetMetadata("SetTargetFramework");
98 var targetFrameworks = projectReference.GetMetadata("TargetFrameworks");
99 var targetFrameworksToSet = targetFrameworks.Split(TargetFrameworksSplitter).Where(s => !String.IsNullOrWhiteSpace(s)).ToList();
100
101 if (String.IsNullOrWhiteSpace(setTargetFramework) && targetFrameworksToSet.Count > 0)
102 {
103 // First, clone the project reference so there are enough duplicates for all of the
104 // requested target frameworks.
105 for (var i = 1; i < targetFrameworksToSet.Count; ++i)
106 {
107 additionalProjectReferences.Add(new TaskItem(projectReference));
108 }
109
110 // Then set the target framework on each project reference.
111 for (var i = 0; i < targetFrameworksToSet.Count; ++i)
112 {
113 var reference = (i == 0) ? projectReference : additionalProjectReferences[i - 1];
114
115 this.SetTargetFrameworkOnProjectReference(reference, targetFrameworksToSet[i]);
116 }
117
118 return true;
119 }
120
121 if (!String.IsNullOrWhiteSpace(setTargetFramework) && !String.IsNullOrWhiteSpace(targetFrameworks))
122 {
123 this.Log.LogWarning("ProjectReference {0} contains metadata for both SetTargetFramework and TargetFrameworks. SetTargetFramework takes precedent so the TargetFrameworks value '{1}' is ignored", projectReference.ItemSpec, targetFrameworks);
124 }
125
126 return false;
63 } 127 }
64 128
65 private void AddPublishPropertiesToProjectReference(ITaskItem projectReference, string publishDir) 129 private void AddPublishPropertiesToProjectReference(ITaskItem projectReference, string publishDir)
@@ -91,5 +155,42 @@ namespace WixToolset.BuildTasks
91 this.Log.LogMessage(MessageImportance.Low, "Adding publish metadata to project reference {0} Targets {1}, BindPath {2}, AdditionalProperties: {3}", 155 this.Log.LogMessage(MessageImportance.Low, "Adding publish metadata to project reference {0} Targets {1}, BindPath {2}, AdditionalProperties: {3}",
92 projectReference.ItemSpec, projectReference.GetMetadata("Targets"), projectReference.GetMetadata("BindPath"), projectReference.GetMetadata("AdditionalProperties")); 156 projectReference.ItemSpec, projectReference.GetMetadata("Targets"), projectReference.GetMetadata("BindPath"), projectReference.GetMetadata("AdditionalProperties"));
93 } 157 }
158
159 private void SetTargetFrameworkOnProjectReference(ITaskItem projectReference, string targetFramework)
160 {
161 projectReference.SetMetadata("SetTargetFramework", $"TargetFramework={targetFramework}");
162
163 var bindName = projectReference.GetMetadata("BindName");
164 if (String.IsNullOrWhiteSpace(bindName))
165 {
166 bindName = Path.GetFileNameWithoutExtension(projectReference.ItemSpec);
167
168 projectReference.SetMetadata("BindName", $"{bindName}.{targetFramework}");
169 }
170
171 this.Log.LogMessage(MessageImportance.Low, "Adding target framework metadata to project reference {0} SetTargetFramework: {1}, BindName: {2}",
172 projectReference.ItemSpec, projectReference.GetMetadata("SetTargetFramework"), projectReference.GetMetadata("BindName"));
173 }
174
175 private static string CalculatePublishDirFromProjectReference(ITaskItem projectReference, string intermediateFolder)
176 {
177 var publishDir = Path.Combine("publish", Path.GetFileNameWithoutExtension(projectReference.ItemSpec));
178
179 return Path.Combine(intermediateFolder, publishDir);
180 }
181
182 private static string AppendTargetFrameworkFromProjectReference(ITaskItem projectReference, string publishDir)
183 {
184 var setTargetFramework = projectReference.GetMetadata("SetTargetFramework");
185
186 if (setTargetFramework.StartsWith("TargetFramework=") && setTargetFramework.Length > "TargetFramework=".Length)
187 {
188 var targetFramework = setTargetFramework.Substring("TargetFramework=".Length);
189
190 publishDir = Path.Combine(publishDir, targetFramework);
191 }
192
193 return publishDir;
194 }
94 } 195 }
95} 196}