Skip to content

Commit

Permalink
Identified another method that is just so usefull I pushed it down to…
Browse files Browse the repository at this point in the history
… extensions
  • Loading branch information
kccarter76 committed Aug 16, 2020
1 parent 97403a8 commit c5674e0
Show file tree
Hide file tree
Showing 5 changed files with 281 additions and 3 deletions.
2 changes: 1 addition & 1 deletion SubSonic.Core.Extensions/Collections.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

namespace SubSonic.Core
{
public static partial class Extensions
public static partial class CoreExtensions
{
public static void AddIfNotExist<TType>(this ICollection<TType> collection, TType element)
{
Expand Down
2 changes: 1 addition & 1 deletion SubSonic.Core.Extensions/Enum.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

namespace SubSonic.Core
{
public static partial class Extensions
public static partial class CoreExtensions
{
public static TEnum Parse<TEnum>(this string source)
where TEnum: struct
Expand Down
248 changes: 248 additions & 0 deletions SubSonic.Core.Extensions/SemVersion.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,248 @@
//
// Copyright (c) Microsoft Corp (https://www.microsoft.com)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

using System;
using System.Globalization;
using System.Text;
using System.Text.RegularExpressions;

namespace SubSonic.Core.Extensions
{
public struct SemVersion : IComparable, IComparable<SemVersion>, IEquatable<SemVersion>
{
public static SemVersion Zero { get; } = new SemVersion(0, 0, 0, null, null, "0.0.0");

static readonly Regex SemVerRegex =
new Regex(
@"(?<Major>0|(?:[1-9]\d*))(?:\.(?<Minor>0|(?:[1-9]\d*))(?:\.(?<Patch>0|(?:[1-9]\d*)))?(?:\-(?<PreRelease>[0-9A-Z\.-]+))?(?:\+(?<Meta>[0-9A-Z\.-]+))?)?",
RegexOptions.CultureInvariant | RegexOptions.ExplicitCapture | RegexOptions.IgnoreCase
);


public int Major { get; }
public int Minor { get; }
public int Patch { get; }
public string PreRelease { get; }
public string Meta { get; }
public bool IsPreRelease { get; }
public bool HasMeta { get; }
public string VersionString { get; }

public SemVersion(int major, int minor, int patch, string preRelease = null, string meta = null) :
this(major, minor, patch, preRelease, meta, null)
{
}

SemVersion(int major, int minor, int patch, string preRelease, string meta, string versionString)
{
Major = major;
Minor = minor;
Patch = patch;
IsPreRelease = !string.IsNullOrEmpty(preRelease);
HasMeta = !string.IsNullOrEmpty(meta);
PreRelease = IsPreRelease ? preRelease : null;
Meta = HasMeta ? meta : null;

if (!string.IsNullOrEmpty(versionString))
{
VersionString = versionString;
}
else
{
var sb = new StringBuilder();
sb.AppendFormat(CultureInfo.InvariantCulture, "{0}.{1}.{2}", Major, Minor, Patch);

if (IsPreRelease)
{
sb.AppendFormat(CultureInfo.InvariantCulture, "-{0}", PreRelease);
}

if (HasMeta)
{
sb.AppendFormat(CultureInfo.InvariantCulture, "+{0}", Meta);
}

VersionString = sb.ToString();
}
}

public static bool TryParse(string version, out SemVersion semVersion)
{
semVersion = Zero;

if (string.IsNullOrEmpty(version))
{
return false;
}

var match = SemVerRegex.Match(version);
if (!match.Success)
{
return false;
}

if (!int.TryParse(
match.Groups["Major"].Value,
NumberStyles.Integer,
CultureInfo.InvariantCulture,
out var major) ||
!int.TryParse(
match.Groups["Minor"].Value,
NumberStyles.Integer,
CultureInfo.InvariantCulture,
out var minor) ||
!int.TryParse(
match.Groups["Patch"].Value,
NumberStyles.Integer,
CultureInfo.InvariantCulture,
out var patch))
{
return false;
}

semVersion = new SemVersion(
major,
minor,
patch,
match.Groups["PreRelease"]?.Value,
match.Groups["Meta"]?.Value,
version);

return true;
}



public bool Equals(SemVersion other)
{
return Major == other.Major
&& Minor == other.Minor
&& Patch == other.Patch
&& string.Equals(PreRelease, other.PreRelease, StringComparison.OrdinalIgnoreCase)
&& string.Equals(Meta, other.Meta, StringComparison.OrdinalIgnoreCase);
}

public int CompareTo(SemVersion other)
{
if (Equals(other))
{
return 0;
}

if (Major > other.Major)
{
return 1;
}

if (Major < other.Major)
{
return -1;
}

if (Minor > other.Minor)
{
return 1;
}

if (Minor < other.Minor)
{
return -1;
}

if (Patch > other.Patch)
{
return 1;
}

if (Patch < other.Patch)
{
return -1;
}

switch (StringComparer.InvariantCultureIgnoreCase.Compare(PreRelease, other.PreRelease))
{
case 1:
return 1;

case -1:
return -1;

default:
return StringComparer.InvariantCultureIgnoreCase.Compare(Meta, other.Meta);
}
}

public int CompareTo(object obj)
{
return obj is SemVersion semVersion
? CompareTo(semVersion)
: -1;
}

public override bool Equals(object obj)
{
return obj is SemVersion semVersion
&& Equals(semVersion);
}

public override int GetHashCode()
{
unchecked
{
var hashCode = Major;
hashCode = hashCode * 397 ^ Minor;
hashCode = hashCode * 397 ^ Patch;
hashCode = hashCode * 397 ^ (PreRelease != null ? StringComparer.OrdinalIgnoreCase.GetHashCode(PreRelease) : 0);
hashCode = hashCode * 397 ^ (Meta != null ? StringComparer.OrdinalIgnoreCase.GetHashCode(Meta) : 0);
return hashCode;
}
}

public override string ToString()
=> VersionString;

// Define the is greater than operator.
public static bool operator >(SemVersion operand1, SemVersion operand2)
=> operand1.CompareTo(operand2) == 1;

// Define the is less than operator.
public static bool operator <(SemVersion operand1, SemVersion operand2)
=> operand1.CompareTo(operand2) == -1;

// Define the is greater than or equal to operator.
public static bool operator >=(SemVersion operand1, SemVersion operand2)
=> operand1.CompareTo(operand2) >= 0;

// Define the is less than or equal to operator.
public static bool operator <=(SemVersion operand1, SemVersion operand2)
=> operand1.CompareTo(operand2) <= 0;

public static bool operator ==(SemVersion left, SemVersion right)
{
return left.Equals(right);
}

public static bool operator !=(SemVersion left, SemVersion right)
{
return !(left == right);
}
}
}
2 changes: 1 addition & 1 deletion SubSonic.Core.Extensions/Strings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

namespace SubSonic.Core
{
public static partial class Extensions
public static partial class CoreExtensions
{
public static bool IsNullOrEmpty(this string source)
{
Expand Down
30 changes: 30 additions & 0 deletions SubSonic.Core.Extensions/Utilities/Path.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
using SubSonic.Core.Extensions;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;

namespace SubSonic.Core
{
public partial class Utilities
{
public static string FindHighestVersionedDirectory(string parentFolder, Func<string, bool> validate)
{
string bestMatch = null;
var bestVersion = SemVersion.Zero;
foreach (var dir in Directory.EnumerateDirectories(parentFolder))
{
var name = Path.GetFileName(dir);
if (SemVersion.TryParse(name, out var version) && version.Major >= 0)
{
if (version > bestVersion && (validate == null || validate(dir)))
{
bestVersion = version;
bestMatch = dir;
}
}
}
return bestMatch;
}
}
}

0 comments on commit c5674e0

Please sign in to comment.