Compare commits

...
24 Commits
Author SHA1 Message Date
Jeremy Pritts 3320be1312 Bump version 2023-06-05 09:45:02 -04:00
Jeremy Pritts 659c382ff7 Support formatting short chinese versions 2023-06-05 09:40:48 -04:00
Jeremy Pritts 4aed9eb024 Support parsing alternate chinese versions 2023-06-05 08:43:50 -04:00
dependabot[bot] 4e6f668e10 Bump NUnit.Analyzers from 3.6.0 to 3.6.1
Bumps [NUnit.Analyzers](https://github.com/nunit/nunit.analyzers) from 3.6.0 to 3.6.1.
- [Release notes](https://github.com/nunit/nunit.analyzers/releases)
- [Changelog](https://github.com/nunit/nunit.analyzers/blob/master/CHANGES.txt)
- [Commits](https://github.com/nunit/nunit.analyzers/compare/3.6.0...3.6.1)

---
updated-dependencies:
- dependency-name: NUnit.Analyzers
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <[email protected]>
2023-06-05 08:10:53 -04:00
dependabot[bot] dc4e81eb28 Bump PolySharp from 1.13.1 to 1.13.2
Bumps [PolySharp](https://github.com/Sergio0694/PolySharp) from 1.13.1 to 1.13.2.
- [Release notes](https://github.com/Sergio0694/PolySharp/releases)
- [Commits](https://github.com/Sergio0694/PolySharp/commits)

---
updated-dependencies:
- dependency-name: PolySharp
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <[email protected]>
2023-06-05 08:07:13 -04:00
dependabot[bot] 0e2a37e920 Bump coverlet.collector from 3.2.0 to 6.0.0
Bumps [coverlet.collector](https://github.com/coverlet-coverage/coverlet) from 3.2.0 to 6.0.0.
- [Release notes](https://github.com/coverlet-coverage/coverlet/releases)
- [Commits](https://github.com/coverlet-coverage/coverlet/compare/v3.2.0...v6.0.0)

---
updated-dependencies:
- dependency-name: coverlet.collector
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <[email protected]>
2023-06-05 08:07:06 -04:00
dependabot[bot] b29d4a7a69 Bump Microsoft.NET.Test.Sdk from 17.6.0 to 17.6.1
Bumps [Microsoft.NET.Test.Sdk](https://github.com/microsoft/vstest) from 17.6.0 to 17.6.1.
- [Release notes](https://github.com/microsoft/vstest/releases)
- [Changelog](https://github.com/microsoft/vstest/blob/main/docs/releases.md)
- [Commits](https://github.com/microsoft/vstest/compare/v17.6.0...v17.6.1)

---
updated-dependencies:
- dependency-name: Microsoft.NET.Test.Sdk
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <[email protected]>
2023-06-01 15:09:18 -04:00
dependabot[bot] 93ee2b0675 Bump Microsoft.NET.Test.Sdk from 17.5.0 to 17.6.0
Bumps [Microsoft.NET.Test.Sdk](https://github.com/microsoft/vstest) from 17.5.0 to 17.6.0.
- [Release notes](https://github.com/microsoft/vstest/releases)
- [Changelog](https://github.com/microsoft/vstest/blob/main/docs/releases.md)
- [Commits](https://github.com/microsoft/vstest/compare/v17.5.0...v17.6.0)

---
updated-dependencies:
- dependency-name: Microsoft.NET.Test.Sdk
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <[email protected]>
2023-05-31 06:04:58 -04:00
dependabot[bot] ebe6802570 Bump NUnit3TestAdapter from 4.4.2 to 4.5.0
Bumps [NUnit3TestAdapter](https://github.com/nunit/nunit3-vs-adapter) from 4.4.2 to 4.5.0.
- [Release notes](https://github.com/nunit/nunit3-vs-adapter/releases)
- [Commits](https://github.com/nunit/nunit3-vs-adapter/compare/V4.4.2...V4.5.0)

---
updated-dependencies:
- dependency-name: NUnit3TestAdapter
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <[email protected]>
2023-05-30 18:37:57 -04:00
dependabot[bot] 97da17c016 Bump actions/setup-dotnet from 3.1.0 to 3.2.0
Bumps [actions/setup-dotnet](https://github.com/actions/setup-dotnet) from 3.1.0 to 3.2.0.
- [Release notes](https://github.com/actions/setup-dotnet/releases)
- [Commits](https://github.com/actions/setup-dotnet/compare/v3.1.0...v3.2.0)

---
updated-dependencies:
- dependency-name: actions/setup-dotnet
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <[email protected]>
2023-05-29 15:13:51 -04:00
dependabot[bot] 475c27c28c Bump actions/setup-dotnet from 3.0.3 to 3.1.0
Bumps [actions/setup-dotnet](https://github.com/actions/setup-dotnet) from 3.0.3 to 3.1.0.
- [Release notes](https://github.com/actions/setup-dotnet/releases)
- [Commits](https://github.com/actions/setup-dotnet/compare/v3.0.3...v3.1.0)

---
updated-dependencies:
- dependency-name: actions/setup-dotnet
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <[email protected]>
2023-05-25 16:37:20 -04:00
dependabot[bot] fb0fb3f1c6 Bump PolySharp from 1.12.1 to 1.13.1
Bumps [PolySharp](https://github.com/Sergio0694/PolySharp) from 1.12.1 to 1.13.1.
- [Release notes](https://github.com/Sergio0694/PolySharp/releases)
- [Commits](https://github.com/Sergio0694/PolySharp/compare/1.12.1...1.13.1)

---
updated-dependencies:
- dependency-name: PolySharp
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <[email protected]>
2023-04-06 22:22:53 -04:00
Jeremy Pritts 182fca60ca Add test case for custom china version 2023-03-16 00:04:38 -04:00
Jeremy Pritts d4609533b2 Bump version to 1.4.0 2023-03-15 23:58:57 -04:00
Jeremy Pritts 46e53d834f NUnit constraint model 2023-03-15 23:56:25 -04:00
Jeremy Pritts 99157d5433 Support parsing custom versions 2023-03-15 23:52:00 -04:00
Jeremy Pritts 5ec33f0518 Simplify ToString 2023-03-15 23:32:35 -04:00
Jeremy Pritts c4a5ab77d4 Refactor parsing tests 2023-03-15 23:10:59 -04:00
Jeremy Pritts ab4df10c87 Remove ParseFromDllName 2023-03-15 23:02:59 -04:00
dependabot[bot] 2d00a1259a Bump NUnit3TestAdapter from 4.4.0 to 4.4.2
Bumps [NUnit3TestAdapter](https://github.com/nunit/nunit3-vs-adapter) from 4.4.0 to 4.4.2.
- [Release notes](https://github.com/nunit/nunit3-vs-adapter/releases)
- [Commits](https://github.com/nunit/nunit3-vs-adapter/compare/V4.4.0...V4.4.2)

---
updated-dependencies:
- dependency-name: NUnit3TestAdapter
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <[email protected]>
2023-03-01 14:05:44 -05:00
dependabot[bot] b65056d08f Bump NUnit3TestAdapter from 4.3.1 to 4.4.0
Bumps [NUnit3TestAdapter](https://github.com/nunit/nunit3-vs-adapter) from 4.3.1 to 4.4.0.
- [Release notes](https://github.com/nunit/nunit3-vs-adapter/releases)
- [Commits](https://github.com/nunit/nunit3-vs-adapter/compare/V4.3.1...V4.4.0)

---
updated-dependencies:
- dependency-name: NUnit3TestAdapter
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <[email protected]>
2023-02-27 14:18:13 -05:00
dependabot[bot] 42c5957429 Bump Microsoft.NET.Test.Sdk from 17.4.1 to 17.5.0
Bumps [Microsoft.NET.Test.Sdk](https://github.com/microsoft/vstest) from 17.4.1 to 17.5.0.
- [Release notes](https://github.com/microsoft/vstest/releases)
- [Changelog](https://github.com/microsoft/vstest/blob/main/docs/releases.md)
- [Commits](https://github.com/microsoft/vstest/compare/v17.4.1...v17.5.0)

---
updated-dependencies:
- dependency-name: Microsoft.NET.Test.Sdk
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <[email protected]>
2023-02-22 13:56:50 -05:00
dependabot[bot] 606e439721 Bump PolySharp from 1.11.0 to 1.12.1
Bumps [PolySharp](https://github.com/Sergio0694/PolySharp) from 1.11.0 to 1.12.1.
- [Release notes](https://github.com/Sergio0694/PolySharp/releases)
- [Commits](https://github.com/Sergio0694/PolySharp/compare/1.11.0...1.12.1)

---
updated-dependencies:
- dependency-name: PolySharp
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <[email protected]>
2023-01-23 17:29:41 -05:00
dependabot[bot] b9a57bd765 Bump PolySharp from 1.10.0 to 1.11.0
Bumps [PolySharp](https://github.com/Sergio0694/PolySharp) from 1.10.0 to 1.11.0.
- [Release notes](https://github.com/Sergio0694/PolySharp/releases)
- [Commits](https://github.com/Sergio0694/PolySharp/compare/1.10.0...1.11.0)

---
updated-dependencies:
- dependency-name: PolySharp
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <[email protected]>
2023-01-19 13:10:01 -05:00
8 changed files with 179 additions and 147 deletions

No files matched your search

+3 -3
View File
@@ -14,7 +14,7 @@ jobs:
steps:
- uses: actions/checkout@v3
- name: Setup .NET
uses: actions/setup-dotnet@v3.0.3
uses: actions/setup-dotnet@v3.2.0
with:
dotnet-version: 7.0.x
- name: Restore dependencies
@@ -31,7 +31,7 @@ jobs:
steps:
- uses: actions/checkout@v3
- name: Setup .NET
uses: actions/setup-dotnet@v3.0.3
uses: actions/setup-dotnet@v3.2.0
with:
dotnet-version: 6.0.x
- name: Restore dependencies
@@ -48,7 +48,7 @@ jobs:
steps:
- uses: actions/checkout@v3
- name: Setup .NET
uses: actions/setup-dotnet@v3.0.3
uses: actions/setup-dotnet@v3.2.0
with:
dotnet-version: |
5.0.x
+26 -14
View File
@@ -9,55 +9,67 @@ public class ComparisonTests
[Test]
public void LessThanIsTransitive()
{
Assert.IsTrue(lowValue < mediumValue);
Assert.IsTrue(mediumValue < highValue);
Assert.IsTrue(lowValue < highValue);
Assert.Multiple(() =>
{
Assert.That(lowValue, Is.LessThan(mediumValue));
Assert.That(mediumValue, Is.LessThan(highValue));
Assert.That(lowValue, Is.LessThan(highValue));
});
}
[Test]
public void GreaterThanIsTransitive()
{
Assert.IsTrue(mediumValue > lowValue);
Assert.IsTrue(highValue > mediumValue);
Assert.IsTrue(highValue > lowValue);
Assert.Multiple(() =>
{
Assert.That(mediumValue, Is.GreaterThan(lowValue));
Assert.That(highValue, Is.GreaterThan(mediumValue));
Assert.That(highValue, Is.GreaterThan(lowValue));
});
}
[Test]
public void WeakInequalityHolds()
{
UnityVersion low = lowValue;
Assert.IsTrue(lowValue <= low);
Assert.That(lowValue, Is.LessThanOrEqualTo(low));
}
[Test]
public void MinimumValueDefinition()
{
Assert.IsTrue(UnityVersion.MinVersion == new UnityVersion(ushort.MinValue, ushort.MinValue, ushort.MinValue, UnityVersionType.Alpha, byte.MinValue));
Assert.That(UnityVersion.MinVersion, Is.EqualTo(new UnityVersion(ushort.MinValue, ushort.MinValue, ushort.MinValue, UnityVersionType.Alpha, byte.MinValue)));
}
[Test]
public void MaximumValueDefinition()
{
Assert.IsTrue(UnityVersion.MaxVersion == new UnityVersion(ushort.MaxValue, ushort.MaxValue, ushort.MaxValue, (UnityVersionType)byte.MaxValue, byte.MaxValue));
Assert.That(UnityVersion.MaxVersion, Is.EqualTo(new UnityVersion(ushort.MaxValue, ushort.MaxValue, ushort.MaxValue, (UnityVersionType)byte.MaxValue, byte.MaxValue)));
}
[Test]
public void AnIncreaseOfTypeNumberMakesInequal()
{
Assert.IsTrue(UnityVersion.MinVersion < new UnityVersion(ushort.MinValue, ushort.MinValue, ushort.MinValue, UnityVersionType.Alpha, 1));
Assert.IsTrue(lowValue < new UnityVersion(lowValue.Major, lowValue.Minor, lowValue.Build, lowValue.Type, (byte)(lowValue.TypeNumber + 1)));
Assert.Multiple(() =>
{
Assert.That(UnityVersion.MinVersion, Is.LessThan(new UnityVersion(ushort.MinValue, ushort.MinValue, ushort.MinValue, UnityVersionType.Alpha, 1)));
Assert.That(lowValue, Is.LessThan(new UnityVersion(lowValue.Major, lowValue.Minor, lowValue.Build, lowValue.Type, (byte)(lowValue.TypeNumber + 1))));
});
}
[Test]
public void AlphaZeroIsTheDefault()
{
Assert.IsTrue(new UnityVersion(2019, 1, 0) < new UnityVersion(2019, 1, 0, UnityVersionType.Final, 1));
Assert.That(new UnityVersion(2019, 1, 0), Is.LessThan(new UnityVersion(2019, 1, 0, UnityVersionType.Final, 1)));
}
[Test]
public void ComparisonMethodsIgnoreUnspecifiedValues()
{
Assert.IsTrue(new UnityVersion(2019, 1, 0, UnityVersionType.Final, 1).IsGreaterEqual(2019, 1, 0));
Assert.IsTrue(new UnityVersion(2019, 1, 0, UnityVersionType.Final, 1).IsLessEqual(2019, 1, 0));
Assert.Multiple(() =>
{
Assert.That(new UnityVersion(2019, 1, 0, UnityVersionType.Final, 1).IsGreaterEqual(2019, 1, 0), Is.True);
Assert.That(new UnityVersion(2019, 1, 0, UnityVersionType.Final, 1).IsLessEqual(2019, 1, 0), Is.True);
});
}
}
+4 -4
View File
@@ -16,14 +16,14 @@ public class DistanceTests
{
ulong distance1 = UnityVersion.Distance(version4, version5);
ulong distance2 = UnityVersion.Distance(version5, version4);
Assert.IsTrue(distance1 == distance2);
Assert.That(distance1, Is.EqualTo(distance2));
}
[Test]
public void DistanceIsZeroForEquivalentVersions()
{
ulong distance = UnityVersion.Distance(version4, version4);
Assert.IsTrue(distance == 0);
Assert.That(distance, Is.EqualTo(0));
}
[Test]
@@ -31,7 +31,7 @@ public class DistanceTests
{
UnityVersion version = new UnityVersion(6, 1);
UnityVersion closest = version.GetClosestVersion(versionArray);
Assert.IsTrue(closest == version6);
Assert.That(closest, Is.EqualTo(version6));
}
[Test]
@@ -39,6 +39,6 @@ public class DistanceTests
{
UnityVersion version = new UnityVersion(5, 4, 9);
UnityVersion closest = version.GetClosestVersion(versionArray);
Assert.IsTrue(closest == version5);
Assert.That(closest, Is.EqualTo(version5));
}
}
+64 -52
View File
@@ -1,66 +1,78 @@
namespace AssetRipper.VersionUtilities.Tests;
using NUnit.Framework.Internal;
using System.Collections.Generic;
namespace AssetRipper.VersionUtilities.Tests;
public class ParsingTests
{
[Test]
public void UnityVersionParsesCorrectly()
[TestCase("4.2.2f1", 4, 2, 2, UnityVersionType.Final, 1, null, "Normal Unity 4 Version")]
[TestCase("4.2.2f1\n1", 4, 2, 2, UnityVersionType.Final, 1, 1, "Custom Unity 4 Version")]
[TestCase("2343.4.5f7", 2343, 4, 5, UnityVersionType.Final, 7, null, "Fictitious Future Version")]
[TestCase("2019.2.2f1c2\n2", 2019, 2, 2, UnityVersionType.China, 2, 2, "Fake Custom Chinese Version")]
[TestCase("2019.4", 2019, 4, 0, UnityVersionType.Final, 1, null, "Major Minor Only")]
[TestCase("2019.4.3", 2019, 4, 3, UnityVersionType.Final, 1, null, "Major Minor Build Only")]
public void UnityVersionParsesCorrectly(string versionString, int major, int minor, int build, UnityVersionType type, int typeNumber, int? customEngine, string name)
{
string version = "2343.4.5f7";
UnityVersion expected = new UnityVersion(2343, 4, 5, UnityVersionType.Final, 7);
Assert.AreEqual(expected, UnityVersion.Parse(version));
UnityVersion expected = new UnityVersion((ushort)major, (ushort)minor, (ushort)build, type, (byte)typeNumber);
UnityVersion parsedVersion = UnityVersion.Parse(versionString, out int? parsedCustomEngine);
Assert.Multiple(() =>
{
Assert.That(parsedCustomEngine, Is.EqualTo(customEngine), $"The custom engine boolean is incorrect for '{name}'");
Assert.That(parsedVersion, Is.EqualTo(expected), $"The parsed version is incorrect for '{name}'");
if (customEngine is not null || typeNumber is not 1)
{
Assert.That(parsedVersion.ToString(UnityVersionFormatFlags.Default, parsedCustomEngine), Is.EqualTo(versionString));
}
});
}
[TestCaseSource(nameof(GenerateRandomVersions), new object[] { 20 })]
public void UnityVersionToStringParsesCorrectly(UnityVersion version)
{
string versionString = version.ToString();
UnityVersion parsedVersion = UnityVersion.Parse(versionString, out int? customEngine);
Assert.Multiple(() =>
{
Assert.That(customEngine, Is.Null);
Assert.That(parsedVersion, Is.EqualTo(version));
});
}
[Test]
public void UnityVersionParsesDllCorrectly()
public void LongChineseVersionFormat()
{
string dllName = "_2343_4_5f7.dll";
UnityVersion expected = new UnityVersion(2343, 4, 5, UnityVersionType.Final, 7);
Assert.AreEqual(expected, UnityVersion.ParseFromDllName(dllName));
}
[Test]
public void UnityVersionParsesDllCorrectlyWithoutExtension()
{
string dllName = "_2343_4_5f7";
UnityVersion expected = new UnityVersion(2343, 4, 5, UnityVersionType.Final, 7);
Assert.AreEqual(expected, UnityVersion.ParseFromDllName(dllName));
}
[Test]
public void UnityVersionParsesDllCorrectlyWithoutLeadingUnderscore()
{
string dllName = "2343_4_5f7.dll";
UnityVersion expected = new UnityVersion(2343, 4, 5, UnityVersionType.Final, 7);
Assert.AreEqual(expected, UnityVersion.ParseFromDllName(dllName));
}
[Test]
public void MajorMinorOnly()
{
string version = "2019.4";
UnityVersion expected = new UnityVersion(2019, 4, 0, UnityVersionType.Final, 1);
Assert.AreEqual(expected, UnityVersion.Parse(version));
}
[Test]
public void MajorMinorBuildOnly()
{
string version = "2019.4.3";
UnityVersion expected = new UnityVersion(2019, 4, 3, UnityVersionType.Final, 1);
Assert.AreEqual(expected, UnityVersion.Parse(version));
}
[Test]
public void ChinaVersionString()
{
string version = "2021.3.11f1c2";//This is an actual version from a game.
//Versions like 2019.3.0f2 and 2020.3.15f2 don't have corresponding Chinese versions.
//Source: https://unity.cn/releases
//This is an actual version from a game.
//Versions like 2019.3.0f2 and 2020.3.15f2 don't have corresponding Chinese versions.
//Source: https://unity.cn/releases
string version = "2021.3.11f1c2";
UnityVersion expected = new UnityVersion(2021, 3, 11, UnityVersionType.China, 2);
Assert.Multiple(() =>
{
Assert.AreEqual(expected, UnityVersion.Parse(version));
Assert.AreEqual(version, expected.ToString());
Assert.That(UnityVersion.Parse(version), Is.EqualTo(expected));
Assert.That(expected.ToString(), Is.EqualTo(version));
});
}
[Test]
public void ShortChineseVersionFormat()
{
//This is an actual version from a game.
//Source: https://github.com/AssetRipper/AssetRipper/issues/841
string version = "2017.4.40c1";
UnityVersion expected = new UnityVersion(2017, 4, 40, UnityVersionType.China, 1);
Assert.Multiple(() =>
{
Assert.That(UnityVersion.Parse(version), Is.EqualTo(expected));
Assert.That(expected.ToString(UnityVersionFormatFlags.UseShortChineseFormat), Is.EqualTo(version));
});
}
private static IEnumerable<UnityVersion> GenerateRandomVersions(int count)
{
Randomizer random = TestContext.CurrentContext.Random;
for (int i = 0; i < count; i++)
{
yield return new UnityVersion(random.NextUShort(), random.NextUShort(), random.NextUShort(), random.NextEnum<UnityVersionType>(), random.NextByte());
}
}
}
@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>netframework3.5;netframework4.0;netframework4.8;net5.0;net6.0;net7.0</TargetFrameworks>
@@ -10,14 +10,18 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.4.1" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.6.1" />
<PackageReference Include="NUnit" Version="3.13.3" />
<PackageReference Include="NUnit3TestAdapter" Version="4.3.1" />
<PackageReference Include="coverlet.collector" Version="3.2.0" />
<PackageReference Include="NUnit3TestAdapter" Version="4.5.0" />
<PackageReference Include="NUnit.Analyzers" Version="3.6.1">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="coverlet.collector" Version="6.0.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\VersionUtilities\VersionUtilities.csproj" />
<ProjectReference Include="..\VersionUtilities\VersionUtilities.csproj" />
</ItemGroup>
</Project>
+45 -66
View File
@@ -1,5 +1,4 @@
using AssetRipper.VersionUtilities.Extensions;
using System.Text;
using System.Text.RegularExpressions;
namespace AssetRipper.VersionUtilities;
@@ -8,64 +7,48 @@ public readonly partial struct UnityVersion
{
private static readonly Regex majorMinorRegex = new Regex(@"^([0-9]+)\.([0-9]+)$", RegexOptions.Compiled);
private static readonly Regex majorMinorBuildRegex = new Regex(@"^([0-9]+)\.([0-9]+)\.([0-9]+)$", RegexOptions.Compiled);
private static readonly Regex normalRegex = new Regex(@"^([0-9]+)\.([0-9]+)\.([0-9]+)\.?([abfpx])([0-9]+)$", RegexOptions.Compiled);
private static readonly Regex chinaRegex = new Regex(@"^([0-9]+)\.([0-9]+)\.([0-9]+)\.?f1c([0-9]+)$", RegexOptions.Compiled);
private static readonly Regex normalRegex = new Regex(@"^([0-9]+)\.([0-9]+)\.([0-9]+)\.?([abcfpx])([0-9]+)(\n[0-9]+)?$", RegexOptions.Compiled);
private static readonly Regex chinaRegex = new Regex(@"^([0-9]+)\.([0-9]+)\.([0-9]+)\.?f1c([0-9]+)(\n[0-9]+)?$", RegexOptions.Compiled);
/// <summary>
/// Serialize the version as a string
/// Serialize the version as a string using <see cref="UnityVersionFormatFlags.Default"/>.
/// </summary>
/// <returns>A new string like 2019.4.3f1</returns>
public override string ToString()
public override string ToString() => ToString(UnityVersionFormatFlags.Default);
/// <summary>
/// Serialize the version as a string
/// </summary>
/// <param name="flags">The flags to control how the version is formatted</param>
/// <returns>A new string containing the formatted version.</returns>
public string ToString(UnityVersionFormatFlags flags)
{
return ToString(false, false, false, false);
return (flags & UnityVersionFormatFlags.ExcludeType) != 0
? ToStringWithoutType()
: Type is not UnityVersionType.China || (flags & UnityVersionFormatFlags.UseShortChineseFormat) != 0
? $"{Major}.{Minor}.{Build}{Type.ToCharacter()}{TypeNumber}"
: $"{Major}.{Minor}.{Build}f1c{TypeNumber}";
}
/// <summary>
/// Serialize the version as a string
/// </summary>
/// <param name="hasUnderscorePrefix">Include the _ prefix</param>
/// <param name="useUnderscoresAsSeparators">Use underscores as separators instead of periods</param>
/// <param name="hasDllExtension">Include the .dll extension</param>
/// <param name="hasSeparatorAfterBuild">Include a separator between <see cref="Build"/> and <see cref="Type"/></param>
/// <returns>A new string generated with those parameters</returns>
public string ToString(bool hasUnderscorePrefix, bool useUnderscoresAsSeparators, bool hasDllExtension, bool hasSeparatorAfterBuild)
/// <param name="flags">The flags to control how the version is formatted</param>
/// <param name="customEngineNumber">The custom engine number to be appended</param>
/// <returns>A new string containing the formatted version.</returns>
public string ToString(UnityVersionFormatFlags flags, int? customEngineNumber)
{
StringBuilder sb = new();
char separator = useUnderscoresAsSeparators ? '_' : '.';
if(hasUnderscorePrefix)
sb.Append('_');
sb.Append(Major);
sb.Append(separator);
sb.Append(Minor);
sb.Append(separator);
sb.Append(Build);
if (hasSeparatorAfterBuild)
{
sb.Append(separator);
}
if (Type == UnityVersionType.China)
{
sb.Append("f1");
sb.Append('c');
sb.Append(TypeNumber);
}
else
{
sb.Append(Type.ToCharacter());
sb.Append(TypeNumber);
}
if(hasDllExtension)
sb.Append(".dll");
return sb.ToString();
return customEngineNumber is null
? ToString(flags)
: (flags & UnityVersionFormatFlags.ExcludeType) != 0
? ToStringWithoutType()
: Type is not UnityVersionType.China || (flags & UnityVersionFormatFlags.UseShortChineseFormat) != 0
? $"{Major}.{Minor}.{Build}{Type.ToCharacter()}{TypeNumber}\n{customEngineNumber}"
: $"{Major}.{Minor}.{Build}f1c{TypeNumber}\n{customEngineNumber}";
}
/// <summary>
/// Serialize the version as a string
/// Serialize the version as a string using only <see cref="Major"/>, <see cref="Minor"/>, and <see cref="Build"/>.
/// </summary>
/// <returns>A new string like 2019.4.3</returns>
public string ToStringWithoutType()
@@ -73,26 +56,6 @@ public readonly partial struct UnityVersion
return $"{Major}.{Minor}.{Build}";
}
/// <summary>
/// Parse a dll name like _2019_4_3f1.dll
/// </summary>
/// <param name="dllName">The name of a dll file</param>
/// <returns>The parsed Unity version</returns>
/// <exception cref="ArgumentNullException">If the string is null or empty</exception>
public static UnityVersion ParseFromDllName(string dllName)
{
if (string.IsNullOrEmpty(dllName))
{
throw new ArgumentNullException(nameof(dllName));
}
if (dllName[0] == '_')
{
dllName = dllName.Substring(1);
}
return Parse(dllName.Replace('_', '.').Replace(".dll", ""));
}
/// <summary>
/// Parse a normal Unity version string
/// </summary>
@@ -100,7 +63,17 @@ public readonly partial struct UnityVersion
/// <returns>The parsed Unity version</returns>
/// <exception cref="ArgumentNullException">If the string is null or empty</exception>
/// <exception cref="ArgumentException">If the string is in an invalid format</exception>
public static UnityVersion Parse(string version)
public static UnityVersion Parse(string version) => Parse(version, out _);
/// <summary>
/// Parse a normal Unity version string
/// </summary>
/// <param name="version">A string to parse</param>
/// <param name="customEngine">True if this version was generated by a custom Unity Engine.</param>
/// <returns>The parsed Unity version</returns>
/// <exception cref="ArgumentNullException">If the string is null or empty</exception>
/// <exception cref="ArgumentException">If the string is in an invalid format</exception>
public static UnityVersion Parse(string version, out int? customEngine)
{
if (string.IsNullOrEmpty(version))
{
@@ -114,6 +87,7 @@ public readonly partial struct UnityVersion
int build = int.Parse(match.Groups[3].Value);
char type = match.Groups[4].Value[0];
int typeNumber = int.Parse(match.Groups[5].Value);
customEngine = ParseNullableInteger(match.Groups[6]);
return new UnityVersion((ushort)major, (ushort)minor, (ushort)build, type.ToUnityVersionType(), (byte)typeNumber);
}
else if (majorMinorBuildRegex.TryMatch(version, out match))
@@ -121,12 +95,14 @@ public readonly partial struct UnityVersion
int major = int.Parse(match.Groups[1].Value);
int minor = int.Parse(match.Groups[2].Value);
int build = int.Parse(match.Groups[3].Value);
customEngine = null;
return new UnityVersion((ushort)major, (ushort)minor, (ushort)build, UnityVersionType.Final, 1);
}
else if (majorMinorRegex.TryMatch(version, out match))
{
int major = int.Parse(match.Groups[1].Value);
int minor = int.Parse(match.Groups[2].Value);
customEngine = null;
return new UnityVersion((ushort)major, (ushort)minor, 0, UnityVersionType.Final, 1);
}
else if (chinaRegex.TryMatch(version, out match))
@@ -135,11 +111,14 @@ public readonly partial struct UnityVersion
int minor = int.Parse(match.Groups[2].Value);
int build = int.Parse(match.Groups[3].Value);
int typeNumber = int.Parse(match.Groups[4].Value);
customEngine = ParseNullableInteger(match.Groups[5]);
return new UnityVersion((ushort)major, (ushort)minor, (ushort)build, UnityVersionType.China, (byte)typeNumber);
}
else
{
throw new ArgumentException($"Invalid version format: {version}", nameof(version));
}
static int? ParseNullableInteger(Capture capture) => capture.Length == 0 ? null : int.Parse(capture.Value);
}
}
@@ -0,0 +1,25 @@
namespace AssetRipper.VersionUtilities;
/// <summary>
/// Flags used when formatting a <see cref="UnityVersion"/>
/// </summary>
[Flags]
public enum UnityVersionFormatFlags
{
/// <summary>
/// The default flags when formatting.
/// </summary>
Default = 0,
/// <summary>
/// Exclude <see cref="UnityVersion.Type"/>, <see cref="UnityVersion.TypeNumber"/>, and the custom engine number when formatting.
/// </summary>
ExcludeType = 1 << 0,
/// <summary>
/// Format chinese versions as 2019.4.3c1 rather than 2019.4.3f1c1
/// </summary>
/// <remarks>
/// An example of the long version can be found in 'unity editor resources' and 'unity_builtin_extra' for the <see href="https://unity.cn/release-notes/full/2019/2019.4.40f1">2019.4.40f1c1</see> version.<br/>
/// An example of the short version can be found in <see href="https://github.com/AssetRipper/AssetRipper/issues/841"/>.
/// </remarks>
UseShortChineseFormat = 1 << 1,
}
+3 -3
View File
@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>netframework3.5;netframework4.0;netstandard2.0;net5.0;net6.0;net7.0</TargetFrameworks>
@@ -8,7 +8,7 @@
<AssemblyName>AssetRipper.VersionUtilities</AssemblyName>
<Authors>ds5678</Authors>
<Company>AssetRipper</Company>
<Version>1.3.1.0</Version>
<Version>1.5.0.0</Version>
<AssemblyVersion>$(Version)</AssemblyVersion>
<PackageId>AssetRipper.VersionUtilities</PackageId>
<PackageTags>C# version unity unity3d</PackageTags>
@@ -32,7 +32,7 @@
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="PolySharp" Version="1.10.0">
<PackageReference Include="PolySharp" Version="1.13.2">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>