Move WixVersion to new WixToolset.Versioning package in libs segment
WixVersion is already used by the Core toolset but could also be useful for bootstrapper applications parsing bundle versions. The WixToolset.Data assembly contains a significant amount of data that bloats its size that bootstrapper applications would never need. Extracting WixVersion to its own assembly makes it much more useable. Fixes 6943
Rob Mensching committed
Oct 2, 2022 at 19:37 UTC
5c509f5611a45bdf9d252b88605537bd28f24a35
24 files changed
+1275
-9
src/internal/SetBuildNumber/Directory.Packages.props.pp
+1
@@ -19,6 +19,7 @@
19
20
<PackageVersion Include="WixToolset.Data" Version="{packageversion}" />
21
<PackageVersion Include="WixToolset.Extensibility" Version="{packageversion}" />
22
+ <PackageVersion Include="WixToolset.Versioning" Version="{packageversion}" />
23
24
<PackageVersion Include="WixToolset.Burn" Version="{packageversion}" />
25
<PackageVersion Include="WixToolset.Dnc.HostGenerator" Version="{packageversion}" />
src/libs/WixToolset.Versioning/WixToolset.Versioning.csproj
new
+14
@@ -0,0 +1,14 @@
1
+<?xml version="1.0" encoding="utf-8"?>
2
+<!-- 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. -->
3
+
4
+<Project Sdk="Microsoft.NET.Sdk">
5
+ <PropertyGroup>
6
+ <TargetFrameworks>netstandard2.0</TargetFrameworks>
7
+ <TargetFrameworks Condition=" '$(Configuration)'=='Release' ">$(TargetFrameworks);net472</TargetFrameworks>
8
+ <LangVersion>7.3</LangVersion>
9
+ <Description>WiX Toolset Versioning</Description>
10
+ <DebugType>embedded</DebugType>
11
+ <PublishRepositoryUrl>true</PublishRepositoryUrl>
12
+ <CreateDocumentationFile>true</CreateDocumentationFile>
13
+ </PropertyGroup>
14
+</Project>
src/libs/WixToolset.Versioning/WixVersion.cs
renamed
+132
-4
@@ -1,6 +1,6 @@
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 WixToolset.Data
3
+namespace WixToolset.Versioning
4
{
5
using System;
6
using System.Collections.Generic;
@@ -11,13 +11,12 @@ namespace WixToolset.Data
11
/// large numbers and semantic versions with 4-part versions with
12
/// or without leading "v" indicators.
13
/// </summary>
14
- [CLSCompliant(false)]
15
- public class WixVersion
14
+ public class WixVersion : IComparable, IComparable<WixVersion>, IEquatable<WixVersion>
15
{
16
/// <summary>
17
/// Gets the prefix of the version if present when parsed. Usually, 'v' or 'V'.
18
/// </summary>
20
- public char? Prefix { get; set; }
19
+ public char? Prefix { get; set; }
20
21
/// <summary>
22
/// Gets or sets the major version.
@@ -74,6 +73,63 @@ namespace WixToolset.Data
73
/// </summary>
74
public string Metadata { get; set; }
75
76
+ /// <summary>
77
+ /// Compare to another WixVersion.
78
+ /// </summary>
79
+ /// <param name="version">WixVersion to compare.</param>
80
+ /// <returns>A comparison between versions.</returns>
81
+ public int CompareTo(WixVersion version)
82
+ {
83
+ return WixVersionComparer.Default.Compare(this, version);
84
+ }
85
+
86
+ /// <summary>
87
+ /// Compare to another object.
88
+ /// </summary>
89
+ /// <param name="version">Object to compare.</param>
90
+ /// <returns>A comparison between objects.</returns>
91
+ public int CompareTo(object version)
92
+ {
93
+ return WixVersionComparer.Default.Compare(this, version as WixVersion);
94
+ }
95
+
96
+ /// <summary>
97
+ /// Returns a value indicating whether the current System.Version object is equal to a specified object.
98
+ /// </summary>
99
+ /// <param name="version">An WixVersion to compare with the current WixVersion object, or null.</param>
100
+ /// <returns>
101
+ /// true if the current WixVersion object and obj are both WixVersion objects,
102
+ /// and every component of the current System.Version object matches the corresponding
103
+ /// component of obj; otherwise, false.
104
+ /// </returns>
105
+ public bool Equals(WixVersion version)
106
+ {
107
+ return WixVersionComparer.Default.Equals(this, version);
108
+ }
109
+
110
+ /// <summary>
111
+ /// Returns a value indicating whether the current WixVersion object is equal to a specified object.
112
+ /// </summary>
113
+ /// <param name="obj">An object to compare with the current WixVersion object, or null.</param>
114
+ /// <returns>
115
+ /// true if the current WixVersion object and obj are both WixVersion objects,
116
+ /// and every component of the current System.Version object matches the corresponding
117
+ /// component of obj; otherwise, false.
118
+ /// </returns>
119
+ public override bool Equals(object obj)
120
+ {
121
+ return WixVersionComparer.Default.Equals(this, obj as WixVersion);
122
+ }
123
+
124
+ /// <summary>
125
+ /// Returns a hash code for the current WixVersion object.
126
+ /// </summary>
127
+ /// <returns>A 32-bit signed integer hash code.</returns>
128
+ public override int GetHashCode()
129
+ {
130
+ return WixVersionComparer.Default.GetHashCode(this);
131
+ }
132
+
133
/// <summary>
134
/// Parse a string value into a <c>WixVersion</c>. The returned version may be invalid.
135
/// </summary>
@@ -331,5 +387,77 @@ namespace WixToolset.Data
387
388
return true;
389
}
390
+
391
+ /// <summary>
392
+ /// Determines whether two specified WixVersion objects are equal.
393
+ /// </summary>
394
+ /// <param name="v1">The first WixVersion object.</param>
395
+ /// <param name="v2">The second WixVersion object.</param>
396
+ /// <returns>true if v1 equals v2; otherwise, false.</returns>
397
+ public static bool operator ==(WixVersion v1, WixVersion v2)
398
+ {
399
+ return WixVersionComparer.Default.Equals(v1, v2);
400
+ }
401
+
402
+ /// <summary>
403
+ /// Determines whether two specified System.Version objects are not equal.
404
+ /// </summary>
405
+ /// <param name="v1">The first WixVersion object.</param>
406
+ /// <param name="v2">The second WixVersion object.</param>
407
+ /// <returns>true if v1 does not equal v2; otherwise, false.</returns>
408
+ public static bool operator !=(WixVersion v1, WixVersion v2)
409
+ {
410
+ return !WixVersionComparer.Default.Equals(v1, v2);
411
+ }
412
+
413
+ /// <summary>
414
+ /// Determines whether the first specified System.Version object is less than the second specified System.Version object.
415
+ /// </summary>
416
+ /// <param name="v1">The first WixVersion object.</param>
417
+ /// <param name="v2">The second WixVersion object.</param>
418
+ /// <returns>true if v1 is less than v2; otherwise, false.</returns>
419
+ /// <exception cref="ArgumentNullException">v1 is null.</exception>
420
+ public static bool operator <(WixVersion v1, WixVersion v2)
421
+ {
422
+ return WixVersionComparer.Default.Compare(v1, v2) == -1;
423
+ }
424
+
425
+ /// <summary>
426
+ /// Determines whether the first specified System.Version object is greater than the second specified System.Version object.
427
+ /// </summary>
428
+ /// <param name="v1">The first WixVersion object.</param>
429
+ /// <param name="v2">The second WixVersion object.</param>
430
+ /// <returns>true if v1 is greater than v2; otherwise, false.</returns>
431
+ public static bool operator >(WixVersion v1, WixVersion v2)
432
+ {
433
+ return WixVersionComparer.Default.Compare(v1, v2) == 1;
434
+ }
435
+
436
+ /// <summary>
437
+ /// Determines whether the first specified System.Version object is less than or equal to the second System.Version object.
438
+ /// </summary>
439
+ /// <param name="v1">The first WixVersion object.</param>
440
+ /// <param name="v2">The second WixVersion object.</param>
441
+ /// <returns>true if v1 is less than or equal to v2; otherwise, false.</returns>
442
+ /// <exception cref="ArgumentNullException">v1 is null.</exception>
443
+ public static bool operator <=(WixVersion v1, WixVersion v2)
444
+ {
445
+ var result = WixVersionComparer.Default.Compare(v1, v2);
446
+
447
+ return result == 0 || result == -1;
448
+ }
449
+
450
+ /// <summary>
451
+ /// Determines whether the first specified System.Version object is greater than or equal to the second specified System.Version object.
452
+ /// </summary>
453
+ /// <param name="v1">The first WixVersion object.</param>
454
+ /// <param name="v2">The second WixVersion object.</param>
455
+ /// <returns>true if v1 is greater than or equal to v2; otherwise, false.</returns>
456
+ public static bool operator >=(WixVersion v1, WixVersion v2)
457
+ {
458
+ var result = WixVersionComparer.Default.Compare(v1, v2);
459
+
460
+ return result == 0 || result == 1;
461
+ }
462
}
463
}
src/libs/WixToolset.Versioning/WixVersionComparer.cs
new
+253
@@ -0,0 +1,253 @@
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 WixToolset.Versioning
4
+{
5
+ using System;
6
+ using System.Collections.Generic;
7
+
8
+ /// <summary>
9
+ /// WixVersion comparer.
10
+ /// </summary>
11
+ public class WixVersionComparer : IEqualityComparer<WixVersion>, IComparer<WixVersion>
12
+ {
13
+ /// <summary>
14
+ /// Default WixVersion comparer.
15
+ /// </summary>
16
+ public static readonly WixVersionComparer Default = new WixVersionComparer();
17
+
18
+ /// <inheritdoc />
19
+ public int Compare(WixVersion x, WixVersion y)
20
+ {
21
+ if ((object)x == y)
22
+ {
23
+ return 0;
24
+ }
25
+
26
+ if (x is null)
27
+ {
28
+ return -1;
29
+ }
30
+
31
+ if (y is null)
32
+ {
33
+ return 1;
34
+ }
35
+
36
+ var result = x.Major.CompareTo(y.Major);
37
+ if (result != 0)
38
+ {
39
+ return result;
40
+ }
41
+
42
+ result = x.Minor.CompareTo(y.Minor);
43
+ if (result != 0)
44
+ {
45
+ return result;
46
+ }
47
+
48
+ result = x.Patch.CompareTo(y.Patch);
49
+ if (result != 0)
50
+ {
51
+ return result;
52
+ }
53
+
54
+ result = x.Revision.CompareTo(y.Revision);
55
+ if (result != 0)
56
+ {
57
+ return result;
58
+ }
59
+
60
+ var xLabelCount = x.Labels?.Length ?? 0;
61
+ var yLabelCount = y.Labels?.Length ?? 0;
62
+ var maxLabelCount = Math.Max(xLabelCount, yLabelCount);
63
+
64
+ if (xLabelCount > 0)
65
+ {
66
+ if (yLabelCount == 0)
67
+ {
68
+ return -1;
69
+ }
70
+ }
71
+ else if (yLabelCount > 0)
72
+ {
73
+ return 1;
74
+ }
75
+
76
+ for (var i = 0; i < maxLabelCount; ++i)
77
+ {
78
+ var xLabel = i < xLabelCount ? x.Labels[i] : null;
79
+ var yLabel = i < yLabelCount ? y.Labels[i] : null;
80
+
81
+ result = CompareReleaseLabel(xLabel, yLabel);
82
+ if (result != 0)
83
+ {
84
+ return result;
85
+ }
86
+ }
87
+
88
+ var compareMetadata = false;
89
+
90
+ if (x.Invalid)
91
+ {
92
+ if (!y.Invalid)
93
+ {
94
+ return -1;
95
+ }
96
+ else
97
+ {
98
+ compareMetadata = true;
99
+ }
100
+ }
101
+ else if (y.Invalid)
102
+ {
103
+ return 1;
104
+ }
105
+
106
+ if (compareMetadata)
107
+ {
108
+ result = String.Compare(x.Metadata, y.Metadata, StringComparison.OrdinalIgnoreCase);
109
+ }
110
+
111
+ return (result == 0) ? 0 : (result < 0) ? -1 : 1;
112
+ }
113
+
114
+ /// <inheritdoc />
115
+ public bool Equals(WixVersion x, WixVersion y)
116
+ {
117
+ if ((object)x == y)
118
+ {
119
+ return true;
120
+ }
121
+
122
+ if (x is null)
123
+ {
124
+ return false;
125
+ }
126
+
127
+ if (y is null)
128
+ {
129
+ return false;
130
+ }
131
+
132
+ if (x.Major != y.Major)
133
+ {
134
+ return false;
135
+ }
136
+
137
+ if (x.Minor != y.Minor)
138
+ {
139
+ return false;
140
+ }
141
+
142
+ if (x.Patch != y.Patch)
143
+ {
144
+ return false;
145
+ }
146
+
147
+ if (x.Revision != y.Revision)
148
+ {
149
+ return false;
150
+ }
151
+
152
+ var labelCount = x.Labels?.Length ?? 0;
153
+ if (labelCount != (y.Labels?.Length ?? 0))
154
+ {
155
+ return false;
156
+ }
157
+
158
+ for (var i = 0; i < labelCount; ++i)
159
+ {
160
+ var result = CompareReleaseLabel(x.Labels[i], y.Labels[i]);
161
+ if (result != 0)
162
+ {
163
+ return false;
164
+ }
165
+ }
166
+
167
+ if (x.Invalid)
168
+ {
169
+ if (y.Invalid)
170
+ {
171
+ return String.Equals(x.Metadata, y.Metadata, StringComparison.OrdinalIgnoreCase);
172
+ }
173
+ else
174
+ {
175
+ return false;
176
+ }
177
+ }
178
+ else if (y.Invalid)
179
+ {
180
+ return false;
181
+ }
182
+
183
+ return true;
184
+ }
185
+
186
+ /// <inheritdoc />
187
+ public int GetHashCode(WixVersion version)
188
+ {
189
+ var hash = 23L;
190
+ hash = hash * 37 + (version.Prefix ?? '\0');
191
+ hash = hash * 37 + version.Major;
192
+ hash = hash * 37 + version.Minor;
193
+ hash = hash * 37 + version.Patch;
194
+ hash = hash * 37 + version.Revision;
195
+ hash = hash * 37 + (version.Invalid ? 1 : 0);
196
+ hash = hash * 37 + (version.HasMajor ? 1 : 0);
197
+ hash = hash * 37 + (version.HasMinor ? 1 : 0);
198
+ hash = hash * 37 + (version.HasPatch ? 1 : 0);
199
+ hash = hash * 37 + (version.HasRevision ? 1 : 0);
200
+
201
+ if (version.Labels != null)
202
+ {
203
+ foreach (var label in version.Labels)
204
+ {
205
+ hash = hash * 37 + label.Label.GetHashCode();
206
+ }
207
+ }
208
+
209
+ hash = hash * 37 + version.Metadata?.GetHashCode() ?? 0;
210
+
211
+ return unchecked((int)hash);
212
+ }
213
+
214
+ private static int CompareReleaseLabel(WixVersionLabel l1, WixVersionLabel l2)
215
+ {
216
+ if (l1 == l2)
217
+ {
218
+ return 0;
219
+ }
220
+ else if (l2 == null)
221
+ {
222
+ return 1;
223
+ }
224
+ else if (l1 == null)
225
+ {
226
+ return -1;
227
+ }
228
+
229
+ if (l1.Numeric.HasValue)
230
+ {
231
+ if (l2.Numeric.HasValue)
232
+ {
233
+ return l1.Numeric.Value.CompareTo(l2.Numeric.Value);
234
+ }
235
+ else
236
+ {
237
+ return -1;
238
+ }
239
+ }
240
+ else
241
+ {
242
+ if (l2.Numeric.HasValue)
243
+ {
244
+ return 1;
245
+ }
246
+ else
247
+ {
248
+ return String.Compare(l1.Label, l2.Label, StringComparison.OrdinalIgnoreCase);
249
+ }
250
+ }
251
+ }
252
+ }
253
+}
src/libs/WixToolset.Versioning/WixVersionLabel.cs
new
+40
@@ -0,0 +1,40 @@
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 WixToolset.Versioning
4
+{
5
+ /// <summary>
6
+ /// Label in a <c>WixVersion</c>.
7
+ /// </summary>
8
+ public class WixVersionLabel
9
+ {
10
+ /// <summary>
11
+ /// Creates a string only version label.
12
+ /// </summary>
13
+ /// <param name="label">String value for version label.</param>
14
+ public WixVersionLabel(string label)
15
+ {
16
+ this.Label = label;
17
+ }
18
+
19
+ /// <summary>
20
+ /// Creates a string version label with numeric value.
21
+ /// </summary>
22
+ /// <param name="label">String value for version label.</param>
23
+ /// <param name="numeric">Numeric value for the version label.</param>
24
+ public WixVersionLabel(string label, uint? numeric)
25
+ {
26
+ this.Label = label;
27
+ this.Numeric = numeric;
28
+ }
29
+
30
+ /// <summary>
31
+ /// Gets the string label value.
32
+ /// </summary>
33
+ public string Label { get; set; }
34
+
35
+ /// <summary>
36
+ /// Gets the optional numeric label value.
37
+ /// </summary>
38
+ public uint? Numeric { get; set; }
39
+ }
40
+}
src/libs/dutil/WixToolset.DUtil/dutil.v3.ncrunchproject
new
+5
@@ -0,0 +1,5 @@
1
+<ProjectConfiguration>
2
+ <Settings>
3
+ <IgnoreThisComponentCompletely>True</IgnoreThisComponentCompletely>
4
+ </Settings>
5
+</ProjectConfiguration>
\ No newline at end of file
src/libs/dutil/test/DUtilUnitTest/DUtilUnitTest.v3.ncrunchproject
new
+5
@@ -0,0 +1,5 @@
1
+<ProjectConfiguration>
2
+ <Settings>
3
+ <IgnoreThisComponentCompletely>True</IgnoreThisComponentCompletely>
4
+ </Settings>
5
+</ProjectConfiguration>
\ No newline at end of file
src/libs/libs.cmd
+24
@@ -3,18 +3,42 @@
3
4
@set _C=Debug
5
@set _L=%~dp0..\..\build\logs
6
+
7
:parse_args
8
@if /i "%1"=="release" set _C=Release
9
+@if /i "%1"=="inc" set _INC=1
10
+@if /i "%1"=="clean" set _CLEAN=1
11
@if not "%1"=="" shift & goto parse_args
12
13
@set _B=%~dp0..\..\build\libs\%_C%
14
15
+:: Clean
16
+
17
+@if "%_INC%"=="" call :clean
18
+@if NOT "%_CLEAN%"=="" goto :end
19
+
20
@echo Building libs %_C%
21
22
msbuild -Restore libs_t.proj -p:Configuration=%_C% -nologo -m -warnaserror -bl:%_L%\libs_build.binlog || exit /b
23
24
+dotnet test %_B%\net6.0\WixToolsetTest.Versioning.dll --nologo -l "trx;LogFileName=%_L%\TestResults\WixToolsetTest.Versioning.trx" || exit /b
25
dotnet test %_B%\x86\DUtilUnitTest.dll --nologo -l "trx;LogFileName=%_L%\TestResults\DutilUnitTest32.trx" || exit /b
26
dotnet test %_B%\x64\DUtilUnitTest.dll --nologo -l "trx;LogFileName=%_L%\TestResults\DutilUnitTest64.trx" || exit /b
27
28
+@goto :end
29
+
30
+:clean
31
+@rd /s/q "..\..\build\libs" 2> nul
32
+@del "..\..\build\artifacts\WixToolset.DUtil.*.nupkg" 2> nul
33
+@del "..\..\build\artifacts\WixToolset.Versioning.*.nupkg" 2> nul
34
+@del "..\..\build\artifacts\WixToolset.WcaUtil.*.nupkg" 2> nul
35
+@del "%_L%\TestResults\WixToolsetTest.Versioning.trx" 2> nul
36
+@del "%_L%\TestResults\DutilUnitTest*.trx" 2> nul
37
+@rd /s/q "%USERPROFILE%\.nuget\packages\wixtoolset.dutil" 2> nul
38
+@rd /s/q "%USERPROFILE%\.nuget\packages\wixtoolset.versioning" 2> nul
39
+@rd /s/q "%USERPROFILE%\.nuget\packages\wixtoolset.wcautil" 2> nul
40
+@exit /b
41
+
42
+:end
43
@popd
44
@endlocal
src/libs/libs.sln
+38
-2
@@ -1,7 +1,7 @@
1
2
Microsoft Visual Studio Solution File, Format Version 12.00
3
-# Visual Studio Version 16
4
-VisualStudioVersion = 16.6.30114.105
3
+# Visual Studio Version 17
4
+VisualStudioVersion = 17.3.32922.545
5
MinimumVisualStudioVersion = 10.0.40219.1
6
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dutil", "dutil\WixToolset.DUtil\dutil.vcxproj", "{1244E671-F108-4334-BA52-8A7517F26ECD}"
7
EndProject
@@ -9,6 +9,10 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DUtilUnitTest", "dutil\test
9
EndProject
10
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wcautil", "wcautil\WixToolset.WcaUtil\wcautil.vcxproj", "{5B3714B6-3A76-463E-8595-D48DA276C512}"
11
EndProject
12
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WixToolset.Versioning", "WixToolset.Versioning\WixToolset.Versioning.csproj", "{7B14B536-4205-4186-B9FD-0765B84F2075}"
13
+EndProject
14
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WixToolsetTest.Versioning", "test\WixToolsetTest.Versioning\WixToolsetTest.Versioning.csproj", "{3D510701-FF05-4E3B-BB99-BDB97963C3F8}"
15
+EndProject
16
Global
17
GlobalSection(SolutionConfigurationPlatforms) = preSolution
18
Debug|Any CPU = Debug|Any CPU
@@ -59,6 +63,38 @@ Global
63
{5B3714B6-3A76-463E-8595-D48DA276C512}.Release|x64.Build.0 = Release|x64
64
{5B3714B6-3A76-463E-8595-D48DA276C512}.Release|x86.ActiveCfg = Release|Win32
65
{5B3714B6-3A76-463E-8595-D48DA276C512}.Release|x86.Build.0 = Release|Win32
66
+ {7B14B536-4205-4186-B9FD-0765B84F2075}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
67
+ {7B14B536-4205-4186-B9FD-0765B84F2075}.Debug|Any CPU.Build.0 = Debug|Any CPU
68
+ {7B14B536-4205-4186-B9FD-0765B84F2075}.Debug|ARM64.ActiveCfg = Debug|Any CPU
69
+ {7B14B536-4205-4186-B9FD-0765B84F2075}.Debug|ARM64.Build.0 = Debug|Any CPU
70
+ {7B14B536-4205-4186-B9FD-0765B84F2075}.Debug|x64.ActiveCfg = Debug|Any CPU
71
+ {7B14B536-4205-4186-B9FD-0765B84F2075}.Debug|x64.Build.0 = Debug|Any CPU
72
+ {7B14B536-4205-4186-B9FD-0765B84F2075}.Debug|x86.ActiveCfg = Debug|Any CPU
73
+ {7B14B536-4205-4186-B9FD-0765B84F2075}.Debug|x86.Build.0 = Debug|Any CPU
74
+ {7B14B536-4205-4186-B9FD-0765B84F2075}.Release|Any CPU.ActiveCfg = Release|Any CPU
75
+ {7B14B536-4205-4186-B9FD-0765B84F2075}.Release|Any CPU.Build.0 = Release|Any CPU
76
+ {7B14B536-4205-4186-B9FD-0765B84F2075}.Release|ARM64.ActiveCfg = Release|Any CPU
77
+ {7B14B536-4205-4186-B9FD-0765B84F2075}.Release|ARM64.Build.0 = Release|Any CPU
78
+ {7B14B536-4205-4186-B9FD-0765B84F2075}.Release|x64.ActiveCfg = Release|Any CPU
79
+ {7B14B536-4205-4186-B9FD-0765B84F2075}.Release|x64.Build.0 = Release|Any CPU
80
+ {7B14B536-4205-4186-B9FD-0765B84F2075}.Release|x86.ActiveCfg = Release|Any CPU
81
+ {7B14B536-4205-4186-B9FD-0765B84F2075}.Release|x86.Build.0 = Release|Any CPU
82
+ {3D510701-FF05-4E3B-BB99-BDB97963C3F8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
83
+ {3D510701-FF05-4E3B-BB99-BDB97963C3F8}.Debug|Any CPU.Build.0 = Debug|Any CPU
84
+ {3D510701-FF05-4E3B-BB99-BDB97963C3F8}.Debug|ARM64.ActiveCfg = Debug|Any CPU
85
+ {3D510701-FF05-4E3B-BB99-BDB97963C3F8}.Debug|ARM64.Build.0 = Debug|Any CPU
86
+ {3D510701-FF05-4E3B-BB99-BDB97963C3F8}.Debug|x64.ActiveCfg = Debug|Any CPU
87
+ {3D510701-FF05-4E3B-BB99-BDB97963C3F8}.Debug|x64.Build.0 = Debug|Any CPU
88
+ {3D510701-FF05-4E3B-BB99-BDB97963C3F8}.Debug|x86.ActiveCfg = Debug|Any CPU
89
+ {3D510701-FF05-4E3B-BB99-BDB97963C3F8}.Debug|x86.Build.0 = Debug|Any CPU
90
+ {3D510701-FF05-4E3B-BB99-BDB97963C3F8}.Release|Any CPU.ActiveCfg = Release|Any CPU
91
+ {3D510701-FF05-4E3B-BB99-BDB97963C3F8}.Release|Any CPU.Build.0 = Release|Any CPU
92
+ {3D510701-FF05-4E3B-BB99-BDB97963C3F8}.Release|ARM64.ActiveCfg = Release|Any CPU
93
+ {3D510701-FF05-4E3B-BB99-BDB97963C3F8}.Release|ARM64.Build.0 = Release|Any CPU
94
+ {3D510701-FF05-4E3B-BB99-BDB97963C3F8}.Release|x64.ActiveCfg = Release|Any CPU
95
+ {3D510701-FF05-4E3B-BB99-BDB97963C3F8}.Release|x64.Build.0 = Release|Any CPU
96
+ {3D510701-FF05-4E3B-BB99-BDB97963C3F8}.Release|x86.ActiveCfg = Release|Any CPU
97
+ {3D510701-FF05-4E3B-BB99-BDB97963C3F8}.Release|x86.Build.0 = Release|Any CPU
98
EndGlobalSection
99
GlobalSection(SolutionProperties) = preSolution
100
HideSolutionNode = FALSE
src/libs/libs.v3.ncrunchsolution
new
+6
@@ -0,0 +1,6 @@
1
+<SolutionConfiguration>
2
+ <Settings>
3
+ <AllowParallelTestExecution>True</AllowParallelTestExecution>
4
+ <SolutionConfigured>True</SolutionConfigured>
5
+ </Settings>
6
+</SolutionConfiguration>
\ No newline at end of file
src/libs/libs_t.proj
+2
@@ -2,5 +2,7 @@
2
<ItemGroup>
3
<ProjectReference Include="dutil\dutil_t.proj" />
4
<ProjectReference Include="wcautil\wcautil_t.proj" />
5
+ <ProjectReference Include="WixToolset.Versioning\WixToolset.Versioning.csproj" Targets="Pack" />
6
+ <ProjectReference Include="test\WixToolsetTest.Versioning\WixToolsetTest.Versioning.csproj" />
7
</ItemGroup>
8
</Project>
src/libs/test/WixToolsetTest.Versioning/VerUtilTestsFixture.cs
new
+683
@@ -0,0 +1,683 @@
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.Versioning
4
+{
5
+ using System;
6
+ using WixToolset.Versioning;
7
+ using Xunit;
8
+
9
+ public class VerUtilTestsFixture
10
+ {
11
+ [Fact]
12
+ public void VerCompareVersionsTreatsMissingRevisionAsZero()
13
+ {
14
+ var version1 = WixVersion.Parse("1.2.3.4");
15
+ var version2 = WixVersion.Parse("1.2.3");
16
+ var version3 = WixVersion.Parse("1.2.3.0");
17
+
18
+ Assert.Null(version1.Prefix);
19
+ Assert.Equal(1U, version1.Major);
20
+ Assert.Equal(2U, version1.Minor);
21
+ Assert.Equal(3U, version1.Patch);
22
+ Assert.Equal(4U, version1.Revision);
23
+ Assert.Null(version1.Labels);
24
+ Assert.Null(version1.Metadata);
25
+ Assert.False(version1.Invalid);
26
+ Assert.True(version1.HasMajor);
27
+ Assert.True(version1.HasMinor);
28
+ Assert.True(version1.HasPatch);
29
+ Assert.True(version1.HasRevision);
30
+
31
+ Assert.Null(version2.Prefix);
32
+ Assert.Equal(1U, version2.Major);
33
+ Assert.Equal(2U, version2.Minor);
34
+ Assert.Equal(3U, version2.Patch);
35
+ Assert.Equal(0U, version2.Revision);
36
+ Assert.Null(version2.Labels);
37
+ Assert.Null(version2.Metadata);
38
+ Assert.False(version2.Invalid);
39
+ Assert.True(version2.HasMajor);
40
+ Assert.True(version2.HasMinor);
41
+ Assert.True(version2.HasPatch);
42
+ Assert.False(version2.HasRevision);
43
+
44
+ Assert.Null(version3.Prefix);
45
+ Assert.Equal(1U, version3.Major);
46
+ Assert.Equal(2U, version3.Minor);
47
+ Assert.Equal(3U, version3.Patch);
48
+ Assert.Equal(0U, version3.Revision);
49
+ Assert.Null(version3.Labels);
50
+ Assert.Null(version3.Metadata);
51
+ Assert.False(version3.Invalid);
52
+ Assert.True(version3.HasMajor);
53
+ Assert.True(version3.HasMinor);
54
+ Assert.True(version3.HasPatch);
55
+ Assert.True(version3.HasRevision);
56
+
57
+ Assert.Equal(1, version1.CompareTo(version2));
58
+ Assert.Equal(0, version3.CompareTo(version2));
59
+ }
60
+
61
+ [Fact]
62
+ public void VerCompareVersionsTreatsNumericReleaseLabelsAsNumbers()
63
+ {
64
+ var version1 = WixVersion.Parse("1.0-2.0");
65
+ var version2 = WixVersion.Parse("1.0-19");
66
+
67
+ Assert.Null(version1.Prefix);
68
+ Assert.Equal(1U, version1.Major);
69
+ Assert.Equal(0U, version1.Minor);
70
+ Assert.Equal(0U, version1.Patch);
71
+ Assert.Equal(0U, version1.Revision);
72
+ Assert.Equal(2, version1.Labels.Length);
73
+
74
+ Assert.Equal(2U, version1.Labels[0].Numeric);
75
+ Assert.Equal("2", version1.Labels[0].Label);
76
+
77
+ Assert.Equal(0U, version1.Labels[1].Numeric);
78
+ Assert.Equal("0", version1.Labels[1].Label);
79
+
80
+ Assert.Null(version1.Metadata);
81
+ Assert.False(version1.Invalid);
82
+ Assert.True(version1.HasMajor);
83
+ Assert.True(version1.HasMinor);
84
+ Assert.False(version1.HasPatch);
85
+ Assert.False(version1.HasRevision);
86
+
87
+
88
+ Assert.Null(version2.Prefix);
89
+ Assert.Equal(1U, version2.Major);
90
+ Assert.Equal(0U, version2.Minor);
91
+ Assert.Equal(0U, version2.Patch);
92
+ Assert.Equal(0U, version2.Revision);
93
+ Assert.Single(version2.Labels);
94
+
95
+ Assert.Equal(19U, version2.Labels[0].Numeric);
96
+ Assert.Equal("19", version2.Labels[0].Label);
97
+
98
+ Assert.Null(version2.Metadata);
99
+ Assert.False(version2.Invalid);
100
+ Assert.True(version2.HasMajor);
101
+ Assert.True(version2.HasMinor);
102
+ Assert.False(version2.HasPatch);
103
+ Assert.False(version2.HasRevision);
104
+
105
+ TestVerutilCompareParsedVersions(version1, version2, -1);
106
+ }
107
+
108
+ [Fact]
109
+ public void VerCompareVersionsHandlesNormallyInvalidVersions()
110
+ {
111
+ var version1 = WixVersion.Parse("10.-4.0");
112
+ var version2 = WixVersion.Parse("10.-2.0");
113
+ var version3 = WixVersion.Parse("0");
114
+ var version4 = WixVersion.Parse("");
115
+ var version5 = WixVersion.Parse("10-2");
116
+ var version6 = WixVersion.Parse("10-4.@");
117
+
118
+
119
+ Assert.Null(version1.Prefix);
120
+ Assert.Equal(10U, version1.Major);
121
+ Assert.Equal(0U, version1.Minor);
122
+ Assert.Equal(0U, version1.Patch);
123
+ Assert.Equal(0U, version1.Revision);
124
+ Assert.Null(version1.Labels);
125
+ Assert.Equal("-4.0", version1.Metadata);
126
+ Assert.True(version1.Invalid);
127
+ Assert.True(version1.HasMajor);
128
+ Assert.False(version1.HasMinor);
129
+ Assert.False(version1.HasPatch);
130
+ Assert.False(version1.HasRevision);
131
+
132
+
133
+ Assert.Null(version2.Prefix);
134
+ Assert.Equal(10U, version2.Major);
135
+ Assert.Equal(0U, version2.Minor);
136
+ Assert.Equal(0U, version2.Patch);
137
+ Assert.Equal(0U, version2.Revision);
138
+ Assert.Null(version2.Labels);
139
+ Assert.Equal("-2.0", version2.Metadata);
140
+ Assert.True(version2.Invalid);
141
+ Assert.True(version2.HasMajor);
142
+ Assert.False(version2.HasMinor);
143
+ Assert.False(version2.HasPatch);
144
+ Assert.False(version2.HasRevision);
145
+
146
+
147
+ Assert.Null(version3.Prefix);
148
+ Assert.Equal(0U, version3.Major);
149
+ Assert.Equal(0U, version3.Minor);
150
+ Assert.Equal(0U, version3.Patch);
151
+ Assert.Equal(0U, version3.Revision);
152
+ Assert.Null(version3.Labels);
153
+ Assert.Null(version3.Metadata);
154
+ Assert.False(version3.Invalid);
155
+ Assert.True(version3.HasMajor);
156
+ Assert.False(version3.HasMinor);
157
+ Assert.False(version3.HasPatch);
158
+ Assert.False(version3.HasRevision);
159
+
160
+ Assert.Null(version4.Prefix);
161
+ Assert.Equal(0U, version4.Major);
162
+ Assert.Equal(0U, version4.Minor);
163
+ Assert.Equal(0U, version4.Patch);
164
+ Assert.Equal(0U, version4.Revision);
165
+ Assert.Null(version4.Labels);
166
+ Assert.Equal(String.Empty, version4.Metadata);
167
+ Assert.True(version4.Invalid);
168
+ Assert.False(version4.HasMajor);
169
+ Assert.False(version4.HasMinor);
170
+ Assert.False(version4.HasPatch);
171
+ Assert.False(version4.HasRevision);
172
+
173
+ Assert.Null(version5.Prefix);
174
+ Assert.Equal(10U, version5.Major);
175
+ Assert.Equal(0U, version5.Minor);
176
+ Assert.Equal(0U, version5.Patch);
177
+ Assert.Equal(0U, version5.Revision);
178
+ Assert.Single(version5.Labels);
179
+ Assert.Equal(2U, version5.Labels[0].Numeric);
180
+ Assert.Equal("2", version5.Labels[0].Label);
181
+
182
+ Assert.Null(version5.Metadata);
183
+ Assert.False(version5.Invalid);
184
+ Assert.True(version5.HasMajor);
185
+ Assert.False(version5.HasMinor);
186
+ Assert.False(version5.HasPatch);
187
+ Assert.False(version5.HasRevision);
188
+
189
+ Assert.Null(version6.Prefix);
190
+ Assert.Equal(10U, version6.Major);
191
+ Assert.Equal(0U, version6.Minor);
192
+ Assert.Equal(0U, version6.Patch);
193
+ Assert.Equal(0U, version6.Revision);
194
+ Assert.Single(version6.Labels);
195
+ Assert.Equal(4U, version6.Labels[0].Numeric);
196
+ Assert.Equal("4", version6.Labels[0].Label);
197
+
198
+ Assert.Equal("@", version6.Metadata);
199
+ Assert.True(version6.Invalid);
200
+ Assert.True(version6.HasMajor);
201
+ Assert.False(version6.HasMinor);
202
+ Assert.False(version6.HasPatch);
203
+ Assert.False(version6.HasRevision);
204
+
205
+ TestVerutilCompareParsedVersions(version1, version2, 1);
206
+ TestVerutilCompareParsedVersions(version3, version4, 1);
207
+ TestVerutilCompareParsedVersions(version5, version6, -1);
208
+ }
209
+
210
+ [Fact]
211
+ public void VerCompareVersionsTreatsHyphenAsVersionSeparator()
212
+ {
213
+ var version1 = WixVersion.Parse("0.0.1-a");
214
+ var version2 = WixVersion.Parse("0-2");
215
+ var version3 = WixVersion.Parse("1-2");
216
+
217
+
218
+ Assert.Null(version1.Prefix);
219
+ Assert.Equal(0U, version1.Major);
220
+ Assert.Equal(0U, version1.Minor);
221
+ Assert.Equal(1U, version1.Patch);
222
+ Assert.Equal(0U, version1.Revision);
223
+ Assert.Single(version1.Labels);
224
+ Assert.Null(version1.Labels[0].Numeric);
225
+ Assert.Equal("a", version1.Labels[0].Label);
226
+
227
+ Assert.Null(version1.Metadata);
228
+ Assert.False(version1.Invalid);
229
+ Assert.True(version1.HasMajor);
230
+ Assert.True(version1.HasMinor);
231
+ Assert.True(version1.HasPatch);
232
+ Assert.False(version1.HasRevision);
233
+
234
+ Assert.Null(version2.Prefix);
235
+ Assert.Equal(0U, version2.Major);
236
+ Assert.Equal(0U, version2.Minor);
237
+ Assert.Equal(0U, version2.Patch);
238
+ Assert.Equal(0U, version2.Revision);
239
+ Assert.Single(version2.Labels);
240
+ Assert.Equal(2U, version2.Labels[0].Numeric);
241
+ Assert.Equal("2", version2.Labels[0].Label);
242
+
243
+ Assert.Null(version2.Metadata);
244
+ Assert.False(version2.Invalid);
245
+ Assert.True(version2.HasMajor);
246
+ Assert.False(version2.HasMinor);
247
+ Assert.False(version2.HasPatch);
248
+ Assert.False(version2.HasRevision);
249
+
250
+ Assert.Null(version3.Prefix);
251
+ Assert.Equal(1U, version3.Major);
252
+ Assert.Equal(0U, version3.Minor);
253
+ Assert.Equal(0U, version3.Patch);
254
+ Assert.Equal(0U, version3.Revision);
255
+ Assert.Single(version3.Labels);
256
+ Assert.Equal(2U, version3.Labels[0].Numeric);
257
+ Assert.Equal("2", version3.Labels[0].Label);
258
+
259
+ Assert.Null(version3.Metadata);
260
+ Assert.False(version3.Invalid);
261
+ Assert.True(version3.HasMajor);
262
+ Assert.False(version3.HasMinor);
263
+ Assert.False(version3.HasPatch);
264
+ Assert.False(version3.HasRevision);
265
+
266
+ TestVerutilCompareParsedVersions(version1, version2, 1);
267
+ TestVerutilCompareParsedVersions(version1, version3, -1);
268
+ }
269
+
270
+ [Fact]
271
+ public void VerCompareVersionsIgnoresLeadingZeroes()
272
+ {
273
+ var version1 = WixVersion.Parse("0.01-a.1");
274
+ var version2 = WixVersion.Parse("0.1.0-a.1");
275
+ var version3 = WixVersion.Parse("0.1-a.b.0");
276
+ var version4 = WixVersion.Parse("0.1.0-a.b.000");
277
+
278
+ Assert.Null(version1.Prefix);
279
+ Assert.Equal(0U, version1.Major);
280
+ Assert.Equal(1U, version1.Minor);
281
+ Assert.Equal(0U, version1.Patch);
282
+ Assert.Equal(0U, version1.Revision);
283
+ Assert.Equal(2, version1.Labels.Length);
284
+ Assert.Null(version1.Labels[0].Numeric);
285
+ Assert.Equal("a", version1.Labels[0].Label);
286
+ Assert.Equal(1U, version1.Labels[1].Numeric);
287
+ Assert.Equal("1", version1.Labels[1].Label);
288
+
289
+ Assert.Null(version1.Metadata);
290
+ Assert.False(version1.Invalid);
291
+ Assert.True(version1.HasMajor);
292
+ Assert.True(version1.HasMinor);
293
+ Assert.False(version1.HasPatch);
294
+ Assert.False(version1.HasRevision);
295
+
296
+ Assert.Null(version2.Prefix);
297
+ Assert.Equal(0U, version2.Major);
298
+ Assert.Equal(1U, version2.Minor);
299
+ Assert.Equal(0U, version2.Patch);
300
+ Assert.Equal(0U, version2.Revision);
301
+ Assert.Equal(2, version2.Labels.Length);
302
+
303
+ Assert.Null(version2.Labels[0].Numeric);
304
+ Assert.Equal("a", version2.Labels[0].Label);
305
+ Assert.Equal(1U, version2.Labels[1].Numeric);
306
+ Assert.Equal("1", version2.Labels[1].Label);
307
+
308
+ Assert.Null(version2.Metadata);
309
+ Assert.False(version2.Invalid);
310
+ Assert.True(version2.HasMajor);
311
+ Assert.True(version2.HasMinor);
312
+ Assert.True(version2.HasPatch);
313
+ Assert.False(version2.HasRevision);
314
+
315
+ Assert.Null(version3.Prefix);
316
+ Assert.Equal(0U, version3.Major);
317
+ Assert.Equal(1U, version3.Minor);
318
+ Assert.Equal(0U, version3.Patch);
319
+ Assert.Equal(0U, version3.Revision);
320
+ Assert.Equal(3, version3.Labels.Length);
321
+ Assert.Null(version3.Labels[0].Numeric);
322
+ Assert.Equal("a", version3.Labels[0].Label);
323
+ Assert.Null(version3.Labels[1].Numeric);
324
+ Assert.Equal("b", version3.Labels[1].Label);
325
+ Assert.Equal(0U, version3.Labels[2].Numeric);
326
+ Assert.Equal("0", version3.Labels[2].Label);
327
+
328
+ Assert.Null(version3.Metadata);
329
+ Assert.False(version3.Invalid);
330
+ Assert.True(version3.HasMajor);
331
+ Assert.True(version3.HasMinor);
332
+ Assert.False(version3.HasPatch);
333
+ Assert.False(version3.HasRevision);
334
+
335
+ Assert.Null(version4.Prefix);
336
+ Assert.Equal(0U, version4.Major);
337
+ Assert.Equal(1U, version4.Minor);
338
+ Assert.Equal(0U, version4.Patch);
339
+ Assert.Equal(0U, version4.Revision);
340
+ Assert.Equal(3, version4.Labels.Length);
341
+ Assert.Null(version4.Labels[0].Numeric);
342
+ Assert.Equal("a", version4.Labels[0].Label);
343
+ Assert.Null(version4.Labels[1].Numeric);
344
+ Assert.Equal("b", version4.Labels[1].Label);
345
+ Assert.Equal(0U, version4.Labels[2].Numeric);
346
+ Assert.Equal("000", version4.Labels[2].Label);
347
+
348
+ Assert.Null(version4.Metadata);
349
+ Assert.False(version4.Invalid);
350
+ Assert.True(version4.HasMajor);
351
+ Assert.True(version4.HasMinor);
352
+ Assert.True(version4.HasPatch);
353
+ Assert.False(version4.HasRevision);
354
+
355
+ TestVerutilCompareParsedVersions(version1, version2, 0);
356
+ TestVerutilCompareParsedVersions(version3, version4, 0);
357
+ }
358
+
359
+ [Fact]
360
+ public void VerCompareVersionsTreatsUnexpectedContentAsMetadata()
361
+ {
362
+ var version1 = WixVersion.Parse("1.2.3+abcd");
363
+ var version2 = WixVersion.Parse("1.2.3.abcd");
364
+ var version3 = WixVersion.Parse("1.2.3.-abcd");
365
+
366
+ Assert.Null(version1.Prefix);
367
+ Assert.Equal(1U, version1.Major);
368
+ Assert.Equal(2U, version1.Minor);
369
+ Assert.Equal(3U, version1.Patch);
370
+ Assert.Equal(0U, version1.Revision);
371
+ Assert.Null(version1.Labels);
372
+ Assert.Equal("abcd", version1.Metadata);
373
+ Assert.False(version1.Invalid);
374
+ Assert.True(version1.HasMajor);
375
+ Assert.True(version1.HasMinor);
376
+ Assert.True(version1.HasPatch);
377
+ Assert.False(version1.HasRevision);
378
+
379
+ Assert.Null(version2.Prefix);
380
+ Assert.Equal(1U, version2.Major);
381
+ Assert.Equal(2U, version2.Minor);
382
+ Assert.Equal(3U, version2.Patch);
383
+ Assert.Equal(0U, version2.Revision);
384
+ Assert.Null(version2.Labels);
385
+ Assert.Equal("abcd", version2.Metadata);
386
+ Assert.True(version2.Invalid);
387
+ Assert.True(version2.HasMajor);
388
+ Assert.True(version2.HasMinor);
389
+ Assert.True(version2.HasPatch);
390
+ Assert.False(version2.HasRevision);
391
+
392
+
393
+ Assert.Null(version3.Prefix);
394
+ Assert.Equal(1U, version3.Major);
395
+ Assert.Equal(2U, version3.Minor);
396
+ Assert.Equal(3U, version3.Patch);
397
+ Assert.Equal(0U, version3.Revision);
398
+ Assert.Null(version3.Labels);
399
+ Assert.Equal("-abcd", version3.Metadata);
400
+ Assert.True(version3.Invalid);
401
+ Assert.True(version3.HasMajor);
402
+ Assert.True(version3.HasMinor);
403
+ Assert.True(version3.HasPatch);
404
+ Assert.False(version3.HasRevision);
405
+
406
+ TestVerutilCompareParsedVersions(version1, version2, 1);
407
+ TestVerutilCompareParsedVersions(version1, version3, 1);
408
+ TestVerutilCompareParsedVersions(version2, version3, 1);
409
+ }
410
+
411
+ [Fact]
412
+ public void VerCompareVersionsIgnoresLeadingV()
413
+ {
414
+ var version1 = WixVersion.Parse("10.20.30.40");
415
+ var version2 = WixVersion.Parse("v10.20.30.40");
416
+ var version3 = WixVersion.Parse("V10.20.30.40");
417
+ var version4 = WixVersion.Parse("v10.20.30.40-abc");
418
+ var version5 = WixVersion.Parse("vvv");
419
+
420
+ Assert.Null(version1.Prefix);
421
+ Assert.Equal(10U, version1.Major);
422
+ Assert.Equal(20U, version1.Minor);
423
+ Assert.Equal(30U, version1.Patch);
424
+ Assert.Equal(40U, version1.Revision);
425
+ Assert.Null(version1.Labels);
426
+ Assert.Null(version1.Metadata);
427
+ Assert.False(version1.Invalid);
428
+ Assert.True(version1.HasMajor);
429
+ Assert.True(version1.HasMinor);
430
+ Assert.True(version1.HasPatch);
431
+ Assert.True(version1.HasRevision);
432
+
433
+ Assert.Equal('v', version2.Prefix);
434
+ Assert.Equal(10U, version2.Major);
435
+ Assert.Equal(20U, version2.Minor);
436
+ Assert.Equal(30U, version2.Patch);
437
+ Assert.Equal(40U, version2.Revision);
438
+ Assert.Null(version2.Labels);
439
+ Assert.Null(version2.Metadata);
440
+ Assert.False(version2.Invalid);
441
+ Assert.True(version2.HasMajor);
442
+ Assert.True(version2.HasMinor);
443
+ Assert.True(version2.HasPatch);
444
+ Assert.True(version2.HasRevision);
445
+
446
+ Assert.Equal('V', version3.Prefix);
447
+ Assert.Equal(10U, version3.Major);
448
+ Assert.Equal(20U, version3.Minor);
449
+ Assert.Equal(30U, version3.Patch);
450
+ Assert.Equal(40U, version3.Revision);
451
+ Assert.Null(version3.Labels);
452
+ Assert.Null(version3.Metadata);
453
+ Assert.False(version3.Invalid);
454
+ Assert.True(version3.HasMajor);
455
+ Assert.True(version3.HasMinor);
456
+ Assert.True(version3.HasPatch);
457
+ Assert.True(version3.HasRevision);
458
+
459
+ Assert.Equal('v', version4.Prefix);
460
+ Assert.Equal(10U, version4.Major);
461
+ Assert.Equal(20U, version4.Minor);
462
+ Assert.Equal(30U, version4.Patch);
463
+ Assert.Equal(40U, version4.Revision);
464
+ Assert.Single(version4.Labels);
465
+ Assert.Null(version4.Labels[0].Numeric);
466
+ Assert.Equal("abc", version4.Labels[0].Label);
467
+
468
+ Assert.Null(version4.Metadata);
469
+ Assert.False(version4.Invalid);
470
+ Assert.True(version4.HasMajor);
471
+ Assert.True(version4.HasMinor);
472
+ Assert.True(version4.HasPatch);
473
+ Assert.True(version4.HasRevision);
474
+
475
+ Assert.Null(version5.Prefix);
476
+ Assert.Equal(0U, version5.Major);
477
+ Assert.Equal(0U, version5.Minor);
478
+ Assert.Equal(0U, version5.Patch);
479
+ Assert.Equal(0U, version5.Revision);
480
+ Assert.Null(version5.Labels);
481
+ Assert.Equal("vvv", version5.Metadata);
482
+ Assert.True(version5.Invalid);
483
+ Assert.False(version5.HasMajor);
484
+ Assert.False(version5.HasMinor);
485
+ Assert.False(version5.HasPatch);
486
+ Assert.False(version5.HasRevision);
487
+
488
+ TestVerutilCompareParsedVersions(version1, version2, 0);
489
+ TestVerutilCompareParsedVersions(version1, version3, 0);
490
+ TestVerutilCompareParsedVersions(version1, version4, 1);
491
+ }
492
+
493
+ [Fact]
494
+ public void VerCompareVersionsHandlesTooLargeNumbers()
495
+ {
496
+ var version1 = WixVersion.Parse("4294967295.4294967295.4294967295.4294967295");
497
+ var version2 = WixVersion.Parse("4294967296.4294967296.4294967296.4294967296");
498
+
499
+ Assert.Null(version1.Prefix);
500
+ Assert.Equal(4294967295, version1.Major);
501
+ Assert.Equal(4294967295, version1.Minor);
502
+ Assert.Equal(4294967295, version1.Patch);
503
+ Assert.Equal(4294967295, version1.Revision);
504
+ Assert.Null(version1.Labels);
505
+ Assert.Null(version1.Metadata);
506
+ Assert.False(version1.Invalid);
507
+ Assert.True(version1.HasMajor);
508
+ Assert.True(version1.HasMinor);
509
+ Assert.True(version1.HasPatch);
510
+ Assert.True(version1.HasRevision);
511
+
512
+ Assert.Null(version2.Prefix);
513
+ Assert.Equal(0U, version2.Major);
514
+ Assert.Equal(0U, version2.Minor);
515
+ Assert.Equal(0U, version2.Patch);
516
+ Assert.Equal(0U, version2.Revision);
517
+ Assert.Null(version2.Labels);
518
+ Assert.Equal("4294967296.4294967296.4294967296.4294967296", version2.Metadata);
519
+ Assert.True(version2.Invalid);
520
+ Assert.False(version2.HasMajor);
521
+ Assert.False(version2.HasMinor);
522
+ Assert.False(version2.HasPatch);
523
+ Assert.False(version2.HasRevision);
524
+
525
+ TestVerutilCompareParsedVersions(version1, version2, 1);
526
+ }
527
+
528
+ [Fact]
529
+ public void VerCompareVersionsIgnoresMetadataForValidVersions()
530
+ {
531
+ var version1 = WixVersion.Parse("1.2.3+abc");
532
+ var version2 = WixVersion.Parse("1.2.3+xyz");
533
+
534
+ Assert.Null(version1.Prefix);
535
+ Assert.Equal(1U, version1.Major);
536
+ Assert.Equal(2U, version1.Minor);
537
+ Assert.Equal(3U, version1.Patch);
538
+ Assert.Equal(0U, version1.Revision);
539
+ Assert.Null(version1.Labels);
540
+ Assert.Equal("abc", version1.Metadata);
541
+ Assert.False(version1.Invalid);
542
+ Assert.True(version1.HasMajor);
543
+ Assert.True(version1.HasMinor);
544
+ Assert.True(version1.HasPatch);
545
+ Assert.False(version1.HasRevision);
546
+
547
+
548
+ Assert.Null(version2.Prefix);
549
+ Assert.Equal(1U, version2.Major);
550
+ Assert.Equal(2U, version2.Minor);
551
+ Assert.Equal(3U, version2.Patch);
552
+ Assert.Equal(0U, version2.Revision);
553
+ Assert.Null(version2.Labels);
554
+ Assert.Equal("xyz", version2.Metadata);
555
+ Assert.False(version2.Invalid);
556
+ Assert.True(version2.HasMajor);
557
+ Assert.True(version2.HasMinor);
558
+ Assert.True(version2.HasPatch);
559
+ Assert.False(version2.HasRevision);
560
+
561
+ TestVerutilCompareParsedVersions(version1, version2, 0);
562
+ }
563
+
564
+ [Fact]
565
+ public void VerParseVersionTreatsTrailingDotsAsInvalid()
566
+ {
567
+ var version1 = WixVersion.Parse(".");
568
+ var version2 = WixVersion.Parse("1.");
569
+ var version3 = WixVersion.Parse("2.1.");
570
+ var version4 = WixVersion.Parse("3.2.1.");
571
+ var version5 = WixVersion.Parse("4.3.2.1.");
572
+ var version6 = WixVersion.Parse("5-.");
573
+ var version7 = WixVersion.Parse("6-a.");
574
+
575
+ Assert.Null(version1.Prefix);
576
+ Assert.Equal(0U, version1.Major);
577
+ Assert.Equal(0U, version1.Minor);
578
+ Assert.Equal(0U, version1.Patch);
579
+ Assert.Equal(0U, version1.Revision);
580
+ Assert.Null(version1.Labels);
581
+ Assert.Equal(".", version1.Metadata);
582
+ Assert.True(version1.Invalid);
583
+ Assert.False(version1.HasMajor);
584
+ Assert.False(version1.HasMinor);
585
+ Assert.False(version1.HasPatch);
586
+ Assert.False(version1.HasRevision);
587
+
588
+
589
+ Assert.Null(version2.Prefix);
590
+ Assert.Equal(1U, version2.Major);
591
+ Assert.Equal(0U, version2.Minor);
592
+ Assert.Equal(0U, version2.Patch);
593
+ Assert.Equal(0U, version2.Revision);
594
+ Assert.Null(version2.Labels);
595
+ Assert.Empty(version2.Metadata);
596
+ Assert.True(version2.Invalid);
597
+ Assert.True(version2.HasMajor);
598
+ Assert.False(version2.HasMinor);
599
+ Assert.False(version2.HasPatch);
600
+ Assert.False(version2.HasRevision);
601
+
602
+
603
+ Assert.Null(version3.Prefix);
604
+ Assert.Equal(2U, version3.Major);
605
+ Assert.Equal(1U, version3.Minor);
606
+ Assert.Equal(0U, version3.Patch);
607
+ Assert.Equal(0U, version3.Revision);
608
+ Assert.Null(version3.Labels);
609
+ Assert.Empty(version3.Metadata);
610
+ Assert.True(version3.Invalid);
611
+ Assert.True(version3.HasMajor);
612
+ Assert.True(version3.HasMinor);
613
+ Assert.False(version3.HasPatch);
614
+ Assert.False(version3.HasRevision);
615
+
616
+ Assert.Null(version4.Prefix);
617
+ Assert.Equal(3U, version4.Major);
618
+ Assert.Equal(2U, version4.Minor);
619
+ Assert.Equal(1U, version4.Patch);
620
+ Assert.Equal(0U, version4.Revision);
621
+ Assert.Null(version4.Labels);
622
+ Assert.Empty(version4.Metadata);
623
+ Assert.True(version4.Invalid);
624
+ Assert.True(version4.HasMajor);
625
+ Assert.True(version4.HasMinor);
626
+ Assert.True(version4.HasPatch);
627
+ Assert.False(version4.HasRevision);
628
+
629
+ Assert.Null(version5.Prefix);
630
+ Assert.Equal(4U, version5.Major);
631
+ Assert.Equal(3U, version5.Minor);
632
+ Assert.Equal(2U, version5.Patch);
633
+ Assert.Equal(1U, version5.Revision);
634
+ Assert.Null(version5.Labels);
635
+ Assert.Empty(version5.Metadata);
636
+ Assert.True(version5.Invalid);
637
+ Assert.True(version5.HasMajor);
638
+ Assert.True(version5.HasMinor);
639
+ Assert.True(version5.HasPatch);
640
+ Assert.True(version5.HasRevision);
641
+
642
+ Assert.Null(version6.Prefix);
643
+ Assert.Equal(5U, version6.Major);
644
+ Assert.Equal(0U, version6.Minor);
645
+ Assert.Equal(0U, version6.Patch);
646
+ Assert.Equal(0U, version6.Revision);
647
+ Assert.Null(version6.Labels);
648
+ Assert.Equal(".", version6.Metadata);
649
+ Assert.True(version6.Invalid);
650
+ Assert.True(version6.HasMajor);
651
+ Assert.False(version6.HasMinor);
652
+ Assert.False(version6.HasPatch);
653
+ Assert.False(version6.HasRevision);
654
+
655
+ Assert.Null(version7.Prefix);
656
+ Assert.Equal(6U, version7.Major);
657
+ Assert.Equal(0U, version7.Minor);
658
+ Assert.Equal(0U, version7.Patch);
659
+ Assert.Equal(0U, version7.Revision);
660
+ Assert.Single(version7.Labels);
661
+ Assert.Null(version7.Labels[0].Numeric);
662
+ Assert.Equal("a", version7.Labels[0].Label);
663
+ Assert.Empty(version7.Metadata);
664
+ Assert.True(version7.Invalid);
665
+ Assert.True(version7.HasMajor);
666
+ Assert.False(version7.HasMinor);
667
+ Assert.False(version7.HasPatch);
668
+ Assert.False(version7.HasRevision);
669
+ }
670
+
671
+ private static void TestVerutilCompareParsedVersions(WixVersion version1, WixVersion version2, int expectedResult)
672
+ {
673
+ var result = version1.CompareTo(version2);
674
+ Assert.Equal(expectedResult, result);
675
+
676
+ result = version2.CompareTo(version1);
677
+ Assert.Equal(expectedResult, -result);
678
+
679
+ var equal = version1.Equals(version2);
680
+ Assert.Equal(expectedResult == 0, equal);
681
+ }
682
+ }
683
+}
src/libs/test/WixToolsetTest.Versioning/WixToolsetTest.Versioning.csproj
new
+17
@@ -0,0 +1,17 @@
1
+<?xml version="1.0" encoding="utf-8"?>
2
+<!-- 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. -->
3
+
4
+<Project Sdk="Microsoft.NET.Sdk">
5
+ <PropertyGroup>
6
+ <TargetFramework>net6.0</TargetFramework>
7
+ <IsWixTestProject>true</IsWixTestProject>
8
+ </PropertyGroup>
9
+
10
+ <ItemGroup>
11
+ <ProjectReference Include="..\..\WixToolset.Versioning\WixToolset.Versioning.csproj" />
12
+ </ItemGroup>
13
+
14
+ <ItemGroup>
15
+ <PackageReference Include="WixBuildTools.TestSupport" />
16
+ </ItemGroup>
17
+</Project>
src/libs/test/WixToolsetTest.Versioning/WixVerFixture.cs
renamed
+45
-2
@@ -1,10 +1,10 @@
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.Data
3
+namespace WixToolsetTest.Versioning
4
{
5
using System;
6
using System.Linq;
7
- using WixToolset.Data;
7
+ using WixToolset.Versioning;
8
using Xunit;
9
10
public class WixVerFixture
@@ -404,5 +404,48 @@ namespace WixToolsetTest.Data
404
Assert.Equal(String.Empty, version.Metadata);
405
Assert.True(version.Invalid);
406
}
407
+
408
+ [Fact]
409
+ public void CanCompareVersions()
410
+ {
411
+ var version1 = WixVersion.Parse("1");
412
+ var version10 = WixVersion.Parse("1.0");
413
+ var version100 = WixVersion.Parse("1.0.0");
414
+ var version2 = WixVersion.Parse("2.0.0");
415
+ var version201 = WixVersion.Parse("2.0.1");
416
+ var version2a = WixVersion.Parse("2-a");
417
+ var version2b = WixVersion.Parse("2-b");
418
+ var versionInvalid3a = WixVersion.Parse("3.-a");
419
+ var versionInvalid3b = WixVersion.Parse("3.-b");
420
+
421
+ Assert.Equal(version1, version1);
422
+ Assert.Equal(version1, version10);
423
+ Assert.True(version1 == version10);
424
+ Assert.True(version1 == version100);
425
+ Assert.True(version1 <= version10);
426
+ Assert.True(version1 >= version10);
427
+ Assert.False(version1 != version10);
428
+ Assert.False(version1 < version10);
429
+ Assert.False(version1 < version100);
430
+ Assert.False(version1 > version10);
431
+ Assert.False(version1 > version100);
432
+
433
+ Assert.NotEqual(version1, version2);
434
+ Assert.True(version1 < version2);
435
+ Assert.False(version1 > version2);
436
+
437
+ Assert.True(version2 > version2a);
438
+ Assert.True(version2 != version2a);
439
+ Assert.False(version2 < version2a);
440
+
441
+ Assert.True(version2 < version201);
442
+
443
+ Assert.True(version2a < version2b);
444
+ Assert.False(version2a > version2b);
445
+
446
+ Assert.True(versionInvalid3a < versionInvalid3b);
447
+
448
+ Assert.True(version1 < versionInvalid3a);
449
+ }
450
}
451
}
src/testresultfilelist.txt
+1
@@ -20,4 +20,5 @@ build/logs/TestResults/WixToolsetTest.ManagedHost.trx
20
build/logs/TestResults/WixToolsetTest.Mba.Core.trx
21
build/logs/TestResults/WixToolsetTest.MsiE2E.trx
22
build/logs/TestResults/WixToolsetTest.Sdk.trx
23
+build/logs/TestResults/WixToolsetTest.Versioning.trx
24
build/logs/TestResults/WixToolsetTest.WixE2ETests.trx
\ No newline at end of file
src/wix/WixToolset.Core.Burn/Bind/BindBundleCommand.cs
+1
@@ -17,6 +17,7 @@ namespace WixToolset.Core.Burn
17
using WixToolset.Extensibility;
18
using WixToolset.Extensibility.Data;
19
using WixToolset.Extensibility.Services;
20
+ using WixToolset.Versioning;
21
22
/// <summary>
23
/// Binds a this.bundle.
src/wix/WixToolset.Core.Burn/Bundles/CreateBundleExeCommand.cs
+1
@@ -15,6 +15,7 @@ namespace WixToolset.Core.Burn.Bundles
15
using WixToolset.Dtf.Resources;
16
using WixToolset.Extensibility.Data;
17
using WixToolset.Extensibility.Services;
18
+ using WixToolset.Versioning;
19
20
internal class CreateBundleExeCommand
21
{
src/wix/WixToolset.Core.Burn/WixToolset.Core.Burn.csproj
+1
-1
@@ -15,7 +15,6 @@
15
</PropertyGroup>
16
17
<ItemGroup>
18
- <ProjectReference Include="..\WixToolset.Core\WixToolset.Core.csproj" />
18
<ProjectReference Include="..\WixToolset.Core.Native\WixToolset.Core.Native.csproj" />
19
</ItemGroup>
20
@@ -24,5 +23,6 @@
23
<PackageReference Include="WixToolset.Data" />
24
<PackageReference Include="WixToolset.Dtf.Resources" />
25
<PackageReference Include="WixToolset.Extensibility" />
26
+ <PackageReference Include="WixToolset.Versioning" />
27
</ItemGroup>
28
</Project>
src/wix/WixToolset.Core.WindowsInstaller/Bind/ProcessPackageSoftwareTagsCommand.cs
+1
@@ -11,6 +11,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
11
using WixToolset.Data.Symbols;
12
using WixToolset.Extensibility.Data;
13
using WixToolset.Extensibility.Services;
14
+ using WixToolset.Versioning;
15
16
internal class ProcessPackageSoftwareTagsCommand
17
{
src/wix/WixToolset.Core.WindowsInstaller/WixToolset.Core.WindowsInstaller.csproj
+1
@@ -19,6 +19,7 @@
19
<ItemGroup>
20
<PackageReference Include="WixToolset.Data" />
21
<PackageReference Include="WixToolset.Extensibility" />
22
+ <PackageReference Include="WixToolset.Versioning" />
23
</ItemGroup>
24
25
<ItemGroup>
src/wix/WixToolset.Core/Common.cs
+1
@@ -14,6 +14,7 @@ namespace WixToolset.Core
14
using WixToolset.Data;
15
using WixToolset.Extensibility;
16
using WixToolset.Extensibility.Services;
17
+ using WixToolset.Versioning;
18
19
/// <summary>
20
/// Common Wix utility methods and types.
src/wix/WixToolset.Core/ExtensibilityServices/BackendHelper.cs
+1
@@ -8,6 +8,7 @@ namespace WixToolset.Core.ExtensibilityServices
8
using WixToolset.Data;
9
using WixToolset.Extensibility.Data;
10
using WixToolset.Extensibility.Services;
11
+ using WixToolset.Versioning;
12
13
internal class BackendHelper : LayoutServices, IBackendHelper
14
{
src/wix/WixToolset.Core/ExtensibilityServices/ParseHelper.cs
+1
@@ -15,6 +15,7 @@ namespace WixToolset.Core.ExtensibilityServices
15
using WixToolset.Extensibility;
16
using WixToolset.Extensibility.Data;
17
using WixToolset.Extensibility.Services;
18
+ using WixToolset.Versioning;
19
20
internal class ParseHelper : IParseHelper
21
{
src/wix/WixToolset.Core/WixToolset.Core.csproj
+1
@@ -17,6 +17,7 @@
17
<ItemGroup>
18
<PackageReference Include="WixToolset.Data" />
19
<PackageReference Include="WixToolset.Extensibility" />
20
+ <PackageReference Include="WixToolset.Versioning" />
21
</ItemGroup>
22
23
<ItemGroup>