Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tl/spike splitting version interface #74

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ public void MatchingVersionsShouldBeGroupedCorrectly(string version)
var ver1 = VersionFactory.CreateDockerTag(version);
var ver2 = VersionFactory.CreateDockerTag(version);

var items = new List<IVersion> {ver1, ver2}.GroupBy(i => i).ToList();
var items = new List<ISortableVersion> {ver1, ver2}.GroupBy(i => i).ToList();
Assert.AreEqual(1, items.Count);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public void TestMatchingVersionsAreGroupedCorrectly(string version)
var ver1 = VersionFactory.CreateMavenVersion(version);
var ver2 = VersionFactory.CreateMavenVersion(version);

var items = new List<IVersion> {ver1, ver2}.GroupBy(i => i).ToList();
var items = new List<ISortableVersion> {ver1, ver2}.GroupBy(i => i).ToList();
Assert.AreEqual(1, items.Count);
}

Expand Down
24 changes: 12 additions & 12 deletions source/Octopus.Versioning.Tests/Maven/Ranges/RangeTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -691,25 +691,25 @@ void checkInvalidRange(string version)
[Test]
public void testContains()
{
IVersion actualVersion = new MavenVersionParser().Parse("2.0.5");
Assert.IsTrue(enforceVersion("2.0.5", actualVersion));
Assert.IsTrue(enforceVersion("2.0.4", actualVersion));
Assert.IsTrue(enforceVersion("[2.0.5]", actualVersion));
Assert.IsFalse(enforceVersion("[2.0.6,)", actualVersion));
Assert.IsFalse(enforceVersion("[2.0.6]", actualVersion));
Assert.IsTrue(enforceVersion("[2.0,2.1]", actualVersion));
Assert.IsFalse(enforceVersion("[2.0,2.0.3]", actualVersion));
Assert.IsTrue(enforceVersion("[2.0,2.0.5]", actualVersion));
Assert.IsFalse(enforceVersion("[2.0,2.0.5)", actualVersion));
ISortableVersion actualSortableVersion = new MavenVersionParser().Parse("2.0.5");
Assert.IsTrue(enforceVersion("2.0.5", actualSortableVersion));
Assert.IsTrue(enforceVersion("2.0.4", actualSortableVersion));
Assert.IsTrue(enforceVersion("[2.0.5]", actualSortableVersion));
Assert.IsFalse(enforceVersion("[2.0.6,)", actualSortableVersion));
Assert.IsFalse(enforceVersion("[2.0.6]", actualSortableVersion));
Assert.IsTrue(enforceVersion("[2.0,2.1]", actualSortableVersion));
Assert.IsFalse(enforceVersion("[2.0,2.0.3]", actualSortableVersion));
Assert.IsTrue(enforceVersion("[2.0,2.0.5]", actualSortableVersion));
Assert.IsFalse(enforceVersion("[2.0,2.0.5)", actualSortableVersion));
}

public bool enforceVersion(string requiredMavenVersionRange, IVersion actualVersion)
public bool enforceVersion(string requiredMavenVersionRange, ISortableVersion actualSortableVersion)
{
MavenVersionRange vr = null;

vr = MavenVersionRange.CreateFromVersionSpec(requiredMavenVersionRange);

return vr.ContainsVersion(actualVersion);
return vr.ContainsVersion(actualSortableVersion);
}

[Test]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ public void MatchingVersionsShouldBeGroupedCorrectly(string version)
var ver1 = VersionFactory.CreateOctopusVersion(version);
var ver2 = VersionFactory.CreateOctopusVersion(version);

var items = new List<IVersion> {ver1, ver2}.GroupBy(i => i).ToList();
var items = new List<ISortableVersion> {ver1, ver2}.GroupBy(i => i).ToList();
Assert.AreEqual(1, items.Count);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ public void IsMask(string mask, bool isMask)
[TestCase("1.i.i", "2.0.0", null)]
public void GetLatestVersionMask(string version, string latestVersion, string expected)
{
var latestVersions = new List<IVersion>
var latestVersions = new List<ISortableVersion>
{
new OctopusVersionParser().Parse(latestVersion)
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ public static bool IsMask(string versionString)
);
}

