Add StandardDirectory conversions
Completes wixtoolset/issues#6416
Rob Mensching committed
Apr 6, 2021 at 13:30 UTC
5df3b188583697ca6f3910224e2135e8bacc56f0
2 files changed
+154
-1
src/WixToolset.Converters/WixConverter.cs
+62
-1
@@ -12,6 +12,7 @@ namespace WixToolset.Converters
12
using System.Xml;
13
using System.Xml.Linq;
14
using WixToolset.Data;
15
+ using WixToolset.Data.WindowsInstaller;
16
using WixToolset.Extensibility.Services;
17
18
/// <summary>
@@ -120,6 +121,7 @@ namespace WixToolset.Converters
121
private static readonly XName ShortcutPropertyElementName = WixNamespace + "ShortcutProperty";
122
private static readonly XName SoftwareTagElementName = WixNamespace + "SoftwareTag";
123
private static readonly XName SoftwareTagRefElementName = WixNamespace + "SoftwareTagRef";
124
+ private static readonly XName StandardDirectoryElementName = WixNamespace + "StandardDirectory";
125
private static readonly XName TagElementName = XNamespace.None + "Tag";
126
private static readonly XName TagRefElementName = XNamespace.None + "TagRef";
127
private static readonly XName TextElementName = WixNamespace + "Text";
@@ -468,7 +470,18 @@ namespace WixToolset.Converters
470
{
471
this.ConvertElement(element);
472
471
- this.ConvertNodes(element.Nodes(), level + 1);
473
+ var before = element.Nodes().ToList();
474
+
475
+ this.ConvertNodes(before, level + 1);
476
+
477
+ // If any nodes were added during the processing of the children,
478
+ // ensure those added children get processed as well.
479
+ var added = element.Nodes().Except(before).ToList();
480
+
481
+ if (added.Any())
482
+ {
483
+ this.ConvertNodes(added, level + 1);
484
+ }
485
}
486
}
487
}
@@ -950,6 +963,44 @@ namespace WixToolset.Converters
963
}
964
}
965
}
966
+
967
+ var id = element.Attribute("Id")?.Value;
968
+
969
+ if (id == "TARGETDIR" &&
970
+ this.OnError(ConverterTestType.TargetDirDeprecated, element, "The TARGETDIR directory should not longer be explicitly defined. Remove the Directory element with Id attribute 'TARGETDIR'."))
971
+ {
972
+ var parentElement = element.Parent;
973
+
974
+ element.Remove();
975
+
976
+ if (parentElement.FirstNode is XText text && String.IsNullOrWhiteSpace(text.Value))
977
+ {
978
+ parentElement.FirstNode.Remove();
979
+ }
980
+
981
+ foreach (var child in element.Nodes())
982
+ {
983
+ parentElement.Add(child);
984
+ }
985
+
986
+ element.RemoveAll();
987
+
988
+ if (parentElement.FirstNode is XText textAgain && String.IsNullOrWhiteSpace(textAgain.Value))
989
+ {
990
+ parentElement.FirstNode.Remove();
991
+ }
992
+ }
993
+ else if (id != null &&
994
+ WindowsInstallerStandard.IsStandardDirectory(id) &&
995
+ this.OnError(ConverterTestType.DefiningStandardDirectoryDeprecated, element, "Standard directories such as '{0}' should no longer be defined using the Directory element. Use the StandardDirectory element instead.", id))
996
+ {
997
+ element.Name = StandardDirectoryElementName;
998
+
999
+ foreach (var attrib in element.Attributes().Where(a => a.Name.LocalName != "Id").ToList())
1000
+ {
1001
+ attrib.Remove();
1002
+ }
1003
+ }
1004
}
1005
1006
private void ConvertFeatureElement(XElement element)
@@ -2254,6 +2305,16 @@ namespace WixToolset.Converters
2305
/// The SoftwareTag element's Type attribute is obsolete.
2306
/// </summary>
2307
SoftwareTagTypeObsolete,
2308
+
2309
+ /// <summary>
2310
+ /// TARGETDIR directory should not longer be explicitly defined.
2311
+ /// </summary>
2312
+ TargetDirDeprecated,
2313
+
2314
+ /// <summary>
2315
+ /// Standard directories should no longer be defined using the Directory element.
2316
+ /// </summary>
2317
+ DefiningStandardDirectoryDeprecated,
2318
}
2319
}
2320
}
src/test/WixToolsetTest.Converters/DirectoryFixture.cs
new
+92
@@ -0,0 +1,92 @@
1
+// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
2
+
3
+namespace WixToolsetTest.Converters
4
+{
5
+ using System;
6
+ using System.Xml.Linq;
7
+ using WixBuildTools.TestSupport;
8
+ using WixToolset.Converters;
9
+ using WixToolsetTest.Converters.Mocks;
10
+ using Xunit;
11
+
12
+ public class DirectoryFixture : BaseConverterFixture
13
+ {
14
+ [Fact]
15
+ public void RemoveTargetDir()
16
+ {
17
+ var parse = String.Join(Environment.NewLine,
18
+ "<?xml version=\"1.0\" encoding=\"utf-16\"?>",
19
+ "<Wix xmlns='http://schemas.microsoft.com/wix/2006/wi'>",
20
+ " <Fragment>",
21
+ " <Directory Id='TARGETDIR' Name='SourceDir'>",
22
+ " <!-- Comment -->",
23
+ " <Directory Id='RootFolder' Name='Root'>",
24
+ " <Directory Id='ChildFolder' Name='Child' />",
25
+ " </Directory>",
26
+ " </Directory>",
27
+ " </Fragment>",
28
+ "</Wix>");
29
+
30
+ var expected = new[]
31
+ {
32
+ "<Wix xmlns=\"http://wixtoolset.org/schemas/v4/wxs\">",
33
+ " <Fragment>",
34
+ " <!-- Comment -->",
35
+ " <Directory Id=\"RootFolder\" Name=\"Root\">",
36
+ " <Directory Id=\"ChildFolder\" Name=\"Child\" />",
37
+ " </Directory>",
38
+ " </Fragment>",
39
+ "</Wix>"
40
+ };
41
+
42
+ var document = XDocument.Parse(parse, LoadOptions.PreserveWhitespace | LoadOptions.SetLineInfo);
43
+
44
+ var messaging = new MockMessaging();
45
+ var converter = new WixConverter(messaging, 2, null, null);
46
+
47
+ var errors = converter.ConvertDocument(document);
48
+ Assert.Equal(3, errors);
49
+
50
+ var actualLines = UnformattedDocumentLines(document);
51
+ WixAssert.CompareLineByLine(expected, actualLines);
52
+ }
53
+
54
+ [Fact]
55
+ public void FixStandardDirectory()
56
+ {
57
+ var parse = String.Join(Environment.NewLine,
58
+ "<?xml version=\"1.0\" encoding=\"utf-16\"?>",
59
+ "<Wix xmlns='http://schemas.microsoft.com/wix/2006/wi'>",
60
+ " <Fragment>",
61
+ " <Directory Id='TARGETDIR' Name='SourceDir'>",
62
+ " <Directory Id='ProgramFilesFolder' Name='PFiles'>",
63
+ " <Directory Id='ChildFolder' Name='Child' />",
64
+ " </Directory>",
65
+ " </Directory>",
66
+ " </Fragment>",
67
+ "</Wix>");
68
+
69
+ var expected = new[]
70
+ {
71
+ "<Wix xmlns=\"http://wixtoolset.org/schemas/v4/wxs\">",
72
+ " <Fragment>",
73
+ " <StandardDirectory Id=\"ProgramFilesFolder\">",
74
+ " <Directory Id=\"ChildFolder\" Name=\"Child\" />",
75
+ " </StandardDirectory>",
76
+ " </Fragment>",
77
+ "</Wix>"
78
+ };
79
+
80
+ var document = XDocument.Parse(parse, LoadOptions.PreserveWhitespace | LoadOptions.SetLineInfo);
81
+
82
+ var messaging = new MockMessaging();
83
+ var converter = new WixConverter(messaging, 2, null, null);
84
+
85
+ var errors = converter.ConvertDocument(document);
86
+ Assert.Equal(4, errors);
87
+
88
+ var actualLines = UnformattedDocumentLines(document);
89
+ WixAssert.CompareLineByLine(expected, actualLines);
90
+ }
91
+ }
92
+}