diff --git a/BSIPA.sln b/BSIPA.sln index f2a38632..f4997616 100644 --- a/BSIPA.sln +++ b/BSIPA.sln @@ -50,6 +50,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IPA.Loader", "IPA.Loader\IP EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Net3-Proxy", "Net3-Proxy\Net3-Proxy.csproj", "{0DEDB099-9A26-4069-A4C1-A76CEB16283B}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SemVer", "SemVer\SemVer.csproj", "{B25EEC48-A5D0-4A63-BA73-5DD43F7F592A}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -224,6 +226,30 @@ Global {0DEDB099-9A26-4069-A4C1-A76CEB16283B}.Verbose|x64.Build.0 = Debug|Any CPU {0DEDB099-9A26-4069-A4C1-A76CEB16283B}.Verbose|x86.ActiveCfg = Debug|Any CPU {0DEDB099-9A26-4069-A4C1-A76CEB16283B}.Verbose|x86.Build.0 = Debug|Any CPU + {B25EEC48-A5D0-4A63-BA73-5DD43F7F592A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B25EEC48-A5D0-4A63-BA73-5DD43F7F592A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B25EEC48-A5D0-4A63-BA73-5DD43F7F592A}.Debug|x64.ActiveCfg = Debug|Any CPU + {B25EEC48-A5D0-4A63-BA73-5DD43F7F592A}.Debug|x64.Build.0 = Debug|Any CPU + {B25EEC48-A5D0-4A63-BA73-5DD43F7F592A}.Debug|x86.ActiveCfg = Debug|Any CPU + {B25EEC48-A5D0-4A63-BA73-5DD43F7F592A}.Debug|x86.Build.0 = Debug|Any CPU + {B25EEC48-A5D0-4A63-BA73-5DD43F7F592A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B25EEC48-A5D0-4A63-BA73-5DD43F7F592A}.Release|Any CPU.Build.0 = Release|Any CPU + {B25EEC48-A5D0-4A63-BA73-5DD43F7F592A}.Release|x64.ActiveCfg = Release|Any CPU + {B25EEC48-A5D0-4A63-BA73-5DD43F7F592A}.Release|x64.Build.0 = Release|Any CPU + {B25EEC48-A5D0-4A63-BA73-5DD43F7F592A}.Release|x86.ActiveCfg = Release|Any CPU + {B25EEC48-A5D0-4A63-BA73-5DD43F7F592A}.Release|x86.Build.0 = Release|Any CPU + {B25EEC48-A5D0-4A63-BA73-5DD43F7F592A}.Verbose_Release|Any CPU.ActiveCfg = Release|Any CPU + {B25EEC48-A5D0-4A63-BA73-5DD43F7F592A}.Verbose_Release|Any CPU.Build.0 = Release|Any CPU + {B25EEC48-A5D0-4A63-BA73-5DD43F7F592A}.Verbose_Release|x64.ActiveCfg = Release|Any CPU + {B25EEC48-A5D0-4A63-BA73-5DD43F7F592A}.Verbose_Release|x64.Build.0 = Release|Any CPU + {B25EEC48-A5D0-4A63-BA73-5DD43F7F592A}.Verbose_Release|x86.ActiveCfg = Release|Any CPU + {B25EEC48-A5D0-4A63-BA73-5DD43F7F592A}.Verbose_Release|x86.Build.0 = Release|Any CPU + {B25EEC48-A5D0-4A63-BA73-5DD43F7F592A}.Verbose|Any CPU.ActiveCfg = Debug|Any CPU + {B25EEC48-A5D0-4A63-BA73-5DD43F7F592A}.Verbose|Any CPU.Build.0 = Debug|Any CPU + {B25EEC48-A5D0-4A63-BA73-5DD43F7F592A}.Verbose|x64.ActiveCfg = Debug|Any CPU + {B25EEC48-A5D0-4A63-BA73-5DD43F7F592A}.Verbose|x64.Build.0 = Debug|Any CPU + {B25EEC48-A5D0-4A63-BA73-5DD43F7F592A}.Verbose|x86.ActiveCfg = Debug|Any CPU + {B25EEC48-A5D0-4A63-BA73-5DD43F7F592A}.Verbose|x86.Build.0 = Debug|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/IPA.Injector/IPA.Injector.csproj b/IPA.Injector/IPA.Injector.csproj index e7f5169a..f44c7342 100644 --- a/IPA.Injector/IPA.Injector.csproj +++ b/IPA.Injector/IPA.Injector.csproj @@ -81,8 +81,12 @@ - + + + + $(MSBuildThisFileDirectory)..\Libs\thirdparty\Hive.Versioning.dll + diff --git a/IPA.Loader/IPA.Loader.csproj b/IPA.Loader/IPA.Loader.csproj index bd4d4609..cfc46967 100644 --- a/IPA.Loader/IPA.Loader.csproj +++ b/IPA.Loader/IPA.Loader.csproj @@ -52,9 +52,13 @@ - - + + + + + $(MSBuildThisFileDirectory)..\Libs\thirdparty\Hive.Versioning.dll + diff --git a/IPA.Loader/Properties/AssemblyInfo.cs b/IPA.Loader/Properties/AssemblyInfo.cs index 456c770b..6f7ebb52 100644 --- a/IPA.Loader/Properties/AssemblyInfo.cs +++ b/IPA.Loader/Properties/AssemblyInfo.cs @@ -1,4 +1,5 @@ -using System.Reflection; +using System; +using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; @@ -18,6 +19,7 @@ using System.Runtime.InteropServices; // to COM components. If you need to access a type in this assembly from // COM, set the ComVisible attribute to true on that type. [assembly: ComVisible(false)] +[assembly: CLSCompliant(false)] // The following GUID is for the ID of the typelib if this project is exposed to COM [assembly: Guid("5ad344f0-01a0-4ca8-92e5-9d095737744d")] diff --git a/Libs/thirdparty/Hive.Versioning.dll b/Libs/thirdparty/Hive.Versioning.dll index 93ed807e..25631609 100644 Binary files a/Libs/thirdparty/Hive.Versioning.dll and b/Libs/thirdparty/Hive.Versioning.dll differ diff --git a/Libs/thirdparty/Hive.Versioning.pdb b/Libs/thirdparty/Hive.Versioning.pdb index 846207fb..c74f836c 100644 Binary files a/Libs/thirdparty/Hive.Versioning.pdb and b/Libs/thirdparty/Hive.Versioning.pdb differ diff --git a/Libs/thirdparty/Hive.Versioning.xml b/Libs/thirdparty/Hive.Versioning.xml index 8143d72c..8a3c5787 100644 --- a/Libs/thirdparty/Hive.Versioning.xml +++ b/Libs/thirdparty/Hive.Versioning.xml @@ -459,7 +459,7 @@ The first argument. The second argument. - The logical disjunction of and . + The logical conjunction of and . diff --git a/SemVer/Range.cs b/SemVer/Range.cs new file mode 100644 index 00000000..1f7a6f32 --- /dev/null +++ b/SemVer/Range.cs @@ -0,0 +1,78 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Hive.Versioning; +using HVersion = Hive.Versioning.Version; + +namespace SemVer +{ + [Obsolete("Use Hive.Versioning.VersionRange instead.")] + public class Range : IEquatable, IEquatable + { + public VersionRange UnderlyingRange { get; } + + private Range(VersionRange real) => UnderlyingRange = real; + + public Range(string rangeSpec, bool loose = false) : this(new(rangeSpec)) + => _ = loose; // loose is ignored because Hive doesn't have an equivalent + + public static Range ForHiveRange(VersionRange real) => new(real); + + public bool IsSatisfied(Version version) => IsSatisfied(version.UnderlyingVersion); + public bool IsSatisfied(HVersion version) => UnderlyingRange.Matches(version); + public bool IsSatisfied(string versionString, bool loose = false) => IsSatisfied(new Version(versionString, loose)); + + public IEnumerable Satisfying(IEnumerable versions) => versions.Where(IsSatisfied); + public IEnumerable Satisfying(IEnumerable versions, bool loose = false) + => versions.Where(v => IsSatisfied(v, loose)); + public Version? MaxSatisfying(IEnumerable versions) => Satisfying(versions).Max(); + public string? MaxSatisfying(IEnumerable versionStrings, bool loose = false) + => MaxSatisfying(ValidVersions(versionStrings, loose))?.ToString(); + public Range Intersect(Range other) => new(UnderlyingRange & other.UnderlyingRange); // the conjunction is the intersection + public override string ToString() => UnderlyingRange.ToString(); + + public bool Equals(Range? other) => UnderlyingRange.Equals(other?.UnderlyingRange); + public bool Equals(VersionRange? other) => UnderlyingRange.Equals(other); + public override bool Equals(object? obj) + => obj switch + { + Range r => Equals(r), + VersionRange vr => Equals(vr), + _ => false + }; + + public static bool operator ==(Range? a, Range? b) => a?.Equals(b) ?? b is null; + + public static bool operator !=(Range? a, Range? b) => !(a == b); + + public override int GetHashCode() => UnderlyingRange.GetHashCode(); + + public static bool IsSatisfied(string rangeSpec, string versionString, bool loose = false) + => new Range(rangeSpec, loose).IsSatisfied(versionString, loose); + public static IEnumerable Satisfying(string rangeSpec, IEnumerable versions, bool loose = false) + => new Range(rangeSpec, loose).Satisfying(versions, loose); + + public static string? MaxSatisfying(string rangeSpec, IEnumerable versions, bool loose = false) + => new Range(rangeSpec, loose).MaxSatisfying(versions, loose); + + private IEnumerable ValidVersions(IEnumerable versionStrings, bool loose) + { + foreach (string versionString in versionStrings) + { + Version? version = null; + try + { + version = new Version(versionString, loose); + } + catch (ArgumentException) + { + } + + if (version is not null) + { + yield return version; + } + } + } + } +} diff --git a/SemVer/SemVer.csproj b/SemVer/SemVer.csproj new file mode 100644 index 00000000..eb567912 --- /dev/null +++ b/SemVer/SemVer.csproj @@ -0,0 +1,16 @@ + + + + + + net461 + enable + + + + + $(MSBuildThisFileDirectory)..\Libs\thirdparty\Hive.Versioning.dll + + + + diff --git a/SemVer/Version.cs b/SemVer/Version.cs new file mode 100644 index 00000000..6db9b027 --- /dev/null +++ b/SemVer/Version.cs @@ -0,0 +1,70 @@ +using System; +using System.Linq; +using HVersion = Hive.Versioning.Version; + +namespace SemVer +{ + [Obsolete("Use Hive.Versioning.Version instead.")] + public class Version : IComparable, IComparable, IComparable, IEquatable, IEquatable + { + public HVersion UnderlyingVersion { get; } + + private Version(HVersion real) => UnderlyingVersion = real; + + public static Version ForHiveVersion(HVersion real) => new(real); + + public Version(string input, bool loose = false) : this(new HVersion(input)) + => _ = loose; // specifically unused because Hive has no equivalent (by design) + public Version(int major, int minor, int patch, string? preRelease = null, string? build = null) + : this(new HVersion(major, minor, patch, + preRelease is null ? Enumerable.Empty() : preRelease.Split('.'), + build is null ? Enumerable.Empty() : build.Split('.'))) + { + } + + public int Major => (int)UnderlyingVersion.Major; + public int Minor => (int)UnderlyingVersion.Minor; + public int Patch => (int)UnderlyingVersion.Patch; + public string PreRelease => string.Join(".", UnderlyingVersion.PreReleaseIds); + public string Build => string.Join(".", UnderlyingVersion.BuildIds); + + public Version BaseVersion() => new(new(UnderlyingVersion.Major, UnderlyingVersion.Minor, UnderlyingVersion.Patch)); + public override string ToString() => UnderlyingVersion.ToString(); + public string Clean() => ToString(); // normally this is the other way around kek + public override int GetHashCode() => UnderlyingVersion.GetHashCode(); + public bool Equals(Version? other) => UnderlyingVersion.Equals(other?.UnderlyingVersion); + public bool Equals(HVersion? other) => UnderlyingVersion.Equals(other); + public override bool Equals(object? obj) + => obj switch + { + Version v => Equals(v), + HVersion h => Equals(h), + _ => false + }; + + public int CompareTo(Version? other) => UnderlyingVersion.CompareTo(other?.UnderlyingVersion); + public int CompareTo(HVersion? other) => UnderlyingVersion.CompareTo(other); + public int CompareTo(object? obj) + => obj switch + { + null => 1, + Version v => CompareTo(v), + HVersion h => CompareTo(h), + _ => throw new ArgumentException("Object is not a Version") + }; + + public static bool operator ==(Version? a, Version? b) + => a?.UnderlyingVersion == b?.UnderlyingVersion; + public static bool operator !=(Version? a, Version? b) + => a?.UnderlyingVersion != b?.UnderlyingVersion; + + public static bool operator >(Version? a, Version? b) + => a is null ? b is not null && b.CompareTo(a) < 0 : a.CompareTo(b) > 0; + public static bool operator >=(Version? a, Version? b) + => !(a < b); + public static bool operator <(Version? a, Version? b) + => a is null ? b is not null && b.CompareTo(a) > 0 : a.CompareTo(b) < 0; + public static bool operator <=(Version? a, Version? b) + => !(a > b); + } +}