Files
Web_FreeCAD_Bitbybit/scripts/check-camotics-gui-tpl.mjs

33 lines
2.8 KiB
JavaScript

import { createHash } from 'node:crypto'
import { execFileSync, spawnSync } from 'node:child_process'
import { readFile, stat } from 'node:fs/promises'
import { resolve } from 'node:path'
const root = resolve(new URL('..', import.meta.url).pathname)
const evidence = JSON.parse(await readFile(resolve(root, 'config/camotics-native-artifact.json'), 'utf8'))
const sha256 = (bytes) => createHash('sha256').update(bytes).digest('hex')
if (evidence.schemaVersion !== 2 || evidence.status !== 'pass' || evidence.build.withGui !== true || evidence.build.withTpl !== true) throw new Error('CAMotics GUI/TPL evidence is not passing.')
const revision = execFileSync('git', ['-C', resolve(root, evidence.source.path), 'rev-parse', 'HEAD'], { encoding: 'utf8' }).trim()
if (revision !== evidence.source.revision) throw new Error(`CAMotics GUI/TPL source revision drift: ${revision}`)
for (const [path, expected] of Object.entries(evidence.artifacts)) {
const absolute = resolve(root, path)
const bytes = await readFile(absolute)
const metadata = await stat(absolute)
const digest = sha256(bytes)
if (!metadata.isFile() || (metadata.mode & 0o111) === 0 || bytes.byteLength !== expected.bytes || digest !== expected.sha256) throw new Error(`CAMotics GUI/TPL artifact drift: ${path}`)
}
const runHelp = (binary, env = {}) => {
const result = spawnSync(resolve(root, binary), ['--help'], { encoding: 'utf8', env: { ...process.env, ...env } })
const output = `${result.stdout}${result.stderr}`
return { status: result.status, output }
}
const camotics = runHelp('CAMotics/camotics', { QT_QPA_PLATFORM: 'offscreen' })
const tplang = runHelp('CAMotics/tplang')
if (camotics.status !== 0 || tplang.status !== 0 || !camotics.output.includes('Usage:') || !tplang.output.includes('Usage:')) throw new Error('CAMotics GUI/TPL help smoke failed.')
if (evidence.guiSmoke.status !== 'pass' || evidence.guiSmoke.window.mapState !== 'IsViewable' || evidence.guiSmoke.window.width !== 1200 || evidence.guiSmoke.window.height !== 800 || evidence.guiSmoke.browserRuntime !== false) throw new Error('CAMotics GUI Xvfb smoke boundary is invalid.')
if (evidence.pipelineBoundary.workspaceNativeGuiAvailable !== true || evidence.pipelineBoundary.workspaceNativeTplAvailable !== true || evidence.pipelineBoundary.browserNativeGuiAvailable !== false || evidence.pipelineBoundary.browserNativeTplAvailable !== false || evidence.pipelineBoundary.canonicalGcodeParser !== 'linuxcnc-wasm') throw new Error('CAMotics GUI/TPL browser boundary is invalid.')
console.log(JSON.stringify({ status: 'camotics-gui-tpl-pass', sourceRevision: revision, version: evidence.source.version, artifacts: evidence.artifacts, smoke: { camotics: { exitCode: camotics.status }, tplang: { exitCode: tplang.status }, gui: evidence.guiSmoke }, browserBoundary: evidence.pipelineBoundary }, null, 2))