Move trampoline files (boot-hook, watcher, overlay) into trampoline/ subdirectory. Add upstream Luma v2.3.1 source at repo root with our additions: - Page::Ha (4th nav tab) with placeholder empty state - HA tab config schema and default entity mapping (ha-home/) - Nav keys renamed: "home" → "start", new "ha" tab between Apps and Settings - All state.rs/view.rs/main.rs/tests.rs updated for 4-tab navigation Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
90 lines
3.0 KiB
JavaScript
90 lines
3.0 KiB
JavaScript
import fs from 'node:fs/promises';
|
|
import path from 'node:path';
|
|
import { fileURLToPath } from 'node:url';
|
|
|
|
const root = path.resolve(import.meta.dirname, '..');
|
|
|
|
function replaceVersion(source, pattern, version, filename) {
|
|
if ([...source.matchAll(pattern)].length !== 1) {
|
|
throw new Error(`Expected one release version in ${filename}.`);
|
|
}
|
|
return source.replace(pattern, (_match, prefix, suffix) => `${prefix}${version}${suffix}`);
|
|
}
|
|
|
|
function updateTomlVersion(source, header, version, filename) {
|
|
let packages = 0;
|
|
const updated = source
|
|
.split(/(?=^\[)/m)
|
|
.map((section) => {
|
|
if (
|
|
section.split(/\r?\n/, 1)[0].trim() !== header ||
|
|
!/^name[ \t]*=[ \t]*"luma"[ \t]*\r?$/m.test(section)
|
|
) {
|
|
return section;
|
|
}
|
|
packages++;
|
|
return replaceVersion(
|
|
section,
|
|
/^([ \t]*version[ \t]*=[ \t]*")[^"\r\n]+(")/gm,
|
|
version,
|
|
filename,
|
|
);
|
|
})
|
|
.join('');
|
|
if (packages !== 1) throw new Error(`Expected one luma package in ${filename}.`);
|
|
return updated;
|
|
}
|
|
|
|
export async function syncVersions(directory = root, { check = false } = {}) {
|
|
const read = (filename) => fs.readFile(path.join(directory, filename), 'utf8');
|
|
const { version } = JSON.parse(await read('package.json'));
|
|
if (typeof version !== 'string' || !/^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)$/.test(version)) {
|
|
throw new Error('package.json must have a numeric major.minor.patch release version.');
|
|
}
|
|
|
|
const filenames = ['appinfo.json', 'Cargo.toml', 'Cargo.lock', 'readme.md'];
|
|
const sources = await Promise.all(filenames.map(read));
|
|
JSON.parse(sources[0]);
|
|
const ipkPattern = /\bcom\.ecklf\.luma_\d+\.\d+\.\d+_arm\.ipk\b/g;
|
|
if (![...sources[3].matchAll(ipkPattern)].length) {
|
|
throw new Error('Expected versioned Luma IPK examples in readme.md.');
|
|
}
|
|
const updated = [
|
|
replaceVersion(
|
|
sources[0],
|
|
/^([ \t]*"version"[ \t]*:[ \t]*")[^"\r\n]+(")/gm,
|
|
version,
|
|
'appinfo.json',
|
|
),
|
|
updateTomlVersion(sources[1], '[package]', version, 'Cargo.toml'),
|
|
updateTomlVersion(sources[2], '[[package]]', version, 'Cargo.lock'),
|
|
sources[3].replace(ipkPattern, `com.ecklf.luma_${version}_arm.ipk`),
|
|
];
|
|
const changed = filenames.filter((_filename, index) => sources[index] !== updated[index]);
|
|
if (check && changed.length) {
|
|
throw new Error(
|
|
`Release versions are out of sync: ${changed.join(', ')}. Run pnpm version:sync.`,
|
|
);
|
|
}
|
|
if (!check) {
|
|
await Promise.all(
|
|
filenames.map((filename, index) =>
|
|
sources[index] === updated[index]
|
|
? undefined
|
|
: fs.writeFile(path.join(directory, filename), updated[index]),
|
|
),
|
|
);
|
|
}
|
|
return { version, changed };
|
|
}
|
|
|
|
if (process.argv[1] && path.resolve(process.argv[1]) === fileURLToPath(import.meta.url)) {
|
|
const check = process.argv.includes('--check');
|
|
const { version, changed } = await syncVersions(root, { check });
|
|
console.log(
|
|
check
|
|
? `Release versions match ${version}.`
|
|
: `Synchronized ${version}: ${changed.join(', ') || 'no changes'}.`,
|
|
);
|
|
}
|