Skip to content

Commit 8c59b05

Browse files
authored
Merge pull request Devolutions#3333 from marticliment/float-versions-to-structs
2 parents 735d2b3 + 272a6fd commit 8c59b05

31 files changed

Lines changed: 176 additions & 119 deletions

File tree

src/UniGetUI.Core.IconStore/IconCacheEngine.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -318,7 +318,7 @@ private static bool ValidateByVersion(CacheableIcon icon, string versionPath)
318318
{
319319
try
320320
{
321-
return File.Exists(versionPath) && CoreTools.GetVersionStringAsFloat(File.ReadAllText(versionPath)) >= CoreTools.GetVersionStringAsFloat(icon.Version);
321+
return File.Exists(versionPath) && CoreTools.VersionStringToStruct(File.ReadAllText(versionPath)) >= CoreTools.VersionStringToStruct(icon.Version);
322322
}
323323
catch (Exception e)
324324
{

src/UniGetUI.Core.Tools.Tests/ToolsTests.cs

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -114,19 +114,24 @@ public async Task TestFileSizeLoader(string uri, long expectedSize)
114114
}
115115

116116
[Theory]
117-
[InlineData("1000.0", 1000.0, 0.0)]
118-
[InlineData("2.4", 2.4, 0.001)]
119-
[InlineData("33a.12-beta", 33.12, 0.0)]
120-
[InlineData("0", 0.0, 0.0)]
121-
[InlineData("", -1, 0.0)]
122-
[InlineData("dfgfdsgdfg", -1, 0.0)]
123-
[InlineData("-12", 12.0, 0.0)]
124-
[InlineData("4.0.0.1.0", 4.001, 0.01)]
125-
[InlineData("2024.30.04.1223", 2024.30041223, 0.0)]
126-
[InlineData("0.0", 0.0, 0.0)]
127-
public void TestGetVersionStringAsFloat(string version, double expected, double tolerance)
117+
[InlineData("1000.0", 1000, 0, 0, 0)]
118+
[InlineData("2.4", 2, 4, 0, 0)]
119+
[InlineData("33a.12-beta5", 33, 12, 5, 0)]
120+
[InlineData("0", 0,0,0,0)]
121+
[InlineData("", 0,0,0,0)]
122+
[InlineData("dfgfdsgdfg", 0,0,0,0)]
123+
[InlineData("-12", 12,0,0,0)]
124+
[InlineData("4.0.0.1.0", 4,0,0,10)]
125+
[InlineData("4.0.0.1.05", 4,0,0,105)]
126+
[InlineData("2024.30.04.1223", 2024, 30, 4, 1223)]
127+
[InlineData("0.0", 0,0,0,0)]
128+
public void TestGetVersionStringAsFloat(string version, int i1, int i2, int i3, int i4)
128129
{
129-
Assert.Equal(expected, CoreTools.GetVersionStringAsFloat(version), tolerance);
130+
CoreTools.Version v = CoreTools.VersionStringToStruct(version);
131+
Assert.Equal(i1, v.Major);
132+
Assert.Equal(i2, v.Minor);
133+
Assert.Equal(i3, v.Patch);
134+
Assert.Equal(i4, v.Remainder);
130135
}
131136

132137
[Theory]

src/UniGetUI.Core.Tools/Tools.cs

Lines changed: 80 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -315,53 +315,104 @@ public static async Task<long> GetFileSizeAsyncAsLong(Uri? url)
315315
return 0;
316316
}
317317

