Count unique archives when estimating extraction space
Adapted from upstream PR #277 (841684012800327d6d6fa6b6fd79d3ab689c9751).
This commit is contained in:
1 parent
8d29a31d2b
commit
94dfd1655e
2 files changed
+38
-1
No files matched your search
@@ -0,0 +1,33 @@
|
||||
"""NSP extraction space estimate: distinct archives count even when they have the same size; the shared base counts once.
|
||||
No game files, keys or Xcode needed (temporary synthetic files only)."""
|
||||
import importlib.util
|
||||
from pathlib import Path
|
||||
import tempfile
|
||||
import unittest
|
||||
|
||||
REPO = Path(__file__).resolve().parents[3]
|
||||
spec = importlib.util.spec_from_file_location('build_ipa_from_nsp', REPO / 'scripts/build_ipa_from_nsp.py')
|
||||
nsp = importlib.util.module_from_spec(spec); spec.loader.exec_module(nsp)
|
||||
|
||||
|
||||
class Space(unittest.TestCase):
|
||||
def test_equal_sized_archives(self):
|
||||
with tempfile.TemporaryDirectory() as tmp:
|
||||
base, update = Path(tmp) / 'base.nsp', Path(tmp) / 'update.nsp'
|
||||
base.write_bytes(b'base'); update.write_bytes(b'updt')
|
||||
self.assertEqual(nsp.picked_nsp_bytes({'v1': (base, update)}), 8)
|
||||
|
||||
def test_shared_base(self):
|
||||
with tempfile.TemporaryDirectory() as tmp:
|
||||
base, first, second = [Path(tmp) / name for name in ('base.nsp', 'first.nsp', 'second.nsp')]
|
||||
base.write_bytes(b'base'); first.write_bytes(b'first'); second.write_bytes(b'second')
|
||||
self.assertEqual(nsp.picked_nsp_bytes({'v0': (base, None), 'v1': (base, first), 'v2': (base, second)}), 15)
|
||||
|
||||
def test_base_without_update(self):
|
||||
with tempfile.TemporaryDirectory() as tmp:
|
||||
base = Path(tmp) / 'base.nsp'; base.write_bytes(b'base')
|
||||
self.assertEqual(nsp.picked_nsp_bytes({'v0': (base, None)}), 4)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
@@ -490,6 +490,10 @@ def pick_nsps(fam, have, versions):
|
||||
return out
|
||||
|
||||
|
||||
def picked_nsp_bytes(picks): # count each archive once, not each distinct size (the base occurs in every version)
|
||||
return sum(p.stat().st_size for p in {p for base, update in picks.values() for p in (base, update) if p is not None})
|
||||
|
||||
|
||||
def can_clone(d): # whether this volume supports APFS clones (nx_extract uses them to save space; without them it writes full copies)
|
||||
a, b = d / '.clone_test', d / '.clone_test2'
|
||||
try:
|
||||
@@ -1750,7 +1754,7 @@ def main(args=None):
|
||||
picks = pick_nsps(fam, have, versions)
|
||||
|
||||
ex = work / 'extract'; ex.mkdir(parents=True, exist_ok=True); (work / 'tmp').mkdir(exist_ok=True)
|
||||
gb = sum({p.stat().st_size for b, u in picks.values() for p in (b, u) if p}) / 2**30 + 6 # extraction + shader cache + slack
|
||||
gb = picked_nsp_bytes(picks) / 2**30 + 6 # extraction + shader cache + slack
|
||||
if free_gb(work) < gb and not all((ex / v).exists() for v in versions): raise BuildError(f'less than {gb:.0f} GB free on the volume of {work}')
|
||||
heapck = provisional and HEAP_CHECK and not args.no_heap_check and not heap_checked(g) # the heap check, when the game needs one (once per provisional profile: it stamps the profile)
|
||||
PROG.plan(1 + len(versions) + bool(fam['dlc']) + 4 - (prepare_xcode or (mac and not mac_pack))) # prepare Xcode (a Mac-only build: the Mac host) replaces app build + IPA pack with one stage (a Mac app: Mac host + Mac app)
|
||||
|
||||
Reference in new issue
Block a user