23 lines
3.3 KiB
JavaScript
23 lines
3.3 KiB
JavaScript
import fs from 'node:fs';
|
|
import path from 'node:path';
|
|
import crypto from 'node:crypto';
|
|
import assert from 'node:assert/strict';
|
|
|
|
// Stage/install tested code only. This tool cannot enable a feature or grant a right.
|
|
const apply=process.argv[2]==='--apply';assert(apply||!process.argv[2]);
|
|
const hash=f=>crypto.createHash('sha256').update(fs.readFileSync(f)).digest('hex');
|
|
const run=JSON.parse(fs.readFileSync('C:/laragon/data/sgf-tempo/run/modular-regression-current.json'));assert.equal(run.id,'2576427d1939');
|
|
const state=JSON.parse(fs.readFileSync(path.join(run.root,'private/receipt-composition-cc50a276c10c/state.json')));assert.equal(state.tag,'cc50a276c10c');assert.equal(state.singleInstallation,true);
|
|
assert.equal(JSON.parse(fs.readFileSync(path.join(state.root,'demo-server.json'))).port,8085);
|
|
const evidence=JSON.parse(fs.readFileSync(path.join(run.root,'private/stock-operations-proof-30defb954337/result.json')));assert(evidence.passed);
|
|
for(const [f,pin]of Object.entries(evidence.source_hashes))assert.equal(hash(f),pin,'Tested source changed: '+f);
|
|
const files=['app/Modules/Inventory/StockOperationsController.php','app/Modules/Purchasing/ReceiptRuntime.php','app/Modules/Identity/Services/IdentityWorkflow.php','app/Shared/Context/ModuleNavigation.php','routes/web.php','config/stock_operations.php','resources/views/stock-operations-workspace.blade.php','public/stock-operations-workspace.mjs','resources/js/StockMenuWorkspace.jsx','packages/inventory-issue/releases/0.1.0/manifest.json','packages/inventory-issue/releases/0.1.0/bootstrap.php','packages/inventory-issue/releases/0.1.0/src/IssueMovementWriter.php'];
|
|
assert.equal(fs.readFileSync('config/stock_operations.php','utf8').includes("'enabled' => false"),true);
|
|
const source=Object.fromEntries(files.map(f=>[f,hash(f)]));const before=Object.fromEntries(files.map(f=>[f,fs.existsSync(path.join(state.app,f))?hash(path.join(state.app,f)):null]));
|
|
const id=crypto.createHash('sha256').update(JSON.stringify({source,before})).digest('hex').slice(0,20);const dest=path.join(state.root,'prepared-stock-operations',id);fs.mkdirSync(dest,{recursive:true});
|
|
for(const f of files){const target=path.join(dest,'files',f);fs.mkdirSync(path.dirname(target),{recursive:true});fs.copyFileSync(f,target);}
|
|
const result={id,composition:state.tag,files:source,before,installed:false,enabled:false,rights_granted:false,new_database:false,new_server:false};
|
|
if(apply){const copied=[];try{for(const f of files){const target=path.join(state.app,f);assert.equal(fs.existsSync(target)?hash(target):null,before[f],'Preserve concurrent change');if(before[f]!==null){const save=path.join(dest,'before',f);fs.mkdirSync(path.dirname(save),{recursive:true});fs.copyFileSync(target,save);}fs.mkdirSync(path.dirname(target),{recursive:true});fs.copyFileSync(path.join(dest,'files',f),target);assert.equal(hash(target),source[f]);copied.push(f);}result.installed=true;}catch(error){for(const f of copied.reverse()){const target=path.join(state.app,f);if(hash(target)!==source[f])continue;if(before[f]===null)fs.unlinkSync(target);else fs.copyFileSync(path.join(dest,'before',f),target);}throw error;}}
|
|
fs.writeFileSync(path.join(dest,apply?'installation.json':'review.json'),JSON.stringify(result,null,2));
|
|
console.log(JSON.stringify({id,installed:result.installed,enabled:false,rights_granted:false,files:files.length}));
|