318+
319+
public struct Version: IComparable
320+
{
321+
public static readonly Version Null = new(-1, -1, -1, -1);
322+
323+
public readonly int Major;
324+
public readonly int Minor;
325+
public readonly int Patch;
326+
public readonly int Remainder;
327+
328+
public Version(int major, int minor = 0, int patch = 0, int remainder = 0)
329+
{
330+
Major = major;
331+
Minor = minor;
332+
Patch = patch;
333+
Remainder = remainder;
334+
}
335+
336+
public int CompareTo(object? other_)
337+
{
338+
if (other_ is not Version other) return 0;
339+
340+
int major = Major.CompareTo(other.Major);
341+
if (major != 0) return major;
342+
343+
int minor = Minor.CompareTo(other.Minor);
344+
if (minor != 0) return minor;
345+
346+
int patch = Patch.CompareTo(other.Patch);
347+
if (patch != 0) return patch;
348+
349+
return Remainder.CompareTo(other.Remainder);
350+
}
351+
352+
public static bool operator ==(Version left, Version right)
353+
=> left.CompareTo(right) == 0;
354+
355+
public static bool operator !=(Version left, Version right)
356+
=> left.CompareTo(right) != 0;
357+
358+
public static bool operator >=(Version left, Version right)
359+
=> left.CompareTo(right) >= 0;
360+
361+
public static bool operator <=(Version left, Version right)
362+
=> left.CompareTo(right) <= 0;
363+
364+
public static bool operator >(Version left, Version right)
365+
=> left.CompareTo(right) > 0;
366+
367+
public static bool operator <(Version left, Version right)
368+
=> left.CompareTo(right) < 0;
369+
370+
public bool Equals(Version other)
371+
=> Major == other.Major && Minor == other.Minor && Patch == other.Patch && Remainder == other.Remainder;
372+
373+
public override bool Equals(object? obj)
374+
=> obj is Version other && Equals(other);
375+
376+
public override int GetHashCode()
377+
=> HashCode.Combine(Major, Minor, Patch, Remainder);
378+
}
379+
318380
/// <summary>
319381
/// Converts a string into a double floating-point number.
320382
/// </summary>
321383
/// <param name="Version">Any string</param>
322384
/// <returns>The best approximation of the string as a Version</returns>
323-
public static double GetVersionStringAsFloat(string Version)
385+
public static Version VersionStringToStruct(string Version)
324386
{
325387
try
326388
{
327-
string _ver = "";
328-
bool _dotAdded = false;
329-
foreach (char _char in Version)
389+
char[] separators = ['.', '-', '/', '#'];
390+
string[] versionItems = ["", "", "", ""];
391+
392+
int dotCount = 0;
393+
bool first = true;
394+
395+
foreach (char c in Version)
330396
{
331-
if (char.IsDigit(_char))
332-
{
333-
_ver += _char;
334-
}
335-
else if (_char == '.')
336-
{
337-
if (!_dotAdded)
338-
{
339-
_ver += _char;
340-
_dotAdded = true;
341-
}
342-
}
397+
if (char.IsDigit(c)) versionItems[dotCount] += c;
398+
else if (!first && separators.Contains(c)) if (dotCount < 3) dotCount++;
399+
first = false;
343400
}
344401

345-
double res = -1;
346-
if (_ver is not "" and not ".")
402+
int[] numbers = { 0, 0, 0, 0 };
403+
for (int i = 0; i < 4; i++)
347404
{
348-
try
349-
{
350-
double val = double.Parse(_ver, CultureInfo.InvariantCulture);
351-
return val;
352-
}
353-
catch
354-
{
355-
// ignored
356-
}
405+
if (int.TryParse(versionItems[i], out int val))
406+
numbers[i] = val;
357407
}
358408

359-
return res;
409+
var ver = new Version(numbers[0], numbers[1], numbers[2], numbers[3]);
410+
return ver;
360411
}
361412
catch
362413
{
363414
Logger.Warn($"Failed to parse version {Version} to float");
364-
return -1;
415+
return CoreTools.Version.Null;
365416
}
366417
}
367418

src/UniGetUI.Interface.BackgroundApi/BackgroundApi.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,7 @@ public void BuildV1WidgetsApi()
201201
continue; // Do not show already processed packages on queue
202202

203203
string icon = $"http://localhost:7058/widgets/v2/get_icon_for_package?packageId={HttpUtility.UrlEncode(package.Id)}&packageSource={HttpUtility.UrlEncode(package.Source.Name)}&token={ApiTokenHolder.Token}";
204-
packages.Append($"{package.Name.Replace('|', '-')}|{package.Id}|{package.Version}|{package.NewVersion}|{package.Source.AsString_DisplayName}|{package.Manager.Name}|{icon}&&");
204+
packages.Append($"{package.Name.Replace('|', '-')}|{package.Id}|{package.VersionString}|{package.NewVersionString}|{package.Source.AsString_DisplayName}|{package.Manager.Name}|{icon}&&");
205205
}
206206

207207
string pkgs_ = packages.ToString();

