47 lines
2.6 KiB
Python
47 lines
2.6 KiB
Python
import hashlib
|
|
import json
|
|
import os
|
|
import pathlib
|
|
import shutil
|
|
import subprocess
|
|
import time
|
|
|
|
root = pathlib.Path(__file__).resolve().parents[2]
|
|
local = root/'.local'
|
|
evidence = pathlib.Path(__file__).resolve().parent
|
|
out = evidence/'binary-compression-records.jsonl'
|
|
assert not out.exists(), 'Refuse to overwrite earlier compression records'
|
|
skip = {'toolchain', 'linux-qa', 'cross-linux-qa', 'package-font-tools'}
|
|
files = []
|
|
for base, dirs, names in os.walk(local, followlinks=False):
|
|
base = pathlib.Path(base)
|
|
dirs[:] = [d for d in dirs if d not in skip and d != 'incremental' and not (base/d).is_symlink()]
|
|
for name in names:
|
|
p = base/name
|
|
if p.suffix.lower() == '.exe' and not p.is_symlink() and p.stat().st_size > 1024*1024:
|
|
assert p.resolve().is_relative_to(local.resolve())
|
|
files.append(p)
|
|
files.sort(key=lambda p: p.stat().st_size, reverse=True)
|
|
(evidence/'binary-compression-candidates.json').write_text(json.dumps(
|
|
[{'path':p.relative_to(root).as_posix(),'bytes':p.stat().st_size} for p in files],indent=2)+'\n',encoding='utf8')
|
|
started=time.time()
|
|
free_before=shutil.disk_usage(root).free
|
|
print(json.dumps({'state':'running','candidates':len(files),'logicalBytes':sum(p.stat().st_size for p in files),'freeBefore':free_before}),flush=True)
|
|
def sha(p):
|
|
with p.open('rb') as f:
|
|
return hashlib.file_digest(f,'sha256').hexdigest()
|
|
with out.open('x',encoding='utf8') as records, (evidence/'binary-compression.log').open('x',encoding='utf8') as log:
|
|
for i,p in enumerate(files,1):
|
|
before=sha(p)
|
|
process=subprocess.run(['compact.exe','/C','/EXE:XPRESS8K','/Q',str(p)],stdout=subprocess.PIPE,stderr=subprocess.STDOUT)
|
|
log.write(process.stdout.decode('utf-8',errors='replace'));log.flush()
|
|
after=sha(p)
|
|
record={'path':p.relative_to(root).as_posix(),'bytes':p.stat().st_size,'shaBefore':before,'shaAfter':after,'exitCode':process.returncode}
|
|
records.write(json.dumps(record)+'\n');records.flush()
|
|
assert process.returncode == 0 and before == after, record
|
|
if i%25 == 0:
|
|
print(json.dumps({'completed':i,'total':len(files),'freeBytes':shutil.disk_usage(root).free}),flush=True)
|
|
result={'state':'complete','files':len(files),'allHashesUnchanged':True,'freeBefore':free_before,'freeAfter':shutil.disk_usage(root).free,'seconds':time.time()-started,'operation':'NTFS executable compression of generated project binaries; no deletions'}
|
|
(evidence/'binary-compression-result.json').write_text(json.dumps(result,indent=2)+'\n',encoding='utf8')
|
|
print(json.dumps(result),flush=True)
|