"""Sign an existing, prepared AFFECTOR release copy from the inside out.""" from pathlib import Path import argparse,subprocess p=argparse.ArgumentParser(description=__doc__);p.add_argument('--app',type=Path,required=True);p.add_argument('--identity',required=True);a=p.parse_args();app=a.app.resolve() if not (app/'Contents/Info.plist').is_file():raise SystemExit('Expected an existing .app bundle') framework=app/'Contents/Resources/Python.framework' for name,target in {'Versions/Current':'3.14','Python':'Versions/Current/Python','Resources':'Versions/Current/Resources','Headers':'Versions/Current/Headers'}.items(): link=framework/name if not link.exists() and not link.is_symlink():link.symlink_to(target) magic={bytes.fromhex(s) for s in ('cffaedfe','cefaedfe','feedfacf','feedface','cafebabe','cafebabf','bebafeca','bfbafeca')} def macho(path): if path.is_symlink() or not path.is_file():return False with path.open('rb') as f:return f.read(4) in magic def sign(path): r=subprocess.run(['codesign','--force','--sign',a.identity,'--timestamp','--options','runtime',str(path)],capture_output=True,text=True) if r.returncode:raise RuntimeError(str(path)+'\n'+r.stderr) binaries=sorted((x for x in app.rglob('*') if macho(x)),key=lambda x:len(x.parts),reverse=True) print('Signing',len(binaries),'native binaries',flush=True) for i,b in enumerate(binaries): sign(b) if (i+1)%25==0:print(i+1,'signed',flush=True) for b in sorted((x for x in app.rglob('*') if x.is_dir() and not x.is_symlink() and x.suffix in ('.app','.framework','.xpc','.appex')),key=lambda x:len(x.parts),reverse=True):sign(b) sign(app);subprocess.run(['codesign','--verify','--deep','--strict',str(app)],check=True) print('Signed and verified',app,flush=True)