|
| 1 | +#!/usr/bin/env node |
| 2 | +/** |
| 3 | + * docs:gen-meta — Pre-build metadata generator for VitePress docs. |
| 4 | + * |
| 5 | + * Checks that the environment is ready (PHP installed, composer dependencies |
| 6 | + * present, bin/spc executable), then runs: |
| 7 | + * bin/spc dev:gen-deps-data → docs/.vitepress/deps-data.json |
| 8 | + * bin/spc dev:gen-ext-docs → docs/.vitepress/ext-data.json |
| 9 | + */ |
| 10 | + |
| 11 | +'use strict' |
| 12 | + |
| 13 | +const { execSync, spawnSync } = require('child_process') |
| 14 | +const fs = require('fs') |
| 15 | +const path = require('path') |
| 16 | + |
| 17 | +// __dirname is docs/.vitepress/, so two levels up is the project root |
| 18 | +const ROOT = path.resolve(__dirname, '../..') |
| 19 | + |
| 20 | +function fail(msg) { |
| 21 | + console.error(`\x1b[31m[gen-meta] ERROR: ${msg}\x1b[0m`) |
| 22 | + process.exit(1) |
| 23 | +} |
| 24 | + |
| 25 | +function info(msg) { |
| 26 | + console.log(`\x1b[36m[gen-meta] ${msg}\x1b[0m`) |
| 27 | +} |
| 28 | + |
| 29 | +function ok(msg) { |
| 30 | + console.log(`\x1b[32m[gen-meta] ${msg}\x1b[0m`) |
| 31 | +} |
| 32 | + |
| 33 | +// --- 1. Check PHP ------------------------------------------------------------ |
| 34 | +info('Checking PHP installation...') |
| 35 | +const phpResult = spawnSync('php', ['--version'], { encoding: 'utf8' }) |
| 36 | +if (phpResult.status !== 0 || phpResult.error) { |
| 37 | + fail( |
| 38 | + 'PHP is not installed or not in PATH.\n' + |
| 39 | + ' Please install PHP 8.1+ and ensure it is available in your PATH.' |
| 40 | + ) |
| 41 | +} |
| 42 | +const phpVersion = phpResult.stdout.split('\n')[0].trim() |
| 43 | +ok(`Found: ${phpVersion}`) |
| 44 | + |
| 45 | +// --- 2. Check composer CLI --------------------------------------------------- |
| 46 | +info('Checking composer...') |
| 47 | +const composerCheck = spawnSync('composer', ['--version'], { encoding: 'utf8' }) |
| 48 | +if (composerCheck.status !== 0 || composerCheck.error) { |
| 49 | + fail( |
| 50 | + 'composer is not installed or not in PATH.\n' + |
| 51 | + ' Please install Composer: https://getcomposer.org/download/' |
| 52 | + ) |
| 53 | +} |
| 54 | +ok(`Found: ${composerCheck.stdout.split('\n')[0].trim()}`) |
| 55 | + |
| 56 | +// --- 3. Install composer dependencies if missing ---------------------------- |
| 57 | +info('Checking composer dependencies...') |
| 58 | +const autoload = path.join(ROOT, 'vendor', 'autoload.php') |
| 59 | +if (!fs.existsSync(autoload)) { |
| 60 | + info('vendor/autoload.php not found — running composer install --no-dev ...') |
| 61 | + const installResult = spawnSync('composer', ['install', '--no-dev'], { |
| 62 | + cwd: ROOT, |
| 63 | + stdio: 'inherit', |
| 64 | + }) |
| 65 | + if (installResult.status !== 0) { |
| 66 | + fail('composer install --no-dev failed (exit code ' + installResult.status + ').') |
| 67 | + } |
| 68 | + ok('Composer dependencies installed.') |
| 69 | +} else { |
| 70 | + ok('Composer vendor directory found.') |
| 71 | +} |
| 72 | + |
| 73 | +// --- 4. Check bin/spc -------------------------------------------------------- |
| 74 | +info('Checking bin/spc...') |
| 75 | +const spc = path.join(ROOT, 'bin', 'spc') |
| 76 | +if (!fs.existsSync(spc)) { |
| 77 | + fail('bin/spc not found. Make sure you are in the project root.') |
| 78 | +} |
| 79 | +// Quick sanity check — list commands |
| 80 | +const spcCheck = spawnSync('php', [spc, 'list', '--format=txt'], { |
| 81 | + cwd: ROOT, |
| 82 | + encoding: 'utf8', |
| 83 | + env: { ...process.env, SPC_EXECUTION_SOURCE: '1' }, |
| 84 | +}) |
| 85 | +if (spcCheck.status !== 0) { |
| 86 | + fail( |
| 87 | + 'bin/spc failed to run.\n' + |
| 88 | + (spcCheck.stderr ?? '') + |
| 89 | + '\n Make sure PHP extensions required by static-php-cli are available.' |
| 90 | + ) |
| 91 | +} |
| 92 | +ok('bin/spc is operational.') |
| 93 | + |
| 94 | +// --- 5. Run dev:gen-deps-data ------------------------------------------------ |
| 95 | +info('Running bin/spc dev:gen-deps-data ...') |
| 96 | +const depsResult = spawnSync('php', [spc, 'dev:gen-deps-data'], { |
| 97 | + cwd: ROOT, |
| 98 | + stdio: 'inherit', |
| 99 | + env: { ...process.env, SPC_EXECUTION_SOURCE: '1' }, |
| 100 | +}) |
| 101 | +if (depsResult.status !== 0) { |
| 102 | + fail('dev:gen-deps-data failed (exit code ' + depsResult.status + ').') |
| 103 | +} |
| 104 | +ok('deps-data.json generated.') |
| 105 | + |
| 106 | +// --- 6. Run dev:gen-ext-docs ------------------------------------------------- |
| 107 | +info('Running bin/spc dev:gen-ext-docs ...') |
| 108 | +const extResult = spawnSync('php', [spc, 'dev:gen-ext-docs'], { |
| 109 | + cwd: ROOT, |
| 110 | + stdio: 'inherit', |
| 111 | + env: { ...process.env, SPC_EXECUTION_SOURCE: '1' }, |
| 112 | +}) |
| 113 | +if (extResult.status !== 0) { |
| 114 | + fail('dev:gen-ext-docs failed (exit code ' + extResult.status + ').') |
| 115 | +} |
| 116 | +ok('ext-data.json generated.') |
| 117 | + |
| 118 | +ok('Metadata generation complete. Proceeding to VitePress build...') |
0 commit comments