public static IVersion GetLatestMaskedVersion(string mask, List<IVersion> versions)
public static ISortableVersion GetLatestMaskedVersion(string mask, List<ISortableVersion> versions)
{
var maskMatch = new MaskMatchedVersion(mask);

Expand Down Expand Up @@ -87,18 +87,18 @@ public static IVersion GetLatestMaskedVersion(string mask, List<IVersion> versio
.FirstOrDefault();
}

public static IVersion ApplyMask(string mask, IVersion currentVersion)
public static ISortableVersion ApplyMask(string mask, ISortableVersion currentSortableVersion)
{
var match = FormatRegex.Match(mask);
if (!match.Success)
return VersionFactory.CreateSemanticVersion(mask);

return currentVersion == null
return currentSortableVersion == null
? GenerateVersionFromMask(new MaskMatchedVersion(mask))
: GenerateVersionFromCurrent(new MaskMatchedVersion(mask), new MaskMatchedVersion(currentVersion.ToString()));
: GenerateVersionFromCurrent(new MaskMatchedVersion(mask), new MaskMatchedVersion(currentSortableVersion.ToString()));
}

static IVersion GenerateVersionFromMask(MaskMatchedVersion mask)
static ISortableVersion GenerateVersionFromMask(MaskMatchedVersion mask)
{
var result = new StringBuilder();
result.Append(mask.Major.EvaluateFromMask());
Expand All @@ -110,7 +110,7 @@ static IVersion GenerateVersionFromMask(MaskMatchedVersion mask)
return VersionFactory.CreateSemanticVersion(result.ToString());
}

static IVersion GenerateVersionFromCurrent(MaskMatchedVersion mask, MaskMatchedVersion current)
static ISortableVersion GenerateVersionFromCurrent(MaskMatchedVersion mask, MaskMatchedVersion current)
{
var result = new StringBuilder();
result.Append(mask.Major.Substitute(current.Major));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public void TestMatchingVersionsAreGroupedCorrectly()
var ver1 = VersionFactory.CreateSemanticVersion(version);
var ver2 = VersionFactory.CreateSemanticVersion(version);

var items = new List<IVersion> {ver1, ver2}.GroupBy(i => i).ToList();
var items = new List<ISortableVersion> {ver1, ver2}.GroupBy(i => i).ToList();
Assert.AreEqual(1, items.Count);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
using NUnit.Framework;
using Octopus.Versioning.Unsortable;

namespace Octopus.Versioning.Tests.Unsortable;

public class UnsortableVersionCompareTests
{
static readonly UnsortableVersionParser UnsortableVersionParser = new();

// [Test]
// [TestCase("release", "release", 0)]
// [TestCase("release", "qrelease", 1)]
// [TestCase("release", "srelease", -1)]
// [TestCase("123", "123", 0)]
// [TestCase("123", "100", 1)]
// [TestCase("123", "321", -1)]
// [TestCase("123Release", "123Release", 0)]
// [TestCase("123Release", "100Release", 1)]
// [TestCase("123Release", "321Release", -1)]
// [TestCase("release-1", "release-1", 0)]
// [TestCase("release-1", "release-0", 1)]
// [TestCase("release-1", "release-2", -1)]
// [TestCase("release.1", "release.1", 0)]
// [TestCase("release.1", "release.0", 1)]
// [TestCase("release.1", "release.2", -1)]
// [TestCase("release_1", "release_1", 0)]
// [TestCase("release_1", "release_0", 1)]
// [TestCase("release_1", "release_2", -1)]
// [TestCase("release-1", "release_1", 0)]
// [TestCase("release.1", "release_1", 0)]
// [TestCase("release-1", "release_0", 1)]
// [TestCase("release.1", "release_2", -1)]
// [TestCase("release+123", "release+321", 0)]
// [TestCase("release-1+123", "release-1+321", 0)]
// [TestCase("release-1+123", "release-0+321", 1)]
// [TestCase("release-1+123", "release-2+321", -1)]
// public void TestComparisons(string version1, string version2, int result)
// {
// var parsedVersion1 = UnsortableVersionParser.Parse(version1);
// var parsedVersion2 = UnsortableVersionParser.Parse(version2);
// Assert.AreEqual(result, parsedVersion1.CompareTo(parsedVersion2));
// }

// [Test]
// [TestCase("release-1", "release-1", true)]
// [TestCase("release-1", "release-2", false)]
// public void TestEquality(string version1, string version2, bool result)
// {
// var parsedVersion1 = UnsortableVersionParser.Parse(version1);
// var parsedVersion2 = UnsortableVersionParser.Parse(version2);
// Assert.AreEqual(result, Equals(parsedVersion1, parsedVersion2));
// }
//
// [Test]
// public void TestGetHashCode()
// {
// var versionString = "release-1";
// var parsedVersion = UnsortableVersionParser.Parse(versionString);
//
// Assert.AreEqual(versionString.GetHashCode(), parsedVersion.GetHashCode());
// }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
using System;
using NUnit.Framework;
using Octopus.Versioning.Unsortable;

namespace Octopus.Versioning.Tests.Unsortable;

[TestFixture]
public class UnsortableVersionParserTests
{
[Test]
// Release
[TestCase("foobar", "foobar", "")]
[TestCase("2db4a87840113c", "2db4a87840113c", "")]
[TestCase("123456", "123456", "")]
[TestCase("foobar-qwerty", "foobar-qwerty", "")]
[TestCase("foobar.qwerty", "foobar.qwerty", "")]
[TestCase("foobar_qwerty", "foobar_qwerty", "")]
[TestCase("foobar-12345", "foobar-12345", "")]
// Metadata
[TestCase("foobar+12345", "foobar", "12345")]
[TestCase("foobar+123.456", "foobar", "123.456")]
[TestCase("foobar+123_456", "foobar", "123_456")]
[TestCase("foobar+123-456", "foobar", "123-456")]
[TestCase("foobar+123+456", "foobar", "123+456")]
[TestCase("foobar+1.2_3-4+5", "foobar", "1.2_3-4+5")]
[TestCase("foobar+qwerty", "foobar", "qwerty")]
[TestCase("foobar-qwerty+12345", "foobar-qwerty", "12345")]
// Fail Cases
[TestCase("!@#$%^", "", "")]
[TestCase("foobar-!@#$%", "", "")]
[TestCase("foobar-qwerty+!@#$%", "", "")]
[TestCase("foo bar", "", "")]
[TestCase("foobar-qwe ty", "", "")]
[TestCase("foobar+123 456", "", "")]
[TestCase("foo bar-qwe ty+123 456", "", "")]
[TestCase("!foobar", "", "")]
[TestCase("foo!bar", "", "")]
[TestCase("foobar!", "", "")]
public void ShouldParseSuccessfully(string input, string expectedRelease, string expectedMetadata)
{
_ = new UnsortableVersionParser().TryParse(input, out var parsedVersion);
AssertVersionNumbersAreZero(parsedVersion);
Assert.AreEqual(expectedRelease, parsedVersion.Release);
Assert.AreEqual(expectedMetadata, parsedVersion.Metadata);
}

[Test]
public void ShouldThrowExceptionOnEmptyInput()
{
var input = "";
Assert.Catch<ArgumentException>(() => new UnsortableVersionParser().Parse(input));
}

[Test]
public void ShouldThrowExceptionOnWhiteSpaceInput()
{
var input = " ";
Assert.Catch<ArgumentException>(() => new UnsortableVersionParser().Parse(input));
}

[Test]
public void ShouldThrowExceptionOnNullInput()
{
Assert.Catch<ArgumentException>(() => new UnsortableVersionParser().Parse(null));
}

[Test]
public void ShouldThrowExceptionOnFailureToParse()
{
var input = "bad versions string";
Assert.Catch<ArgumentException>(() => new UnsortableVersionParser().Parse(input));
}

void AssertVersionNumbersAreZero(UnsortableSortableVersion sortableVersion)
{
Assert.AreEqual(0, sortableVersion.Major);
Assert.AreEqual(0, sortableVersion.Minor);
Assert.AreEqual(0, sortableVersion.Patch);
Assert.AreEqual(0, sortableVersion.Revision);
}
}
33 changes: 33 additions & 0 deletions source/Octopus.Versioning/ISortableVersion.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
using System;
using System.Collections.Generic;

namespace Octopus.Versioning
{
/// <summary>
/// Represents the base components of a version recognised by Octopus.
/// The terminolgy here comes from SemVer, but can be mapped to other
/// versioning schemes like Maven.
///
/// All classes should reference this interface, but there are some
/// exceptions.
///
/// Some modelling classes need to reference the SemanticVersionConverter
/// to ensure that constructor paramaters and properties of the type
/// IVersion are converted to and from a SemanticVersion object.
///
/// JSON converters like SemanticVersionConverter assume that
/// any version object being stored in the database is a SemanticVersion
/// object. This is because Octopus assumes the use of SemanticVersion
/// in all processes other than external feeds, which do not have
/// version information directly saved in the database.
///
/// The version factory classes also need to know about the conrete
/// classes.
///
/// Outside of those two use cases, all other references to a version
/// should be through this interface.
/// </summary>
public interface ISortableVersion : IVersion, IComparable
{
}
}
27 changes: 1 addition & 26 deletions source/Octopus.Versioning/IVersion.cs
Original file line number Diff line number Diff line change
@@ -1,33 +1,8 @@
using System;
using System.Collections.Generic;

namespace Octopus.Versioning
{
/// <summary>
/// Represents the base components of a version recognised by Octopus.
/// The terminolgy here comes from SemVer, but can be mapped to other
/// versioning schemes like Maven.
///
/// All classes should reference this interface, but there are some
/// exceptions.
///
/// Some modelling classes need to reference the SemanticVersionConverter
/// to ensure that constructor paramaters and properties of the type
/// IVersion are converted to and from a SemanticVersion object.
///
/// JSON converters like SemanticVersionConverter assume that
/// any version object being stored in the database is a SemanticVersion
/// object. This is because Octopus assumes the use of SemanticVersion
/// in all processes other than external feeds, which do not have
/// version information directly saved in the database.
///
/// The version factory classes also need to know about the conrete
/// classes.
///
/// Outside of those two use cases, all other references to a version
/// should be through this interface.
/// </summary>
public interface IVersion : IComparable
public interface IVersion
{
int Major { get; }
int Minor { get; }
Expand Down
2 changes: 1 addition & 1 deletion source/Octopus.Versioning/IVersionComparer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ namespace Octopus.Versioning
/// IVersionComparer represents a version comparer capable of sorting and determining the equality of
/// SemanticVersion objects.
/// </summary>
public interface IVersionComparer : IEqualityComparer<IVersion?>, IComparer<IVersion?>
public interface IVersionComparer : IEqualityComparer<ISortableVersion?>, IComparer<ISortableVersion?>
{
}
}
10 changes: 5 additions & 5 deletions source/Octopus.Versioning/Maven/MavenPackageID.cs
Original file line number Diff line number Diff line change
Expand Up @@ -84,15 +84,15 @@ public MavenPackageID([NotNull]

public MavenPackageID([NotNull]
string? id,
IVersion version) : this(id)
ISortableVersion sortableVersion) : this(id)
{
if (string.IsNullOrWhiteSpace(id) || id.Split(':').Length != 2)
throw new ArgumentException("Package ID must be in the format Group:Artifact e.g. com.google.guava:guava or junit:junit.");

if (version == null)
if (sortableVersion == null)
throw new ArgumentException("version can not be null");

Version = version.ToString();
Version = sortableVersion.ToString();
}

/// <summary>
Expand Down Expand Up @@ -154,7 +154,7 @@ public MavenPackageID([NotNull]
public string? Classifier { get; }
public string DisplayName => ToString(DISPLAY_DELIMITER);

public IVersion? SemanticVersion => Version == null ? null : new MavenVersionParser().Parse(Version);
public ISortableVersion? SemanticVersion => Version == null ? null : new MavenVersionParser().Parse(Version);

/// <summary>
/// The path to the metadata file for the artifact
Expand Down Expand Up @@ -248,7 +248,7 @@ public string DefaultArtifactPath
/// <param name="version">The optional version</param>
/// <returns>A MavenPackageID created to match the package id an optional packaging defined in the UI</returns>
/// <exception cref="ArgumentException">thrown if the input is not in the correct format</exception>
public static MavenPackageID CreatePackageIdFromOctopusInput(string input, IVersion? version = null)
public static MavenPackageID CreatePackageIdFromOctopusInput(string input, ISortableVersion? version = null)
{
var splitVersion = input.Split(':').ToList();
if (!(splitVersion.Count >= 2 && splitVersion.Count <= 4))
Expand Down
2 changes: 1 addition & 1 deletion source/Octopus.Versioning/Maven/MavenVersion.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

namespace Octopus.Versioning.Maven
{
public class MavenVersion : IVersion
public class MavenVersion : ISortableVersion
{
public MavenVersion(int major,
int minor,
Expand Down
Loading
Loading