mirror of
https://github.com/bryanthaboi/gen1recomp.git
synced 2026-08-17 19:24:01 +02:00
feat(mods): enhance mod management with profile controls and dependency checks
- Added dedicated profile control in the MODS panel for easier profile management. - Implemented dependency checking during mod installation and updates to ensure compatibility. - Improved manifest parsing to support GitHub repository hints for dependencies. - Enhanced UI interactions for saving and renaming profiles. - Updated tests to cover new functionality and ensure stability.
This commit is contained in:
+43
-22
@@ -31,26 +31,6 @@ local function violation(strict, id, message)
|
||||
Logger.warn("[%s] %s", tostring(id), message)
|
||||
end
|
||||
|
||||
-- "id" or "id@<range>"; a malformed id or range fails for every api level
|
||||
-- because there is no sane fallback reading for it
|
||||
local function parseSpecs(list, field)
|
||||
local specs = {}
|
||||
for _, entry in ipairs(list) do
|
||||
assert(type(entry) == "string" and entry ~= "",
|
||||
field .. " entries must be non-empty strings")
|
||||
local id, range = entry:match("^([%w_%-]+)@(.+)$")
|
||||
if not id then
|
||||
id = entry:match("^([%w_%-]+)$")
|
||||
assert(id, ("malformed %s entry %q"):format(field, entry))
|
||||
range = nil
|
||||
end
|
||||
local ok, err = Semver.validRange(range)
|
||||
assert(ok, ("malformed %s range in %q: %s"):format(field, entry, tostring(err)))
|
||||
specs[#specs + 1] = { id = id, range = range }
|
||||
end
|
||||
return specs
|
||||
end
|
||||
|
||||
-- Optional GitHub repo for launcher auto-update / other-versions.
|
||||
-- Accepts "owner/repo" or a github.com URL; empty/absent means no updates.
|
||||
function Manifest.parseGithub(value)
|
||||
@@ -73,6 +53,47 @@ function Manifest.parseGithub(value)
|
||||
return owner .. "/" .. repo
|
||||
end
|
||||
|
||||
-- "id", "id@<range>", "id@<range>#<github>", "id#<github>", or table entry
|
||||
local function parseSpecs(list, field, sources)
|
||||
local specs = {}
|
||||
sources = type(sources) == "table" and sources or {}
|
||||
for _, entry in ipairs(list) do
|
||||
local id, range, ghHint
|
||||
if type(entry) == "table" then
|
||||
id = entry.id
|
||||
range = entry.range or entry.version
|
||||
ghHint = entry.github or entry.repo
|
||||
elseif type(entry) == "string" and entry ~= "" then
|
||||
local main, hashRepo = entry:match("^([^#]+)#(.*)$")
|
||||
if main then
|
||||
entry = main
|
||||
ghHint = hashRepo
|
||||
end
|
||||
id, range = entry:match("^([%w_%-]+)@(.+)$")
|
||||
if not id then
|
||||
id = entry:match("^([%w_%-]+)$")
|
||||
assert(id, ("malformed %s entry %q"):format(field, entry))
|
||||
range = nil
|
||||
end
|
||||
else
|
||||
error(field .. " entries must be non-empty strings or tables")
|
||||
end
|
||||
assert(id, ("malformed %s entry"):format(field))
|
||||
local ok, err = Semver.validRange(range)
|
||||
assert(ok, ("malformed %s range in %q: %s"):format(field, tostring(entry), tostring(err)))
|
||||
|
||||
local parsedGh = nil
|
||||
local rawGh = ghHint or sources[id]
|
||||
if rawGh then
|
||||
local okGh, cleanGh = pcall(Manifest.parseGithub, rawGh)
|
||||
if okGh and cleanGh then parsedGh = cleanGh end
|
||||
end
|
||||
|
||||
specs[#specs + 1] = { id = id, range = range, github = parsedGh }
|
||||
end
|
||||
return specs
|
||||
end
|
||||
|
||||
-- conflicts + incompatible (alias) merged, first-wins on duplicate ids
|
||||
local function mergeConflictLists(conflicts, incompatible)
|
||||
local seen, out = {}, {}
|
||||
@@ -248,8 +269,8 @@ function Manifest.validate(raw, path)
|
||||
optional_dependencies = array(raw.optional_dependencies),
|
||||
conflicts = conflicts,
|
||||
incompatible = array(raw.incompatible),
|
||||
dependencySpecs = parseSpecs(array(raw.dependencies), "dependencies"),
|
||||
optionalSpecs = parseSpecs(array(raw.optional_dependencies), "optional_dependencies"),
|
||||
dependencySpecs = parseSpecs(array(raw.dependencies), "dependencies", raw.dependency_sources),
|
||||
optionalSpecs = parseSpecs(array(raw.optional_dependencies), "optional_dependencies", raw.dependency_sources),
|
||||
conflictSpecs = parseSpecs(conflicts, "conflicts"),
|
||||
category = raw.category or "OTHER",
|
||||
game_version = raw.game_version,
|
||||
|
||||
Reference in New Issue
Block a user