mirror of
https://github.com/bryanthaboi/gen1recomp.git
synced 2026-08-15 07:41:21 +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:
@@ -138,7 +138,25 @@ check(not pcall(Manifest.parseGithub, "not a repo"),
|
||||
check(not pcall(Manifest.validate, {
|
||||
id = "badgh", name = "Bad", version = "1.0.0", entry = "main.lua",
|
||||
github = "ftp://example.com/x",
|
||||
}), "a bad github field fails manifest validation")
|
||||
}), "an unsupported github URL fails validation")
|
||||
|
||||
-- ------- dependency github repo spec hints & dependency resolver
|
||||
local depGh = Manifest.validate({
|
||||
id = "depgh", name = "DepGH", version = "1.0.0", entry = "main.lua",
|
||||
dependencies = { "colorlib@^1.2.0#Acme/ColorLib", "soundpack#Acme/SoundPack" },
|
||||
dependency_sources = { helper = "Acme/Helper" },
|
||||
})
|
||||
check(depGh.dependencySpecs[1].id == "colorlib" and depGh.dependencySpecs[1].github == "Acme/ColorLib",
|
||||
"dependency spec hash hint parses github owner/repo")
|
||||
check(depGh.dependencySpecs[2].id == "soundpack" and depGh.dependencySpecs[2].github == "Acme/SoundPack",
|
||||
"dependency spec hash hint without range parses github owner/repo")
|
||||
|
||||
local LauncherMods = require("src.mods.LauncherMods")
|
||||
local depCheck = LauncherMods.checkDependencies(depGh)
|
||||
check(depCheck.hasIssues == true, "missing dependencies trigger issues verdict")
|
||||
check(#depCheck.deps == 2, "dependency check lists all specs")
|
||||
check(depCheck.deps[1].status == "missing", "absent dependency reports missing")
|
||||
check(depCheck.deps[1].safeUrl == "https://github.com/Acme/ColorLib", "safeUrl built from validated github repo")
|
||||
|
||||
local v1 = Manifest.validate({
|
||||
id = "v1", name = "V1", version = "1.0.0", entry = "main.lua",
|
||||
@@ -519,8 +537,26 @@ local emptyLoader = Loader.new({ fs = memfs({}) })
|
||||
check(emptyLoader:load(pristine) == true, "an empty mods dir still loads clean")
|
||||
check(#emptyLoader:status().errors == 0, "no mods means no diagnostics")
|
||||
check(#emptyLoader.order == 0, "no mods means an empty load order")
|
||||
check(pristine.pokemon.A.hp == 1 and next(pristine.items) == nil,
|
||||
"no-mod load leaves data untouched")
|
||||
-- ------- dependency resolver conflict detection test
|
||||
local LauncherMods = require("src.mods.LauncherMods")
|
||||
local testTargetManifest = Manifest.validate({
|
||||
id = "new_mod",
|
||||
name = "New Mod",
|
||||
version = "1.0.0",
|
||||
entry = "main.lua",
|
||||
incompatible = { "colorlib" },
|
||||
}, "mods/new_mod")
|
||||
local installedColorlib = Manifest.validate({
|
||||
id = "colorlib",
|
||||
name = "Color Lib",
|
||||
version = "1.0.0",
|
||||
entry = "main.lua",
|
||||
}, "mods/colorlib")
|
||||
local depConflictCheck = LauncherMods.checkDependencies(testTargetManifest, nil, nil, { installedColorlib })
|
||||
check(depConflictCheck.hasIssues == true, "conflict with colorlib triggers hasIssues")
|
||||
check(#depConflictCheck.deps == 1 and depConflictCheck.deps[1].status == "conflict",
|
||||
"incompatible mod is flagged as status conflict")
|
||||
check(depConflictCheck.deps[1].kind == "conflict", "conflict item carries kind conflict")
|
||||
|
||||
Runtime.install(savedEvents, savedHooks)
|
||||
|
||||
|
||||
@@ -1162,6 +1162,18 @@ seedOpts.modProfiles = {}
|
||||
ModProfile.ensureFirst(seedOpts, ms.status.available, {})
|
||||
check(#seedOpts.modProfiles == 0, "seeding never runs twice")
|
||||
|
||||
local LauncherMods = require("src.mods.LauncherMods")
|
||||
local testProfOpts = { activeProfile = "P1", modProfiles = { { name = "P1", enabled = { a = true } } } }
|
||||
local dupSnap = LauncherMods.duplicateProfile("P1", testProfOpts)
|
||||
check(dupSnap and dupSnap.name == "P1 (Copy)" and testProfOpts.activeProfile == "P1 (Copy)",
|
||||
"duplicateProfile creates P1 (Copy) and activates it")
|
||||
check(LauncherMods.renameProfile("P1 (Copy)", "RenamedP", testProfOpts) == true,
|
||||
"renameProfile renames active profile")
|
||||
check(testProfOpts.activeProfile == "RenamedP", "activeProfile updates on rename")
|
||||
check(LauncherMods.deleteProfile("RenamedP", testProfOpts) == true, "deleteProfile removes profile")
|
||||
check(#testProfOpts.modProfiles == 1 and testProfOpts.modProfiles[1].name == "P1", "only original profile remains")
|
||||
check(testProfOpts.activeProfile == "P1", "activeProfile falls back to remaining profile")
|
||||
|
||||
-- permissions rows
|
||||
local permy = manifest("permy", { permissions = { "network" } })
|
||||
local msP = ManagerState.new(managerGame(fakeLoader({ permy })))
|
||||
|
||||
Reference in New Issue
Block a user