Files
SGF/scripts/launch-sgf.mjs
2026-11-11 09:00:17 +02:00

15 lines
3.2 KiB
JavaScript

import fs from 'node:fs';import path from 'node:path';import assert from 'node:assert/strict';import {spawnSync} from 'node:child_process';
const action=process.argv[2]??'start';assert(['start','status'].includes(action),'Only start/status; no reset, migration or provisioning');
const run=JSON.parse(fs.readFileSync('C:/laragon/data/sgf-tempo/run/modular-regression-current.json'));assert.equal(run.id,'2576427d1939');assert.equal(run.port,55439);const expected='C:/laragon/data/sgf-tempo/run/modular-regression-'+run.id;assert.equal(path.resolve(run.root),path.resolve(expected));assert.equal(path.resolve(run.cluster),path.resolve(expected+'/postgres'));assert.equal(path.resolve(fs.realpathSync(run.cluster)),path.resolve(run.cluster));
const s=JSON.parse(fs.readFileSync(expected+'/private/receipt-composition-cc50a276c10c/state.json'));assert.equal(s.tag,'cc50a276c10c');assert.equal(s.singleInstallation,true);const pg='C:/Program Files/PostgreSQL/17/bin/';
const call=(exe,args,options={})=>spawnSync(exe,args,{encoding:'utf8',windowsHide:true,...options});let status=call(pg+'pg_ctl.exe',['-D',run.cluster,'status']);assert([0,3].includes(status.status),'Owned database status unavailable; preserve its files');
if(status.status===3&&action==='start'){
const ready=call(pg+'pg_isready.exe',['-h','127.0.0.1','-p','55439']);assert.notEqual(ready.status,0,'Unexpected service on owned cluster port; do not replace it');
const started=call(pg+'pg_ctl.exe',['-D',run.cluster,'-l',expected+'/postgres.log','-w','-t','20','start']);assert.equal(started.status,0,'Existing database did not start; no recovery files were deleted');status=call(pg+'pg_ctl.exe',['-D',run.cluster,'status']);
}
if(status.status!==0){console.log(JSON.stringify({running:false,entry:'http://127.0.0.1:8085/sgf',new_database:false}));process.exit(2);}
const check=call(pg+'psql.exe',['-X','-h','127.0.0.1','-p','55439','-U',s.env.DB_USERNAME,'-d',s.env.DB_DATABASE,'-Atq','-v','ON_ERROR_STOP=1','-c',"BEGIN READ ONLY; SELECT current_database()||'|'||current_user||'|'||current_setting('cluster_name'); COMMIT;"],{env:{...process.env,PGPASSWORD:s.env.DB_PASSWORD}});assert.equal(check.status,0,'Selected application database unavailable');assert.equal(check.stdout.trim(),'budget_core_sgf_cc50a276c10c|ir_composition_cc50a276c10c|sgf_modular_regression_'+run.id,'Wrong database identity; no fallback');
if(action==='start'){const started=call('C:/laragon/tools/sgf-tempo/node-v24.22.1-win-arm64/node.exe',[path.resolve('scripts/purchasing-single-installation.mjs'),'start'],{cwd:path.resolve('.')});assert.equal(started.status,0,'Existing8085 application did not start');}
let response;for(let attempt=0;attempt<12;attempt++){try{response=await fetch('http://127.0.0.1:8085/sgf',{signal:AbortSignal.timeout(3000)});if(response.status===200)break;await response.text();}catch{}await new Promise(resolve=>setTimeout(resolve,250));}
assert(response&&response.status===200,'SGF entry did not become available');assert.equal(response.headers.get('x-sgf-installation'),s.tag);await response.text();console.log(JSON.stringify({running:true,entry:'http://127.0.0.1:8085/sgf',same_installation:true,sgc_required:false,new_database:false,new_demo:false,cache_cleared:false}));