VSEARCH / scripts /refresh.mjs
bep40's picture
Semantic search fix for VSEARCH (semantic-image-field):
d5530f7 verified
Raw History Blame Contribute Delete
3.61 kB
#!/usr/bin/env node
import { execFileSync } from 'node:child_process';
import { existsSync, readFileSync, rmSync, writeFileSync } from 'node:fs';
const REPO = 'bep40/semantic-image-field';
const CLONE = '/tmp/space';
const STABLE_BUNDLE = 'assets/index.js';
const STABLE_STYLE = 'assets/app.css';
const MIRROR = ['products.json', 'promos.json'];
const COMMITTABLE = ['index.html', 'public/catalogue', 'dist/catalogue', 'dist/assets', 'dist/share', 'public/share'];
const ok = m => console.log(`[refresh] ${m}`);
function run(command, args, { cwd = CLONE } = {}) {
return execFileSync(command, args, { cwd, encoding: 'utf8', stdio: ['ignore', 'pipe', 'pipe'], maxBuffer: 64 * 1024 * 1024 });
}
function shell(script, cwd = CLONE) { return run('bash', ['-lc', script], { cwd }); }
function git(...args) {
return run('git', ['-c', `http.extraheader=Authorization: Bearer ${process.env.HF_TOKEN}`, ...args]);
}
function main() {
if (!process.env.HF_TOKEN) throw new Error('HF_TOKEN required');
rmSync(CLONE, { recursive: true, force: true });
run('mkdir', ['-p', CLONE]);
run('git', ['clone', '-q', `--filter=blob:none`, '--no-checkout', `https://huggingface.co/spaces/${REPO}`], { cwd: '/' });
git('checkout', '-q', '-B', 'main', 'main');
ok('cloned');
shell('set -euo pipefail; npm install --silent --no-audit --no-fund');
ok('dependencies installed');
shell('set -euo pipefail; node scripts/sync-catalogue.mjs');
for (const file of MIRROR) {
const count = JSON.parse(readFileSync(`public/catalogue/${file}`, 'utf8')).length;
ok(`public/catalogue/${file}: ${count} entries`);
}
shell('set -euo pipefail; npm run build');
ok('built');
for (const file of MIRROR) {
const served = `dist/catalogue/${file}`;
const source = JSON.parse(readFileSync(`public/catalogue/${file}`, 'utf8')).length;
const built = JSON.parse(readFileSync(served, 'utf8')).length;
if (source !== built) throw new Error(`${served} has ${built} but mirror has ${source}`);
ok(`served mirror verified: ${file} (${built} entries)`);
}
const htmlPath = `${CLONE}/index.html`;
let html = readFileSync(htmlPath, 'utf8');
if (/\.\/dist\/assets\/index\.js\b/.test(html) && /\.\/dist\/assets\/app\.css\b/.test(html)) {
ok('index.html already references stable bundle');
} else {
let next = html.replace(/(\.\/dist\/assets\/)index-[A-Za-z0-9_-]+\.js\b/g, `$1${STABLE_BUNDLE.slice('assets/'.length)}`);
next = next.replace(/(\.\/dist\/assets\/)index-[A-Za-z0-9_-]+\.css\b/g, `$1${STABLE_STYLE.slice('assets/'.length)}`);
if (next === html) throw new Error('index.html names bundle in unexpected way');
writeFileSync(htmlPath, next);
ok('index.html repointed to ' + STABLE_BUNDLE);
}
for (const asset of [STABLE_BUNDLE, STABLE_STYLE]) {
if (!existsSync(`${CLONE}/dist/${asset}`)) throw new Error(`dist/${asset} missing`);
}
const commit = shell(`set -euo pipefail;
git config user.name "semantic-image-field refresh";
git config user.email "refresh@hf.space";
git add -- ${COMMITTABLE.map(p => `'${p}'`).join(' ')};
if git diff --cached --quiet; then echo NOCHANGE; else git commit -q -m "chore: rebuild with semantic search fix"; echo COMMITTED; fi`).trim();
if (commit.includes('COMMITTED')) {
git('push', '-q', 'origin', 'main');
ok('pushed — the static Space will rebuild');
} else {
ok(`no change needed (HEAD ${shell('git rev-parse --short HEAD').trim()})`);
}
console.log('REFRESH_OK');
}
try { main(); }
catch (e) { console.error('REFRESH_FAILED:', e.message, e.stderr || ''); process.exitCode = 1; }