@joebigelow / wix / commits / 4442f947

Push TARGETDIR down to child Components

Fixes 7340

Rob Mensching committed Apr 4, 2023 at 01:15 UTC 4442f9473ac50ae8337ea053e4810ddcb128cbf2
2 files changed +92 -3
src/wix/WixToolset.Converters/WixConverter.cs
+15 -2
@@ -1118,6 +1118,8 @@ namespace WixToolset.Converters
1118 {
1119 if (this.OnInformation(ConverterTestType.TargetDirDeprecated, element, "The TARGETDIR directory should no longer be explicitly defined. Remove the Directory element with Id attribute 'TARGETDIR'."))
1120 {
1121 + AddTargetDirDirectoryAttributeToComponents(element);
1122 +
1123 RemoveElementKeepChildren(element);
1124 }
1125 }
@@ -1143,9 +1145,11 @@ namespace WixToolset.Converters
1145 {
1146 if (this.OnInformation(ConverterTestType.StandardDirectoryRefDeprecated, element, "The {0} directory should no longer be explicitly referenced. Remove the DirectoryRef element with Id attribute '{0}'.", id))
1147 {
1148 + AddTargetDirDirectoryAttributeToComponents(element);
1149 +
1150 RemoveElementKeepChildren(element);
1151
1148 - this.OnError(ConverterTestType.TargetDirRefRemoved, element, "A reference to the TARGETDIR Directory was removed. This may cause the Fragment that defined TARGETDIR to not be included in the final output. If this happens, reference a different element in the Fragment to replace the old reference to TARGEDIR.");
1152 + this.OnError(ConverterTestType.TargetDirRefRemoved, element, "A reference to the TARGETDIR Directory was removed. This can cause unintended side effects. See the conversion FAQ for more information: https://wixtoolset.org/docs/fourthree/faqs/#converting-packages");
1153 }
1154 }
1155 else if (this.OnInformation(ConverterTestType.StandardDirectoryRefDeprecated, element, "The standard directory '{0}' should no longer be directly referenced. Use the StandardDirectory element instead.", id))
@@ -2810,6 +2814,15 @@ namespace WixToolset.Converters
2814 return value;
2815 }
2816
2817 + private static void AddTargetDirDirectoryAttributeToComponents(XElement element)
2818 + {
2819 + // Move the TARGETDIR reference to the Component Directory attribute
2820 + foreach (var xComponent in element.Elements(ComponentElementName).Where(x => x.Attribute("Directory") is null))
2821 + {
2822 + xComponent.Add(new XAttribute("Directory", "TARGETDIR"));
2823 + }
2824 + }
2825 +
2826 private static void RemoveElementKeepChildren(XElement element)
2827 {
2828 var parentElement = element.Parent;
@@ -3317,7 +3330,7 @@ namespace WixToolset.Converters
3330 WixMbaPrereqPackageIdDeprecated,
3331
3332 /// <summary>
3320 - /// A reference to the TARGETDIR Directory was removed. This may cause the Fragment that defined TARGETDIR to not be included in the final output. If this happens, reference a different element in the Fragment to replace the old reference to TARGEDIR.
3333 + /// A reference to the TARGETDIR Directory was removed. This can cause unintended side effects. See the conversion FAQ for more information: https://wixtoolset.org/docs/fourthree/faqs/#converting-packages
3334 /// </summary>
3335 TargetDirRefRemoved,
3336
src/wix/test/WixToolsetTest.Converters/DirectoryFixture.cs
+77 -1
@@ -94,7 +94,7 @@ namespace WixToolsetTest.Converters
94 "[Converted] This file contains an XML declaration on the first line. (DeclarationPresent)",
95 "[Converted] The namespace 'http://schemas.microsoft.com/wix/2006/wi' is out of date. It must be 'http://wixtoolset.org/schemas/v4/wxs'. (XmlnsValueWrong)",
96 "[Converted] The TARGETDIR directory should no longer be explicitly referenced. Remove the DirectoryRef element with Id attribute 'TARGETDIR'. (StandardDirectoryRefDeprecated)",
97 - "A reference to the TARGETDIR Directory was removed. This may cause the Fragment that defined TARGETDIR to not be included in the final output. If this happens, reference a different element in the Fragment to replace the old reference to TARGEDIR. (TargetDirRefRemoved)",
97 + "A reference to the TARGETDIR Directory was removed. This can cause unintended side effects. See the conversion FAQ for more information: https://wixtoolset.org/docs/fourthree/faqs/#converting-packages (TargetDirRefRemoved)",
98 }, messaging.Messages.Select(m => m.ToString()).ToArray());
99 Assert.Equal(4, errors);
100 }
@@ -211,6 +211,82 @@ namespace WixToolsetTest.Converters
211 Assert.Equal(5, errors);
212 }
213
214 + [Fact]
215 + public void RemoveTargetDirWithComponents()
216 + {
217 + var parse = String.Join(Environment.NewLine,
218 + "<?xml version=\"1.0\" encoding=\"utf-16\"?>",
219 + "<Wix xmlns='http://schemas.microsoft.com/wix/2006/wi'>",
220 + " <Fragment>",
221 + " <DirectoryRef Id='TARGETDIR'>",
222 + " <Component Id='C1'>",
223 + " <File Source='c1.txt' />",
224 + " </Component>",
225 + " <Component Id='C2'>",
226 + " <File Source='c2.txt' />",
227 + " </Component>",
228 + " </DirectoryRef>",
229 + " </Fragment>",
230 + " <Fragment>",
231 + " <Directory Id='TARGETDIR'>",
232 + " <Component Id='C3'>",
233 + " <File Source='c3.txt' />",
234 + " </Component>",
235 + " <Component Id='C4' Directory='PreExisting'>",
236 + " <File Source='c4.txt' />",
237 + " </Component>",
238 + " </Directory>",
239 + " </Fragment>",
240 + "</Wix>");
241 +
242 + var expected = new[]
243 + {
244 + "<Wix xmlns=\"http://wixtoolset.org/schemas/v4/wxs\">",
245 + " <Fragment>",
246 + " <Component Id=\"C1\" Directory=\"TARGETDIR\">",
247 + " <File Id=\"c1.txt\" Source=\"c1.txt\" />",
248 + " </Component>",
249 + " <Component Id=\"C2\" Directory=\"TARGETDIR\">",
250 + " <File Id=\"c2.txt\" Source=\"c2.txt\" />",
251 + " </Component>",
252 + " </Fragment>",
253 + " <Fragment>",
254 + " <Component Id=\"C3\" Directory=\"TARGETDIR\">",
255 + " <File Id=\"c3.txt\" Source=\"c3.txt\" />",
256 + " </Component>",
257 + " <Component Id=\"C4\" Directory=\"PreExisting\">",
258 + " <File Id=\"c4.txt\" Source=\"c4.txt\" />",
259 + " </Component>",
260 + " </Fragment>",
261 + "</Wix>"
262 + };
263 +
264 + var document = XDocument.Parse(parse, LoadOptions.PreserveWhitespace | LoadOptions.SetLineInfo);
265 +
266 + var messaging = new MockMessaging();
267 + var converter = new WixConverter(messaging, 2, null, null);
268 +
269 + var errors = converter.ConvertDocument(document);
270 +
271 + var actualLines = UnformattedDocumentLines(document);
272 + WixAssert.CompareLineByLine(expected, actualLines);
273 +
274 + WixAssert.CompareLineByLine(new[]
275 + {
276 + "[Converted] This file contains an XML declaration on the first line. (DeclarationPresent)",
277 + "[Converted] The namespace 'http://schemas.microsoft.com/wix/2006/wi' is out of date. It must be 'http://wixtoolset.org/schemas/v4/wxs'. (XmlnsValueWrong)",
278 + "[Converted] The TARGETDIR directory should no longer be explicitly referenced. Remove the DirectoryRef element with Id attribute 'TARGETDIR'. (StandardDirectoryRefDeprecated)",
279 + "A reference to the TARGETDIR Directory was removed. This can cause unintended side effects. See the conversion FAQ for more information: https://wixtoolset.org/docs/fourthree/faqs/#converting-packages (TargetDirRefRemoved)",
280 + "[Converted] The file id is being updated to 'c1.txt' to ensure it remains the same as the v3 default (AssignAnonymousFileId)",
281 + "[Converted] The file id is being updated to 'c2.txt' to ensure it remains the same as the v3 default (AssignAnonymousFileId)",
282 + "[Converted] The TARGETDIR directory should no longer be explicitly defined. Remove the Directory element with Id attribute 'TARGETDIR'. (TargetDirDeprecated)",
283 + "[Converted] The file id is being updated to 'c3.txt' to ensure it remains the same as the v3 default (AssignAnonymousFileId)",
284 + "[Converted] The file id is being updated to 'c4.txt' to ensure it remains the same as the v3 default (AssignAnonymousFileId)"
285 + }, messaging.Messages.Select(m => m.ToString()).ToArray());
286 +
287 + Assert.Equal(9, errors);
288 + }
289 +
290 [Fact]
291 public void ErrorOnEmptyStandardDirectoryRef()
292 {