From 5c509f5611a45bdf9d252b88605537bd28f24a35 Mon Sep 17 00:00:00 2001 From: Rob Mensching Date: Sun, 2 Oct 2022 19:37:55 -0700 Subject: 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 --- src/api/wix/WixToolset.Data/WixVersion.cs | 335 ---------- .../wix/test/WixToolsetTest.Data/WixVerFixture.cs | 408 ------------ .../SetBuildNumber/Directory.Packages.props.pp | 1 + .../WixToolset.Versioning.csproj | 14 + src/libs/WixToolset.Versioning/WixVersion.cs | 463 ++++++++++++++ .../WixToolset.Versioning/WixVersionComparer.cs | 253 ++++++++ src/libs/WixToolset.Versioning/WixVersionLabel.cs | 40 ++ .../dutil/WixToolset.DUtil/dutil.v3.ncrunchproject | 5 + .../DUtilUnitTest/DUtilUnitTest.v3.ncrunchproject | 5 + src/libs/libs.cmd | 24 + src/libs/libs.sln | 40 +- src/libs/libs.v3.ncrunchsolution | 6 + src/libs/libs_t.proj | 2 + .../VerUtilTestsFixture.cs | 683 +++++++++++++++++++++ .../WixToolsetTest.Versioning.csproj | 17 + .../WixToolsetTest.Versioning/WixVerFixture.cs | 451 ++++++++++++++ src/testresultfilelist.txt | 1 + .../WixToolset.Core.Burn/Bind/BindBundleCommand.cs | 1 + .../Bundles/CreateBundleExeCommand.cs | 1 + .../WixToolset.Core.Burn.csproj | 2 +- .../Bind/ProcessPackageSoftwareTagsCommand.cs | 1 + .../WixToolset.Core.WindowsInstaller.csproj | 1 + src/wix/WixToolset.Core/Common.cs | 1 + .../ExtensibilityServices/BackendHelper.cs | 1 + .../ExtensibilityServices/ParseHelper.cs | 1 + src/wix/WixToolset.Core/WixToolset.Core.csproj | 1 + 26 files changed, 2012 insertions(+), 746 deletions(-) delete mode 100644 src/api/wix/WixToolset.Data/WixVersion.cs delete mode 100644 src/api/wix/test/WixToolsetTest.Data/WixVerFixture.cs create mode 100644 src/libs/WixToolset.Versioning/WixToolset.Versioning.csproj create mode 100644 src/libs/WixToolset.Versioning/WixVersion.cs create mode 100644 src/libs/WixToolset.Versioning/WixVersionComparer.cs create mode 100644 src/libs/WixToolset.Versioning/WixVersionLabel.cs create mode 100644 src/libs/dutil/WixToolset.DUtil/dutil.v3.ncrunchproject create mode 100644 src/libs/dutil/test/DUtilUnitTest/DUtilUnitTest.v3.ncrunchproject create mode 100644 src/libs/libs.v3.ncrunchsolution create mode 100644 src/libs/test/WixToolsetTest.Versioning/VerUtilTestsFixture.cs create mode 100644 src/libs/test/WixToolsetTest.Versioning/WixToolsetTest.Versioning.csproj create mode 100644 src/libs/test/WixToolsetTest.Versioning/WixVerFixture.cs diff --git a/src/api/wix/WixToolset.Data/WixVersion.cs b/src/api/wix/WixToolset.Data/WixVersion.cs deleted file mode 100644 index a0de7a10..00000000 --- a/src/api/wix/WixToolset.Data/WixVersion.cs +++ /dev/null @@ -1,335 +0,0 @@ -// 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. - -namespace WixToolset.Data -{ - using System; - using System.Collections.Generic; - - /// - /// WiX Toolset's representation of a version designed to support - /// a different version types including 4-part versions with very - /// large numbers and semantic versions with 4-part versions with - /// or without leading "v" indicators. - /// - [CLSCompliant(false)] - public class WixVersion - { - /// - /// Gets the prefix of the version if present when parsed. Usually, 'v' or 'V'. - /// - public char? Prefix { get; set; } - - /// - /// Gets or sets the major version. - /// - public uint Major { get; set; } - - /// - /// Gets or sets the minor version. - /// - public uint Minor { get; set; } - - /// - /// Gets or sets the patch version. - /// - public uint Patch { get; set; } - - /// - /// Gets or sets the revision version. - /// - public uint Revision { get; set; } - - /// - /// Gets or sets whether the version did not parse correctly. - /// - public bool Invalid { get; set; } - - /// - /// Gets or sets whether the major version was defined. - /// - public bool HasMajor { get; set; } - - /// - /// Gets or sets the whether the minor version was defined. - /// - public bool HasMinor { get; set; } - - /// - /// Gets or sets the whether the patch version was defined. - /// - public bool HasPatch { get; set; } - - /// - /// Gets or sets the whether the revision version was defined. - /// - public bool HasRevision { get; set; } - - /// - /// Gets or sets the labels in the version. - /// - public WixVersionLabel[] Labels { get; set; } - - /// - /// Gets or sets the metadata in the version. - /// - public string Metadata { get; set; } - - /// - /// Parse a string value into a WixVersion. The returned version may be invalid. - /// - /// String value to parse into a version. - /// Parsed version. - public static WixVersion Parse(string parse) - { - var version = new WixVersion(); - - var labels = new List(); - var start = 0; - var end = parse.Length; - - if (end > 0 && (parse[0] == 'v' || parse[0] == 'V')) - { - version.Prefix = parse[0]; - - ++start; - } - - var partBegin = start; - var partEnd = start; - var lastPart = false; - var trailingDot = false; - var invalid = false; - var currentPart = 0; - var parsedVersionNumber = false; - var expectedReleaseLabels = false; - - // Parse version number - while (start < end) - { - trailingDot = false; - - // Find end of part. - for (; ; ) - { - if (partEnd >= end) - { - lastPart = true; - break; - } - - var ch = parse[partEnd]; - - switch (ch) - { - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - ++partEnd; - continue; - case '.': - trailingDot = true; - break; - case '-': - case '+': - lastPart = true; - break; - default: - invalid = true; - break; - } - - break; - } - - var partLength = partEnd - partBegin; - if (invalid || partLength <= 0) - { - invalid = true; - break; - } - - // Parse version part. - var s = parse.Substring(partBegin, partLength); - if (!UInt32.TryParse(s, out var part)) - { - invalid = true; - break; - } - - switch (currentPart) - { - case 0: - version.Major = part; - version.HasMajor = true; - break; - case 1: - version.Minor = part; - version.HasMinor = true; - break; - case 2: - version.Patch = part; - version.HasPatch = true; - break; - case 3: - version.Revision = part; - version.HasRevision = true; - break; - } - - if (trailingDot) - { - ++partEnd; - } - partBegin = partEnd; - ++currentPart; - - if (4 <= currentPart || lastPart) - { - parsedVersionNumber = true; - break; - } - } - - invalid |= !parsedVersionNumber || trailingDot; - - if (!invalid && partBegin < end && parse[partBegin] == '-') - { - partBegin = partEnd = partBegin + 1; - expectedReleaseLabels = true; - lastPart = false; - } - - while (expectedReleaseLabels && partBegin < end) - { - trailingDot = false; - - // Find end of part. - for (; ; ) - { - if (partEnd >= end) - { - lastPart = true; - break; - } - - var ch = parse[partEnd]; - if (ch >= '0' && ch <= '9' || - ch >= 'A' && ch <= 'Z' || - ch >= 'a' && ch <= 'z' || - ch == '-') - { - ++partEnd; - continue; - } - else if (ch == '+') - { - lastPart = true; - } - else if (ch == '.') - { - trailingDot = true; - } - else - { - invalid = true; - } - - break; - } - - var partLength = partEnd - partBegin; - if (invalid || partLength <= 0) - { - invalid = true; - break; - } - - WixVersionLabel label; - var partString = parse.Substring(partBegin, partLength); - if (UInt32.TryParse(partString, out var numericPart)) - { - label = new WixVersionLabel(partString, numericPart); - } - else - { - label = new WixVersionLabel(partString); - } - - labels.Add(label); - - if (trailingDot) - { - ++partEnd; - } - partBegin = partEnd; - - if (lastPart) - { - break; - } - } - - invalid |= expectedReleaseLabels && (labels.Count == 0 || trailingDot); - - if (!invalid && partBegin < end) - { - if (parse[partBegin] == '+') - { - version.Metadata = parse.Substring(partBegin + 1); - } - else - { - invalid = true; - } - } - - version.Labels = labels.Count == 0 ? null : labels.ToArray(); - - if (invalid) - { - // If the prefix was parsed but the rest of the version was - // invalid, store the full invalid version in the Metadata - // and clear the prefix. - if (version.Prefix.HasValue && partBegin == 1) - { - version.Prefix = null; - version.Metadata = parse; - } - else // store the remaining invalid content in Metadata. - { - version.Metadata = (partBegin < end) ? parse.Substring(partBegin) : String.Empty; - } - - version.Invalid = true; - } - - return version; - } - - /// - /// Tries to parse a string value into a valid WixVersion. - /// - /// String value to parse into a version. - /// Parsed version. - /// True if the version was successfully parsed, or false otherwise. - public static bool TryParse(string parse, out WixVersion version) - { - version = WixVersion.Parse(parse); - - if (version.Invalid) - { - version = null; - return false; - } - - return true; - } - } -} diff --git a/src/api/wix/test/WixToolsetTest.Data/WixVerFixture.cs b/src/api/wix/test/WixToolsetTest.Data/WixVerFixture.cs deleted file mode 100644 index 56c72896..00000000 --- a/src/api/wix/test/WixToolsetTest.Data/WixVerFixture.cs +++ /dev/null @@ -1,408 +0,0 @@ -// 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. - -namespace WixToolsetTest.Data -{ - using System; - using System.Linq; - using WixToolset.Data; - using Xunit; - - public class WixVerFixture - { - [Fact] - public void CannotParseEmptyStringAsVersion() - { - Assert.False(WixVersion.TryParse(String.Empty, out var version)); - Assert.Null(version); - } - - [Fact] - public void CanParseEmptyStringAsInvalidVersion() - { - var version = WixVersion.Parse(String.Empty); - Assert.Empty(version.Metadata); - Assert.True(version.Invalid); - } - - [Fact] - public void CannotParseInvalidStringAsVersion() - { - Assert.False(WixVersion.TryParse("invalid", out var version)); - Assert.Null(version); - } - - [Fact] - public void CanParseInvalidStringAsInvalidVersion() - { - var version = WixVersion.Parse("invalid"); - Assert.Equal("invalid", version.Metadata); - Assert.True(version.Invalid); - } - - [Fact] - public void CanParseFourPartVersion() - { - Assert.True(WixVersion.TryParse("1.2.3.4", out var version)); - Assert.Null(version.Prefix); - Assert.Equal((uint)1, version.Major); - Assert.Equal((uint)2, version.Minor); - Assert.Equal((uint)3, version.Patch); - Assert.Equal((uint)4, version.Revision); - Assert.True(version.HasMajor); - Assert.True(version.HasMinor); - Assert.True(version.HasPatch); - Assert.True(version.HasRevision); - Assert.Null(version.Labels); - Assert.Null(version.Metadata); - Assert.False(version.Invalid); - } - - [Fact] - public void CanParseThreePartVersion() - { - Assert.True(WixVersion.TryParse("1.2.3", out var version)); - Assert.Null(version.Prefix); - Assert.Equal((uint)1, version.Major); - Assert.Equal((uint)2, version.Minor); - Assert.Equal((uint)3, version.Patch); - Assert.Equal((uint)0, version.Revision); - Assert.True(version.HasMajor); - Assert.True(version.HasMinor); - Assert.True(version.HasPatch); - Assert.False(version.HasRevision); - Assert.Null(version.Labels); - Assert.Null(version.Metadata); - Assert.False(version.Invalid); - } - - [Fact] - public void CanParseFourPartVersionWithTrailingZero() - { - Assert.True(WixVersion.TryParse("1.2.3.0", out var version)); - Assert.Null(version.Prefix); - Assert.Equal((uint)1, version.Major); - Assert.Equal((uint)2, version.Minor); - Assert.Equal((uint)3, version.Patch); - Assert.Equal((uint)0, version.Revision); - Assert.True(version.HasMajor); - Assert.True(version.HasMinor); - Assert.True(version.HasPatch); - Assert.True(version.HasRevision); - Assert.Null(version.Labels); - Assert.Null(version.Metadata); - Assert.False(version.Invalid); - } - - [Fact] - public void CanParseNumericReleaseLabels() - { - Assert.True(WixVersion.TryParse("1.2-19", out var version)); - Assert.Null(version.Prefix); - Assert.Equal((uint)1, version.Major); - Assert.Equal((uint)2, version.Minor); - Assert.Equal((uint)0, version.Patch); - Assert.Equal((uint)0, version.Revision); - Assert.True(version.HasMajor); - Assert.True(version.HasMinor); - Assert.False(version.HasPatch); - Assert.False(version.HasRevision); - Assert.Equal(new[] { "19" }, version.Labels.Select(l => l.Label).ToArray()); - Assert.Equal(new uint?[] { 19 }, version.Labels.Select(l => l.Numeric).ToArray()); - Assert.Null(version.Metadata); - Assert.False(version.Invalid); - } - - [Fact] - public void CanParseDottedNumericReleaseLabels() - { - Assert.True(WixVersion.TryParse("1.2-2.0", out var version)); - Assert.Null(version.Prefix); - Assert.Equal((uint)1, version.Major); - Assert.Equal((uint)2, version.Minor); - Assert.Equal((uint)0, version.Patch); - Assert.Equal((uint)0, version.Revision); - Assert.True(version.HasMajor); - Assert.True(version.HasMinor); - Assert.False(version.HasPatch); - Assert.False(version.HasRevision); - Assert.Equal(new[] { "2", "0" }, version.Labels.Select(l => l.Label).ToArray()); - Assert.Equal(new uint?[] { 2, 0 }, version.Labels.Select(l => l.Numeric).ToArray()); - Assert.Null(version.Metadata); - Assert.False(version.Invalid); - } - - [Fact] - public void CanParseHyphenAsVersionSeparator() - { - Assert.True(WixVersion.TryParse("0.0.1-a", out var version)); - Assert.Null(version.Prefix); - Assert.Equal((uint)0, version.Major); - Assert.Equal((uint)0, version.Minor); - Assert.Equal((uint)1, version.Patch); - Assert.Equal((uint)0, version.Revision); - Assert.True(version.HasMajor); - Assert.True(version.HasMinor); - Assert.True(version.HasPatch); - Assert.False(version.HasRevision); - Assert.Equal(new[] { "a" }, version.Labels.Select(l => l.Label).ToArray()); - Assert.Equal(new uint?[] { null }, version.Labels.Select(l => l.Numeric).ToArray()); - Assert.Null(version.Metadata); - Assert.False(version.Invalid); - } - - [Fact] - public void CanParseIgnoringLeadingZeros() - { - Assert.True(WixVersion.TryParse("0.01-a.000", out var version)); - Assert.Null(version.Prefix); - Assert.Equal((uint)0, version.Major); - Assert.Equal((uint)1, version.Minor); - Assert.Equal((uint)0, version.Patch); - Assert.Equal((uint)0, version.Revision); - Assert.True(version.HasMajor); - Assert.True(version.HasMinor); - Assert.False(version.HasPatch); - Assert.False(version.HasRevision); - Assert.Equal(new[] { "a", "000" }, version.Labels.Select(l => l.Label).ToArray()); - Assert.Equal(new uint?[] { null, 0 }, version.Labels.Select(l => l.Numeric).ToArray()); - Assert.Null(version.Metadata); - Assert.False(version.Invalid); - } - - [Fact] - public void CanParseMetadata() - { - Assert.True(WixVersion.TryParse("1.2.3+abcd", out var version)); - Assert.Null(version.Prefix); - Assert.Equal((uint)1, version.Major); - Assert.Equal((uint)2, version.Minor); - Assert.Equal((uint)3, version.Patch); - Assert.Equal((uint)0, version.Revision); - Assert.True(version.HasMajor); - Assert.True(version.HasMinor); - Assert.True(version.HasPatch); - Assert.False(version.HasRevision); - Assert.Null(version.Labels); - Assert.Equal("abcd", version.Metadata); - Assert.False(version.Invalid); - } - - [Fact] - public void CannotParseUnexpectedContentAsMetadata() - { - Assert.False(WixVersion.TryParse("1.2.3.abcd", out var version)); - Assert.Null(version); - Assert.False(WixVersion.TryParse("1.2.3.-abcd", out version)); - Assert.Null(version); - } - - [Fact] - public void CanParseUnexpectedContentAsInvalidMetadata() - { - var version = WixVersion.Parse("1.2.3.abcd"); - Assert.Equal("abcd", version.Metadata); - Assert.True(version.Invalid); - - version = WixVersion.Parse("1.2.3.-abcd"); - Assert.Equal("-abcd", version.Metadata); - Assert.True(version.Invalid); - } - - [Fact] - public void CanParseLeadingPrefix() - { - Assert.True(WixVersion.TryParse("v10.20.30.40", out var version)); - Assert.Equal('v', version.Prefix); - Assert.Equal((uint)10, version.Major); - Assert.Equal((uint)20, version.Minor); - Assert.Equal((uint)30, version.Patch); - Assert.Equal((uint)40, version.Revision); - Assert.True(version.HasMajor); - Assert.True(version.HasMinor); - Assert.True(version.HasPatch); - Assert.True(version.HasRevision); - Assert.Null(version.Labels); - Assert.Null(version.Metadata); - Assert.False(version.Invalid); - - Assert.True(WixVersion.TryParse("V100.200.300.400", out var version2)); - Assert.Equal('V', version2.Prefix); - Assert.Equal((uint)100, version2.Major); - Assert.Equal((uint)200, version2.Minor); - Assert.Equal((uint)300, version2.Patch); - Assert.Equal((uint)400, version2.Revision); - Assert.True(version.HasMajor); - Assert.True(version.HasMinor); - Assert.True(version.HasPatch); - Assert.True(version.HasRevision); - Assert.Null(version2.Labels); - Assert.Null(version2.Metadata); - Assert.False(version.Invalid); - } - - [Fact] - public void CanParseVeryLargeNumbers() - { - Assert.True(WixVersion.TryParse("4294967295.4294967295.4294967295.4294967295", out var version)); - Assert.Null(version.Prefix); - Assert.Equal(4294967295, version.Major); - Assert.Equal(4294967295, version.Minor); - Assert.Equal(4294967295, version.Patch); - Assert.Equal(4294967295, version.Revision); - Assert.True(version.HasMajor); - Assert.True(version.HasMinor); - Assert.True(version.HasPatch); - Assert.True(version.HasRevision); - Assert.Null(version.Labels); - Assert.Null(version.Metadata); - Assert.False(version.Invalid); - } - - [Fact] - public void CannotParseTooLargeNumbers() - { - Assert.False(WixVersion.TryParse("4294967296.4294967296.4294967296.4294967296", out var version)); - Assert.Null(version); - } - - [Fact] - public void CanParseInvalidTooLargeNumbers() - { - var version = WixVersion.Parse("4294967296.4294967296.4294967296.4294967296"); - Assert.Equal(0U, version.Major); - Assert.Equal("4294967296.4294967296.4294967296.4294967296", version.Metadata); - Assert.True(version.Invalid); - } - - [Fact] - public void CanParseInvalidTooLargeNumbersWithPrefix() - { - var version = WixVersion.Parse("v4294967296.4294967296.4294967296.4294967296"); - Assert.Equal("v4294967296.4294967296.4294967296.4294967296", version.Metadata); - Assert.Null(version.Prefix); - Assert.True(version.Invalid); - } - - [Fact] - public void CanParseLabelsWithMetadata() - { - Assert.True(WixVersion.TryParse("1.2.3.4-a.b.c.d.5+abc123", out var version)); - Assert.Null(version.Prefix); - Assert.Equal((uint)1, version.Major); - Assert.Equal((uint)2, version.Minor); - Assert.Equal((uint)3, version.Patch); - Assert.Equal((uint)4, version.Revision); - Assert.True(version.HasMajor); - Assert.True(version.HasMinor); - Assert.True(version.HasPatch); - Assert.True(version.HasRevision); - Assert.Equal(new[] { "a", "b", "c", "d", "5" }, version.Labels.Select(l => l.Label).ToArray()); - Assert.Equal(new uint?[] { null, null, null, null, 5 }, version.Labels.Select(l => l.Numeric).ToArray()); - Assert.Equal("abc123", version.Metadata); - Assert.False(version.Invalid); - } - - [Fact] - public void CanParseVersionWithTrailingDotsAsInvalid() - { - var version = WixVersion.Parse("."); - Assert.Null(version.Prefix); - Assert.Equal(0U, version.Major); - Assert.Equal(0U, version.Minor); - Assert.Equal(0U, version.Patch); - Assert.Equal(0U, version.Revision); - Assert.Null(version.Labels); - Assert.False(version.HasMajor); - Assert.False(version.HasMinor); - Assert.False(version.HasPatch); - Assert.False(version.HasRevision); - Assert.Equal(".", version.Metadata); - Assert.True(version.Invalid); - - version = WixVersion.Parse("1."); - Assert.Null(version.Prefix); - Assert.Equal(1U, version.Major); - Assert.Equal(0U, version.Minor); - Assert.Equal(0U, version.Patch); - Assert.Equal(0U, version.Revision); - Assert.Null(version.Labels); - Assert.True(version.HasMajor); - Assert.False(version.HasMinor); - Assert.False(version.HasPatch); - Assert.False(version.HasRevision); - Assert.Equal(String.Empty, version.Metadata); - Assert.True(version.Invalid); - - version = WixVersion.Parse("2.1."); - Assert.Null(version.Prefix); - Assert.Equal(2U, version.Major); - Assert.Equal(1U, version.Minor); - Assert.Equal(0U, version.Patch); - Assert.Equal(0U, version.Revision); - Assert.Null(version.Labels); - Assert.True(version.HasMajor); - Assert.True(version.HasMinor); - Assert.False(version.HasPatch); - Assert.False(version.HasRevision); - Assert.Equal(String.Empty, version.Metadata); - Assert.True(version.Invalid); - - version = WixVersion.Parse("3.2.1."); - Assert.Null(version.Prefix); - Assert.Equal(3U, version.Major); - Assert.Equal(2U, version.Minor); - Assert.Equal(1U, version.Patch); - Assert.Equal(0U, version.Revision); - Assert.Null(version.Labels); - Assert.True(version.HasMajor); - Assert.True(version.HasMinor); - Assert.True(version.HasPatch); - Assert.False(version.HasRevision); - Assert.Equal(String.Empty, version.Metadata); - Assert.True(version.Invalid); - - version = WixVersion.Parse("4.3.2.1."); - Assert.Null(version.Prefix); - Assert.Equal(4U, version.Major); - Assert.Equal(3U, version.Minor); - Assert.Equal(2U, version.Patch); - Assert.Equal(1U, version.Revision); - Assert.Null(version.Labels); - Assert.True(version.HasMajor); - Assert.True(version.HasMinor); - Assert.True(version.HasPatch); - Assert.True(version.HasRevision); - Assert.Equal(String.Empty, version.Metadata); - Assert.True(version.Invalid); - - version = WixVersion.Parse("5-."); - Assert.Null(version.Prefix); - Assert.Equal(5U, version.Major); - Assert.Equal(0U, version.Minor); - Assert.Equal(0U, version.Patch); - Assert.Equal(0U, version.Revision); - Assert.Null(version.Labels); - Assert.True(version.HasMajor); - Assert.False(version.HasMinor); - Assert.False(version.HasPatch); - Assert.False(version.HasRevision); - Assert.Equal(".", version.Metadata); - Assert.True(version.Invalid); - - version = WixVersion.Parse("6-a."); - Assert.Null(version.Prefix); - Assert.Equal(6U, version.Major); - Assert.Equal(0U, version.Minor); - Assert.Equal(0U, version.Patch); - Assert.Equal(0U, version.Revision); - Assert.Equal(new[] { "a" }, version.Labels.Select(l => l.Label).ToArray()); - Assert.Equal(new uint?[] { null }, version.Labels.Select(l => l.Numeric).ToArray()); - Assert.True(version.HasMajor); - Assert.False(version.HasMinor); - Assert.False(version.HasPatch); - Assert.False(version.HasRevision); - Assert.Equal(String.Empty, version.Metadata); - Assert.True(version.Invalid); - } - } -} diff --git a/src/internal/SetBuildNumber/Directory.Packages.props.pp b/src/internal/SetBuildNumber/Directory.Packages.props.pp index f77fcffa..d06990fe 100644 --- a/src/internal/SetBuildNumber/Directory.Packages.props.pp +++ b/src/internal/SetBuildNumber/Directory.Packages.props.pp @@ -19,6 +19,7 @@ + diff --git a/src/libs/WixToolset.Versioning/WixToolset.Versioning.csproj b/src/libs/WixToolset.Versioning/WixToolset.Versioning.csproj new file mode 100644 index 00000000..2c23f391 --- /dev/null +++ b/src/libs/WixToolset.Versioning/WixToolset.Versioning.csproj @@ -0,0 +1,14 @@ + + + + + + netstandard2.0 + $(TargetFrameworks);net472 + 7.3 + WiX Toolset Versioning + embedded + true + true + + diff --git a/src/libs/WixToolset.Versioning/WixVersion.cs b/src/libs/WixToolset.Versioning/WixVersion.cs new file mode 100644 index 00000000..7333701f --- /dev/null +++ b/src/libs/WixToolset.Versioning/WixVersion.cs @@ -0,0 +1,463 @@ +// 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. + +namespace WixToolset.Versioning +{ + using System; + using System.Collections.Generic; + + /// + /// WiX Toolset's representation of a version designed to support + /// a different version types including 4-part versions with very + /// large numbers and semantic versions with 4-part versions with + /// or without leading "v" indicators. + /// + public class WixVersion : IComparable, IComparable, IEquatable + { + /// + /// Gets the prefix of the version if present when parsed. Usually, 'v' or 'V'. + /// + public char? Prefix { get; set; } + + /// + /// Gets or sets the major version. + /// + public uint Major { get; set; } + + /// + /// Gets or sets the minor version. + /// + public uint Minor { get; set; } + + /// + /// Gets or sets the patch version. + /// + public uint Patch { get; set; } + + /// + /// Gets or sets the revision version. + /// + public uint Revision { get; set; } + + /// + /// Gets or sets whether the version did not parse correctly. + /// + public bool Invalid { get; set; } + + /// + /// Gets or sets whether the major version was defined. + /// + public bool HasMajor { get; set; } + + /// + /// Gets or sets the whether the minor version was defined. + /// + public bool HasMinor { get; set; } + + /// + /// Gets or sets the whether the patch version was defined. + /// + public bool HasPatch { get; set; } + + /// + /// Gets or sets the whether the revision version was defined. + /// + public bool HasRevision { get; set; } + + /// + /// Gets or sets the labels in the version. + /// + public WixVersionLabel[] Labels { get; set; } + + /// + /// Gets or sets the metadata in the version. + /// + public string Metadata { get; set; } + + /// + /// Compare to another WixVersion. + /// + /// WixVersion to compare. + /// A comparison between versions. + public int CompareTo(WixVersion version) + { + return WixVersionComparer.Default.Compare(this, version); + } + + /// + /// Compare to another object. + /// + /// Object to compare. + /// A comparison between objects. + public int CompareTo(object version) + { + return WixVersionComparer.Default.Compare(this, version as WixVersion); + } + + /// + /// Returns a value indicating whether the current System.Version object is equal to a specified object. + /// + /// An WixVersion to compare with the current WixVersion object, or null. + /// + /// true if the current WixVersion object and obj are both WixVersion objects, + /// and every component of the current System.Version object matches the corresponding + /// component of obj; otherwise, false. + /// + public bool Equals(WixVersion version) + { + return WixVersionComparer.Default.Equals(this, version); + } + + /// + /// Returns a value indicating whether the current WixVersion object is equal to a specified object. + /// + /// An object to compare with the current WixVersion object, or null. + /// + /// true if the current WixVersion object and obj are both WixVersion objects, + /// and every component of the current System.Version object matches the corresponding + /// component of obj; otherwise, false. + /// + public override bool Equals(object obj) + { + return WixVersionComparer.Default.Equals(this, obj as WixVersion); + } + + /// + /// Returns a hash code for the current WixVersion object. + /// + /// A 32-bit signed integer hash code. + public override int GetHashCode() + { + return WixVersionComparer.Default.GetHashCode(this); + } + + /// + /// Parse a string value into a WixVersion. The returned version may be invalid. + /// + /// String value to parse into a version. + /// Parsed version. + public static WixVersion Parse(string parse) + { + var version = new WixVersion(); + + var labels = new List(); + var start = 0; + var end = parse.Length; + + if (end > 0 && (parse[0] == 'v' || parse[0] == 'V')) + { + version.Prefix = parse[0]; + + ++start; + } + + var partBegin = start; + var partEnd = start; + var lastPart = false; + var trailingDot = false; + var invalid = false; + var currentPart = 0; + var parsedVersionNumber = false; + var expectedReleaseLabels = false; + + // Parse version number + while (start < end) + { + trailingDot = false; + + // Find end of part. + for (; ; ) + { + if (partEnd >= end) + { + lastPart = true; + break; + } + + var ch = parse[partEnd]; + + switch (ch) + { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + ++partEnd; + continue; + case '.': + trailingDot = true; + break; + case '-': + case '+': + lastPart = true; + break; + default: + invalid = true; + break; + } + + break; + } + + var partLength = partEnd - partBegin; + if (invalid || partLength <= 0) + { + invalid = true; + break; + } + + // Parse version part. + var s = parse.Substring(partBegin, partLength); + if (!UInt32.TryParse(s, out var part)) + { + invalid = true; + break; + } + + switch (currentPart) + { + case 0: + version.Major = part; + version.HasMajor = true; + break; + case 1: + version.Minor = part; + version.HasMinor = true; + break; + case 2: + version.Patch = part; + version.HasPatch = true; + break; + case 3: + version.Revision = part; + version.HasRevision = true; + break; + } + + if (trailingDot) + { + ++partEnd; + } + partBegin = partEnd; + ++currentPart; + + if (4 <= currentPart || lastPart) + { + parsedVersionNumber = true; + break; + } + } + + invalid |= !parsedVersionNumber || trailingDot; + + if (!invalid && partBegin < end && parse[partBegin] == '-') + { + partBegin = partEnd = partBegin + 1; + expectedReleaseLabels = true; + lastPart = false; + } + + while (expectedReleaseLabels && partBegin < end) + { + trailingDot = false; + + // Find end of part. + for (; ; ) + { + if (partEnd >= end) + { + lastPart = true; + break; + } + + var ch = parse[partEnd]; + if (ch >= '0' && ch <= '9' || + ch >= 'A' && ch <= 'Z' || + ch >= 'a' && ch <= 'z' || + ch == '-') + { + ++partEnd; + continue; + } + else if (ch == '+') + { + lastPart = true; + } + else if (ch == '.') + { + trailingDot = true; + } + else + { + invalid = true; + } + + break; + } + + var partLength = partEnd - partBegin; + if (invalid || partLength <= 0) + { + invalid = true; + break; + } + + WixVersionLabel label; + var partString = parse.Substring(partBegin, partLength); + if (UInt32.TryParse(partString, out var numericPart)) + { + label = new WixVersionLabel(partString, numericPart); + } + else + { + label = new WixVersionLabel(partString); + } + + labels.Add(label); + + if (trailingDot) + { + ++partEnd; + } + partBegin = partEnd; + + if (lastPart) + { + break; + } + } + + invalid |= expectedReleaseLabels && (labels.Count == 0 || trailingDot); + + if (!invalid && partBegin < end) + { + if (parse[partBegin] == '+') + { + version.Metadata = parse.Substring(partBegin + 1); + } + else + { + invalid = true; + } + } + + version.Labels = labels.Count == 0 ? null : labels.ToArray(); + + if (invalid) + { + // If the prefix was parsed but the rest of the version was + // invalid, store the full invalid version in the Metadata + // and clear the prefix. + if (version.Prefix.HasValue && partBegin == 1) + { + version.Prefix = null; + version.Metadata = parse; + } + else // store the remaining invalid content in Metadata. + { + version.Metadata = (partBegin < end) ? parse.Substring(partBegin) : String.Empty; + } + + version.Invalid = true; + } + + return version; + } + + /// + /// Tries to parse a string value into a valid WixVersion. + /// + /// String value to parse into a version. + /// Parsed version. + /// True if the version was successfully parsed, or false otherwise. + public static bool TryParse(string parse, out WixVersion version) + { + version = WixVersion.Parse(parse); + + if (version.Invalid) + { + version = null; + return false; + } + + return true; + } + + /// + /// Determines whether two specified WixVersion objects are equal. + /// + /// The first WixVersion object. + /// The second WixVersion object. + /// true if v1 equals v2; otherwise, false. + public static bool operator ==(WixVersion v1, WixVersion v2) + { + return WixVersionComparer.Default.Equals(v1, v2); + } + + /// + /// Determines whether two specified System.Version objects are not equal. + /// + /// The first WixVersion object. + /// The second WixVersion object. + /// true if v1 does not equal v2; otherwise, false. + public static bool operator !=(WixVersion v1, WixVersion v2) + { + return !WixVersionComparer.Default.Equals(v1, v2); + } + + /// + /// Determines whether the first specified System.Version object is less than the second specified System.Version object. + /// + /// The first WixVersion object. + /// The second WixVersion object. + /// true if v1 is less than v2; otherwise, false. + /// v1 is null. + public static bool operator <(WixVersion v1, WixVersion v2) + { + return WixVersionComparer.Default.Compare(v1, v2) == -1; + } + + /// + /// Determines whether the first specified System.Version object is greater than the second specified System.Version object. + /// + /// The first WixVersion object. + /// The second WixVersion object. + /// true if v1 is greater than v2; otherwise, false. + public static bool operator >(WixVersion v1, WixVersion v2) + { + return WixVersionComparer.Default.Compare(v1, v2) == 1; + } + + /// + /// Determines whether the first specified System.Version object is less than or equal to the second System.Version object. + /// + /// The first WixVersion object. + /// The second WixVersion object. + /// true if v1 is less than or equal to v2; otherwise, false. + /// v1 is null. + public static bool operator <=(WixVersion v1, WixVersion v2) + { + var result = WixVersionComparer.Default.Compare(v1, v2); + + return result == 0 || result == -1; + } + + /// + /// Determines whether the first specified System.Version object is greater than or equal to the second specified System.Version object. + /// + /// The first WixVersion object. + /// The second WixVersion object. + /// true if v1 is greater than or equal to v2; otherwise, false. + public static bool operator >=(WixVersion v1, WixVersion v2) + { + var result = WixVersionComparer.Default.Compare(v1, v2); + + return result == 0 || result == 1; + } + } +} diff --git a/src/libs/WixToolset.Versioning/WixVersionComparer.cs b/src/libs/WixToolset.Versioning/WixVersionComparer.cs new file mode 100644 index 00000000..be203634 --- /dev/null +++ b/src/libs/WixToolset.Versioning/WixVersionComparer.cs @@ -0,0 +1,253 @@ +// 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. + +namespace WixToolset.Versioning +{ + using System; + using System.Collections.Generic; + + /// + /// WixVersion comparer. + /// + public class WixVersionComparer : IEqualityComparer, IComparer + { + /// + /// Default WixVersion comparer. + /// + public static readonly WixVersionComparer Default = new WixVersionComparer(); + + /// + public int Compare(WixVersion x, WixVersion y) + { + if ((object)x == y) + { + return 0; + } + + if (x is null) + { + return -1; + } + + if (y is null) + { + return 1; + } + + var result = x.Major.CompareTo(y.Major); + if (result != 0) + { + return result; + } + + result = x.Minor.CompareTo(y.Minor); + if (result != 0) + { + return result; + } + + result = x.Patch.CompareTo(y.Patch); + if (result != 0) + { + return result; + } + + result = x.Revision.CompareTo(y.Revision); + if (result != 0) + { + return result; + } + + var xLabelCount = x.Labels?.Length ?? 0; + var yLabelCount = y.Labels?.Length ?? 0; + var maxLabelCount = Math.Max(xLabelCount, yLabelCount); + + if (xLabelCount > 0) + { + if (yLabelCount == 0) + { + return -1; + } + } + else if (yLabelCount > 0) + { + return 1; + } + + for (var i = 0; i < maxLabelCount; ++i) + { + var xLabel = i < xLabelCount ? x.Labels[i] : null; + var yLabel = i < yLabelCount ? y.Labels[i] : null; + + result = CompareReleaseLabel(xLabel, yLabel); + if (result != 0) + { + return result; + } + } + + var compareMetadata = false; + + if (x.Invalid) + { + if (!y.Invalid) + { + return -1; + } + else + { + compareMetadata = true; + } + } + else if (y.Invalid) + { + return 1; + } + + if (compareMetadata) + { + result = String.Compare(x.Metadata, y.Metadata, StringComparison.OrdinalIgnoreCase); + } + + return (result == 0) ? 0 : (result < 0) ? -1 : 1; + } + + /// + public bool Equals(WixVersion x, WixVersion y) + { + if ((object)x == y) + { + return true; + } + + if (x is null) + { + return false; + } + + if (y is null) + { + return false; + } + + if (x.Major != y.Major) + { + return false; + } + + if (x.Minor != y.Minor) + { + return false; + } + + if (x.Patch != y.Patch) + { + return false; + } + + if (x.Revision != y.Revision) + { + return false; + } + + var labelCount = x.Labels?.Length ?? 0; + if (labelCount != (y.Labels?.Length ?? 0)) + { + return false; + } + + for (var i = 0; i < labelCount; ++i) + { + var result = CompareReleaseLabel(x.Labels[i], y.Labels[i]); + if (result != 0) + { + return false; + } + } + + if (x.Invalid) + { + if (y.Invalid) + { + return String.Equals(x.Metadata, y.Metadata, StringComparison.OrdinalIgnoreCase); + } + else + { + return false; + } + } + else if (y.Invalid) + { + return false; + } + + return true; + } + + /// + public int GetHashCode(WixVersion version) + { + var hash = 23L; + hash = hash * 37 + (version.Prefix ?? '\0'); + hash = hash * 37 + version.Major; + hash = hash * 37 + version.Minor; + hash = hash * 37 + version.Patch; + hash = hash * 37 + version.Revision; + hash = hash * 37 + (version.Invalid ? 1 : 0); + hash = hash * 37 + (version.HasMajor ? 1 : 0); + hash = hash * 37 + (version.HasMinor ? 1 : 0); + hash = hash * 37 + (version.HasPatch ? 1 : 0); + hash = hash * 37 + (version.HasRevision ? 1 : 0); + + if (version.Labels != null) + { + foreach (var label in version.Labels) + { + hash = hash * 37 + label.Label.GetHashCode(); + } + } + + hash = hash * 37 + version.Metadata?.GetHashCode() ?? 0; + + return unchecked((int)hash); + } + + private static int CompareReleaseLabel(WixVersionLabel l1, WixVersionLabel l2) + { + if (l1 == l2) + { + return 0; + } + else if (l2 == null) + { + return 1; + } + else if (l1 == null) + { + return -1; + } + + if (l1.Numeric.HasValue) + { + if (l2.Numeric.HasValue) + { + return l1.Numeric.Value.CompareTo(l2.Numeric.Value); + } + else + { + return -1; + } + } + else + { + if (l2.Numeric.HasValue) + { + return 1; + } + else + { + return String.Compare(l1.Label, l2.Label, StringComparison.OrdinalIgnoreCase); + } + } + } + } +} diff --git a/src/libs/WixToolset.Versioning/WixVersionLabel.cs b/src/libs/WixToolset.Versioning/WixVersionLabel.cs new file mode 100644 index 00000000..c5dcb875 --- /dev/null +++ b/src/libs/WixToolset.Versioning/WixVersionLabel.cs @@ -0,0 +1,40 @@ +// 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. + +namespace WixToolset.Versioning +{ + /// + /// Label in a WixVersion. + /// + public class WixVersionLabel + { + /// + /// Creates a string only version label. + /// + /// String value for version label. + public WixVersionLabel(string label) + { + this.Label = label; + } + + /// + /// Creates a string version label with numeric value. + /// + /// String value for version label. + /// Numeric value for the version label. + public WixVersionLabel(string label, uint? numeric) + { + this.Label = label; + this.Numeric = numeric; + } + + /// + /// Gets the string label value. + /// + public string Label { get; set; } + + /// + /// Gets the optional numeric label value. + /// + public uint? Numeric { get; set; } + } +} diff --git a/src/libs/dutil/WixToolset.DUtil/dutil.v3.ncrunchproject b/src/libs/dutil/WixToolset.DUtil/dutil.v3.ncrunchproject new file mode 100644 index 00000000..319cd523 --- /dev/null +++ b/src/libs/dutil/WixToolset.DUtil/dutil.v3.ncrunchproject @@ -0,0 +1,5 @@ + + + True + + \ No newline at end of file diff --git a/src/libs/dutil/test/DUtilUnitTest/DUtilUnitTest.v3.ncrunchproject b/src/libs/dutil/test/DUtilUnitTest/DUtilUnitTest.v3.ncrunchproject new file mode 100644 index 00000000..319cd523 --- /dev/null +++ b/src/libs/dutil/test/DUtilUnitTest/DUtilUnitTest.v3.ncrunchproject @@ -0,0 +1,5 @@ + + + True + + \ No newline at end of file diff --git a/src/libs/libs.cmd b/src/libs/libs.cmd index e3107fbc..e9402701 100644 --- a/src/libs/libs.cmd +++ b/src/libs/libs.cmd @@ -3,18 +3,42 @@ @set _C=Debug @set _L=%~dp0..\..\build\logs + :parse_args @if /i "%1"=="release" set _C=Release +@if /i "%1"=="inc" set _INC=1 +@if /i "%1"=="clean" set _CLEAN=1 @if not "%1"=="" shift & goto parse_args @set _B=%~dp0..\..\build\libs\%_C% +:: Clean + +@if "%_INC%"=="" call :clean +@if NOT "%_CLEAN%"=="" goto :end + @echo Building libs %_C% msbuild -Restore libs_t.proj -p:Configuration=%_C% -nologo -m -warnaserror -bl:%_L%\libs_build.binlog || exit /b +dotnet test %_B%\net6.0\WixToolsetTest.Versioning.dll --nologo -l "trx;LogFileName=%_L%\TestResults\WixToolsetTest.Versioning.trx" || exit /b dotnet test %_B%\x86\DUtilUnitTest.dll --nologo -l "trx;LogFileName=%_L%\TestResults\DutilUnitTest32.trx" || exit /b dotnet test %_B%\x64\DUtilUnitTest.dll --nologo -l "trx;LogFileName=%_L%\TestResults\DutilUnitTest64.trx" || exit /b +@goto :end + +:clean +@rd /s/q "..\..\build\libs" 2> nul +@del "..\..\build\artifacts\WixToolset.DUtil.*.nupkg" 2> nul +@del "..\..\build\artifacts\WixToolset.Versioning.*.nupkg" 2> nul +@del "..\..\build\artifacts\WixToolset.WcaUtil.*.nupkg" 2> nul +@del "%_L%\TestResults\WixToolsetTest.Versioning.trx" 2> nul +@del "%_L%\TestResults\DutilUnitTest*.trx" 2> nul +@rd /s/q "%USERPROFILE%\.nuget\packages\wixtoolset.dutil" 2> nul +@rd /s/q "%USERPROFILE%\.nuget\packages\wixtoolset.versioning" 2> nul +@rd /s/q "%USERPROFILE%\.nuget\packages\wixtoolset.wcautil" 2> nul +@exit /b + +:end @popd @endlocal diff --git a/src/libs/libs.sln b/src/libs/libs.sln index e0a4a149..1c9c10d1 100644 --- a/src/libs/libs.sln +++ b/src/libs/libs.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.6.30114.105 +# Visual Studio Version 17 +VisualStudioVersion = 17.3.32922.545 MinimumVisualStudioVersion = 10.0.40219.1 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dutil", "dutil\WixToolset.DUtil\dutil.vcxproj", "{1244E671-F108-4334-BA52-8A7517F26ECD}" EndProject @@ -9,6 +9,10 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DUtilUnitTest", "dutil\test EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wcautil", "wcautil\WixToolset.WcaUtil\wcautil.vcxproj", "{5B3714B6-3A76-463E-8595-D48DA276C512}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WixToolset.Versioning", "WixToolset.Versioning\WixToolset.Versioning.csproj", "{7B14B536-4205-4186-B9FD-0765B84F2075}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WixToolsetTest.Versioning", "test\WixToolsetTest.Versioning\WixToolsetTest.Versioning.csproj", "{3D510701-FF05-4E3B-BB99-BDB97963C3F8}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -59,6 +63,38 @@ Global {5B3714B6-3A76-463E-8595-D48DA276C512}.Release|x64.Build.0 = Release|x64 {5B3714B6-3A76-463E-8595-D48DA276C512}.Release|x86.ActiveCfg = Release|Win32 {5B3714B6-3A76-463E-8595-D48DA276C512}.Release|x86.Build.0 = Release|Win32 + {7B14B536-4205-4186-B9FD-0765B84F2075}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7B14B536-4205-4186-B9FD-0765B84F2075}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7B14B536-4205-4186-B9FD-0765B84F2075}.Debug|ARM64.ActiveCfg = Debug|Any CPU + {7B14B536-4205-4186-B9FD-0765B84F2075}.Debug|ARM64.Build.0 = Debug|Any CPU + {7B14B536-4205-4186-B9FD-0765B84F2075}.Debug|x64.ActiveCfg = Debug|Any CPU + {7B14B536-4205-4186-B9FD-0765B84F2075}.Debug|x64.Build.0 = Debug|Any CPU + {7B14B536-4205-4186-B9FD-0765B84F2075}.Debug|x86.ActiveCfg = Debug|Any CPU + {7B14B536-4205-4186-B9FD-0765B84F2075}.Debug|x86.Build.0 = Debug|Any CPU + {7B14B536-4205-4186-B9FD-0765B84F2075}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7B14B536-4205-4186-B9FD-0765B84F2075}.Release|Any CPU.Build.0 = Release|Any CPU + {7B14B536-4205-4186-B9FD-0765B84F2075}.Release|ARM64.ActiveCfg = Release|Any CPU + {7B14B536-4205-4186-B9FD-0765B84F2075}.Release|ARM64.Build.0 = Release|Any CPU + {7B14B536-4205-4186-B9FD-0765B84F2075}.Release|x64.ActiveCfg = Release|Any CPU + {7B14B536-4205-4186-B9FD-0765B84F2075}.Release|x64.Build.0 = Release|Any CPU + {7B14B536-4205-4186-B9FD-0765B84F2075}.Release|x86.ActiveCfg = Release|Any CPU + {7B14B536-4205-4186-B9FD-0765B84F2075}.Release|x86.Build.0 = Release|Any CPU + {3D510701-FF05-4E3B-BB99-BDB97963C3F8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3D510701-FF05-4E3B-BB99-BDB97963C3F8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3D510701-FF05-4E3B-BB99-BDB97963C3F8}.Debug|ARM64.ActiveCfg = Debug|Any CPU + {3D510701-FF05-4E3B-BB99-BDB97963C3F8}.Debug|ARM64.Build.0 = Debug|Any CPU + {3D510701-FF05-4E3B-BB99-BDB97963C3F8}.Debug|x64.ActiveCfg = Debug|Any CPU + {3D510701-FF05-4E3B-BB99-BDB97963C3F8}.Debug|x64.Build.0 = Debug|Any CPU + {3D510701-FF05-4E3B-BB99-BDB97963C3F8}.Debug|x86.ActiveCfg = Debug|Any CPU + {3D510701-FF05-4E3B-BB99-BDB97963C3F8}.Debug|x86.Build.0 = Debug|Any CPU + {3D510701-FF05-4E3B-BB99-BDB97963C3F8}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3D510701-FF05-4E3B-BB99-BDB97963C3F8}.Release|Any CPU.Build.0 = Release|Any CPU + {3D510701-FF05-4E3B-BB99-BDB97963C3F8}.Release|ARM64.ActiveCfg = Release|Any CPU + {3D510701-FF05-4E3B-BB99-BDB97963C3F8}.Release|ARM64.Build.0 = Release|Any CPU + {3D510701-FF05-4E3B-BB99-BDB97963C3F8}.Release|x64.ActiveCfg = Release|Any CPU + {3D510701-FF05-4E3B-BB99-BDB97963C3F8}.Release|x64.Build.0 = Release|Any CPU + {3D510701-FF05-4E3B-BB99-BDB97963C3F8}.Release|x86.ActiveCfg = Release|Any CPU + {3D510701-FF05-4E3B-BB99-BDB97963C3F8}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/src/libs/libs.v3.ncrunchsolution b/src/libs/libs.v3.ncrunchsolution new file mode 100644 index 00000000..10420ac9 --- /dev/null +++ b/src/libs/libs.v3.ncrunchsolution @@ -0,0 +1,6 @@ + + + True + True + + \ No newline at end of file diff --git a/src/libs/libs_t.proj b/src/libs/libs_t.proj index 8c35f1c3..5c23cbf7 100644 --- a/src/libs/libs_t.proj +++ b/src/libs/libs_t.proj @@ -2,5 +2,7 @@ + + diff --git a/src/libs/test/WixToolsetTest.Versioning/VerUtilTestsFixture.cs b/src/libs/test/WixToolsetTest.Versioning/VerUtilTestsFixture.cs new file mode 100644 index 00000000..3dff28c6 --- /dev/null +++ b/src/libs/test/WixToolsetTest.Versioning/VerUtilTestsFixture.cs @@ -0,0 +1,683 @@ +// 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. + +namespace WixToolsetTest.Versioning +{ + using System; + using WixToolset.Versioning; + using Xunit; + + public class VerUtilTestsFixture + { + [Fact] + public void VerCompareVersionsTreatsMissingRevisionAsZero() + { + var version1 = WixVersion.Parse("1.2.3.4"); + var version2 = WixVersion.Parse("1.2.3"); + var version3 = WixVersion.Parse("1.2.3.0"); + + Assert.Null(version1.Prefix); + Assert.Equal(1U, version1.Major); + Assert.Equal(2U, version1.Minor); + Assert.Equal(3U, version1.Patch); + Assert.Equal(4U, version1.Revision); + Assert.Null(version1.Labels); + Assert.Null(version1.Metadata); + Assert.False(version1.Invalid); + Assert.True(version1.HasMajor); + Assert.True(version1.HasMinor); + Assert.True(version1.HasPatch); + Assert.True(version1.HasRevision); + + Assert.Null(version2.Prefix); + Assert.Equal(1U, version2.Major); + Assert.Equal(2U, version2.Minor); + Assert.Equal(3U, version2.Patch); + Assert.Equal(0U, version2.Revision); + Assert.Null(version2.Labels); + Assert.Null(version2.Metadata); + Assert.False(version2.Invalid); + Assert.True(version2.HasMajor); + Assert.True(version2.HasMinor); + Assert.True(version2.HasPatch); + Assert.False(version2.HasRevision); + + Assert.Null(version3.Prefix); + Assert.Equal(1U, version3.Major); + Assert.Equal(2U, version3.Minor); + Assert.Equal(3U, version3.Patch); + Assert.Equal(0U, version3.Revision); + Assert.Null(version3.Labels); + Assert.Null(version3.Metadata); + Assert.False(version3.Invalid); + Assert.True(version3.HasMajor); + Assert.True(version3.HasMinor); + Assert.True(version3.HasPatch); + Assert.True(version3.HasRevision); + + Assert.Equal(1, version1.CompareTo(version2)); + Assert.Equal(0, version3.CompareTo(version2)); + } + + [Fact] + public void VerCompareVersionsTreatsNumericReleaseLabelsAsNumbers() + { + var version1 = WixVersion.Parse("1.0-2.0"); + var version2 = WixVersion.Parse("1.0-19"); + + Assert.Null(version1.Prefix); + Assert.Equal(1U, version1.Major); + Assert.Equal(0U, version1.Minor); + Assert.Equal(0U, version1.Patch); + Assert.Equal(0U, version1.Revision); + Assert.Equal(2, version1.Labels.Length); + + Assert.Equal(2U, version1.Labels[0].Numeric); + Assert.Equal("2", version1.Labels[0].Label); + + Assert.Equal(0U, version1.Labels[1].Numeric); + Assert.Equal("0", version1.Labels[1].Label); + + Assert.Null(version1.Metadata); + Assert.False(version1.Invalid); + Assert.True(version1.HasMajor); + Assert.True(version1.HasMinor); + Assert.False(version1.HasPatch); + Assert.False(version1.HasRevision); + + + Assert.Null(version2.Prefix); + Assert.Equal(1U, version2.Major); + Assert.Equal(0U, version2.Minor); + Assert.Equal(0U, version2.Patch); + Assert.Equal(0U, version2.Revision); + Assert.Single(version2.Labels); + + Assert.Equal(19U, version2.Labels[0].Numeric); + Assert.Equal("19", version2.Labels[0].Label); + + Assert.Null(version2.Metadata); + Assert.False(version2.Invalid); + Assert.True(version2.HasMajor); + Assert.True(version2.HasMinor); + Assert.False(version2.HasPatch); + Assert.False(version2.HasRevision); + + TestVerutilCompareParsedVersions(version1, version2, -1); + } + + [Fact] + public void VerCompareVersionsHandlesNormallyInvalidVersions() + { + var version1 = WixVersion.Parse("10.-4.0"); + var version2 = WixVersion.Parse("10.-2.0"); + var version3 = WixVersion.Parse("0"); + var version4 = WixVersion.Parse(""); + var version5 = WixVersion.Parse("10-2"); + var version6 = WixVersion.Parse("10-4.@"); + + + Assert.Null(version1.Prefix); + Assert.Equal(10U, version1.Major); + Assert.Equal(0U, version1.Minor); + Assert.Equal(0U, version1.Patch); + Assert.Equal(0U, version1.Revision); + Assert.Null(version1.Labels); + Assert.Equal("-4.0", version1.Metadata); + Assert.True(version1.Invalid); + Assert.True(version1.HasMajor); + Assert.False(version1.HasMinor); + Assert.False(version1.HasPatch); + Assert.False(version1.HasRevision); + + + Assert.Null(version2.Prefix); + Assert.Equal(10U, version2.Major); + Assert.Equal(0U, version2.Minor); + Assert.Equal(0U, version2.Patch); + Assert.Equal(0U, version2.Revision); + Assert.Null(version2.Labels); + Assert.Equal("-2.0", version2.Metadata); + Assert.True(version2.Invalid); + Assert.True(version2.HasMajor); + Assert.False(version2.HasMinor); + Assert.False(version2.HasPatch); + Assert.False(version2.HasRevision); + + + Assert.Null(version3.Prefix); + Assert.Equal(0U, version3.Major); + Assert.Equal(0U, version3.Minor); + Assert.Equal(0U, version3.Patch); + Assert.Equal(0U, version3.Revision); + Assert.Null(version3.Labels); + Assert.Null(version3.Metadata); + Assert.False(version3.Invalid); + Assert.True(version3.HasMajor); + Assert.False(version3.HasMinor); + Assert.False(version3.HasPatch); + Assert.False(version3.HasRevision); + + Assert.Null(version4.Prefix); + Assert.Equal(0U, version4.Major); + Assert.Equal(0U, version4.Minor); + Assert.Equal(0U, version4.Patch); + Assert.Equal(0U, version4.Revision); + Assert.Null(version4.Labels); + Assert.Equal(String.Empty, version4.Metadata); + Assert.True(version4.Invalid); + Assert.False(version4.HasMajor); + Assert.False(version4.HasMinor); + Assert.False(version4.HasPatch); + Assert.False(version4.HasRevision); + + Assert.Null(version5.Prefix); + Assert.Equal(10U, version5.Major); + Assert.Equal(0U, version5.Minor); + Assert.Equal(0U, version5.Patch); + Assert.Equal(0U, version5.Revision); + Assert.Single(version5.Labels); + Assert.Equal(2U, version5.Labels[0].Numeric); + Assert.Equal("2", version5.Labels[0].Label); + + Assert.Null(version5.Metadata); + Assert.False(version5.Invalid); + Assert.True(version5.HasMajor); + Assert.False(version5.HasMinor); + Assert.False(version5.HasPatch); + Assert.False(version5.HasRevision); + + Assert.Null(version6.Prefix); + Assert.Equal(10U, version6.Major); + Assert.Equal(0U, version6.Minor); + Assert.Equal(0U, version6.Patch); + Assert.Equal(0U, version6.Revision); + Assert.Single(version6.Labels); + Assert.Equal(4U, version6.Labels[0].Numeric); + Assert.Equal("4", version6.Labels[0].Label); + + Assert.Equal("@", version6.Metadata); + Assert.True(version6.Invalid); + Assert.True(version6.HasMajor); + Assert.False(version6.HasMinor); + Assert.False(version6.HasPatch); + Assert.False(version6.HasRevision); + + TestVerutilCompareParsedVersions(version1, version2, 1); + TestVerutilCompareParsedVersions(version3, version4, 1); + TestVerutilCompareParsedVersions(version5, version6, -1); + } + + [Fact] + public void VerCompareVersionsTreatsHyphenAsVersionSeparator() + { + var version1 = WixVersion.Parse("0.0.1-a"); + var version2 = WixVersion.Parse("0-2"); + var version3 = WixVersion.Parse("1-2"); + + + Assert.Null(version1.Prefix); + Assert.Equal(0U, version1.Major); + Assert.Equal(0U, version1.Minor); + Assert.Equal(1U, version1.Patch); + Assert.Equal(0U, version1.Revision); + Assert.Single(version1.Labels); + Assert.Null(version1.Labels[0].Numeric); + Assert.Equal("a", version1.Labels[0].Label); + + Assert.Null(version1.Metadata); + Assert.False(version1.Invalid); + Assert.True(version1.HasMajor); + Assert.True(version1.HasMinor); + Assert.True(version1.HasPatch); + Assert.False(version1.HasRevision); + + Assert.Null(version2.Prefix); + Assert.Equal(0U, version2.Major); + Assert.Equal(0U, version2.Minor); + Assert.Equal(0U, version2.Patch); + Assert.Equal(0U, version2.Revision); + Assert.Single(version2.Labels); + Assert.Equal(2U, version2.Labels[0].Numeric); + Assert.Equal("2", version2.Labels[0].Label); + + Assert.Null(version2.Metadata); + Assert.False(version2.Invalid); + Assert.True(version2.HasMajor); + Assert.False(version2.HasMinor); + Assert.False(version2.HasPatch); + Assert.False(version2.HasRevision); + + Assert.Null(version3.Prefix); + Assert.Equal(1U, version3.Major); + Assert.Equal(0U, version3.Minor); + Assert.Equal(0U, version3.Patch); + Assert.Equal(0U, version3.Revision); + Assert.Single(version3.Labels); + Assert.Equal(2U, version3.Labels[0].Numeric); + Assert.Equal("2", version3.Labels[0].Label); + + Assert.Null(version3.Metadata); + Assert.False(version3.Invalid); + Assert.True(version3.HasMajor); + Assert.False(version3.HasMinor); + Assert.False(version3.HasPatch); + Assert.False(version3.HasRevision); + + TestVerutilCompareParsedVersions(version1, version2, 1); + TestVerutilCompareParsedVersions(version1, version3, -1); + } + + [Fact] + public void VerCompareVersionsIgnoresLeadingZeroes() + { + var version1 = WixVersion.Parse("0.01-a.1"); + var version2 = WixVersion.Parse("0.1.0-a.1"); + var version3 = WixVersion.Parse("0.1-a.b.0"); + var version4 = WixVersion.Parse("0.1.0-a.b.000"); + + Assert.Null(version1.Prefix); + Assert.Equal(0U, version1.Major); + Assert.Equal(1U, version1.Minor); + Assert.Equal(0U, version1.Patch); + Assert.Equal(0U, version1.Revision); + Assert.Equal(2, version1.Labels.Length); + Assert.Null(version1.Labels[0].Numeric); + Assert.Equal("a", version1.Labels[0].Label); + Assert.Equal(1U, version1.Labels[1].Numeric); + Assert.Equal("1", version1.Labels[1].Label); + + Assert.Null(version1.Metadata); + Assert.False(version1.Invalid); + Assert.True(version1.HasMajor); + Assert.True(version1.HasMinor); + Assert.False(version1.HasPatch); + Assert.False(version1.HasRevision); + + Assert.Null(version2.Prefix); + Assert.Equal(0U, version2.Major); + Assert.Equal(1U, version2.Minor); + Assert.Equal(0U, version2.Patch); + Assert.Equal(0U, version2.Revision); + Assert.Equal(2, version2.Labels.Length); + + Assert.Null(version2.Labels[0].Numeric); + Assert.Equal("a", version2.Labels[0].Label); + Assert.Equal(1U, version2.Labels[1].Numeric); + Assert.Equal("1", version2.Labels[1].Label); + + Assert.Null(version2.Metadata); + Assert.False(version2.Invalid); + Assert.True(version2.HasMajor); + Assert.True(version2.HasMinor); + Assert.True(version2.HasPatch); + Assert.False(version2.HasRevision); + + Assert.Null(version3.Prefix); + Assert.Equal(0U, version3.Major); + Assert.Equal(1U, version3.Minor); + Assert.Equal(0U, version3.Patch); + Assert.Equal(0U, version3.Revision); + Assert.Equal(3, version3.Labels.Length); + Assert.Null(version3.Labels[0].Numeric); + Assert.Equal("a", version3.Labels[0].Label); + Assert.Null(version3.Labels[1].Numeric); + Assert.Equal("b", version3.Labels[1].Label); + Assert.Equal(0U, version3.Labels[2].Numeric); + Assert.Equal("0", version3.Labels[2].Label); + + Assert.Null(version3.Metadata); + Assert.False(version3.Invalid); + Assert.True(version3.HasMajor); + Assert.True(version3.HasMinor); + Assert.False(version3.HasPatch); + Assert.False(version3.HasRevision); + + Assert.Null(version4.Prefix); + Assert.Equal(0U, version4.Major); + Assert.Equal(1U, version4.Minor); + Assert.Equal(0U, version4.Patch); + Assert.Equal(0U, version4.Revision); + Assert.Equal(3, version4.Labels.Length); + Assert.Null(version4.Labels[0].Numeric); + Assert.Equal("a", version4.Labels[0].Label); + Assert.Null(version4.Labels[1].Numeric); + Assert.Equal("b", version4.Labels[1].Label); + Assert.Equal(0U, version4.Labels[2].Numeric); + Assert.Equal("000", version4.Labels[2].Label); + + Assert.Null(version4.Metadata); + Assert.False(version4.Invalid); + Assert.True(version4.HasMajor); + Assert.True(version4.HasMinor); + Assert.True(version4.HasPatch); + Assert.False(version4.HasRevision); + + TestVerutilCompareParsedVersions(version1, version2, 0); + TestVerutilCompareParsedVersions(version3, version4, 0); + } + + [Fact] + public void VerCompareVersionsTreatsUnexpectedContentAsMetadata() + { + var version1 = WixVersion.Parse("1.2.3+abcd"); + var version2 = WixVersion.Parse("1.2.3.abcd"); + var version3 = WixVersion.Parse("1.2.3.-abcd"); + + Assert.Null(version1.Prefix); + Assert.Equal(1U, version1.Major); + Assert.Equal(2U, version1.Minor); + Assert.Equal(3U, version1.Patch); + Assert.Equal(0U, version1.Revision); + Assert.Null(version1.Labels); + Assert.Equal("abcd", version1.Metadata); + Assert.False(version1.Invalid); + Assert.True(version1.HasMajor); + Assert.True(version1.HasMinor); + Assert.True(version1.HasPatch); + Assert.False(version1.HasRevision); + + Assert.Null(version2.Prefix); + Assert.Equal(1U, version2.Major); + Assert.Equal(2U, version2.Minor); + Assert.Equal(3U, version2.Patch); + Assert.Equal(0U, version2.Revision); + Assert.Null(version2.Labels); + Assert.Equal("abcd", version2.Metadata); + Assert.True(version2.Invalid); + Assert.True(version2.HasMajor); + Assert.True(version2.HasMinor); + Assert.True(version2.HasPatch); + Assert.False(version2.HasRevision); + + + Assert.Null(version3.Prefix); + Assert.Equal(1U, version3.Major); + Assert.Equal(2U, version3.Minor); + Assert.Equal(3U, version3.Patch); + Assert.Equal(0U, version3.Revision); + Assert.Null(version3.Labels); + Assert.Equal("-abcd", version3.Metadata); + Assert.True(version3.Invalid); + Assert.True(version3.HasMajor); + Assert.True(version3.HasMinor); + Assert.True(version3.HasPatch); + Assert.False(version3.HasRevision); + + TestVerutilCompareParsedVersions(version1, version2, 1); + TestVerutilCompareParsedVersions(version1, version3, 1); + TestVerutilCompareParsedVersions(version2, version3, 1); + } + + [Fact] + public void VerCompareVersionsIgnoresLeadingV() + { + var version1 = WixVersion.Parse("10.20.30.40"); + var version2 = WixVersion.Parse("v10.20.30.40"); + var version3 = WixVersion.Parse("V10.20.30.40"); + var version4 = WixVersion.Parse("v10.20.30.40-abc"); + var version5 = WixVersion.Parse("vvv"); + + Assert.Null(version1.Prefix); + Assert.Equal(10U, version1.Major); + Assert.Equal(20U, version1.Minor); + Assert.Equal(30U, version1.Patch); + Assert.Equal(40U, version1.Revision); + Assert.Null(version1.Labels); + Assert.Null(version1.Metadata); + Assert.False(version1.Invalid); + Assert.True(version1.HasMajor); + Assert.True(version1.HasMinor); + Assert.True(version1.HasPatch); + Assert.True(version1.HasRevision); + + Assert.Equal('v', version2.Prefix); + Assert.Equal(10U, version2.Major); + Assert.Equal(20U, version2.Minor); + Assert.Equal(30U, version2.Patch); + Assert.Equal(40U, version2.Revision); + Assert.Null(version2.Labels); + Assert.Null(version2.Metadata); + Assert.False(version2.Invalid); + Assert.True(version2.HasMajor); + Assert.True(version2.HasMinor); + Assert.True(version2.HasPatch); + Assert.True(version2.HasRevision); + + Assert.Equal('V', version3.Prefix); + Assert.Equal(10U, version3.Major); + Assert.Equal(20U, version3.Minor); + Assert.Equal(30U, version3.Patch); + Assert.Equal(40U, version3.Revision); + Assert.Null(version3.Labels); + Assert.Null(version3.Metadata); + Assert.False(version3.Invalid); + Assert.True(version3.HasMajor); + Assert.True(version3.HasMinor); + Assert.True(version3.HasPatch); + Assert.True(version3.HasRevision); + + Assert.Equal('v', version4.Prefix); + Assert.Equal(10U, version4.Major); + Assert.Equal(20U, version4.Minor); + Assert.Equal(30U, version4.Patch); + Assert.Equal(40U, version4.Revision); + Assert.Single(version4.Labels); + Assert.Null(version4.Labels[0].Numeric); + Assert.Equal("abc", version4.Labels[0].Label); + + Assert.Null(version4.Metadata); + Assert.False(version4.Invalid); + Assert.True(version4.HasMajor); + Assert.True(version4.HasMinor); + Assert.True(version4.HasPatch); + Assert.True(version4.HasRevision); + + Assert.Null(version5.Prefix); + Assert.Equal(0U, version5.Major); + Assert.Equal(0U, version5.Minor); + Assert.Equal(0U, version5.Patch); + Assert.Equal(0U, version5.Revision); + Assert.Null(version5.Labels); + Assert.Equal("vvv", version5.Metadata); + Assert.True(version5.Invalid); + Assert.False(version5.HasMajor); + Assert.False(version5.HasMinor); + Assert.False(version5.HasPatch); + Assert.False(version5.HasRevision); + + TestVerutilCompareParsedVersions(version1, version2, 0); + TestVerutilCompareParsedVersions(version1, version3, 0); + TestVerutilCompareParsedVersions(version1, version4, 1); + } + + [Fact] + public void VerCompareVersionsHandlesTooLargeNumbers() + { + var version1 = WixVersion.Parse("4294967295.4294967295.4294967295.4294967295"); + var version2 = WixVersion.Parse("4294967296.4294967296.4294967296.4294967296"); + + Assert.Null(version1.Prefix); + Assert.Equal(4294967295, version1.Major); + Assert.Equal(4294967295, version1.Minor); + Assert.Equal(4294967295, version1.Patch); + Assert.Equal(4294967295, version1.Revision); + Assert.Null(version1.Labels); + Assert.Null(version1.Metadata); + Assert.False(version1.Invalid); + Assert.True(version1.HasMajor); + Assert.True(version1.HasMinor); + Assert.True(version1.HasPatch); + Assert.True(version1.HasRevision); + + Assert.Null(version2.Prefix); + Assert.Equal(0U, version2.Major); + Assert.Equal(0U, version2.Minor); + Assert.Equal(0U, version2.Patch); + Assert.Equal(0U, version2.Revision); + Assert.Null(version2.Labels); + Assert.Equal("4294967296.4294967296.4294967296.4294967296", version2.Metadata); + Assert.True(version2.Invalid); + Assert.False(version2.HasMajor); + Assert.False(version2.HasMinor); + Assert.False(version2.HasPatch); + Assert.False(version2.HasRevision); + + TestVerutilCompareParsedVersions(version1, version2, 1); + } + + [Fact] + public void VerCompareVersionsIgnoresMetadataForValidVersions() + { + var version1 = WixVersion.Parse("1.2.3+abc"); + var version2 = WixVersion.Parse("1.2.3+xyz"); + + Assert.Null(version1.Prefix); + Assert.Equal(1U, version1.Major); + Assert.Equal(2U, version1.Minor); + Assert.Equal(3U, version1.Patch); + Assert.Equal(0U, version1.Revision); + Assert.Null(version1.Labels); + Assert.Equal("abc", version1.Metadata); + Assert.False(version1.Invalid); + Assert.True(version1.HasMajor); + Assert.True(version1.HasMinor); + Assert.True(version1.HasPatch); + Assert.False(version1.HasRevision); + + + Assert.Null(version2.Prefix); + Assert.Equal(1U, version2.Major); + Assert.Equal(2U, version2.Minor); + Assert.Equal(3U, version2.Patch); + Assert.Equal(0U, version2.Revision); + Assert.Null(version2.Labels); + Assert.Equal("xyz", version2.Metadata); + Assert.False(version2.Invalid); + Assert.True(version2.HasMajor); + Assert.True(version2.HasMinor); + Assert.True(version2.HasPatch); + Assert.False(version2.HasRevision); + + TestVerutilCompareParsedVersions(version1, version2, 0); + } + + [Fact] + public void VerParseVersionTreatsTrailingDotsAsInvalid() + { + var version1 = WixVersion.Parse("."); + var version2 = WixVersion.Parse("1."); + var version3 = WixVersion.Parse("2.1."); + var version4 = WixVersion.Parse("3.2.1."); + var version5 = WixVersion.Parse("4.3.2.1."); + var version6 = WixVersion.Parse("5-."); + var version7 = WixVersion.Parse("6-a."); + + Assert.Null(version1.Prefix); + Assert.Equal(0U, version1.Major); + Assert.Equal(0U, version1.Minor); + Assert.Equal(0U, version1.Patch); + Assert.Equal(0U, version1.Revision); + Assert.Null(version1.Labels); + Assert.Equal(".", version1.Metadata); + Assert.True(version1.Invalid); + Assert.False(version1.HasMajor); + Assert.False(version1.HasMinor); + Assert.False(version1.HasPatch); + Assert.False(version1.HasRevision); + + + Assert.Null(version2.Prefix); + Assert.Equal(1U, version2.Major); + Assert.Equal(0U, version2.Minor); + Assert.Equal(0U, version2.Patch); + Assert.Equal(0U, version2.Revision); + Assert.Null(version2.Labels); + Assert.Empty(version2.Metadata); + Assert.True(version2.Invalid); + Assert.True(version2.HasMajor); + Assert.False(version2.HasMinor); + Assert.False(version2.HasPatch); + Assert.False(version2.HasRevision); + + + Assert.Null(version3.Prefix); + Assert.Equal(2U, version3.Major); + Assert.Equal(1U, version3.Minor); + Assert.Equal(0U, version3.Patch); + Assert.Equal(0U, version3.Revision); + Assert.Null(version3.Labels); + Assert.Empty(version3.Metadata); + Assert.True(version3.Invalid); + Assert.True(version3.HasMajor); + Assert.True(version3.HasMinor); + Assert.False(version3.HasPatch); + Assert.False(version3.HasRevision); + + Assert.Null(version4.Prefix); + Assert.Equal(3U, version4.Major); + Assert.Equal(2U, version4.Minor); + Assert.Equal(1U, version4.Patch); + Assert.Equal(0U, version4.Revision); + Assert.Null(version4.Labels); + Assert.Empty(version4.Metadata); + Assert.True(version4.Invalid); + Assert.True(version4.HasMajor); + Assert.True(version4.HasMinor); + Assert.True(version4.HasPatch); + Assert.False(version4.HasRevision); + + Assert.Null(version5.Prefix); + Assert.Equal(4U, version5.Major); + Assert.Equal(3U, version5.Minor); + Assert.Equal(2U, version5.Patch); + Assert.Equal(1U, version5.Revision); + Assert.Null(version5.Labels); + Assert.Empty(version5.Metadata); + Assert.True(version5.Invalid); + Assert.True(version5.HasMajor); + Assert.True(version5.HasMinor); + Assert.True(version5.HasPatch); + Assert.True(version5.HasRevision); + + Assert.Null(version6.Prefix); + Assert.Equal(5U, version6.Major); + Assert.Equal(0U, version6.Minor); + Assert.Equal(0U, version6.Patch); + Assert.Equal(0U, version6.Revision); + Assert.Null(version6.Labels); + Assert.Equal(".", version6.Metadata); + Assert.True(version6.Invalid); + Assert.True(version6.HasMajor); + Assert.False(version6.HasMinor); + Assert.False(version6.HasPatch); + Assert.False(version6.HasRevision); + + Assert.Null(version7.Prefix); + Assert.Equal(6U, version7.Major); + Assert.Equal(0U, version7.Minor); + Assert.Equal(0U, version7.Patch); + Assert.Equal(0U, version7.Revision); + Assert.Single(version7.Labels); + Assert.Null(version7.Labels[0].Numeric); + Assert.Equal("a", version7.Labels[0].Label); + Assert.Empty(version7.Metadata); + Assert.True(version7.Invalid); + Assert.True(version7.HasMajor); + Assert.False(version7.HasMinor); + Assert.False(version7.HasPatch); + Assert.False(version7.HasRevision); + } + + private static void TestVerutilCompareParsedVersions(WixVersion version1, WixVersion version2, int expectedResult) + { + var result = version1.CompareTo(version2); + Assert.Equal(expectedResult, result); + + result = version2.CompareTo(version1); + Assert.Equal(expectedResult, -result); + + var equal = version1.Equals(version2); + Assert.Equal(expectedResult == 0, equal); + } + } +} diff --git a/src/libs/test/WixToolsetTest.Versioning/WixToolsetTest.Versioning.csproj b/src/libs/test/WixToolsetTest.Versioning/WixToolsetTest.Versioning.csproj new file mode 100644 index 00000000..0ac65fec --- /dev/null +++ b/src/libs/test/WixToolsetTest.Versioning/WixToolsetTest.Versioning.csproj @@ -0,0 +1,17 @@ + + + + + + net6.0 + true + + + + + + + + + + diff --git a/src/libs/test/WixToolsetTest.Versioning/WixVerFixture.cs b/src/libs/test/WixToolsetTest.Versioning/WixVerFixture.cs new file mode 100644 index 00000000..9026cba6 --- /dev/null +++ b/src/libs/test/WixToolsetTest.Versioning/WixVerFixture.cs @@ -0,0 +1,451 @@ +// 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. + +namespace WixToolsetTest.Versioning +{ + using System; + using System.Linq; + using WixToolset.Versioning; + using Xunit; + + public class WixVerFixture + { + [Fact] + public void CannotParseEmptyStringAsVersion() + { + Assert.False(WixVersion.TryParse(String.Empty, out var version)); + Assert.Null(version); + } + + [Fact] + public void CanParseEmptyStringAsInvalidVersion() + { + var version = WixVersion.Parse(String.Empty); + Assert.Empty(version.Metadata); + Assert.True(version.Invalid); + } + + [Fact] + public void CannotParseInvalidStringAsVersion() + { + Assert.False(WixVersion.TryParse("invalid", out var version)); + Assert.Null(version); + } + + [Fact] + public void CanParseInvalidStringAsInvalidVersion() + { + var version = WixVersion.Parse("invalid"); + Assert.Equal("invalid", version.Metadata); + Assert.True(version.Invalid); + } + + [Fact] + public void CanParseFourPartVersion() + { + Assert.True(WixVersion.TryParse("1.2.3.4", out var version)); + Assert.Null(version.Prefix); + Assert.Equal((uint)1, version.Major); + Assert.Equal((uint)2, version.Minor); + Assert.Equal((uint)3, version.Patch); + Assert.Equal((uint)4, version.Revision); + Assert.True(version.HasMajor); + Assert.True(version.HasMinor); + Assert.True(version.HasPatch); + Assert.True(version.HasRevision); + Assert.Null(version.Labels); + Assert.Null(version.Metadata); + Assert.False(version.Invalid); + } + + [Fact] + public void CanParseThreePartVersion() + { + Assert.True(WixVersion.TryParse("1.2.3", out var version)); + Assert.Null(version.Prefix); + Assert.Equal((uint)1, version.Major); + Assert.Equal((uint)2, version.Minor); + Assert.Equal((uint)3, version.Patch); + Assert.Equal((uint)0, version.Revision); + Assert.True(version.HasMajor); + Assert.True(version.HasMinor); + Assert.True(version.HasPatch); + Assert.False(version.HasRevision); + Assert.Null(version.Labels); + Assert.Null(version.Metadata); + Assert.False(version.Invalid); + } + + [Fact] + public void CanParseFourPartVersionWithTrailingZero() + { + Assert.True(WixVersion.TryParse("1.2.3.0", out var version)); + Assert.Null(version.Prefix); + Assert.Equal((uint)1, version.Major); + Assert.Equal((uint)2, version.Minor); + Assert.Equal((uint)3, version.Patch); + Assert.Equal((uint)0, version.Revision); + Assert.True(version.HasMajor); + Assert.True(version.HasMinor); + Assert.True(version.HasPatch); + Assert.True(version.HasRevision); + Assert.Null(version.Labels); + Assert.Null(version.Metadata); + Assert.False(version.Invalid); + } + + [Fact] + public void CanParseNumericReleaseLabels() + { + Assert.True(WixVersion.TryParse("1.2-19", out var version)); + Assert.Null(version.Prefix); + Assert.Equal((uint)1, version.Major); + Assert.Equal((uint)2, version.Minor); + Assert.Equal((uint)0, version.Patch); + Assert.Equal((uint)0, version.Revision); + Assert.True(version.HasMajor); + Assert.True(version.HasMinor); + Assert.False(version.HasPatch); + Assert.False(version.HasRevision); + Assert.Equal(new[] { "19" }, version.Labels.Select(l => l.Label).ToArray()); + Assert.Equal(new uint?[] { 19 }, version.Labels.Select(l => l.Numeric).ToArray()); + Assert.Null(version.Metadata); + Assert.False(version.Invalid); + } + + [Fact] + public void CanParseDottedNumericReleaseLabels() + { + Assert.True(WixVersion.TryParse("1.2-2.0", out var version)); + Assert.Null(version.Prefix); + Assert.Equal((uint)1, version.Major); + Assert.Equal((uint)2, version.Minor); + Assert.Equal((uint)0, version.Patch); + Assert.Equal((uint)0, version.Revision); + Assert.True(version.HasMajor); + Assert.True(version.HasMinor); + Assert.False(version.HasPatch); + Assert.False(version.HasRevision); + Assert.Equal(new[] { "2", "0" }, version.Labels.Select(l => l.Label).ToArray()); + Assert.Equal(new uint?[] { 2, 0 }, version.Labels.Select(l => l.Numeric).ToArray()); + Assert.Null(version.Metadata); + Assert.False(version.Invalid); + } + + [Fact] + public void CanParseHyphenAsVersionSeparator() + { + Assert.True(WixVersion.TryParse("0.0.1-a", out var version)); + Assert.Null(version.Prefix); + Assert.Equal((uint)0, version.Major); + Assert.Equal((uint)0, version.Minor); + Assert.Equal((uint)1, version.Patch); + Assert.Equal((uint)0, version.Revision); + Assert.True(version.HasMajor); + Assert.True(version.HasMinor); + Assert.True(version.HasPatch); + Assert.False(version.HasRevision); + Assert.Equal(new[] { "a" }, version.Labels.Select(l => l.Label).ToArray()); + Assert.Equal(new uint?[] { null }, version.Labels.Select(l => l.Numeric).ToArray()); + Assert.Null(version.Metadata); + Assert.False(version.Invalid); + } + + [Fact] + public void CanParseIgnoringLeadingZeros() + { + Assert.True(WixVersion.TryParse("0.01-a.000", out var version)); + Assert.Null(version.Prefix); + Assert.Equal((uint)0, version.Major); + Assert.Equal((uint)1, version.Minor); + Assert.Equal((uint)0, version.Patch); + Assert.Equal((uint)0, version.Revision); + Assert.True(version.HasMajor); + Assert.True(version.HasMinor); + Assert.False(version.HasPatch); + Assert.False(version.HasRevision); + Assert.Equal(new[] { "a", "000" }, version.Labels.Select(l => l.Label).ToArray()); + Assert.Equal(new uint?[] { null, 0 }, version.Labels.Select(l => l.Numeric).ToArray()); + Assert.Null(version.Metadata); + Assert.False(version.Invalid); + } + + [Fact] + public void CanParseMetadata() + { + Assert.True(WixVersion.TryParse("1.2.3+abcd", out var version)); + Assert.Null(version.Prefix); + Assert.Equal((uint)1, version.Major); + Assert.Equal((uint)2, version.Minor); + Assert.Equal((uint)3, version.Patch); + Assert.Equal((uint)0, version.Revision); + Assert.True(version.HasMajor); + Assert.True(version.HasMinor); + Assert.True(version.HasPatch); + Assert.False(version.HasRevision); + Assert.Null(version.Labels); + Assert.Equal("abcd", version.Metadata); + Assert.False(version.Invalid); + } + + [Fact] + public void CannotParseUnexpectedContentAsMetadata() + { + Assert.False(WixVersion.TryParse("1.2.3.abcd", out var version)); + Assert.Null(version); + Assert.False(WixVersion.TryParse("1.2.3.-abcd", out version)); + Assert.Null(version); + } + + [Fact] + public void CanParseUnexpectedContentAsInvalidMetadata() + { + var version = WixVersion.Parse("1.2.3.abcd"); + Assert.Equal("abcd", version.Metadata); + Assert.True(version.Invalid); + + version = WixVersion.Parse("1.2.3.-abcd"); + Assert.Equal("-abcd", version.Metadata); + Assert.True(version.Invalid); + } + + [Fact] + public void CanParseLeadingPrefix() + { + Assert.True(WixVersion.TryParse("v10.20.30.40", out var version)); + Assert.Equal('v', version.Prefix); + Assert.Equal((uint)10, version.Major); + Assert.Equal((uint)20, version.Minor); + Assert.Equal((uint)30, version.Patch); + Assert.Equal((uint)40, version.Revision); + Assert.True(version.HasMajor); + Assert.True(version.HasMinor); + Assert.True(version.HasPatch); + Assert.True(version.HasRevision); + Assert.Null(version.Labels); + Assert.Null(version.Metadata); + Assert.False(version.Invalid); + + Assert.True(WixVersion.TryParse("V100.200.300.400", out var version2)); + Assert.Equal('V', version2.Prefix); + Assert.Equal((uint)100, version2.Major); + Assert.Equal((uint)200, version2.Minor); + Assert.Equal((uint)300, version2.Patch); + Assert.Equal((uint)400, version2.Revision); + Assert.True(version.HasMajor); + Assert.True(version.HasMinor); + Assert.True(version.HasPatch); + Assert.True(version.HasRevision); + Assert.Null(version2.Labels); + Assert.Null(version2.Metadata); + Assert.False(version.Invalid); + } + + [Fact] + public void CanParseVeryLargeNumbers() + { + Assert.True(WixVersion.TryParse("4294967295.4294967295.4294967295.4294967295", out var version)); + Assert.Null(version.Prefix); + Assert.Equal(4294967295, version.Major); + Assert.Equal(4294967295, version.Minor); + Assert.Equal(4294967295, version.Patch); + Assert.Equal(4294967295, version.Revision); + Assert.True(version.HasMajor); + Assert.True(version.HasMinor); + Assert.True(version.HasPatch); + Assert.True(version.HasRevision); + Assert.Null(version.Labels); + Assert.Null(version.Metadata); + Assert.False(version.Invalid); + } + + [Fact] + public void CannotParseTooLargeNumbers() + { + Assert.False(WixVersion.TryParse("4294967296.4294967296.4294967296.4294967296", out var version)); + Assert.Null(version); + } + + [Fact] + public void CanParseInvalidTooLargeNumbers() + { + var version = WixVersion.Parse("4294967296.4294967296.4294967296.4294967296"); + Assert.Equal(0U, version.Major); + Assert.Equal("4294967296.4294967296.4294967296.4294967296", version.Metadata); + Assert.True(version.Invalid); + } + + [Fact] + public void CanParseInvalidTooLargeNumbersWithPrefix() + { + var version = WixVersion.Parse("v4294967296.4294967296.4294967296.4294967296"); + Assert.Equal("v4294967296.4294967296.4294967296.4294967296", version.Metadata); + Assert.Null(version.Prefix); + Assert.True(version.Invalid); + } + + [Fact] + public void CanParseLabelsWithMetadata() + { + Assert.True(WixVersion.TryParse("1.2.3.4-a.b.c.d.5+abc123", out var version)); + Assert.Null(version.Prefix); + Assert.Equal((uint)1, version.Major); + Assert.Equal((uint)2, version.Minor); + Assert.Equal((uint)3, version.Patch); + Assert.Equal((uint)4, version.Revision); + Assert.True(version.HasMajor); + Assert.True(version.HasMinor); + Assert.True(version.HasPatch); + Assert.True(version.HasRevision); + Assert.Equal(new[] { "a", "b", "c", "d", "5" }, version.Labels.Select(l => l.Label).ToArray()); + Assert.Equal(new uint?[] { null, null, null, null, 5 }, version.Labels.Select(l => l.Numeric).ToArray()); + Assert.Equal("abc123", version.Metadata); + Assert.False(version.Invalid); + } + + [Fact] + public void CanParseVersionWithTrailingDotsAsInvalid() + { + var version = WixVersion.Parse("."); + Assert.Null(version.Prefix); + Assert.Equal(0U, version.Major); + Assert.Equal(0U, version.Minor); + Assert.Equal(0U, version.Patch); + Assert.Equal(0U, version.Revision); + Assert.Null(version.Labels); + Assert.False(version.HasMajor); + Assert.False(version.HasMinor); + Assert.False(version.HasPatch); + Assert.False(version.HasRevision); + Assert.Equal(".", version.Metadata); + Assert.True(version.Invalid); + + version = WixVersion.Parse("1."); + Assert.Null(version.Prefix); + Assert.Equal(1U, version.Major); + Assert.Equal(0U, version.Minor); + Assert.Equal(0U, version.Patch); + Assert.Equal(0U, version.Revision); + Assert.Null(version.Labels); + Assert.True(version.HasMajor); + Assert.False(version.HasMinor); + Assert.False(version.HasPatch); + Assert.False(version.HasRevision); + Assert.Equal(String.Empty, version.Metadata); + Assert.True(version.Invalid); + + version = WixVersion.Parse("2.1."); + Assert.Null(version.Prefix); + Assert.Equal(2U, version.Major); + Assert.Equal(1U, version.Minor); + Assert.Equal(0U, version.Patch); + Assert.Equal(0U, version.Revision); + Assert.Null(version.Labels); + Assert.True(version.HasMajor); + Assert.True(version.HasMinor); + Assert.False(version.HasPatch); + Assert.False(version.HasRevision); + Assert.Equal(String.Empty, version.Metadata); + Assert.True(version.Invalid); + + version = WixVersion.Parse("3.2.1."); + Assert.Null(version.Prefix); + Assert.Equal(3U, version.Major); + Assert.Equal(2U, version.Minor); + Assert.Equal(1U, version.Patch); + Assert.Equal(0U, version.Revision); + Assert.Null(version.Labels); + Assert.True(version.HasMajor); + Assert.True(version.HasMinor); + Assert.True(version.HasPatch); + Assert.False(version.HasRevision); + Assert.Equal(String.Empty, version.Metadata); + Assert.True(version.Invalid); + + version = WixVersion.Parse("4.3.2.1."); + Assert.Null(version.Prefix); + Assert.Equal(4U, version.Major); + Assert.Equal(3U, version.Minor); + Assert.Equal(2U, version.Patch); + Assert.Equal(1U, version.Revision); + Assert.Null(version.Labels); + Assert.True(version.HasMajor); + Assert.True(version.HasMinor); + Assert.True(version.HasPatch); + Assert.True(version.HasRevision); + Assert.Equal(String.Empty, version.Metadata); + Assert.True(version.Invalid); + + version = WixVersion.Parse("5-."); + Assert.Null(version.Prefix); + Assert.Equal(5U, version.Major); + Assert.Equal(0U, version.Minor); + Assert.Equal(0U, version.Patch); + Assert.Equal(0U, version.Revision); + Assert.Null(version.Labels); + Assert.True(version.HasMajor); + Assert.False(version.HasMinor); + Assert.False(version.HasPatch); + Assert.False(version.HasRevision); + Assert.Equal(".", version.Metadata); + Assert.True(version.Invalid); + + version = WixVersion.Parse("6-a."); + Assert.Null(version.Prefix); + Assert.Equal(6U, version.Major); + Assert.Equal(0U, version.Minor); + Assert.Equal(0U, version.Patch); + Assert.Equal(0U, version.Revision); + Assert.Equal(new[] { "a" }, version.Labels.Select(l => l.Label).ToArray()); + Assert.Equal(new uint?[] { null }, version.Labels.Select(l => l.Numeric).ToArray()); + Assert.True(version.HasMajor); + Assert.False(version.HasMinor); + Assert.False(version.HasPatch); + Assert.False(version.HasRevision); + Assert.Equal(String.Empty, version.Metadata); + Assert.True(version.Invalid); + } + + [Fact] + public void CanCompareVersions() + { + var version1 = WixVersion.Parse("1"); + var version10 = WixVersion.Parse("1.0"); + var version100 = WixVersion.Parse("1.0.0"); + var version2 = WixVersion.Parse("2.0.0"); + var version201 = WixVersion.Parse("2.0.1"); + var version2a = WixVersion.Parse("2-a"); + var version2b = WixVersion.Parse("2-b"); + var versionInvalid3a = WixVersion.Parse("3.-a"); + var versionInvalid3b = WixVersion.Parse("3.-b"); + + Assert.Equal(version1, version1); + Assert.Equal(version1, version10); + Assert.True(version1 == version10); + Assert.True(version1 == version100); + Assert.True(version1 <= version10); + Assert.True(version1 >= version10); + Assert.False(version1 != version10); + Assert.False(version1 < version10); + Assert.False(version1 < version100); + Assert.False(version1 > version10); + Assert.False(version1 > version100); + + Assert.NotEqual(version1, version2); + Assert.True(version1 < version2); + Assert.False(version1 > version2); + + Assert.True(version2 > version2a); + Assert.True(version2 != version2a); + Assert.False(version2 < version2a); + + Assert.True(version2 < version201); + + Assert.True(version2a < version2b); + Assert.False(version2a > version2b); + + Assert.True(versionInvalid3a < versionInvalid3b); + + Assert.True(version1 < versionInvalid3a); + } + } +} diff --git a/src/testresultfilelist.txt b/src/testresultfilelist.txt index 87de7c4e..59584e64 100644 --- a/src/testresultfilelist.txt +++ b/src/testresultfilelist.txt @@ -20,4 +20,5 @@ build/logs/TestResults/WixToolsetTest.ManagedHost.trx build/logs/TestResults/WixToolsetTest.Mba.Core.trx build/logs/TestResults/WixToolsetTest.MsiE2E.trx build/logs/TestResults/WixToolsetTest.Sdk.trx +build/logs/TestResults/WixToolsetTest.Versioning.trx build/logs/TestResults/WixToolsetTest.WixE2ETests.trx \ No newline at end of file diff --git a/src/wix/WixToolset.Core.Burn/Bind/BindBundleCommand.cs b/src/wix/WixToolset.Core.Burn/Bind/BindBundleCommand.cs index d001bf50..6ae3520f 100644 --- a/src/wix/WixToolset.Core.Burn/Bind/BindBundleCommand.cs +++ b/src/wix/WixToolset.Core.Burn/Bind/BindBundleCommand.cs @@ -17,6 +17,7 @@ namespace WixToolset.Core.Burn using WixToolset.Extensibility; using WixToolset.Extensibility.Data; using WixToolset.Extensibility.Services; + using WixToolset.Versioning; /// /// Binds a this.bundle. diff --git a/src/wix/WixToolset.Core.Burn/Bundles/CreateBundleExeCommand.cs b/src/wix/WixToolset.Core.Burn/Bundles/CreateBundleExeCommand.cs index 4aed18da..aa4730fb 100644 --- a/src/wix/WixToolset.Core.Burn/Bundles/CreateBundleExeCommand.cs +++ b/src/wix/WixToolset.Core.Burn/Bundles/CreateBundleExeCommand.cs @@ -15,6 +15,7 @@ namespace WixToolset.Core.Burn.Bundles using WixToolset.Dtf.Resources; using WixToolset.Extensibility.Data; using WixToolset.Extensibility.Services; + using WixToolset.Versioning; internal class CreateBundleExeCommand { diff --git a/src/wix/WixToolset.Core.Burn/WixToolset.Core.Burn.csproj b/src/wix/WixToolset.Core.Burn/WixToolset.Core.Burn.csproj index 754af45e..d56ed326 100644 --- a/src/wix/WixToolset.Core.Burn/WixToolset.Core.Burn.csproj +++ b/src/wix/WixToolset.Core.Burn/WixToolset.Core.Burn.csproj @@ -15,7 +15,6 @@ - @@ -24,5 +23,6 @@ + diff --git a/src/wix/WixToolset.Core.WindowsInstaller/Bind/ProcessPackageSoftwareTagsCommand.cs b/src/wix/WixToolset.Core.WindowsInstaller/Bind/ProcessPackageSoftwareTagsCommand.cs index 67815fcf..1348f163 100644 --- a/src/wix/WixToolset.Core.WindowsInstaller/Bind/ProcessPackageSoftwareTagsCommand.cs +++ b/src/wix/WixToolset.Core.WindowsInstaller/Bind/ProcessPackageSoftwareTagsCommand.cs @@ -11,6 +11,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind using WixToolset.Data.Symbols; using WixToolset.Extensibility.Data; using WixToolset.Extensibility.Services; + using WixToolset.Versioning; internal class ProcessPackageSoftwareTagsCommand { diff --git a/src/wix/WixToolset.Core.WindowsInstaller/WixToolset.Core.WindowsInstaller.csproj b/src/wix/WixToolset.Core.WindowsInstaller/WixToolset.Core.WindowsInstaller.csproj index fa4ae68c..1f01fff9 100644 --- a/src/wix/WixToolset.Core.WindowsInstaller/WixToolset.Core.WindowsInstaller.csproj +++ b/src/wix/WixToolset.Core.WindowsInstaller/WixToolset.Core.WindowsInstaller.csproj @@ -19,6 +19,7 @@ + diff --git a/src/wix/WixToolset.Core/Common.cs b/src/wix/WixToolset.Core/Common.cs index c838463d..f581e1a4 100644 --- a/src/wix/WixToolset.Core/Common.cs +++ b/src/wix/WixToolset.Core/Common.cs @@ -14,6 +14,7 @@ namespace WixToolset.Core using WixToolset.Data; using WixToolset.Extensibility; using WixToolset.Extensibility.Services; + using WixToolset.Versioning; /// /// Common Wix utility methods and types. diff --git a/src/wix/WixToolset.Core/ExtensibilityServices/BackendHelper.cs b/src/wix/WixToolset.Core/ExtensibilityServices/BackendHelper.cs index 4a5cc607..43f7aa01 100644 --- a/src/wix/WixToolset.Core/ExtensibilityServices/BackendHelper.cs +++ b/src/wix/WixToolset.Core/ExtensibilityServices/BackendHelper.cs @@ -8,6 +8,7 @@ namespace WixToolset.Core.ExtensibilityServices using WixToolset.Data; using WixToolset.Extensibility.Data; using WixToolset.Extensibility.Services; + using WixToolset.Versioning; internal class BackendHelper : LayoutServices, IBackendHelper { diff --git a/src/wix/WixToolset.Core/ExtensibilityServices/ParseHelper.cs b/src/wix/WixToolset.Core/ExtensibilityServices/ParseHelper.cs index 5f4ac726..0ec5b514 100644 --- a/src/wix/WixToolset.Core/ExtensibilityServices/ParseHelper.cs +++ b/src/wix/WixToolset.Core/ExtensibilityServices/ParseHelper.cs @@ -15,6 +15,7 @@ namespace WixToolset.Core.ExtensibilityServices using WixToolset.Extensibility; using WixToolset.Extensibility.Data; using WixToolset.Extensibility.Services; + using WixToolset.Versioning; internal class ParseHelper : IParseHelper { diff --git a/src/wix/WixToolset.Core/WixToolset.Core.csproj b/src/wix/WixToolset.Core/WixToolset.Core.csproj index f2ee3a2c..42b0c0c7 100644 --- a/src/wix/WixToolset.Core/WixToolset.Core.csproj +++ b/src/wix/WixToolset.Core/WixToolset.Core.csproj @@ -17,6 +17,7 @@ + -- cgit v1.2.3-55-g6feb