aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRob Mensching <rob@firegiant.com>2022-12-08 16:59:30 -0800
committerRob Mensching <rob@firegiant.com>2022-12-11 00:26:50 -0800
commit7d41de1a726038d71873db48e9f5a575578679f5 (patch)
treee9248cd362da6624a720a2b8c4d7f4e82b5e6443
parentf7ff100a87f82b2a9b762d377cd5f0e6cd6cf86c (diff)
downloadwix-7d41de1a726038d71873db48e9f5a575578679f5.tar.gz
wix-7d41de1a726038d71873db48e9f5a575578679f5.tar.bz2
wix-7d41de1a726038d71873db48e9f5a575578679f5.zip
Handle references to standard directories
Closes 7072
-rw-r--r--src/wix/WixToolset.Converters/WixConverter.cs101
-rw-r--r--src/wix/test/WixToolsetTest.Converters/DirectoryFixture.cs80
2 files changed, 136 insertions, 45 deletions
diff --git a/src/wix/WixToolset.Converters/WixConverter.cs b/src/wix/WixToolset.Converters/WixConverter.cs
index c7069e5f..61bd0f79 100644
--- a/src/wix/WixToolset.Converters/WixConverter.cs
+++ b/src/wix/WixToolset.Converters/WixConverter.cs
@@ -1094,40 +1094,18 @@ namespace WixToolset.Converters
1094 1094
1095 var id = element.Attribute("Id")?.Value; 1095 var id = element.Attribute("Id")?.Value;
1096 1096
1097 if (id == "TARGETDIR" && 1097 if (id == "TARGETDIR")
1098 this.OnInformation(ConverterTestType.TargetDirDeprecated, element, "The TARGETDIR directory should not longer be explicitly defined. Remove the Directory element with Id attribute 'TARGETDIR'."))
1099 { 1098 {
1100 var parentElement = element.Parent; 1099 if (this.OnInformation(ConverterTestType.TargetDirDeprecated, element, "The TARGETDIR directory should no longer be explicitly defined. Remove the Directory element with Id attribute 'TARGETDIR'."))
1101
1102 element.Remove();
1103
1104 if (parentElement.FirstNode is XText text && String.IsNullOrWhiteSpace(text.Value))
1105 {
1106 parentElement.FirstNode.Remove();
1107 }
1108
1109 foreach (var child in element.Nodes())
1110 { 1100 {
1111 parentElement.Add(child); 1101 RemoveElementKeepChildren(element);
1112 }
1113
1114 element.RemoveAll();
1115
1116 if (parentElement.FirstNode is XText textAgain && String.IsNullOrWhiteSpace(textAgain.Value))
1117 {
1118 parentElement.FirstNode.Remove();
1119 } 1102 }
1120 } 1103 }
1121 else if (id != null && 1104 else if (id != null &&
1122 WindowsInstallerStandard.IsStandardDirectory(id) && 1105 WindowsInstallerStandard.IsStandardDirectory(id) &&
1123 this.OnInformation(ConverterTestType.DefiningStandardDirectoryDeprecated, element, "Standard directories such as '{0}' should no longer be defined using the Directory element. Use the StandardDirectory element instead.", id)) 1106 this.OnInformation(ConverterTestType.DefiningStandardDirectoryDeprecated, element, "Standard directories such as '{0}' should no longer be defined using the Directory element. Use the StandardDirectory element instead.", id))
1124 { 1107 {
1125 element.Name = StandardDirectoryElementName; 1108 RenameElementToStandardDirectory(element);
1126
1127 foreach (var attrib in element.Attributes().Where(a => a.Name.LocalName != "Id").ToList())
1128 {
1129 attrib.Remove();
1130 }
1131 } 1109 }
1132 } 1110 }
1133 1111
@@ -1135,28 +1113,22 @@ namespace WixToolset.Converters
1135 { 1113 {
1136 var id = element.Attribute("Id")?.Value; 1114 var id = element.Attribute("Id")?.Value;
1137 1115
1138 if (id == "TARGETDIR" && 1116 if (id != null && WindowsInstallerStandard.IsStandardDirectory(id))
1139 this.OnInformation(ConverterTestType.TargetDirRefDeprecated, element, "The TARGETDIR directory should not longer be explicitly referenced. Remove the DirectoryRef element with Id attribute 'TARGETDIR'."))
1140 { 1117 {
1141 var parentElement = element.Parent; 1118 if (!element.HasElements)
1142
1143 element.Remove();
1144
1145 if (parentElement.FirstNode is XText text && String.IsNullOrWhiteSpace(text.Value))
1146 { 1119 {
1147 parentElement.FirstNode.Remove(); 1120 this.OnError(ConverterTestType.EmptyStandardDirectoryRefNotConvertable, element, "Referencing '{0}' directory directly is no longer supported. The DirectoryRef will not be removed but you will probably need to reference a more specific directory.", id);
1148 } 1121 }
1149 1122 else if (id == "TARGETDIR")
1150 foreach (var child in element.Nodes())
1151 { 1123 {
1152 parentElement.Add(child); 1124 if (this.OnInformation(ConverterTestType.StandardDirectoryRefDeprecated, element, "The {0} directory should no longer be explicitly referenced. Remove the DirectoryRef element with Id attribute '{0}'.", id))
1125 {
1126 RemoveElementKeepChildren(element);
1127 }
1153 } 1128 }
1154 1129 else if (this.OnInformation(ConverterTestType.StandardDirectoryRefDeprecated, element, "The standard directory '{0}' should no longer be directly referenced. Use the StandardDirectory element instead.", id))
1155 element.RemoveAll();
1156
1157 if (parentElement.FirstNode is XText textAgain && String.IsNullOrWhiteSpace(textAgain.Value))
1158 { 1130 {
1159 parentElement.FirstNode.Remove(); 1131 RenameElementToStandardDirectory(element);
1160 } 1132 }
1161 } 1133 }
1162 } 1134 }
@@ -2725,6 +2697,40 @@ namespace WixToolset.Converters
2725 return value; 2697 return value;
2726 } 2698 }
2727 2699
2700 private static void RemoveElementKeepChildren(XElement element)
2701 {
2702 var parentElement = element.Parent;
2703
2704 element.Remove();
2705
2706 if (parentElement.FirstNode is XText text && String.IsNullOrWhiteSpace(text.Value))
2707 {
2708 parentElement.FirstNode.Remove();
2709 }
2710
2711 foreach (var child in element.Nodes())
2712 {
2713 parentElement.Add(child);
2714 }
2715
2716 element.RemoveAll();
2717
2718 if (parentElement.FirstNode is XText textAgain && String.IsNullOrWhiteSpace(textAgain.Value))
2719 {
2720 parentElement.FirstNode.Remove();
2721 }
2722 }
2723
2724 private static void RenameElementToStandardDirectory(XElement element)
2725 {
2726 element.Name = StandardDirectoryElementName;
2727
2728 foreach (var attrib in element.Attributes().Where(a => a.Name.LocalName != "Id").ToList())
2729 {
2730 attrib.Remove();
2731 }
2732 }
2733
2728 private static bool TryGetInnerText(XElement element, out string value, out List<XNode> comments) 2734 private static bool TryGetInnerText(XElement element, out string value, out List<XNode> comments)
2729 { 2735 {
2730 return TryGetInnerText(element, out value, out comments, new List<XNode>()); 2736 return TryGetInnerText(element, out value, out comments, new List<XNode>());
@@ -3138,7 +3144,7 @@ namespace WixToolset.Converters
3138 SoftwareTagTypeObsolete, 3144 SoftwareTagTypeObsolete,
3139 3145
3140 /// <summary> 3146 /// <summary>
3141 /// TARGETDIR directory should not longer be explicitly defined. 3147 /// TARGETDIR directory should no longer be explicitly defined.
3142 /// </summary> 3148 /// </summary>
3143 TargetDirDeprecated, 3149 TargetDirDeprecated,
3144 3150
@@ -3178,9 +3184,14 @@ namespace WixToolset.Converters
3178 CustomActionIdsIncludePlatformSuffix, 3184 CustomActionIdsIncludePlatformSuffix,
3179 3185
3180 /// <summary> 3186 /// <summary>
3181 /// The TARGETDIR directory should not longer be explicitly referenced. 3187 /// The {0} directory should no longer be explicitly referenced. Remove the DirectoryRef element with Id attribute '{0}'.
3188 /// </summary>
3189 StandardDirectoryRefDeprecated,
3190
3191 /// <summary>
3192 /// Referencing '{0}' directory directly is no longer supported. The DirectoryRef will not be removed but you will probably need to reference a more specific directory.
3182 /// </summary> 3193 /// </summary>
3183 TargetDirRefDeprecated, 3194 EmptyStandardDirectoryRefNotConvertable,
3184 } 3195 }
3185 } 3196 }
3186} 3197}
diff --git a/src/wix/test/WixToolsetTest.Converters/DirectoryFixture.cs b/src/wix/test/WixToolsetTest.Converters/DirectoryFixture.cs
index 6f233509..e992bf30 100644
--- a/src/wix/test/WixToolsetTest.Converters/DirectoryFixture.cs
+++ b/src/wix/test/WixToolsetTest.Converters/DirectoryFixture.cs
@@ -3,6 +3,7 @@
3namespace WixToolsetTest.Converters 3namespace WixToolsetTest.Converters
4{ 4{
5 using System; 5 using System;
6 using System.Linq;
6 using System.Xml.Linq; 7 using System.Xml.Linq;
7 using WixInternal.TestSupport; 8 using WixInternal.TestSupport;
8 using WixToolset.Converters; 9 using WixToolset.Converters;
@@ -130,6 +131,42 @@ namespace WixToolsetTest.Converters
130 } 131 }
131 132
132 [Fact] 133 [Fact]
134 public void FixStandardDirectoryRef()
135 {
136 var parse = String.Join(Environment.NewLine,
137 "<?xml version=\"1.0\" encoding=\"utf-16\"?>",
138 "<Wix xmlns='http://schemas.microsoft.com/wix/2006/wi'>",
139 " <Fragment>",
140 " <DirectoryRef Id='ProgramFilesFolder'>",
141 " <Directory Id='ChildFolder' Name='Child' />",
142 " </DirectoryRef>",
143 " </Fragment>",
144 "</Wix>");
145
146 var expected = new[]
147 {
148 "<Wix xmlns=\"http://wixtoolset.org/schemas/v4/wxs\">",
149 " <Fragment>",
150 " <StandardDirectory Id=\"ProgramFilesFolder\">",
151 " <Directory Id=\"ChildFolder\" Name=\"Child\" />",
152 " </StandardDirectory>",
153 " </Fragment>",
154 "</Wix>"
155 };
156
157 var document = XDocument.Parse(parse, LoadOptions.PreserveWhitespace | LoadOptions.SetLineInfo);
158
159 var messaging = new MockMessaging();
160 var converter = new WixConverter(messaging, 2, null, null);
161
162 var errors = converter.ConvertDocument(document);
163
164 var actualLines = UnformattedDocumentLines(document);
165 WixAssert.CompareLineByLine(expected, actualLines);
166 Assert.Equal(3, errors);
167 }
168
169 [Fact]
133 public void RemoveTargetDirRefAndFixStandardDirectory() 170 public void RemoveTargetDirRefAndFixStandardDirectory()
134 { 171 {
135 var parse = String.Join(Environment.NewLine, 172 var parse = String.Join(Environment.NewLine,
@@ -166,5 +203,48 @@ namespace WixToolsetTest.Converters
166 WixAssert.CompareLineByLine(expected, actualLines); 203 WixAssert.CompareLineByLine(expected, actualLines);
167 Assert.Equal(4, errors); 204 Assert.Equal(4, errors);
168 } 205 }
206
207 [Fact]
208 public void ErrorOnEmptyStandardDirectoryRef()
209 {
210 var parse = String.Join(Environment.NewLine,
211 "<Wix xmlns='http://schemas.microsoft.com/wix/2006/wi'>",
212 " <Fragment>",
213 " <DirectoryRef Id='TARGETDIR' />",
214 " <DirectoryRef Id='ProgramFilesFolder' />",
215 " <DirectoryRef Id='DesktopFolder' />",
216 " </Fragment>",
217 "</Wix>");
218
219 var expected = new[]
220 {
221 "<Wix xmlns=\"http://wixtoolset.org/schemas/v4/wxs\">",
222 " <Fragment>",
223 " <DirectoryRef Id=\"TARGETDIR\" />",
224 " <DirectoryRef Id=\"ProgramFilesFolder\" />",
225 " <DirectoryRef Id=\"DesktopFolder\" />",
226 " </Fragment>",
227 "</Wix>"
228 };
229
230 var document = XDocument.Parse(parse, LoadOptions.PreserveWhitespace | LoadOptions.SetLineInfo);
231
232 var messaging = new MockMessaging();
233 var converter = new WixConverter(messaging, 2, null, null);
234
235 var errors = converter.ConvertDocument(document);
236
237 WixAssert.CompareLineByLine(new[]
238 {
239 "[Converted] The namespace 'http://schemas.microsoft.com/wix/2006/wi' is out of date. It must be 'http://wixtoolset.org/schemas/v4/wxs'. (XmlnsValueWrong)",
240 "Referencing 'TARGETDIR' directory directly is no longer supported. The DirectoryRef will not be removed but you will probably need to reference a more specific directory. (EmptyStandardDirectoryRefNotConvertable)",
241 "Referencing 'ProgramFilesFolder' directory directly is no longer supported. The DirectoryRef will not be removed but you will probably need to reference a more specific directory. (EmptyStandardDirectoryRefNotConvertable)",
242 "Referencing 'DesktopFolder' directory directly is no longer supported. The DirectoryRef will not be removed but you will probably need to reference a more specific directory. (EmptyStandardDirectoryRefNotConvertable)"
243 }, messaging.Messages.Select(m => m.ToString()).ToArray());
244
245 var actualLines = UnformattedDocumentLines(document);
246 WixAssert.CompareLineByLine(expected, actualLines);
247 Assert.Equal(4, errors);
248 }
169 } 249 }
170} 250}