Skip to content

Commit

Permalink
Merge #4173 Autogenerate spec version for modpacks
Browse files Browse the repository at this point in the history
  • Loading branch information
HebaruSan committed Sep 4, 2024
2 parents 512beec + d479821 commit fde0845
Show file tree
Hide file tree
Showing 5 changed files with 132 additions and 118 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ All notable changes to this project will be documented in this file.
- [GUI] Add mod support links to Help menu (#4154 by: HebaruSan)
- [GUI] Don't hide other providing mods for installed, make installed bold (#4163 by: HebaruSan)
- [CLI] Set headless mode automatically (#4166 by: HebaruSan)
- [Core] Autogenerate spec version for modpacks (#4173 by: HebaruSan)

### Bugfixes

Expand Down
4 changes: 2 additions & 2 deletions Core/Registry/RegistryManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -481,8 +481,7 @@ public CkanModule GenerateModpack(bool recommends = false, bool with_versions =
var crit = gameInstance.VersionCriteria();
var minAndMax = crit.MinAndMax;
var module = new CkanModule(
// v1.18 to allow Unlicense
new ModuleVersion("v1.18"),
new ModuleVersion("v1.6"),
Identifier.Sanitize(name),
name,
string.Format(Properties.Resources.RegistryManagerDefaultModpackAbstract, gameInstanceName),
Expand Down Expand Up @@ -517,6 +516,7 @@ public CkanModule GenerateModpack(bool recommends = false, bool with_versions =
{
module.depends = rels;
}
module.spec_version = SpecVersionAnalyzer.MinimumSpecVersion(module);

return module;
}
Expand Down
127 changes: 127 additions & 0 deletions Core/Types/SpecVersionAnalyzer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
using System.Collections.Generic;
using System.Linq;

using Newtonsoft.Json.Linq;

using CKAN.Versioning;

namespace CKAN
{
public static class SpecVersionAnalyzer
{
public static ModuleVersion MinimumSpecVersion(CkanModule module)
=> MinimumSpecVersion(JObject.FromObject(module));

public static ModuleVersion MinimumSpecVersion(JObject json)
// Add new stuff at the top, versions in this function should be in descending order
=> json["download_hash"] is JObject hashes
&& (!hashes.ContainsKey("sha256") || !hashes.ContainsKey("sha1")) ? v1p35

: json["download"] is JArray ? v1p34

: AllRelationships(json).Any(rel => rel.ContainsKey("any_of")
&& rel.ContainsKey("choice_help_text")) ? v1p31

: HasLicense(json, "MPL-2.0") ? v1p30

: (json["install"] as JArray)?.OfType<JObject>().Any(stanza =>
(((string?)stanza["install_to"])?.StartsWith("Ships/Script") ?? false)
|| ((string?)stanza["install_to"] == "Ships" && (
// find: .../Script, install_to: Ships
((string?)stanza["find"])?.Split(new char[] {'/'})?.LastOrDefault() == "Script"
// file: .../Script, install_to: Ships
|| ((string?)stanza["file"])?.Split(new char[] {'/'})?.LastOrDefault() == "Script"
// install_to: Ships, as: Script
|| (((string?)stanza["as"])?.EndsWith("Script") ?? false)))) ?? false ? v1p29

: (string?)json["kind"] == "dlc" ? v1p28

: json.ContainsKey("replaced_by") ? v1p26

: AllRelationships(json).Any(rel => rel.ContainsKey("any_of")) ? v1p26

: (json["install"] as JArray)?.OfType<JObject>()
.Any(stanza => (string?)stanza["install_to"] == "Missions") ?? false ? v1p25

: (json["install"] as JArray)?.OfType<JObject>()
.Any(stanza => stanza.ContainsKey("include_only")
|| stanza.ContainsKey("include_only_regexp")) ?? false ? v1p24

: HasLicense(json, "Unlicense") ? v1p18

: (json["install"] as JArray)?.OfType<JObject>()
.Any(stanza => stanza.ContainsKey("as")) ?? false ? v1p18

: json.ContainsKey("ksp_version_strict") ? v1p16

: (json["install"] as JArray)?.OfType<JObject>()
.Any(stanza => ((string?)stanza["install_to"] ?? "").StartsWith("Ships/@thumbs")) ?? false ? v1p16

: (json["install"] as JArray)?.OfType<JObject>()
.Any(stanza => stanza.ContainsKey("find_matches_files")) ?? false ? v1p16

: (json["install"] as JArray)?.OfType<JObject>()
.Any(stanza => (string?)stanza["install_to"] == "Scenarios") ?? false ? v1p14

: (json["install"] as JArray)?.OfType<JObject>()
.Any(stanza => ((string?)stanza["install_to"] ?? "").StartsWith("Ships/")) ?? false ? v1p12

: (json["install"] as JArray)?.OfType<JObject>()
.Any(stanza => stanza.ContainsKey("find_regexp")
|| stanza.ContainsKey("filter_regexp")) ?? false ? v1p10

: json["license"] is JArray ? v1p8

: (string?)json["kind"] == "metapackage" ? v1p6

: (json["install"] as JArray)?.OfType<JObject>()
.Any(stanza => stanza.ContainsKey("find")) ?? false ? v1p4

: HasLicense(json, "WTFPL") ? v1p2

: json.ContainsKey("supports") ? v1p2

: (json["install"] as JArray)?.OfType<JObject>()
.Any(stanza => ((string?)stanza["install_to"] ?? "").StartsWith("GameData/")) ?? false ? v1p2

: v1p0;

private static bool HasLicense(JObject json,
string name)
=> json["license"] is JArray array ? array.Contains(name)
: json["license"] is JToken token && ((string?)token) == name;

private static IEnumerable<JObject> AllRelationships(JObject json)
=> relProps.SelectMany(p => json[p] is JArray array ? array.OfType<JObject>()
: Enumerable.Empty<JObject>());

private static readonly string[] relProps = new string[]
{
"depends",
"recommends",
"suggests",
"conflicts",
"supports"
};

private static readonly ModuleVersion v1p0 = new ModuleVersion("v1.0");
private static readonly ModuleVersion v1p2 = new ModuleVersion("v1.2");
private static readonly ModuleVersion v1p4 = new ModuleVersion("v1.4");
private static readonly ModuleVersion v1p6 = new ModuleVersion("v1.6");
private static readonly ModuleVersion v1p8 = new ModuleVersion("v1.8");
private static readonly ModuleVersion v1p10 = new ModuleVersion("v1.10");
private static readonly ModuleVersion v1p12 = new ModuleVersion("v1.12");
private static readonly ModuleVersion v1p14 = new ModuleVersion("v1.14");
private static readonly ModuleVersion v1p16 = new ModuleVersion("v1.16");
private static readonly ModuleVersion v1p18 = new ModuleVersion("v1.18");
private static readonly ModuleVersion v1p24 = new ModuleVersion("v1.24");
private static readonly ModuleVersion v1p25 = new ModuleVersion("v1.25");
private static readonly ModuleVersion v1p26 = new ModuleVersion("v1.26");
private static readonly ModuleVersion v1p28 = new ModuleVersion("v1.28");
private static readonly ModuleVersion v1p29 = new ModuleVersion("v1.29");
private static readonly ModuleVersion v1p30 = new ModuleVersion("v1.30");
private static readonly ModuleVersion v1p31 = new ModuleVersion("v1.31");
private static readonly ModuleVersion v1p34 = new ModuleVersion("v1.34");
private static readonly ModuleVersion v1p35 = new ModuleVersion("v1.35");
}
}
1 change: 1 addition & 0 deletions GUI/Controls/EditModpack.cs
Original file line number Diff line number Diff line change
Expand Up @@ -349,6 +349,7 @@ private void ExportModpackButton_Click(object? sender, EventArgs? e)
{
module.suggests = null;
}
module.spec_version = SpecVersionAnalyzer.MinimumSpecVersion(module);
CkanModule.ToFile(ApplyCheckboxes(module), filename);
Utilities.OpenFileBrowser(filename);
task?.SetResult(true);
Expand Down
117 changes: 1 addition & 116 deletions Netkan/Transformers/SpecVersionTransformer.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
using System.Collections.Generic;
using System.Linq;

using Newtonsoft.Json.Linq;
using log4net;

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

Expand All @@ -24,7 +21,7 @@ public IEnumerable<Metadata> Transform(Metadata metadata,
TransformOptions? opts)
{
var json = metadata.Json();
var minVersion = MinimumSpecVersion(json);
var minVersion = SpecVersionAnalyzer.MinimumSpecVersion(json);
if (metadata.SpecVersion == null || metadata.SpecVersion != minVersion)
{
log.InfoFormat("Setting spec version {0}", minVersion);
Expand All @@ -37,118 +34,6 @@ public IEnumerable<Metadata> Transform(Metadata metadata,
}
}

private static ModuleVersion MinimumSpecVersion(JObject json)
// Add new stuff at the top, versions in this function should be in descending order
=> json["download_hash"] is JObject hashes
&& (!hashes.ContainsKey("sha256") || !hashes.ContainsKey("sha1")) ? v1p35

: json["download"] is JArray ? v1p34

: AllRelationships(json).Any(rel => rel.ContainsKey("any_of")
&& rel.ContainsKey("choice_help_text")) ? v1p31

: HasLicense(json, "MPL-2.0") ? v1p30

: (json["install"] as JArray)?.OfType<JObject>().Any(stanza =>
(((string?)stanza["install_to"])?.StartsWith("Ships/Script") ?? false)
|| ((string?)stanza["install_to"] == "Ships" && (
// find: .../Script, install_to: Ships
((string?)stanza["find"])?.Split(new char[] {'/'})?.LastOrDefault() == "Script"
// file: .../Script, install_to: Ships
|| ((string?)stanza["file"])?.Split(new char[] {'/'})?.LastOrDefault() == "Script"
// install_to: Ships, as: Script
|| (((string?)stanza["as"])?.EndsWith("Script") ?? false)))) ?? false ? v1p29

: (string?)json["kind"] == "dlc" ? v1p28

: json.ContainsKey("replaced_by") ? v1p26

: AllRelationships(json).Any(rel => rel.ContainsKey("any_of")) ? v1p26

: (json["install"] as JArray)?.OfType<JObject>()
.Any(stanza => (string?)stanza["install_to"] == "Missions") ?? false ? v1p25

: (json["install"] as JArray)?.OfType<JObject>()
.Any(stanza => stanza.ContainsKey("include_only")
|| stanza.ContainsKey("include_only_regexp")) ?? false ? v1p24

: HasLicense(json, "Unlicense") ? v1p18

: (json["install"] as JArray)?.OfType<JObject>()
.Any(stanza => stanza.ContainsKey("as")) ?? false ? v1p18

: json.ContainsKey("ksp_version_strict") ? v1p16

: (json["install"] as JArray)?.OfType<JObject>()
.Any(stanza => ((string?)stanza["install_to"] ?? "").StartsWith("Ships/@thumbs")) ?? false ? v1p16

: (json["install"] as JArray)?.OfType<JObject>()
.Any(stanza => stanza.ContainsKey("find_matches_files")) ?? false ? v1p16

: (json["install"] as JArray)?.OfType<JObject>()
.Any(stanza => (string?)stanza["install_to"] == "Scenarios") ?? false ? v1p14

: (json["install"] as JArray)?.OfType<JObject>()
.Any(stanza => ((string?)stanza["install_to"] ?? "").StartsWith("Ships/")) ?? false ? v1p12

: (json["install"] as JArray)?.OfType<JObject>()
.Any(stanza => stanza.ContainsKey("find_regexp")
|| stanza.ContainsKey("filter_regexp")) ?? false ? v1p10

: json["license"] is JArray ? v1p8

: (string?)json["kind"] == "metapackage" ? v1p6

: (json["install"] as JArray)?.OfType<JObject>()
.Any(stanza => stanza.ContainsKey("find")) ?? false ? v1p4

: HasLicense(json, "WTFPL") ? v1p2

: json.ContainsKey("supports") ? v1p2

: (json["install"] as JArray)?.OfType<JObject>()
.Any(stanza => ((string?)stanza["install_to"] ?? "").StartsWith("GameData/")) ?? false ? v1p2

: v1p0;

private static bool HasLicense(JObject json,
string name)
=> json["license"] is JArray array ? array.Contains(name)
: json["license"] is JToken token && ((string?)token) == name;

private static IEnumerable<JObject> AllRelationships(JObject json)
=> relProps.SelectMany(p => json[p] is JArray array ? array.OfType<JObject>()
: Enumerable.Empty<JObject>());

private static readonly string[] relProps = new string[]
{
"depends",
"recommends",
"suggests",
"conflicts",
"supports"
};

private static readonly ModuleVersion v1p0 = new ModuleVersion("v1.0");
private static readonly ModuleVersion v1p2 = new ModuleVersion("v1.2");
private static readonly ModuleVersion v1p4 = new ModuleVersion("v1.4");
private static readonly ModuleVersion v1p6 = new ModuleVersion("v1.6");
private static readonly ModuleVersion v1p8 = new ModuleVersion("v1.8");
private static readonly ModuleVersion v1p10 = new ModuleVersion("v1.10");
private static readonly ModuleVersion v1p12 = new ModuleVersion("v1.12");
private static readonly ModuleVersion v1p14 = new ModuleVersion("v1.14");
private static readonly ModuleVersion v1p16 = new ModuleVersion("v1.16");
private static readonly ModuleVersion v1p18 = new ModuleVersion("v1.18");
private static readonly ModuleVersion v1p24 = new ModuleVersion("v1.24");
private static readonly ModuleVersion v1p25 = new ModuleVersion("v1.25");
private static readonly ModuleVersion v1p26 = new ModuleVersion("v1.26");
private static readonly ModuleVersion v1p28 = new ModuleVersion("v1.28");
private static readonly ModuleVersion v1p29 = new ModuleVersion("v1.29");
private static readonly ModuleVersion v1p30 = new ModuleVersion("v1.30");
private static readonly ModuleVersion v1p31 = new ModuleVersion("v1.31");
private static readonly ModuleVersion v1p34 = new ModuleVersion("v1.34");
private static readonly ModuleVersion v1p35 = new ModuleVersion("v1.35");

private static readonly ILog log = LogManager.GetLogger(typeof(SpecVersionTransformer));
}
}

0 comments on commit fde0845

Please sign in to comment.