#!/usr/bin/env node import { readFileSync, writeFileSync } from 'node:fs' import { parseVersion } from './changelog-version.mjs' // Mirrors the product entries of book_path() in projects/start-docs/build.sh. const PRODUCT_BOOKS = Object.freeze({ 'start-os': 'start-os', 'start-tunnel': 'start-tunnel', 'start-sdk': 'packaging', 'start-wrt': 'start-wrt', }) const LABELLED_BY_RELEASE = new Set(['start-os', 'start-wrt']) function bookOf(line) { return line === '' || line.startsWith('#') || line.includes('@') ? null : line.split('=')[0] } function bookLines(conf) { return new Map( conf .split('\n') .filter(line => bookOf(line) !== null) .map(line => [bookOf(line), line]), ) } export function releaseLabel(project, version) { const [[major, minor]] = parseVersion(project, version) return project === 'start-os' ? `0.${major}.${minor}.x` : `${major}.${minor}.x` } // Archives and non-product books follow the selected site tree. export function reconcile(tagged, published, project, version, site = tagged) { const own = PRODUCT_BOOKS[project] const ownLine = LABELLED_BY_RELEASE.has(project) ? `${own}=${releaseLabel(project, version)}` : bookLines(tagged).get(own) const others = Object.values(PRODUCT_BOOKS).filter(book => book !== own) const held = bookLines(published) const lines = site .trimEnd() .split('\n') .flatMap(line => { const book = bookOf(line) if (book === own) return [ownLine ?? line] if (others.includes(book)) return held.has(book) ? [held.get(book)] : [] return [line] }) const present = new Set(lines.map(bookOf)) for (const book of [own, ...others]) { const line = book === own ? ownLine : held.get(book) if (line !== undefined && !present.has(book)) lines.push(line) } const current = bookLines(lines.join('\n')) const reconciled = lines.filter(line => { const [entry, tag] = line.split('@') return !tag || current.get(bookOf(entry)) !== entry }) return `${reconciled.join('\n')}\n` } if (process.argv[1]?.endsWith('docs-versions.mjs')) { const [project, version, publishedPath, taggedPath, sitePath = taggedPath] = process.argv.slice(2) writeFileSync( sitePath, reconcile( readFileSync(taggedPath, 'utf8'), readFileSync(publishedPath, 'utf8'), project, version, readFileSync(sitePath, 'utf8'), ), ) }