CoolFace
Modelpublic

candypunk/NanoJev-Web

sourceHugging Faceotherupdated 4d agoView on Hugging Face
1likes26downloads
release.py38 linesDownload Raw Back to scripts
1"""Verify or export the exact public files listed in MANIFEST.json."""2import argparse,gzip,hashlib,json,tarfile3from pathlib import Path4ROOT=Path(__file__).resolve().parents[1]5FORBIDDEN={'.local','.runtime','.venv','node_modules','__pycache__','.git','runs','bench'}6def digest(path):7    h=hashlib.sha256()8    with path.open('rb') as f:9        for block in iter(lambda:f.read(8*1024*1024),b''):h.update(block)10    return h.hexdigest()11def verify():12    manifest=json.loads((ROOT/'MANIFEST.json').read_text())13    for name,info in manifest['files'].items():14        p=Path(name)15        if name=='bench.command' or p.is_absolute() or '..' in p.parts or set(p.parts)&FORBIDDEN or any(x.startswith('.env') for x in p.parts):raise ValueError('Forbidden manifest path')16        file=ROOT/p17        if file.is_symlink() or not file.is_file() or ROOT not in file.resolve().parents:raise ValueError('Release file missing or not a regular contained file')18        if file.stat().st_size!=info['bytes'] or digest(file)!=info['sha256']:raise ValueError('Release checksum mismatch: '+name)19    return manifest20 21def export(path,manifest):22    path=path.resolve()23    if path==ROOT or ROOT in path.parents:raise ValueError('Export outside the release directory')24    path.parent.mkdir(parents=True,exist_ok=True)25    if path.exists():raise ValueError('Output already exists; choose a new filename')26    with path.open('xb') as raw,gzip.GzipFile(filename='',fileobj=raw,mode='wb',mtime=0,compresslevel=6) as gz,tarfile.open(fileobj=gz,mode='w') as archive:27        for name in sorted([*manifest['files'],'MANIFEST.json']):28            file=ROOT/name;info=tarfile.TarInfo('NanoJev-Web/'+name)29            info.size=file.stat().st_size;info.mode=0o755 if name.endswith('.command') or name.endswith('.sh') else 0o64430            info.uid=info.gid=0;info.uname=info.gname='';info.mtime=031            with file.open('rb') as src:archive.addfile(info,src)32    checksum=digest(path);path.with_suffix(path.suffix+'.sha256').write_text(checksum+'  '+path.name+'\n')33    print(json.dumps({'archive':path.name,'bytes':path.stat().st_size,'sha256':checksum}))34if __name__=='__main__':35    p=argparse.ArgumentParser(description=__doc__);p.add_argument('--export',type=Path);a=p.parse_args();m=verify()36    print(json.dumps({'verified':True,'files':len(m['files']),'bytes':sum(i['bytes'] for i in m['files'].values())}))37    if a.export:export(a.export,m)38