Skip to content

Commit

Permalink
Relax SemanticVersion constructors to not require minor and patch (Po…
Browse files Browse the repository at this point in the history
…werShell#3696)

`$psversiontable.psversion -gt "3.0"` which is used by PowerShellGet to determine if a module is compatible with the current version of PowerShell.

Change is to allow specifying only major or major+minor where the missing segments default to zero by providing overloaded constructors and allow
the string parsing method to not require major, minor, and patch segments to all be specified (only major is required).

Based on the [response](semver/semver#368) from the maintainer of semver, there is no requirement to have strict
conformance for the inputs to the constructor and allowing "3.0" to result in a semver of 3.0.0 is reasonable.
  • Loading branch information
SteveL-MSFT authored and lzybkr committed May 8, 2017
1 parent 5938688 commit 6342944
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 9 deletions.
27 changes: 23 additions & 4 deletions src/System.Management.Automation/engine/PSVersionInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -465,6 +465,25 @@ public SemanticVersion(int major, int minor, int patch)
Label = null;
}

/// <summary>
/// Construct a SemanticVersion.
/// </summary>
/// <param name="major">The major version</param>
/// <param name="minor">The minor version</param>
/// <exception cref="PSArgumentException">
/// If <paramref name="major"/> or <paramref name="minor"/> is less than 0.
/// </exception>
public SemanticVersion(int major, int minor) : this(major, minor, 0) {}

/// <summary>
/// Construct a SemanticVersion.
/// </summary>
/// <param name="major">The major version</param>
/// <exception cref="PSArgumentException">
/// If <paramref name="major"/> is less than 0.
/// </exception>
public SemanticVersion(int major) : this(major, 0, 0) {}

private const string LabelPropertyName = "PSSemanticVersionLabel";

/// <summary>
Expand Down Expand Up @@ -584,24 +603,24 @@ private static bool TryParseVersion(string version, ref VersionResult result)

var versionSansLabel = (dashIndex < 0) ? version : version.Substring(0, dashIndex);
string[] parsedComponents = versionSansLabel.Split(Utils.Separators.Dot);
if (parsedComponents.Length != 3)
if (parsedComponents.Length > 3)
{
result.SetFailure(ParseFailureKind.ArgumentException);
return false;
}

int major, minor, patch;
int major = 0, minor = 0, patch = 0;
if (!TryParseComponent(parsedComponents[0], "major", ref result, out major))
{
return false;
}

if (!TryParseComponent(parsedComponents[1], "minor", ref result, out minor))
if (parsedComponents.Length >= 2 && !TryParseComponent(parsedComponents[1], "minor", ref result, out minor))
{
return false;
}

if (!TryParseComponent(parsedComponents[2], "patch", ref result, out patch))
if (parsedComponents.Length == 3 && !TryParseComponent(parsedComponents[2], "patch", ref result, out patch))
{
return false;
}
Expand Down
28 changes: 23 additions & 5 deletions test/powershell/engine/SemanticVersion.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,20 @@ Describe "SemanticVersion api tests" -Tags 'CI' {
$v.Patch | Should Be 0
$v.Label | Should BeNullOrEmpty
$v.ToString() | Should Be "1.0.0"

$v = [SemanticVersion]::new("3.0")
$v.Major | Should Be 3
$v.Minor | Should Be 0
$v.Patch | Should Be 0
$v.Label | Should BeNullOrEmpty
$v.ToString() | Should Be "3.0.0"

$v = [SemanticVersion]::new("2")
$v.Major | Should Be 2
$v.Minor | Should Be 0
$v.Patch | Should Be 0
$v.Label | Should BeNullOrEmpty
$v.ToString() | Should Be "2.0.0"
}

# After the above test, we trust the properties and rely on ToString for validation
Expand All @@ -27,6 +41,12 @@ Describe "SemanticVersion api tests" -Tags 'CI' {

$v = [SemanticVersion]::new(3, 2, 0, "beta.1")
$v.ToString() | Should Be "3.2.0-beta.1"

$v = [SemanticVersion]::new(3, 1)
$v.ToString() | Should Be "3.1.0"

$v = [SemanticVersion]::new(3)
$v.ToString() | Should Be "3.0.0"
}

It "version arg constructor" {
Expand Down Expand Up @@ -57,6 +77,8 @@ Describe "SemanticVersion api tests" -Tags 'CI' {
@{ 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 }
@{ lhs = $v2_1_0; rhs = "3.0"}
@{ lhs = "1.5"; rhs = $v2_1_0}
)
It "less than" -TestCases $testCases {
param($lhs, $rhs)
Expand Down Expand Up @@ -121,8 +143,8 @@ Describe "SemanticVersion api tests" -Tags 'CI' {
@{ expectedResult = $false; version = "" }
@{ expectedResult = $false; version = "1.0.0-" }
@{ expectedResult = $false; version = "-" }
@{ 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." }
Expand Down Expand Up @@ -178,10 +200,6 @@ Describe "SemanticVersion api tests" -Tags 'CI' {
# 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
}
}

Expand Down

0 comments on commit 6342944

Please sign in to comment.