src/UniGetUI.PAckageEngine.Interfaces/IPackage.cs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System.ComponentModel;
2+
using UniGetUI.Core.Tools;
23
using UniGetUI.Interface.Enums;
34
using UniGetUI.PackageEngine.Classes.Serializable;
45
using UniGetUI.PackageEngine.Structs;
@@ -12,12 +13,12 @@ public interface IPackage : INotifyPropertyChanged, IEquatable<IPackage>
1213
public bool IsChecked { get; set; }
1314
public string Name { get; }
1415
public string Id { get; }
15-
public string Version { get; }
16-
public double VersionAsFloat { get; }
17-
public double NewVersionAsFloat { get; }
16+
public string VersionString { get; }
17+
public CoreTools.Version NormalizedVersion { get; }
18+
public CoreTools.Version NormalizedNewVersion { get; }
1819
public IManagerSource Source { get; }
1920
public IPackageManager Manager { get; }
20-
public string NewVersion { get; }
21+
public string NewVersionString { get; }
2122
public bool IsUpgradable { get; }
2223
public ref OverridenInstallationOptions OverridenOptions { get; }
2324
public string AutomationName { get; }

src/UniGetUI.PackageEngine.Managers.Cargo/Cargo.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ protected override IReadOnlyList<Package> FindPackages_UnSafe(string query)
103103
var package = Packages[i];
104104
try
105105
{
106-
var versionInfo = CratesIOClient.GetManifestVersion(package.Id, package.Version);
106+
var versionInfo = CratesIOClient.GetManifestVersion(package.Id, package.VersionString);
107107
if (versionInfo.bin_names?.Length > 0)
108108
{
109109
BinPackages.Add(package);

src/UniGetUI.PackageEngine.Managers.Cargo/Helpers/CargoPkgDetailsHelper.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ protected override void GetDetails_UnSafe(IPackageDetails details)
3838
var categories = manifest.categories?.Select(c => c.category);
3939
details.Tags = [.. keywords, .. categories];
4040

41-
var versionData = manifest.versions.Where((v) => v.num == details.Package.Version).First();
41+
var versionData = manifest.versions.Where((v) => v.num == details.Package.VersionString).First();
4242

4343
details.Author = versionData.published_by?.name;
4444
details.License = versionData.license;

src/UniGetUI.PackageEngine.Managers.Cargo/Helpers/CargoPkgOperationHelper.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ internal sealed class CargoPkgOperationHelper(Cargo cargo) : PackagePkgOperation
88
{
99
protected override IReadOnlyList<string> _getOperationParameters(IPackage package, IInstallationOptions options, OperationType operation)
1010
{
11-
var version = options.Version == string.Empty ? package.Version : options.Version;
11+
var version = options.Version == string.Empty ? package.VersionString : options.Version;
1212
List<string> parameters = operation switch
1313
{
1414
OperationType.Install => [Manager.Properties.InstallVerb, "--version", version, package.Id],

src/UniGetUI.PackageEngine.Managers.Chocolatey/Chocolatey.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ namespace UniGetUI.PackageEngine.Managers.ChocolateyManager
1919
public class Chocolatey : BaseNuGet
2020
{
2121
public static new string[] FALSE_PACKAGE_IDS = ["Directory", "", "Did", "Features?", "Validation", "-", "being", "It", "Error", "L'accs", "Maximum", "This", "Output is package name ", "operable", "Invalid"];
22-
public static new string[] FALSE_PACKAGE_VERSIONS = ["", "Did", "Features?", "Validation", "-", "being", "It", "Error", "L'accs", "Maximum", "This", "packages", "current version", "installed version", "is", "program", "validations", "argument", "no"];
22+
public static new string[] FALSE_PACKAGE_VERSIONS = ["", "of", "Did", "Features?", "Validation", "-", "being", "It", "Error", "L'accs", "Maximum", "This", "packages", "current version", "installed version", "is", "program", "validations", "argument", "no"];
2323

2424
public Chocolatey()
2525
{

src/UniGetUI.PackageEngine.Managers.Generic.NuGet/BaseNuGet.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ public sealed override void Initialize()
3434
private struct SearchResult
3535
{
3636
public string version;
37-
public double version_float;
37+
public CoreTools.Version version_float;
3838
public string id;
3939
}
4040

@@ -82,7 +82,7 @@ protected sealed override IReadOnlyList<Package> FindPackages_UnSafe(string quer
8282

8383
string id = Regex.Match(match.Value, "Id='([^<>']+)'").Groups[1].Value;
8484
string version = Regex.Match(match.Value, "Version='([^<>']+)'").Groups[1].Value;
85-
double float_version = CoreTools.GetVersionStringAsFloat(version);
85+
var float_version = CoreTools.VersionStringToStruct(version);
8686
// Match title = Regex.Match(match.Value, "<title[ \\\"\\=A-Za-z0-9]+>([^<>]+)<\\/title>");
8787

8888
if (AlreadyProcessedPackages.TryGetValue(id, out var value) && value.version_float >= float_version)

0 commit comments

Comments
 (0)