Files
Kaloyan DanchevandClaude Opus 4.6 cbea5a322f
CI / Identify a merged version PR (push) Canceled after 0s
CI / Rust checks, rendering, and native package (push) Canceled after 0s
CI / Publish release and Homebrew feed (push) Canceled after 0s
Release PR / Maintain Version Packages PR (push) Canceled after 0s
Merge Luma launcher fork into monorepo
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>
2026-10-24 11:52:55 +03:00

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'}.`,
);
}