13 lines
4.5 KiB
JavaScript
13 lines
4.5 KiB
JavaScript
import fs from 'node:fs';import path from 'node:path';import net from 'node:net';import crypto from 'node:crypto';import {spawn,spawnSync} from 'node:child_process';
|
|
const [nativeTag,observerTag]=process.argv.slice(2);if(![nativeTag,observerTag].every(t=>/^[a-f0-9]{12}$/.test(t??'')))throw Error('Two explicit fresh QA identifiers required');
|
|
const run=JSON.parse(fs.readFileSync('C:/laragon/data/sgf-tempo/run/modular-regression-current.json')),nativeFile=path.join(run.root,'private/stock-ledger-'+nativeTag+'/settings.json'),observerFile=path.join(run.root,'private/stock-ledger-observer-'+observerTag+'/settings.json'),n=JSON.parse(fs.readFileSync(nativeFile)),o=JSON.parse(fs.readFileSync(observerFile)),php='C:/laragon/tools/sgf-tempo/php-8.4.27/php.exe',hash=f=>crypto.createHash('sha256').update(fs.readFileSync(f)).digest('hex');
|
|
if(o.source.database!==n.database||fs.existsSync(path.join(n.root,'demo-servers.json')))throw Error('Fresh matching source/observer required');
|
|
const bundle=path.join(n.root,'bundle'),files={};fs.mkdirSync(bundle);const copy=(from,to,relative)=>{fs.mkdirSync(path.dirname(to),{recursive:true});fs.copyFileSync(from,to);files[relative]=hash(to);};for(const pkg of ['payables','general-ledger']){copy('packages/'+pkg+'/bootstrap.php',path.join(bundle,pkg,'bootstrap.php'),pkg+'/bootstrap.php');for(const dir of ['src','ui']){const walk=p=>{for(const e of fs.readdirSync(p,{withFileTypes:true})){if(e.isSymbolicLink())throw Error('Bundle link refused');const f=path.join(p,e.name);if(e.isDirectory())walk(f);else{const relative=path.relative('packages',f).replaceAll('\\','/');copy(f,path.join(bundle,relative),relative);}}};walk('packages/'+pkg+'/'+dir);}}
|
|
copy('integrations/purchasing/StockValuationAdapter.php',path.join(bundle,'integrations/purchasing/StockValuationAdapter.php'),'integrations/purchasing/StockValuationAdapter.php');fs.writeFileSync(path.join(bundle,'manifest.json'),JSON.stringify({format:'sgf.stock-ledger.qa-runtime.v1',files},null,2));
|
|
n.ledger=path.join(bundle,'general-ledger');n.payables=path.join(bundle,'payables');n.adapter=path.join(bundle,'integrations/purchasing/StockValuationAdapter.php');n.bundle_manifest_sha256=hash(path.join(bundle,'manifest.json'));fs.writeFileSync(nativeFile,JSON.stringify(n,null,2));
|
|
const baseline=spawnSync(php,[path.resolve('scripts/stock-ledger-entry.php'),nativeFile,'demo-baseline'],{encoding:'utf8',windowsHide:true,timeout:30000});fs.writeFileSync(path.join(n.root,'baseline.log'),baseline.stdout+baseline.stderr);if(baseline.status!==0||!fs.existsSync(path.join(n.root,'demo-baseline.json')))throw Error('Fresh baseline failed');
|
|
o.public=path.join(o.storage,'public');fs.mkdirSync(o.public,{recursive:true});fs.writeFileSync(observerFile,JSON.stringify(o,null,2));const build=spawnSync(process.execPath,['node_modules/vite/bin/vite.js','build','--outDir',path.join(o.public,'build'),'--emptyOutDir'],{encoding:'utf8',windowsHide:true,timeout:120000,maxBuffer:2*1024*1024});fs.writeFileSync(path.join(o.root,'build.log'),build.stdout+build.stderr);if(build.status!==0)throw Error('Private SGF asset build failed');
|
|
const free=async start=>{for(let port=start;port<start+20;port++){const available=await new Promise(resolve=>{const server=net.createServer();server.once('error',()=>resolve(false));server.listen(port,'127.0.0.1',()=>server.close(()=>resolve(true)));});if(available)return port;}throw Error('No free dedicated proof port');};const nativePort=await free(8060),observerPort=await free(nativePort+1);
|
|
const launch=(root,router,port,settings,key,docroot)=>{const log=fs.openSync(path.join(root,'demo-server.log'),'a'),args=['-S','127.0.0.1:'+port,...(docroot?['-t',docroot]:[]),path.resolve(router)],child=spawn(php,args,{cwd:process.cwd(),detached:true,windowsHide:true,stdio:['ignore',log,log],env:{...process.env,[key]:settings}});child.unref();return child.pid;};
|
|
const nativePid=launch(n.root,'scripts/stock-ledger-http-router.php',nativePort,nativeFile,'STOCK_LEDGER_SETTINGS'),observerPid=launch(o.root,'scripts/stock-ledger-observer-router.php',observerPort,observerFile,'STOCK_OBSERVER_SETTINGS',o.public);const servers={native:{port:nativePort,pid:nativePid,entry:`http://127.0.0.1:${nativePort}/qa/stock`},sgf:{port:observerPort,pid:observerPid,entry:`http://127.0.0.1:${observerPort}/qa/stock-observer/reader?open=1`},native_tag:nativeTag,observer_tag:observerTag,bundle_manifest_sha256:n.bundle_manifest_sha256};fs.writeFileSync(path.join(n.root,'demo-servers.json'),JSON.stringify(servers,null,2));console.log(JSON.stringify(servers));
|