mirror of
https://github.com/boykopovar/AnyPS5.git
synced 2026-11-05 13:20:11 +00:00
fix(tools): empty a reused audit work directory and report broken module links
Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
1 parent
aeaa3b58f0
commit
14f37caae6
2 files changed
+36
-2
No files matched your search
+5
-2
@@ -12,7 +12,8 @@ import unwrap_self
|
||||
DESCRIPTION = """Audit the imports of an extracted title before it is launched. Unwraps the dump's eboot.bin and the modules
|
||||
it ships (sce_module/, sce_modules/ and prx/, Unity's Media/Modules/ and Media/Plugins/, and .prx files beside
|
||||
eboot.bin) into a work directory, converts them with relinker --registry, and runs tools/import_audit.py on the
|
||||
registries with the unwrapped modules as --modules. The dump is only read. Exit code: that of import_audit.py, or 2
|
||||
registries with the unwrapped modules as --modules. The dump is only read; the source/ and output/ directories of a
|
||||
reused --work directory are emptied first. Exit code: that of import_audit.py, or 2
|
||||
when unwrapping or conversion fails."""
|
||||
|
||||
STANDARD_DIRECTORIES = ("sce_module", "sce_modules", "prx")
|
||||
@@ -35,7 +36,7 @@ def stage(source, destination):
|
||||
|
||||
|
||||
def modules_of(directory):
|
||||
return sorted(path for path in directory.iterdir() if path.is_file() and path.suffix.lower() in MODULE_SUFFIXES)
|
||||
return sorted(path for path in directory.iterdir() if (path.is_file() or path.is_symlink()) and path.suffix.lower() in MODULE_SUFFIXES)
|
||||
|
||||
|
||||
def prepare(dump, source, log=print):
|
||||
@@ -92,6 +93,8 @@ def main(argv=None):
|
||||
with tempfile.TemporaryDirectory() as temporary:
|
||||
work = Path(args.work) if args.work else Path(temporary)
|
||||
source, output = work / "source", work / "output"
|
||||
for generated in (source, output):
|
||||
shutil.rmtree(generated, ignore_errors=True)
|
||||
output.mkdir(parents=True, exist_ok=True)
|
||||
try:
|
||||
module_directories, extra = prepare(dump, source)
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import contextlib
|
||||
import io
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
@@ -101,6 +102,36 @@ class AuditDumpTests(unittest.TestCase):
|
||||
self.assertEqual(argv[:2], [str(output / "app.libc.prx.guest.prx.registry.json"), str(output / "app.registry.json")])
|
||||
self.assertEqual(argv[2:], ["--libs", "libs-a", "--libs", "libs-b", "--modules", str(work / "source" / "sce_module"), "--json", "report.json"])
|
||||
|
||||
def test_a_reused_work_directory_does_not_audit_registries_left_by_an_earlier_run(self):
|
||||
work = self.root / "work"
|
||||
stale = work / "output" / "app.old.prx.guest.prx.registry.json"
|
||||
stale.parent.mkdir(parents=True)
|
||||
stale.write_text("[]")
|
||||
(work / "source" / "sce_module").mkdir(parents=True)
|
||||
(work / "source" / "sce_module" / "gone.prx").write_bytes(ELF)
|
||||
|
||||
def relink(command, capture_output, text):
|
||||
(Path(command[-1]).parent / "app.registry.json").write_text("[]")
|
||||
return subprocess.CompletedProcess(command, 0, "", "")
|
||||
|
||||
with mock.patch.object(subprocess, "run", side_effect=relink), mock.patch.object(audit_dump.import_audit, "main", return_value=0) as audit:
|
||||
code, _ = self.run_main(self.dump, "--relinker", self.relinker, "--libs", "libs", "--work", work)
|
||||
self.assertEqual(code, 0)
|
||||
self.assertEqual(audit.call_args.args[0][:2], [str(work / "output" / "app.registry.json"), "--libs"])
|
||||
self.assertFalse((work / "source" / "sce_module" / "gone.prx").exists())
|
||||
|
||||
def test_a_broken_module_link_fails_instead_of_being_skipped(self):
|
||||
(self.dump / "sce_module").mkdir()
|
||||
try:
|
||||
os.symlink(self.dump / "sce_module" / "missing.prx", self.dump / "sce_module" / "libc.prx")
|
||||
except OSError:
|
||||
self.skipTest("symbolic links unavailable")
|
||||
with mock.patch.object(subprocess, "run") as run:
|
||||
code, errors = self.run_main(self.dump, "--relinker", self.relinker, "--libs", "libs")
|
||||
self.assertEqual(code, 2)
|
||||
self.assertIn("libc.prx", errors)
|
||||
run.assert_not_called()
|
||||
|
||||
def test_a_relinker_failure_returns_2_with_its_message(self):
|
||||
with mock.patch.object(subprocess, "run", return_value=subprocess.CompletedProcess([], 3, "", "bad input")), mock.patch.object(audit_dump.import_audit, "main") as audit:
|
||||
code, errors = self.run_main(self.dump, "--relinker", self.relinker, "--libs", "libs")
|
||||
|
||||
Reference in new issue
Block a user