"""Extend the immutable 41a5 QA tree; active application files are never edited.""" from pathlib import Path from datetime import datetime, timezone import json, shutil, subprocess, sys, re R=Path(__file__).resolve().parent.parent;P=R/'storage/app/private/investmoz-v2/portal-audit' old=json.loads((P/'onboarding-governance-plan.json').read_text(encoding='utf-8')) base=Path(old['source']);assert base.parent==P and old['target']['port']==55441 if len(sys.argv)>1: stamp=sys.argv[1];assert re.fullmatch(r'\d{8}_\d{6}',stamp) S=P/('onboarding-qa-internal-'+stamp);assert S.is_dir() and S.parent==P db='onboarding_internal_'+stamp+'_test' xml=(base/'onboarding-phpunit.xml').read_text(encoding='utf-8') xml=xml.replace(str(base).replace('\\','/'),str(S).replace('\\','/')).replace(str(base),str(S)).replace(old['target']['database'],db) (S/'phpunit.xml').write_text(xml,encoding='utf-8') plan={'at':datetime.now(timezone.utc).isoformat(),'source':str(S),'target':{'database':db,'host':'127.0.0.1','port':55441},'base_delta':'41a5ce778932','base_source':str(base),'active_application_changes':0,'active_database_writes':0} (P/'internal-designation-plan.json').write_text(json.dumps(plan,indent=2),encoding='utf-8') print(json.dumps(plan));raise SystemExit(0) stamp=datetime.now(timezone.utc).strftime('%Y%m%d_%H%M%S') S=P/('onboarding-qa-internal-'+stamp);S.mkdir() for folder in ['app','config','database','routes','resources','tests','bootstrap','public/build']: shutil.copytree(base/folder,S/folder) for file in ['artisan','qa-autoload.php','.env','public/index.php','composer.json','composer.lock','package.json','package-lock.json','tsconfig.json','vite.config.ts','components.json']: if (base/file).exists(): (S/file).parent.mkdir(parents=True,exist_ok=True);shutil.copyfile(base/file,S/file) for folder in ['storage/app/private','storage/logs','storage/framework/cache/data','storage/framework/sessions','storage/framework/views','bootstrap/cache']: (S/folder).mkdir(parents=True,exist_ok=True) for name,target in [('vendor',R/'vendor'),('node_modules',R/'node_modules')]: p=str(S/name).replace("'","''");t=str(target).replace("'","''") subprocess.run(['powershell.exe','-NoProfile','-Command',f"New-Item -ItemType Junction -Path '{p}' -Target '{t}' | Out-Null"],check=True,capture_output=True) db='onboarding_internal_'+stamp+'_test' php='C:/laragon/bin/php/php-8.5.11-Win32-vs17-x64/php.exe' create=S/'create-qa-database.php' create.write_text('''PDO::ERRMODE_EXCEPTION]); if((int)$p->query('SELECT inet_server_port()')->fetchColumn()!==55441 || !preg_match('/^onboarding_internal_\\d{8}_\\d{6}_test$/D',$argv[1]))throw new RuntimeException('QA refused'); $p->exec('CREATE DATABASE "'.$argv[1].'" OWNER investmoz_test'); ''',encoding='utf-8') subprocess.run([php,str(create),db],cwd=S,capture_output=True,check=True) env=(S/'.env').read_text(encoding='utf-8') env=env.replace(old['target']['database'],db).replace('http://127.0.0.1:18117','http://127.0.0.1:18118').replace('investmoz_onboarding_qa','investmoz_internal_onboarding_qa') (S/'.env').write_text(env,encoding='utf-8') xml=(base/'onboarding-phpunit.xml').read_text(encoding='utf-8') xml=xml.replace(str(base).replace('\\','/'),str(S).replace('\\','/')).replace(str(base),str(S)).replace(old['target']['database'],db) (S/'phpunit.xml').write_text(xml,encoding='utf-8') plan={'at':datetime.now(timezone.utc).isoformat(),'source':str(S),'target':{'database':db,'host':'127.0.0.1','port':55441}, 'base_delta':'41a5ce778932','base_source':str(base),'active_application_changes':0,'active_database_writes':0} (P/'internal-designation-plan.json').write_text(json.dumps(plan,indent=2),encoding='utf-8') print(json.dumps(plan))