diff --git a/CHANGELOG.md b/CHANGELOG.md index 5c9445c90..8ed3f47cd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -81,6 +81,7 @@ All notable changes to this project will be documented in this file. - [CLI] Ability to update repos without a game instance (#4161 by: HebaruSan) - [Multiple] Nullable references, net8.0, blend registry alert dot, netkan fixes (#4171, #4176 by: HebaruSan) - [Netkan] SourceForge kref (#4172, #4174 by: HebaruSan) +- [Netkan] Inflation error for multi-hosted mods with mismatched versions (#4178 by: HebaruSan) ## v1.34.4 (Niven) diff --git a/Netkan/Model/Metadata.cs b/Netkan/Model/Metadata.cs index a137211f9..b36028902 100644 --- a/Netkan/Model/Metadata.cs +++ b/Netkan/Model/Metadata.cs @@ -34,6 +34,18 @@ internal sealed class Metadata public bool Staged { get; private set; } public string? StagingReason { get; private set; } + public string[] Hosts + => (_json.TryGetValue(DownloadPropertyName, out JToken? downloadToken) + ? downloadToken.Type == JTokenType.String + && (string?)downloadToken is string url + ? Enumerable.Repeat(url, 1) + : downloadToken.Children() + .Select(ch => (string?)ch) + .OfType() + : Enumerable.Empty()) + .Select(u => new Uri(u).Host) + .ToArray(); + public Metadata(JObject? json) { if (json == null) diff --git a/Netkan/Processors/Inflator.cs b/Netkan/Processors/Inflator.cs index f6918151b..7e9f9a553 100644 --- a/Netkan/Processors/Inflator.cs +++ b/Netkan/Processors/Inflator.cs @@ -49,15 +49,22 @@ internal IEnumerable Inflate(string filename, Metadata[] netkans, Tran } log.Debug("Input successfully passed pre-validation"); - var ckans = netkans - .SelectMany(netkan => transformer.Transform(netkan, opts)) - .GroupBy(module => module.Version) - .Select(grp => Metadata.Merge(grp.ToArray())) - .SelectMany(merged => specVersionTransformer.Transform(merged, opts)) - .SelectMany(withSpecVersion => sortTransformer.Transform(withSpecVersion, opts)) - .ToList(); + var ckans = netkans.SelectMany(netkan => transformer.Transform(netkan, opts)) + .GroupBy(module => module.Version) + .Select(grp => Metadata.Merge(grp.ToArray())) + .SelectMany(merged => specVersionTransformer.Transform(merged, opts)) + .SelectMany(withSpecVersion => sortTransformer.Transform(withSpecVersion, opts)) + .ToList(); log.Debug("Finished transformation"); + if (ckans.Count > (opts?.Releases ?? 1)) + { + throw new Kraken(string.Format("Generated {0} modules but only {1} requested: {2}", + ckans.Count, + opts?.Releases ?? 1, + string.Join("; ", ckans.Select(DescribeHosting)))); + } + foreach (Metadata ckan in ckans) { ckanValidator.ValidateCkan(ckan, netkans.First()); @@ -123,6 +130,9 @@ private static void PurgeDownloads(IHttpService http, NetFileCache cache) } } + private string DescribeHosting(Metadata metadata) + => $"{metadata.Version} on {string.Join(", ", metadata.Hosts)}"; + private readonly NetFileCache cache; private readonly IHttpService http;