diff options
author | Rob Mensching <rob@firegiant.com> | 2022-12-08 16:59:30 -0800 |
---|---|---|
committer | Rob Mensching <rob@firegiant.com> | 2022-12-11 00:26:50 -0800 |
commit | 7d41de1a726038d71873db48e9f5a575578679f5 (patch) | |
tree | e9248cd362da6624a720a2b8c4d7f4e82b5e6443 | |
parent | f7ff100a87f82b2a9b762d377cd5f0e6cd6cf86c (diff) | |
download | wix-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.cs | 101 | ||||
-rw-r--r-- | src/wix/test/WixToolsetTest.Converters/DirectoryFixture.cs | 80 |
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 @@ | |||
3 | namespace WixToolsetTest.Converters | 3 | namespace 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 | } |