@joebigelow / wix-1 / commits / 84a26c3b

WIXFEAT:4763 Change "string" variable type to literal and add "formatted".

Sean Hall committed Aug 4, 2020 at 19:08 UTC 84a26c3bf9d7a88a7dcbbca4d65b004307600ba2
2 files changed +140
src/WixToolset.Converters/WixConverter.cs
+54
@@ -73,6 +73,7 @@ namespace WixToolset.Converters
73 private static readonly XName ShortcutPropertyElementName = WixNamespace + "ShortcutProperty";
74 private static readonly XName TextElementName = WixNamespace + "Text";
75 private static readonly XName UITextElementName = WixNamespace + "UIText";
76 + private static readonly XName VariableElementName = WixNamespace + "Variable";
77 private static readonly XName UtilCloseApplicationElementName = WixUtilNamespace + "CloseApplication";
78 private static readonly XName UtilPermissionExElementName = WixUtilNamespace + "PermissionEx";
79 private static readonly XName UtilXmlConfigElementName = WixUtilNamespace + "XmlConfig";
@@ -162,6 +163,7 @@ namespace WixToolset.Converters
163 { WixConverter.ShortcutPropertyElementName, this.ConvertShortcutPropertyElement },
164 { WixConverter.TextElementName, this.ConvertTextElement },
165 { WixConverter.UITextElementName, this.ConvertUITextElement },
166 + { WixConverter.VariableElementName, this.ConvertVariableElement },
167 { WixConverter.UtilCloseApplicationElementName, this.ConvertUtilCloseApplicationElementName },
168 { WixConverter.UtilPermissionExElementName, this.ConvertUtilPermissionExElement },
169 { WixConverter.UtilXmlConfigElementName, this.ConvertUtilXmlConfigElement },
@@ -814,6 +816,28 @@ namespace WixToolset.Converters
816 }
817 }
818
819 + private void ConvertVariableElement(XElement xVariable)
820 + {
821 + var xType = xVariable.Attribute("Type");
822 + var xValue = xVariable.Attribute("Value");
823 + if (this.SourceVersion < 4)
824 + {
825 + if (xType == null)
826 + {
827 + if (WasImplicitlyStringTyped(xValue?.Value) &&
828 + this.OnError(ConverterTestType.AssignVariableTypeFormatted, xVariable, "The \"string\" variable type now denotes a literal string. Use \"formatted\" to keep the previous behavior."))
829 + {
830 + xVariable.Add(new XAttribute("Type", "formatted"));
831 + }
832 + }
833 + else if (xType.Value == "string" &&
834 + this.OnError(ConverterTestType.AssignVariableTypeFormatted, xVariable, "The \"string\" variable type now denotes a literal string. Use \"formatted\" to keep the previous behavior."))
835 + {
836 + xType.Value = "formatted";
837 + }
838 + }
839 + }
840 +
841 private void ConvertPropertyElement(XElement xProperty)
842 {
843 var xId = xProperty.Attribute("Id");
@@ -1105,6 +1129,31 @@ namespace WixToolset.Converters
1129 }
1130 }
1131
1132 + private static bool WasImplicitlyStringTyped(string value)
1133 + {
1134 + if (value == null)
1135 + {
1136 + return false;
1137 + }
1138 + else if (value.StartsWith("v", StringComparison.OrdinalIgnoreCase))
1139 + {
1140 + if (Int32.TryParse(value.Substring(1), NumberStyles.None, CultureInfo.InvariantCulture.NumberFormat, out var _))
1141 + {
1142 + return false;
1143 + }
1144 + else if (Version.TryParse(value.Substring(1), out var _))
1145 + {
1146 + return false;
1147 + }
1148 + }
1149 + else if (Int64.TryParse(value, NumberStyles.Integer, CultureInfo.InvariantCulture.NumberFormat, out var _))
1150 + {
1151 + return false;
1152 + }
1153 +
1154 + return true;
1155 + }
1156 +
1157 /// <summary>
1158 /// Converter test types. These are used to condition error messages down to warnings.
1159 /// </summary>
@@ -1229,6 +1278,11 @@ namespace WixToolset.Converters
1278 /// DpiAwareness is new and is defaulted to 'perMonitorV2' which is a change in behavior.
1279 /// </summary>
1280 AssignBootstrapperApplicationDpiAwareness,
1281 +
1282 + /// <summary>
1283 + /// The string variable type was previously treated as formatted.
1284 + /// </summary>
1285 + AssignVariableTypeFormatted,
1286 }
1287 }
1288 }
src/test/WixToolsetTest.Converters/VariableFixture.cs new
+86
@@ -0,0 +1,86 @@
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 VariableFixture : BaseConverterFixture
13 + {
14 + [Fact]
15 + public void FixFormattedType()
16 + {
17 + var parse = String.Join(Environment.NewLine,
18 + "<Wix xmlns='http://schemas.microsoft.com/wix/2006/wi'>",
19 + " <Fragment>",
20 + " <Variable Name='ExplicitString' Type='string' Value='explicit' />",
21 + " <Variable Name='ImplicitNumber' Value='42' />",
22 + " <Variable Name='ImplicitString' Value='implicit' />",
23 + " <Variable Name='ImplicitVersion' Value='v2' />",
24 + " <Variable Name='NoTypeOrValue' />",
25 + " </Fragment>",
26 + "</Wix>");
27 +
28 + var expected = new[]
29 + {
30 + "<Wix xmlns=\"http://wixtoolset.org/schemas/v4/wxs\">",
31 + " <Fragment>",
32 + " <Variable Name=\"ExplicitString\" Type=\"formatted\" Value=\"explicit\" />",
33 + " <Variable Name=\"ImplicitNumber\" Value=\"42\" />",
34 + " <Variable Name=\"ImplicitString\" Value=\"implicit\" Type=\"formatted\" />",
35 + " <Variable Name=\"ImplicitVersion\" Value=\"v2\" />",
36 + " <Variable Name=\"NoTypeOrValue\" />",
37 + " </Fragment>",
38 + "</Wix>"
39 + };
40 +
41 + var document = XDocument.Parse(parse, LoadOptions.PreserveWhitespace | LoadOptions.SetLineInfo);
42 +
43 + var messaging = new MockMessaging();
44 + var converter = new WixConverter(messaging, 2, null, null);
45 +
46 + var errors = converter.ConvertDocument(document);
47 + Assert.Equal(3, errors);
48 +
49 + var actualLines = UnformattedDocumentLines(document);
50 + WixAssert.CompareLineByLine(expected, actualLines);
51 + }
52 +
53 + [Fact]
54 + public void DoesntFixFormattedTypeFromV4()
55 + {
56 + var parse = String.Join(Environment.NewLine,
57 + "<Wix xmlns='http://wixtoolset.org/schemas/v4/wxs'>",
58 + " <Fragment>",
59 + " <Variable Name='ImplicitString' Value='implicit' />",
60 + " <Variable Name='ExplicitString' Type='string' Value='explicit' />",
61 + " </Fragment>",
62 + "</Wix>");
63 +
64 + var expected = new[]
65 + {
66 + "<Wix xmlns=\"http://wixtoolset.org/schemas/v4/wxs\">",
67 + " <Fragment>",
68 + " <Variable Name=\"ImplicitString\" Value=\"implicit\" />",
69 + " <Variable Name=\"ExplicitString\" Type=\"string\" Value=\"explicit\" />",
70 + " </Fragment>",
71 + "</Wix>"
72 + };
73 +
74 + var document = XDocument.Parse(parse, LoadOptions.PreserveWhitespace | LoadOptions.SetLineInfo);
75 +
76 + var messaging = new MockMessaging();
77 + var converter = new WixConverter(messaging, 2, null, null);
78 +
79 + var errors = converter.ConvertDocument(document);
80 + Assert.Equal(0, errors);
81 +
82 + var actualLines = UnformattedDocumentLines(document);
83 + WixAssert.CompareLineByLine(expected, actualLines);
84 + }
85 + }
86 +}