diff --git a/CHANGELOG.md b/CHANGELOG.md index 3d2867a0a2..b8a62ae58b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -63,6 +63,7 @@ All notable changes to this project will be documented in this file. - [Build] Rename GH1866 test, fix invalid char test, fix equality assertion order (#3509 by: HebaruSan; reviewed: DasSkelett) - [Netkan] Enforce a few more spec version requirements (#3505 by: HebaruSan; reviewed: DasSkelett) - [Netkan] Allow overriding resources.remote-avc (#3451 by: HebaruSan; reviewed: DasSkelett) +- [Netkan] Sort GitHub releases (#3571 by: HebaruSan; reviewed: DasSkelett) ## v1.30.4 (Hubble) diff --git a/Netkan/Sources/Github/GithubApi.cs b/Netkan/Sources/Github/GithubApi.cs index f72f4e87ae..f3ed354cd8 100644 --- a/Netkan/Sources/Github/GithubApi.cs +++ b/Netkan/Sources/Github/GithubApi.cs @@ -3,9 +3,11 @@ using System.Linq; using System.Net; using System.Text.RegularExpressions; + using log4net; using Newtonsoft.Json; using Newtonsoft.Json.Linq; + using CKAN.NetKAN.Services; using CKAN.Versioning; @@ -67,58 +69,28 @@ public IEnumerable GetAllReleases(GithubRef reference) { var json = Call($"repos/{reference.Repository}/releases?per_page={perPage}&page={page}"); Log.Debug("Parsing JSON..."); - var releases = JArray.Parse(json); - - // Finding the most recent *stable* release means filtering - // out on pre-releases. - - foreach (var release in releases) - { - // First, check for prerelease status... - if (reference.UsePrerelease == (bool)release["prerelease"]) - { - var version = new ModuleVersion((string)release["tag_name"]); - var author = (string)release["author"]["login"]; - - List allAssets; - - if (reference.UseSourceArchive) - { - Log.Debug("Using GitHub source archive"); - Uri download = new Uri((string)release["zipball_url"]); - DateTime? updated = (DateTime)release["published_at"]; - allAssets = new List { new GithubReleaseAsset(version.ToString(), download, updated) }; - } - else - { - allAssets = new List(); - var assets = (JArray)release["assets"]; - - foreach (var asset in assets.Where(asset => reference.Filter.IsMatch((string)asset["name"]))) - { - Log.DebugFormat("Using GitHub asset: {0}", asset["name"]); - Uri download = new Uri((string)asset["browser_download_url"]); - DateTime? updated = (DateTime)asset["updated_at"]; - - allAssets.Add(new GithubReleaseAsset( - (string)asset["name"], download, updated - ) - ); - } - } - - if (allAssets.Any()) - { - yield return new GithubRelease(author, version, allAssets); - } - } - } - - if (releases.Count < perPage) + var jsonReleases = JArray.Parse(json); + if (jsonReleases.Count < 1) { // That's all folks! break; } + var ghReleases = jsonReleases + .Select(rel => new GithubRelease(reference, rel)) + .Where(ghRel => + // Finding the most recent *stable* release means filtering + // out on pre-releases. + ghRel.PreRelease == reference.UsePrerelease + // Skip releases without assets + && ghRel.Assets.Any()) + // Insurance against GitHub returning them in the wrong order + .OrderByDescending(ghRel => ghRel.PublishedAt) + .ToList(); + + foreach (var ghRel in ghReleases) + { + yield return ghRel; + } } } diff --git a/Netkan/Sources/Github/GithubRelease.cs b/Netkan/Sources/Github/GithubRelease.cs index f88e740223..584f8681e3 100644 --- a/Netkan/Sources/Github/GithubRelease.cs +++ b/Netkan/Sources/Github/GithubRelease.cs @@ -1,20 +1,48 @@ using System; +using System.Linq; using System.Collections.Generic; + +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + using CKAN.Versioning; namespace CKAN.NetKAN.Sources.Github { - public sealed class GithubRelease + internal sealed class GithubRelease { - public string Author { get; } - public ModuleVersion Tag { get; } - public List Assets { get; } + public readonly string Author; + public readonly ModuleVersion Tag; + public readonly List Assets; + public readonly bool PreRelease; + public readonly DateTime? PublishedAt; + + public GithubRelease(GithubRef reference, JToken json) + { + PreRelease = (bool)json["prerelease"]; + Tag = new ModuleVersion((string)json["tag_name"]); + Author = (string)json["author"]["login"]; + PublishedAt = (DateTime?)json["published_at"]; + Assets = reference.UseSourceArchive + ? new List { + new GithubReleaseAsset( + Tag.ToString(), + new Uri((string)json["zipball_url"]), + PublishedAt) + } : ((JArray)json["assets"]) + .Where(asset => reference.Filter.IsMatch((string)asset["name"])) + .Select(asset => new GithubReleaseAsset( + (string)asset["name"], + new Uri((string)asset["browser_download_url"]), + (DateTime?)asset["updated_at"])) + .ToList(); + } public GithubRelease(string author, ModuleVersion tag, List assets) { - Author = author; - Tag = tag; - Assets = assets; + Author = author; + Tag = tag; + Assets = assets; } } }