- Introduced a Makefile for streamlined commands related to building, running, and managing presentations. - Created package.json to define project metadata, dependencies, and scripts for development and testing. - Added .gitignore entries to exclude build artifacts and temporary files from version control. - Included playwright.config.mjs for end-to-end testing setup with Playwright. - Added README.md for project documentation, outlining setup instructions and development guidelines.
94 lines
2.3 KiB
JavaScript
94 lines
2.3 KiB
JavaScript
#!/usr/bin/env node
|
|
/**
|
|
* make run : sync + build tous les decks, puis VitePress dev + watch slides/
|
|
* → rebuild ciblé + sync pour refléter les sources.
|
|
*/
|
|
import path from 'node:path'
|
|
import { fileURLToPath } from 'node:url'
|
|
import { spawn, execFileSync } from 'node:child_process'
|
|
import chokidar from 'chokidar'
|
|
import { listPresentationSlugs } from './list-slugs.mjs'
|
|
|
|
const __dirname = path.dirname(fileURLToPath(import.meta.url))
|
|
const root = path.resolve(__dirname, '..')
|
|
const slidesDir = path.join(root, 'slides')
|
|
|
|
/** Aligne sync, decks et VitePress sur base=/ (ignore SITE_BASE du .env). Voir tools/site-base.mjs */
|
|
const runEnv =
|
|
process.env.SKIP_PORTAL_DEV === '1'
|
|
? process.env
|
|
: { ...process.env, TALKS_PORTAL_DEV: '1' }
|
|
|
|
function sync() {
|
|
execFileSync(process.execPath, [path.join(root, 'tools', 'sync-portal.mjs')], {
|
|
stdio: 'inherit',
|
|
cwd: root,
|
|
env: runEnv,
|
|
})
|
|
}
|
|
|
|
function buildDeck(slug) {
|
|
execFileSync(process.execPath, [path.join(root, 'tools', 'build-deck.mjs'), slug], {
|
|
stdio: 'inherit',
|
|
cwd: root,
|
|
env: runEnv,
|
|
})
|
|
}
|
|
|
|
function buildAllDecks() {
|
|
const slugs = listPresentationSlugs(root)
|
|
for (const slug of slugs) buildDeck(slug)
|
|
}
|
|
|
|
sync()
|
|
buildAllDecks()
|
|
|
|
const pending = new Set()
|
|
let flushTimer = null
|
|
function flush() {
|
|
flushTimer = null
|
|
sync()
|
|
for (const slug of pending) {
|
|
try {
|
|
buildDeck(slug)
|
|
} catch {
|
|
/* build-deck a déjà loggé */
|
|
}
|
|
}
|
|
pending.clear()
|
|
}
|
|
|
|
chokidar
|
|
.watch(slidesDir, {
|
|
ignoreInitial: true,
|
|
ignored: (p) => path.basename(p).startsWith('.') || p.includes(`${path.sep}wip_`),
|
|
})
|
|
.on('all', (_evt, fp) => {
|
|
const rel = path.relative(slidesDir, fp)
|
|
const slug = rel.split(path.sep)[0]
|
|
if (!slug || slug.startsWith('wip_')) return
|
|
pending.add(slug)
|
|
clearTimeout(flushTimer)
|
|
flushTimer = setTimeout(flush, 450)
|
|
})
|
|
|
|
const vitepressBin = path.join(root, 'node_modules', '.bin', 'vitepress')
|
|
const child = spawn(vitepressBin, ['dev', 'portal'], {
|
|
cwd: root,
|
|
stdio: 'inherit',
|
|
env: runEnv,
|
|
shell: process.platform === 'win32',
|
|
})
|
|
|
|
function die() {
|
|
try {
|
|
child.kill('SIGTERM')
|
|
} catch {
|
|
/* ignore */
|
|
}
|
|
process.exit(0)
|
|
}
|
|
process.on('SIGINT', die)
|
|
process.on('SIGTERM', die)
|
|
child.on('exit', (code) => process.exit(code ?? 0))
|