Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Don't raise inflation errors for single-hosted prereleases of multi-hosted mods #4273

Merged
merged 1 commit into from
Dec 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion Netkan/CmdLineOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,12 @@ internal class CmdLineOptions
[Option("queues", HelpText = "Input,Output queue names for Queue Inflator mode")]
public string? Queues { get; set; }

[Option("highest-version", HelpText = "Highest known version for auto-epoching")]
[Option("highest-version", HelpText = "Highest known non-prerelease version for auto-epoching")]
public string? HighestVersion { get; set; }

[Option("highest-version-prerelease", HelpText = "Highest known prerelease version for auto-epoching")]
public string? HighestVersionPrerelease { get; set; }

[Option("validate-ckan", HelpText = "Name of .ckan file to check for errors")]
public string? ValidateCkan { get; set; }

Expand Down
7 changes: 7 additions & 0 deletions Netkan/Processors/QueueHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -152,13 +152,20 @@ private IEnumerable<SendMessageBatchRequestEntry> Inflate(Message msg)
highVer = new ModuleVersion(highVerAttr.StringValue);
}

ModuleVersion? highVerPre = null;
if (msg.MessageAttributes.TryGetValue("HighestVersionPrerelease", out MessageAttributeValue? highVerPreAttr))
{
highVerPre = new ModuleVersion(highVerPreAttr.StringValue);
}

log.InfoFormat("Inflating {0}", netkans.First().Identifier);
IEnumerable<Metadata>? ckans = null;
bool caught = false;
string? caughtMessage = null;
var opts = new TransformOptions(releases,
null,
highVer,
highVerPre,
netkans.First().Staged,
netkans.First().StagingReason);
try
Expand Down
1 change: 1 addition & 0 deletions Netkan/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ is string[] array
ParseReleases(Options.Releases),
ParseSkipReleases(Options.SkipReleases),
ParseHighestVersion(Options.HighestVersion),
ParseHighestVersion(Options.HighestVersionPrerelease),
netkans.First().Staged,
netkans.First().StagingReason))
.ToArray();
Expand Down
77 changes: 51 additions & 26 deletions Netkan/Transformers/EpochTransformer.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
using System;
using System.Linq;
using System.Collections.Generic;

using log4net;
using Newtonsoft.Json.Linq;

using CKAN.Versioning;
using CKAN.NetKAN.Model;

