/
githubmirror
/
node
Обзор
Документация
Войти
/
githubmirror
/
node
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
tools/doc/addon-verify.mjs
107 строк
3 KB
Anna Henningsen
src: officially deprecate `node::ObjectWrap`
14 июн 2026, 02:12
14 июн 2026, 02:12
fc28d94
Код
Авторство
О чём код?
#!/usr/bin/env node // Extracts C++ addon examples from doc/api/addons.md into numbered test // directories under test/addons/. // // Each code block to extract is preceded by a marker in the markdown: // // <!-- addon-verify-file worker_support/addon.cc [...] --> // ```cpp // #include <node.h> // ... // ``` // // This produces test/addons/01_worker_support/addon.cc. // Sections are numbered in order of first appearance. import { mkdirSync, writeFileSync } from 'node:fs'; import { open } from 'node:fs/promises'; import { join } from 'node:path'; import { parseArgs } from 'node:util'; const { values } = parseArgs({ options: { input: { type: 'string' }, output: { type: 'string' }, }, }); if (!values.input || !values.output) { console.error('Usage: addon-verify.mjs --input <file> --output <dir>'); process.exit(1); } const src = await open(values.input, 'r'); const MARKER_RE = /^<!--\s*addon-verify-file\s+(?<filenames>((\S+?)\/(\S+)\s?)+)\s*-->$/; const entries = []; let nextBlockIsAddonVerifyFile = false; let expectedClosingFenceMarker; for await (const line of src.readLines()) { if (expectedClosingFenceMarker) { // We're inside a Addon snippet if (line === expectedClosingFenceMarker) { // End of the snippet expectedClosingFenceMarker = null; continue; } entries.at(-1).contentRef.content += `${line}\n`; } if (nextBlockIsAddonVerifyFile) { if (line) { expectedClosingFenceMarker = line.replace(/\w/g, ''); nextBlockIsAddonVerifyFile = false; } continue; } const match = MARKER_RE.exec(line); if (match) { nextBlockIsAddonVerifyFile = true; const { filenames } = match.groups; // Use a single contentRef for files with identical contents const contentRef = { content: '' }; for (const filename of filenames.split(/\s+/).filter(Boolean)) { const [dir, name] = filename.split('/'); entries.push({ dir, name, contentRef }); } } } // Collect files grouped by section directory name. const sections = Map.groupBy(entries, (e) => e.dir); let idx = 0; for (const [name, files] of sections) { const dirName = `${String(++idx).padStart(2, '0')}_${name}`; const dir = join(values.output, dirName); mkdirSync(dir, { recursive: true }); for (const file of files) { let { content } = file.contentRef; if (file.name === 'test.js') { content = "'use strict';\n" + "const common = require('../../common');\n" + content.replace( "'./build/Release/addon'", // eslint-disable-next-line no-template-curly-in-string '`./build/${common.buildType}/addon`', ); } writeFileSync(join(dir, file.name), content); } // Generate binding.gyp const names = files.map((f) => f.name); writeFileSync(join(dir, 'binding.gyp'), JSON.stringify({ targets: [{ target_name: 'addon', sources: names, includes: ['../common.gypi'], }], })); console.log(`Generated ${dirName} with files: ${names.join(', ')}`); }