From be8e39782f53d5853b14ff4b09a35ef219c85cf2 Mon Sep 17 00:00:00 2001 From: "Jason Shirk (POWERSHELL)" Date: Fri, 22 Jul 2016 19:03:13 -0700 Subject: [PATCH 1/3] Add SemanticVersion type --- .../NugetLightRequest.cs | 2 + .../nugetlightprovider.cs | 2 + .../PackageList/ExePackageInstaller.cs | 1 + .../PackageList/NupkgInstaller.cs | 1 + .../PackageList/PackageListParser.cs | 2 + .../PackageList/PackageListRequest.cs | 1 + .../engine/PSVersionInfo.cs | 450 ++++++++++++++++++ 7 files changed, 459 insertions(+) diff --git a/src/Microsoft.PackageManagement.NuGetProvider/NugetLightRequest.cs b/src/Microsoft.PackageManagement.NuGetProvider/NugetLightRequest.cs index 6f437885e..5bc0aa951 100644 --- a/src/Microsoft.PackageManagement.NuGetProvider/NugetLightRequest.cs +++ b/src/Microsoft.PackageManagement.NuGetProvider/NugetLightRequest.cs @@ -20,6 +20,8 @@ using System.Net; using Microsoft.PackageManagement.Provider.Utility; + using SemanticVersion = Microsoft.PackageManagement.Provider.Utility.SemanticVersion; + /// /// This class drives the Request class that is an interface exposed from the PackageManagement Platform to the provider to use. /// diff --git a/src/Microsoft.PackageManagement.NuGetProvider/nugetlightprovider.cs b/src/Microsoft.PackageManagement.NuGetProvider/nugetlightprovider.cs index b21a211ca..5bc32760e 100644 --- a/src/Microsoft.PackageManagement.NuGetProvider/nugetlightprovider.cs +++ b/src/Microsoft.PackageManagement.NuGetProvider/nugetlightprovider.cs @@ -11,6 +11,8 @@ namespace Microsoft.PackageManagement.NuGetProvider using System.Reflection; using System.Management.Automation; + using SemanticVersion = Microsoft.PackageManagement.Provider.Utility.SemanticVersion; + /// /// A Package provider to the PackageManagement Platform. /// diff --git a/src/Microsoft.PackageManagement.PackageSourceListProvider/PackageList/ExePackageInstaller.cs b/src/Microsoft.PackageManagement.PackageSourceListProvider/PackageList/ExePackageInstaller.cs index a36cf3405..d3539d802 100644 --- a/src/Microsoft.PackageManagement.PackageSourceListProvider/PackageList/ExePackageInstaller.cs +++ b/src/Microsoft.PackageManagement.PackageSourceListProvider/PackageList/ExePackageInstaller.cs @@ -29,6 +29,7 @@ namespace Microsoft.PackageManagement.PackageSourceListProvider using Microsoft.PackageManagement.Provider.Utility; using Microsoft.Win32; using ErrorCategory = PackageManagement.Internal.ErrorCategory; + using SemanticVersion = Microsoft.PackageManagement.Provider.Utility.SemanticVersion; internal static class ExePackageInstaller { diff --git a/src/Microsoft.PackageManagement.PackageSourceListProvider/PackageList/NupkgInstaller.cs b/src/Microsoft.PackageManagement.PackageSourceListProvider/PackageList/NupkgInstaller.cs index 54a580a7f..30e538785 100644 --- a/src/Microsoft.PackageManagement.PackageSourceListProvider/PackageList/NupkgInstaller.cs +++ b/src/Microsoft.PackageManagement.PackageSourceListProvider/PackageList/NupkgInstaller.cs @@ -27,6 +27,7 @@ namespace Microsoft.PackageManagement.PackageSourceListProvider using Microsoft.PackageManagement.Provider.Utility; using ErrorCategory = PackageManagement.Internal.ErrorCategory; using System.Globalization; + using SemanticVersion = Microsoft.PackageManagement.Provider.Utility.SemanticVersion; internal static class NupkgInstaller { diff --git a/src/Microsoft.PackageManagement.PackageSourceListProvider/PackageList/PackageListParser.cs b/src/Microsoft.PackageManagement.PackageSourceListProvider/PackageList/PackageListParser.cs index afb0cb025..f1194779b 100644 --- a/src/Microsoft.PackageManagement.PackageSourceListProvider/PackageList/PackageListParser.cs +++ b/src/Microsoft.PackageManagement.PackageSourceListProvider/PackageList/PackageListParser.cs @@ -9,6 +9,8 @@ using Microsoft.PackageManagement.Provider.Utility; using System.Reflection; using System.Globalization; +using SemanticVersion = Microsoft.PackageManagement.Provider.Utility.SemanticVersion; + namespace Microsoft.PackageManagement.PackageSourceListProvider { internal static class JsonParser diff --git a/src/Microsoft.PackageManagement.PackageSourceListProvider/PackageList/PackageListRequest.cs b/src/Microsoft.PackageManagement.PackageSourceListProvider/PackageList/PackageListRequest.cs index 7429a0815..e04536575 100644 --- a/src/Microsoft.PackageManagement.PackageSourceListProvider/PackageList/PackageListRequest.cs +++ b/src/Microsoft.PackageManagement.PackageSourceListProvider/PackageList/PackageListRequest.cs @@ -34,6 +34,7 @@ namespace Microsoft.PackageManagement.PackageSourceListProvider using Microsoft.PackageManagement.Implementation; using Microsoft.PackageManagement.Internal.Api; using Microsoft.PackageManagement.Provider.Utility; + using SemanticVersion = Microsoft.PackageManagement.Provider.Utility.SemanticVersion; public abstract class PackageSourceListRequest : Request { diff --git a/src/System.Management.Automation/engine/PSVersionInfo.cs b/src/System.Management.Automation/engine/PSVersionInfo.cs index 041466847..5b88ba3d6 100644 --- a/src/System.Management.Automation/engine/PSVersionInfo.cs +++ b/src/System.Management.Automation/engine/PSVersionInfo.cs @@ -4,6 +4,8 @@ Copyright (c) Microsoft Corporation. All rights reserved. using System.Diagnostics; using System.Reflection; using System.Collections; +using System.Globalization; +using System.Management.Automation.Internal; using Microsoft.Win32; namespace System.Management.Automation @@ -289,4 +291,452 @@ namespace System.Management.Automation #endregion } + + /// + /// An implementation of semantic versioning (http://semver.org) + /// that can be converted to/from . + /// + /// When converting to , a PSNoteProperty is + /// added to the instance to store the semantic version label so + /// that it can be recovered when creating a new SemanticVersion. + /// + public sealed class SemanticVersion : IComparable, IComparable, IEquatable + { + /// + /// Construct a SemanticVersion from a string. + /// + /// The version to parse + /// + /// + /// + /// + public SemanticVersion(string version) + { + var v = SemanticVersion.Parse(version); + + Major = v.Major; + Minor = v.Minor; + Patch = v.Patch; + Label = v.Label; + } + + /// + /// Construct a SemanticVersion. + /// + /// The major version + /// The minor version + /// The minor version + /// The label for the version + /// + /// If , , or is less than 0. + /// + /// + /// If is null or an empty string. + /// + public SemanticVersion(int major, int minor, int patch, string label) + : this(major, minor, patch) + { + if (string.IsNullOrEmpty(label)) throw PSTraceSource.NewArgumentNullException(nameof(label)); + + Label = label; + } + + /// + /// Construct a SemanticVersion. + /// + /// The major version + /// The minor version + /// The minor version + /// + /// If , , or is less than 0. + /// + public SemanticVersion(int major, int minor, int patch) + { + if (major < 0) throw PSTraceSource.NewArgumentException(nameof(major)); + if (minor < 0) throw PSTraceSource.NewArgumentException(nameof(minor)); + if (patch < 0) throw PSTraceSource.NewArgumentException(nameof(patch)); + + Major = major; + Minor = minor; + Patch = patch; + Label = null; + } + + const string LabelPropertyName = "PSSemanticVersionLabel"; + + /// + /// Construct a from a , + /// copying the NoteProperty storing the label if the expected property exists. + /// + /// The version. + public SemanticVersion(Version version) + { + if (version.Revision > 0 || version.Build < 0) throw PSTraceSource.NewArgumentException(nameof(version)); + + Major = version.Major; + Minor = version.Minor; + Patch = version.Build; + var psobj = new PSObject(version); + var labelNote = psobj.Properties[LabelPropertyName]; + if (labelNote != null) + { + Label = labelNote.Value as string; + } + } + + /// + /// Convert a to a . + /// If there is a , it is added as a NoteProperty to the + /// result so that you can round trip back to a + /// without losing the label. + /// + /// + public static implicit operator Version(SemanticVersion semver) + { + var result = new Version(semver.Major, semver.Minor, semver.Patch); + + if (!string.IsNullOrEmpty(semver.Label)) + { + var psobj = new PSObject(result); + psobj.Properties.Add(new PSNoteProperty(LabelPropertyName, semver.Label)); + } + + return result; + } + + /// + /// The major version number, never negative. + /// + public int Major { get; } + + /// + /// The minor version number, never negative. + /// + public int Minor { get; } + + /// + /// The patch version, -1 if not specified. + /// + public int Patch { get; } + + /// + /// The last component in a SemanticVersion - may be null if not specified. + /// + public string Label { get; } + + /// + /// Parse and return the result if it is a valid , otherwise throws an exception. + /// + /// The string to parse + /// + /// + /// + /// + /// + public static SemanticVersion Parse(string version) + { + if (version == null) throw PSTraceSource.NewArgumentNullException(nameof(version)); + + var r = new VersionResult(); + r.Init(true); + TryParseVersion(version, ref r); + + return r._parsedVersion; + } + + /// + /// Parse and return true if it is a valid , otherwise return false. + /// No exceptions are raised. + /// + /// The string to parse + /// The return value when the string is a valid + public static bool TryParse(string version, out SemanticVersion result) + { + if (version != null) + { + var r = new VersionResult(); + r.Init(false); + + if (TryParseVersion(version, ref r)) + { + result = r._parsedVersion; + return true; + } + } + + result = null; + return false; + } + + private static bool TryParseVersion(string version, ref VersionResult result) + { + var dashIndex = version.IndexOf('-'); + + // Empty label? + if (dashIndex == version.Length - 1) + { + result.SetFailure(ParseFailureKind.ArgumentException); + return false; + } + + var versionSansLabel = (dashIndex < 0) ? version : version.Substring(0, dashIndex); + string[] parsedComponents = versionSansLabel.Split(Utils.Separators.Dot); + if (parsedComponents.Length != 3) + { + result.SetFailure(ParseFailureKind.ArgumentException); + return false; + } + + int major, minor, patch; + if (!TryParseComponent(parsedComponents[0], "major", ref result, out major)) + { + return false; + } + + if (!TryParseComponent(parsedComponents[1], "minor", ref result, out minor)) + { + return false; + } + + if (!TryParseComponent(parsedComponents[2], "patch", ref result, out patch)) + { + return false; + } + + result._parsedVersion = dashIndex < 0 + ? new SemanticVersion(major, minor, patch) + : new SemanticVersion(major, minor, patch, version.Substring(dashIndex + 1)); + return true; + } + + private static bool TryParseComponent(string component, string componentName, ref VersionResult result, out int parsedComponent) + { + if (!Int32.TryParse(component, NumberStyles.Integer, CultureInfo.InvariantCulture, out parsedComponent)) + { + result.SetFailure(ParseFailureKind.FormatException, component); + return false; + } + + if (parsedComponent < 0) + { + result.SetFailure(ParseFailureKind.ArgumentOutOfRangeException, componentName); + return false; + } + + return true; + } + + /// + /// ToString + /// + public override string ToString() + { + if (Patch < 0) + { + return string.IsNullOrEmpty(Label) + ? StringUtil.Format("{0}.{1}", Major, Minor) + : StringUtil.Format("{0}.{1}-{2}", Major, Minor, Label); + } + + return string.IsNullOrEmpty(Label) + ? StringUtil.Format("{0}.{1}.{2}", Major, Minor, Patch) + : StringUtil.Format("{0}.{1}.{2}-{3}", Major, Minor, Patch, Label); + } + + /// + /// Implement + /// + public int CompareTo(object version) + { + if (version == null) + { + return 1; + } + + var v = version as SemanticVersion; + if (v == null) + { + throw PSTraceSource.NewArgumentException(nameof(version)); + } + + return CompareTo(v); + } + + /// + /// Implement + /// + public int CompareTo(SemanticVersion value) + { + if ((object)value == null) + return 1; + + if (Major != value.Major) + return Major > value.Major ? 1 : -1; + + if (Minor != value.Minor) + return Minor > value.Minor ? 1 : -1; + + if (Patch != value.Patch) + return Patch > value.Patch ? 1 : -1; + + if (Label == null) + return value.Label == null ? 0 : 1; + + if (value.Label == null) + return -1; + + if (!string.Equals(Label, value.Label, StringComparison.Ordinal)) + return string.Compare(Label, value.Label, StringComparison.Ordinal); + + return 0; + } + + /// + /// Override + /// + public override bool Equals(object obj) + { + return Equals(obj as SemanticVersion); + } + + /// + /// Implement + /// + public bool Equals(SemanticVersion other) + { + return other != null && + (Major == other.Major) && (Minor == other.Minor) && (Patch == other.Patch) && + string.Equals(Label, other.Label, StringComparison.Ordinal); + } + + /// + /// Override + /// + public override int GetHashCode() + { + return Utils.CombineHashCodes( + Major.GetHashCode(), + Minor.GetHashCode(), + Patch.GetHashCode(), + Label == null ? 0 : Label.GetHashCode()); + } + + /// + /// Overloaded == operator + /// + public static bool operator ==(SemanticVersion v1, SemanticVersion v2) + { + if (object.ReferenceEquals(v1, null)) { + return object.ReferenceEquals(v2, null); + } + + return v1.Equals(v2); + } + + /// + /// Overloaded != operator + /// + public static bool operator !=(SemanticVersion v1, SemanticVersion v2) + { + return !(v1 == v2); + } + + /// + /// Overloaded < operator + /// + public static bool operator <(SemanticVersion v1, SemanticVersion v2) + { + if ((object) v1 == null) throw PSTraceSource.NewArgumentException(nameof(v1)); + return (v1.CompareTo(v2) < 0); + } + + /// + /// Overloaded <= operator + /// + public static bool operator <=(SemanticVersion v1, SemanticVersion v2) + { + if ((object) v1 == null) throw PSTraceSource.NewArgumentException(nameof(v1)); + return (v1.CompareTo(v2) <= 0); + } + + /// + /// Overloaded > operator + /// + public static bool operator >(SemanticVersion v1, SemanticVersion v2) + { + return (v2 < v1); + } + + /// + /// Overloaded >= operator + /// + public static bool operator >=(SemanticVersion v1, SemanticVersion v2) + { + return (v2 <= v1); + } + + internal enum ParseFailureKind + { + ArgumentException, + ArgumentOutOfRangeException, + FormatException + } + + internal struct VersionResult + { + internal SemanticVersion _parsedVersion; + internal ParseFailureKind _failure; + internal string _exceptionArgument; + internal bool _canThrow; + + internal void Init(bool canThrow) + { + _canThrow = canThrow; + } + + internal void SetFailure(ParseFailureKind failure) + { + SetFailure(failure, String.Empty); + } + + internal void SetFailure(ParseFailureKind failure, string argument) + { + _failure = failure; + _exceptionArgument = argument; + if (_canThrow) + { + throw GetVersionParseException(); + } + } + + internal Exception GetVersionParseException() + { + switch (_failure) + { + case ParseFailureKind.ArgumentException: + return PSTraceSource.NewArgumentException("version"); + case ParseFailureKind.ArgumentOutOfRangeException: + throw new ValidationMetadataException("ValidateRangeTooSmall", + null, Metadata.ValidateRangeSmallerThanMinRangeFailure, + _exceptionArgument, "0"); + case ParseFailureKind.FormatException: + // Regenerate the FormatException as would be thrown by Int32.Parse() + try + { + Int32.Parse(_exceptionArgument, CultureInfo.InvariantCulture); + } + catch (FormatException e) + { + return e; + } + catch (OverflowException e) + { + return e; + } + break; + } + return PSTraceSource.NewArgumentException("version"); + } + } + } } From 8e8ade947d8887681cbb54dc80fbe2bc0174c761 Mon Sep 17 00:00:00 2001 From: "Jason Shirk (POWERSHELL)" Date: Fri, 22 Jul 2016 19:03:34 -0700 Subject: [PATCH 2/3] Add SemanticVersion tests --- .../engine/SemanticVersion.Tests.ps1 | 187 ++++++++++++++++++ 1 file changed, 187 insertions(+) create mode 100644 test/powershell/engine/SemanticVersion.Tests.ps1 diff --git a/test/powershell/engine/SemanticVersion.Tests.ps1 b/test/powershell/engine/SemanticVersion.Tests.ps1 new file mode 100644 index 000000000..c350dcfc7 --- /dev/null +++ b/test/powershell/engine/SemanticVersion.Tests.ps1 @@ -0,0 +1,187 @@ +using namespace System.Management.Automation +using namespace System.Management.Automation.Language + +Describe "SemanticVersion api tests" { + Context "constructing valid versions" { + It "string argument constructor" { + $v = [SemanticVersion]::new("1.2.3-alpha") + $v.Major | Should Be 1 + $v.Minor | Should Be 2 + $v.Patch | Should Be 3 + $v.Label | Should Be "alpha" + $v.ToString() | Should Be "1.2.3-alpha" + + $v = [SemanticVersion]::new("1.0.0") + $v.Major | Should Be 1 + $v.Minor | Should Be 0 + $v.Patch | Should Be 0 + $v.Label | Should BeNullOrEmpty + $v.ToString() | Should Be "1.0.0" + } + + # After the above test, we trust the properties and rely on ToString for validation + + It "int args constructor" { + $v = [SemanticVersion]::new(1, 0, 0) + $v.ToString() | Should Be "1.0.0" + + $v = [SemanticVersion]::new(3, 2, 0, "beta.1") + $v.ToString() | Should Be "3.2.0-beta.1" + } + + It "version arg constructor" { + $v = [SemanticVersion]::new([Version]::new(1, 2, 3)) + $v.ToString() | Should Be '1.2.3' + } + + It "semantic version can round trip through version" { + $v1 = [SemanticVersion]::new(3, 2, 1, "prerelease") + $v2 = [SemanticVersion]::new([Version]$v1) + $v2.ToString() | Should Be "3.2.1-prerelease" + } + } + + Context "Comparisons" { + $v1_0_0 = [SemanticVersion]::new(1, 0, 0) + $v1_1_0 = [SemanticVersion]::new(1, 1, 0) + $v1_1_1 = [SemanticVersion]::new(1, 1, 1) + $v2_1_0 = [SemanticVersion]::new(2, 1, 0) + $v1_0_0_alpha = [SemanticVersion]::new(1, 0, 0, "alpha") + $v1_0_0_beta = [SemanticVersion]::new(1, 0, 0, "beta") + + $testCases = @( + @{ lhs = $v1_0_0; rhs = $v1_1_0 } + @{ lhs = $v1_0_0; rhs = $v1_1_1 } + @{ lhs = $v1_1_0; rhs = $v1_1_1 } + @{ lhs = $v1_0_0; rhs = $v2_1_0 } + @{ lhs = $v1_0_0_alpha; rhs = $v1_0_0_beta } + @{ lhs = $v1_0_0_alpha; rhs = $v1_0_0 } + @{ lhs = $v1_0_0_beta; rhs = $v1_0_0 } + ) + It "less than" -TestCases $testCases { + param($lhs, $rhs) + $lhs -lt $rhs | Should Be $true + $rhs -lt $lhs | Should Be $false + } + It "less than or equal" -TestCases $testCases { + param($lhs, $rhs) + $lhs -le $rhs | Should Be $true + $rhs -le $lhs | Should Be $false + $lhs -le $lhs | Should Be $true + $rhs -le $rhs | Should Be $true + } + It "greater than" -TestCases $testCases { + param($lhs, $rhs) + $lhs -gt $rhs | Should Be $false + $rhs -gt $lhs | Should Be $true + } + It "greater than or equal" -TestCases $testCases { + param($lhs, $rhs) + $lhs -ge $rhs | Should Be $false + $rhs -ge $lhs | Should Be $true + $lhs -ge $lhs | Should Be $true + $rhs -ge $rhs | Should Be $true + } + + $testCases = @( + @{ operand = $v1_0_0 } + @{ operand = $v1_0_0_alpha } + ) + It "Equality" -TestCases $testCases { + param($operand) + $operand -eq $operand | Should Be $true + $operand -ne $operand | Should Be $false + $null -eq $operand | Should Be $false + $operand -eq $null | Should Be $false + $null -ne $operand | Should Be $true + $operand -ne $null | Should Be $true + } + + It "comparisons with null" { + $v1_0_0 -lt $null | Should Be $false + $null -lt $v1_0_0 | Should Be $true + $v1_0_0 -le $null | Should Be $false + $null -le $v1_0_0 | Should Be $true + $v1_0_0 -gt $null | Should Be $true + $null -gt $v1_0_0 | Should Be $false + $v1_0_0 -ge $null | Should Be $true + $null -ge $v1_0_0 | Should Be $false + } + } + + Context "error handling" { + + # The specific errors aren't too useful here, but noted in comments + # so when we pick up a version of Pester that will let us check FullyQualifiedErrorId, + # it's easier to tweak the tests + + $testCases = @( + @{ expectedResult = $false; version = $null } + @{ expectedResult = $false; version = [NullString]::Value } + @{ expectedResult = $false; version = "" } + @{ expectedResult = $false; version = "1.0.0-" } + @{ expectedResult = $false; version = "-" } + @{ expectedResult = $false; version = "-alpha" } + @{ expectedResult = $false; version = "1.0" } # REVIEW - should this be allowed + @{ expectedResult = $false; version = "1..0" } + @{ expectedResult = $false; version = "1.0.-alpha" } + @{ expectedResult = $false; version = "1.0." } + @{ expectedResult = $false; version = ".0.0" } + ) + + It "parts of version missing" -TestCases $testCases { + param($version, $expectedResult) + { [SemanticVersion]::new($version) } | Should Throw # PSArgumentException + { [SemanticVersion]::Parse($version) } | Should Throw # PSArgumentException + $semVer = $null + [SemanticVersion]::TryParse($_, [ref]$semVer) | Should Be $expectedResult + $semVer | Should Be $null + } + + $testCases = @( + @{ expectedResult = $false; version = "-1.0.0" } + @{ expectedResult = $false; version = "1.-1.0" } + @{ expectedResult = $false; version = "1.0.-1" } + ) + + It "range check of versions" -TestCases $testCases { + param($version, $expectedResult) + { [SemanticVersion]::new($version) } | Should Throw # PSArgumentException + { [SemanticVersion]::Parse($version) } | Should Throw # PSArgumentException + $semVer = $null + [SemanticVersion]::TryParse($_, [ref]$semVer) | Should Be $expectedResult + $semVer | Should Be $null + } + + $testCases = @( + @{ expectedResult = $false; version = "aa.0.0" } + @{ expectedResult = $false; version = "1.bb.0" } + @{ expectedResult = $false; version = "1.0.cc" } + ) + + It "format errors" -TestCases $testCases { + param($version, $expectedResult) + { [SemanticVersion]::new($version) } | Should Throw # PSArgumentException + { [SemanticVersion]::Parse($version) } | Should Throw # PSArgumentException + $semVer = $null + [SemanticVersion]::TryParse($_, [ref]$semVer) | Should Be $expectedResult + $semVer | Should Be $null + } + + It "Negative version arguments" { + { [SemanticVersion]::new(-1, 0) } | Should Throw # PSArgumentException + { [SemanticVersion]::new(1, -1) } | Should Throw # PSArgumentException + { [SemanticVersion]::new(1, 1, -1) } | Should Throw # PSArgumentException + } + + It "Incompatible version throws" { + # Revision isn't supported + { [SemanticVersion]::new([Version]::new(0, 0, 0, 4)) } | Should Throw # PSArgumentException + { [SemanticVersion]::new([Version]::new("1.2.3.4")) } | Should Throw # PSArgumentException + + # Build is required + { [SemanticVersion]::new([Version]::new(1, 2)) } | Should Throw # PSArgumentException + { [SemanticVersion]::new([Version]::new("1.2")) } | Should Throw # PSArgumentException + } + } +} \ No newline at end of file From 9a20bf6f971c30ba90f0f5af064f7511755285eb Mon Sep 17 00:00:00 2001 From: "Jason Shirk (POWERSHELL)" Date: Tue, 26 Jul 2016 13:42:12 -0700 Subject: [PATCH 3/3] Change $PSVersionTable.PSVersion to 6.0.0-alpha --- .../engine/PSVersionInfo.cs | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/System.Management.Automation/engine/PSVersionInfo.cs b/src/System.Management.Automation/engine/PSVersionInfo.cs index 5b88ba3d6..7a8ba3b8b 100644 --- a/src/System.Management.Automation/engine/PSVersionInfo.cs +++ b/src/System.Management.Automation/engine/PSVersionInfo.cs @@ -39,6 +39,7 @@ namespace System.Management.Automation static Version _psV4Version = new Version(4, 0); static Version _psV5Version = new Version(5, 0); static Version _psV51Version = new Version(5, 1, NTVerpVars.PRODUCTBUILD, NTVerpVars.PRODUCTBUILD_QFE); + static SemanticVersion _psV6Version = new SemanticVersion(6, 0, 0, "alpha"); /// /// A constant to track current PowerShell Edition @@ -59,11 +60,11 @@ namespace System.Management.Automation { _psVersionTable = new Hashtable(StringComparer.OrdinalIgnoreCase); - _psVersionTable[PSVersionInfo.PSVersionName] = _psV51Version; + _psVersionTable[PSVersionInfo.PSVersionName] = _psV6Version; _psVersionTable["PSEdition"] = PSEditionValue; _psVersionTable["BuildVersion"] = GetBuildVersion(); _psVersionTable["GitCommitId"] = GetCommitInfo(); - _psVersionTable["PSCompatibleVersions"] = new Version[] { _psV1Version, _psV2Version, _psV3Version, _psV4Version, _psV5Version, _psV51Version }; + _psVersionTable["PSCompatibleVersions"] = new Version[] { _psV1Version, _psV2Version, _psV3Version, _psV4Version, _psV5Version, _psV51Version, _psV6Version }; _psVersionTable[PSVersionInfo.SerializationVersionName] = new Version(InternalSerializer.DefaultVersion); _psVersionTable[PSVersionInfo.PSRemotingProtocolVersionName] = RemotingConstants.ProtocolVersion; _psVersionTable[PSVersionInfo.WSManStackVersionName] = GetWSManStackVersion(); @@ -142,7 +143,7 @@ namespace System.Management.Automation { get { - return (Version) GetPSVersionTable()[PSVersionInfo.PSVersionName]; + return (SemanticVersion) GetPSVersionTable()[PSVersionInfo.PSVersionName]; } } @@ -249,6 +250,10 @@ namespace System.Management.Automation static internal bool IsValidPSVersion(Version version) { + if (version.Major == _psV6Version.Major) + { + return version.Minor == _psV6Version.Minor; + } if (version.Major == _psV5Version.Major) { return (version.Minor == _psV5Version.Minor || version.Minor == _psV51Version.Minor); @@ -288,6 +293,11 @@ namespace System.Management.Automation get { return _psV51Version; } } + static internal SemanticVersion PSV6Version + { + get { return _psV6Version; } + } + #endregion }