Expand Down Expand Up @@ -29,7 +32,7 @@ public IEnumerable<Metadata> Transform(Metadata metadata, TransformOptions? opts

if (uint.TryParse(epoch.ToString(), out uint epochNumber))
{
//Implicit if zero. No need to add
// Implicit if zero. No need to add
if (epochNumber != 0)
{
json["version"] = epochNumber + ":" + json["version"];
Expand All @@ -43,40 +46,62 @@ public IEnumerable<Metadata> Transform(Metadata metadata, TransformOptions? opts
}
}

if (json.TryGetValue("x_netkan_allow_out_of_order", out JToken? allowOOO) && (bool)allowOOO)
if (json.TryGetValue("x_netkan_allow_out_of_order", out JToken? allowOOO)
&& (bool)allowOOO)
{
Log.Debug("Out of order versions enabled in netkan, skipping OOO check");
}
else if (opts?.HighestVersion != null && (string?)json["version"] is string v)
else if (opts != null
&& (string?)json["version"] is string v
&& (metadata.Prerelease
? new ModuleVersion?[]
{
opts.HighestVersionPrerelease,
opts.HighestVersion,
}
: new ModuleVersion?[]
{
opts.HighestVersion,
})
.OfType<ModuleVersion>()
.Max()
is ModuleVersion highest)
{
json["version"] = CheckOutOfOrder(opts, highest,
new ModuleVersion(v))
.ToString();
}

yield return new Metadata(json);
}

private static ModuleVersion CheckOutOfOrder(TransformOptions opts,
ModuleVersion highest,
ModuleVersion start)
{
// Ensure we are greater or equal to the previous max
ModuleVersion current = start;
while (current < highest)
{
Log.DebugFormat("Auto-epoching out of order version: {0} < {1}",
current, highest);
// Increment epoch if too small
current = current.IncrementEpoch();
}
if (!highest.EpochEquals(current) && start < highest && highest < current)
{
// Ensure we are greater or equal to the previous max
ModuleVersion startV = new ModuleVersion(v);
ModuleVersion currentV = startV;
while (currentV < opts.HighestVersion)
if (opts.FlakyAPI)
{
Log.DebugFormat("Auto-epoching out of order version: {0} < {1}",
currentV, opts.HighestVersion);
// Increment epoch if too small
currentV = currentV.IncrementEpoch();
throw new Kraken($"Out-of-order version found on unreliable server: {start} < {highest} < {current}");
}
if (!opts.HighestVersion.EpochEquals(currentV)
&& startV < opts.HighestVersion && opts.HighestVersion < currentV)
else
{
if (opts.FlakyAPI)
{
throw new Kraken($"Out-of-order version found on unreliable server: {startV} < {opts.HighestVersion} < {currentV}");
}
else
{
// New file, tell the Indexer to be careful
opts.Staged = true;
opts.StagingReasons.Add($"Auto-epoching out of order version: {startV} < {opts.HighestVersion} < {currentV}");
}
// New file, tell the Indexer to be careful
opts.Staged = true;
opts.StagingReasons.Add($"Auto-epoching out of order version: {start} < {highest} < {current}");
}
json["version"] = currentV.ToString();
}

yield return new Metadata(json);
return current;
}
}
}
13 changes: 8 additions & 5 deletions Netkan/Transformers/ITransformer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,16 @@ internal class TransformOptions
public TransformOptions(int? releases,
int? skipReleases,
ModuleVersion? highVer,
ModuleVersion? highVerPre,
bool staged,
string? stagingReason)
{
Releases = releases;
SkipReleases = skipReleases;
HighestVersion = highVer;
Staged = staged;
StagingReasons = new List<string>();
Releases = releases;
SkipReleases = skipReleases;
HighestVersion = highVer;
HighestVersionPrerelease = highVerPre;
Staged = staged;
StagingReasons = new List<string>();
if (stagingReason != null && !string.IsNullOrEmpty(stagingReason))
{
StagingReasons.Add(stagingReason);
Expand All @@ -26,6 +28,7 @@ public TransformOptions(int? releases,
public readonly int? Releases;
public readonly int? SkipReleases;
public readonly ModuleVersion? HighestVersion;
public readonly ModuleVersion? HighestVersionPrerelease;
public bool Staged;
public readonly List<string> StagingReasons;
public bool FlakyAPI = false;
Expand Down
2 changes: 1 addition & 1 deletion Tests/NetKAN/MainClass.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ namespace Tests.NetKAN
[TestFixture]
public class MainClassTests
{
private readonly TransformOptions opts = new TransformOptions(1, null, null, false, null);
private readonly TransformOptions opts = new TransformOptions(1, null, null, null, false, null);

[Test]
public void FixVersionStringsUnharmed()
Expand Down
2 changes: 1 addition & 1 deletion Tests/NetKAN/NetkanOverride.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ namespace Tests.NetKAN
public class NetkanOverride
{
private JObject? such_metadata;
private readonly TransformOptions opts = new TransformOptions(1, null, null, false, null);
private readonly TransformOptions opts = new TransformOptions(1, null, null, null, false, null);

[SetUp]
public void Setup()
Expand Down
2 changes: 1 addition & 1 deletion Tests/NetKAN/Transformers/AvcKrefTransformerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ namespace Tests.NetKAN.Transformers
[TestFixture]
public sealed class AvcKrefTransformerTests
{
private readonly TransformOptions opts = new TransformOptions(1, null, null, false, null);
private readonly TransformOptions opts = new TransformOptions(1, null, null, null, false, null);

[Test,
TestCase(
Expand Down
2 changes: 1 addition & 1 deletion Tests/NetKAN/Transformers/AvcTransformerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ namespace Tests.NetKAN.Transformers
[TestFixture]
public sealed class AvcTransformerTests
{
private readonly TransformOptions opts = new TransformOptions(1, null, null, false, null);
private readonly TransformOptions opts = new TransformOptions(1, null, null, null, false, null);
private readonly IGame game = new KerbalSpaceProgram();

[Test]
Expand Down
2 changes: 1 addition & 1 deletion Tests/NetKAN/Transformers/CurseTransformerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ namespace Tests.NetKAN.Transformers
[TestFixture]
public sealed class CurseTransformerTests
{
private readonly TransformOptions opts = new TransformOptions(1, null, null, false, null);
private readonly TransformOptions opts = new TransformOptions(1, null, null, null, false, null);

// GH #199: Don't pre-fill KSP version fields if we see a ksp_min/max
[Test]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ namespace Tests.NetKAN.Transformers
[TestFixture]
public sealed class DownloadAttributeTransformerTests
{
private readonly TransformOptions opts = new TransformOptions(1, null, null, false, null);
private readonly TransformOptions opts = new TransformOptions(1, null, null, null, false, null);

[Test]
[Category("Cache")]
Expand Down
54 changes: 39 additions & 15 deletions Tests/NetKAN/Transformers/EpochTransformerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,33 +10,56 @@ namespace Tests.NetKAN.Transformers
[TestFixture]
public sealed class EpochTransformerTests
{
[Test,
TestCase("1.1", null, "1.1"),
TestCase("1.1", "1.1", "1.1"),
TestCase("1.1", "1.2", "1:1.1"),
TestCase("1.1", "5:1.1", "5:1.1"),
TestCase("1.1", "5:1.2", "6:1.1"),
TestCase("0.7", "0.65", "1:0.7"),
TestCase("2.5", "v2.4", "1:2.5"),
TestCase("2.5", "V2.4", "1:2.5"),
TestCase("v2.5", "vV2.4", "1:v2.5"),
[
TestCase("1.1", null, null, false, "1.1", false),
TestCase("1.1", null, null, true, "1.1", false),
TestCase("1.1", "1.1", null, false, "1.1", false),
TestCase("1.1", "1.2", null, false, "1:1.1", true),
TestCase("1.1", "5:1.1", null, false, "5:1.1", false),
TestCase("1.1", "5:1.2", null, false, "6:1.1", true),
TestCase("0.7", "0.65", null, false, "1:0.7", true),
TestCase("2.5", "v2.4", null, false, "1:2.5", true),
TestCase("2.5", "V2.4", null, false, "1:2.5", true),
TestCase("v2.5", "vV2.4", null, false, "1:v2.5", true),

// Non-prerelease with a prerelease on another host
TestCase("1.0", "1.0", "2.0", false, "1.0", false),
// Prerelease with no normal releases
TestCase("1.0", null, "1.0", true, "1.0", false),
// Updating a prerelease to a normal release
TestCase("2.0", "1.0", "2.0", false, "2.0", false),
// Prerelease needing an epoch boost
TestCase("2.0", "1.0", "3.0", true, "1:2.0", true),
// The previous prerelease is old
TestCase("1.5", "2.0", "1.0", true, "1:1.5", true),
]
public void Transform_WithHighVersionParam_MatchesExpected(string version, string highVer, string expected)
public void Transform_WithHighVersionParam_MatchesExpected(string version,
string? highVer,
string? highVerPre,
bool prerelease,
string expected,
bool staged)
{
// Arrange
var json = new JObject()
{
{ "spec_version", "v1.4" },
{ "identifier", "AwesomeMod" },
{ "version", version },
{ "spec_version", "v1.4" },
{ "identifier", "AwesomeMod" },
{ "version", version },
{ "release_status", prerelease
? "testing"
: "stable" },
};
ITransformer sut = new EpochTransformer();
TransformOptions opts = new TransformOptions(
1,
null,
string.IsNullOrEmpty(highVer)
highVer is null or ""
? null
: new ModuleVersion(highVer),
highVerPre is null or ""
? null
: new ModuleVersion(highVerPre),
false,
null
);
Expand All @@ -47,6 +70,7 @@ public void Transform_WithHighVersionParam_MatchesExpected(string version, strin

// Assert
Assert.AreEqual(expected, (string?)transformedJson["version"]);
Assert.AreEqual(staged, opts.Staged);
}
}
}
2 changes: 1 addition & 1 deletion Tests/NetKAN/Transformers/GeneratedByTransformerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ namespace Tests.NetKAN.Transformers
[TestFixture]
public sealed class GeneratedByTransformerTests
{
private readonly TransformOptions opts = new TransformOptions(1, null, null, false, null);
private readonly TransformOptions opts = new TransformOptions(1, null, null, null, false, null);

[Test]
public void AddsGeneratedByProperty()
Expand Down
8 changes: 4 additions & 4 deletions Tests/NetKAN/Transformers/GithubTransformerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ namespace Tests.NetKAN.Transformers
[TestFixture]
public sealed class GithubTransformerTests
{
private readonly TransformOptions opts = new TransformOptions(1, null, null, false, null);
private readonly TransformOptions opts = new TransformOptions(1, null, null, null, false, null);

private Mock<IGithubApi>? apiMockUp;

Expand Down Expand Up @@ -192,7 +192,7 @@ public void Transform_MultipleReleases_TransformsAll()
// Act
var results = sut.Transform(
new Metadata(json),
new TransformOptions(2, null, null, false, null)
new TransformOptions(2, null, null, null, false, null)
);
var transformedJsons = results.Select(result => result.Json()).ToArray();

Expand Down Expand Up @@ -230,7 +230,7 @@ public void Transform_MultipleAssets_TransformsAll()
// Act
var results = sut.Transform(
new Metadata(json),
new TransformOptions(1, 3, null, false, null)
new TransformOptions(1, 3, null, null, false, null)
);
var transformedJsons = results.Select(result => result.Json()).ToArray();

Expand Down Expand Up @@ -268,7 +268,7 @@ public void Transform_SkipReleases_SkipsCorrectly()
// Act
var results = sut.Transform(
new Metadata(json),
new TransformOptions(2, 1, null, false, null)
new TransformOptions(2, 1, null, null, false, null)
).ToArray();

// Assert
Expand Down
2 changes: 1 addition & 1 deletion Tests/NetKAN/Transformers/HttpTransformerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ namespace Tests.NetKAN.Transformers
[TestFixture]
public sealed class HttpTransformerTests
{
private readonly TransformOptions opts = new TransformOptions(1, null, null, false, null);
private readonly TransformOptions opts = new TransformOptions(1, null, null, null, false, null);

[TestCase("#/ckan/github/foo/bar")]
[TestCase("#/ckan/netkan/http://awesomemod.example/awesomemod.netkan")]
Expand Down
2 changes: 1 addition & 1 deletion Tests/NetKAN/Transformers/InstallSizeTransformerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,6 @@ public void Transform_NormalModule_CorrectInstallSize()
Assert.AreEqual(52291, (int?)transformedJson["install_size"]);
}

private readonly TransformOptions opts = new TransformOptions(1, null, null, false, null);
private readonly TransformOptions opts = new TransformOptions(1, null, null, null, false, null);
}
}
2 changes: 1 addition & 1 deletion Tests/NetKAN/Transformers/InternalCkanTransformerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ namespace Tests.NetKAN.Transformers
[TestFixture]
public sealed class InternalCkanTransformerTests
{
private readonly TransformOptions opts = new TransformOptions(1, null, null, false, null);
private readonly TransformOptions opts = new TransformOptions(1, null, null, null, false, null);

[Test]
public void AddsMissingProperties()
Expand Down
2 changes: 1 addition & 1 deletion Tests/NetKAN/Transformers/MetaNetkanTransformerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ namespace Tests.NetKAN.Transformers
[TestFixture]
public sealed class MetaNetkanTransformerTests
{
private readonly TransformOptions opts = new TransformOptions(1, null, null, false, null);
private readonly TransformOptions opts = new TransformOptions(1, null, null, null, false, null);

[Test]
public void DoesNothingWhenNoMatch()
Expand Down
Loading
Loading