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
+}