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
{