node/tools/doc/addon-verify.js
Rod Vagg d5d024d6ec Revert "build,tools: check freshness of doc addons"
This reverts commit 2cb9e2a6f7.

Reverted along with d9b59def7 as this introduces freshness checks that
are too stringent without the comprehensive dependency checking of
introduced in d9b59def7 so `make test` won't work with this.

Ref: https://github.com/nodejs/node/pull/17407
PR-URL: https://github.com/nodejs/node/pull/18287
Reviewed-By: Gireesh Punathil <gpunathi@in.ibm.com>
Reviewed-By: Richard Lau <riclau@uk.ibm.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
2018-01-25 08:17:53 +11:00

110 lines
2.9 KiB
JavaScript

'use strict';
const { strictEqual } = require('assert');
const fs = require('fs');
const path = require('path');
const marked = require('marked');
const auto = 'Auto-generated by `node tools/doc/addon-verify.js`';
const rootDir = path.resolve(__dirname, '..', '..');
const doc = path.resolve(rootDir, 'doc', 'api', 'addons.md');
const verifyDir = path.resolve(rootDir, 'test', 'addons');
let id = 0;
let currentHeader;
const addons = {};
const content = fs.readFileSync(doc, 'utf8');
for (const { text, type } of marked.lexer(content)) {
if (type === 'heading' && text) {
currentHeader = text;
addons[currentHeader] = {
files: {}
};
}
if (type === 'code') {
const match = text.match(/^\/\/\s+(.*\.(?:cc|h|js))[\r\n]/);
if (match !== null) {
addons[currentHeader].files[match[1]] = text;
}
}
}
for (const header in addons) {
let { files } = addons[header];
// must have a .cc and a .js to be a valid test
if (!Object.keys(files).some((name) => /\.cc$/.test(name)) ||
!Object.keys(files).some((name) => /\.js$/.test(name))) {
continue;
}
const blockName = header
.toLowerCase()
.replace(/\s/g, '_')
.replace(/[^a-z\d_]/g, '');
const dir = path.resolve(
verifyDir,
`${(++id < 10 ? '0' : '') + id}_${blockName}`
);
files = Object.entries(files).map(([name, content]) => {
if (name === 'test.js') content = boilerplate(name, content);
content = `// ${auto}\n${content}`;
if (name.endsWith('.h')) {
content = content.replace(/(#(ifndef|define) \w+_H)/g,
'$1 // NOLINT(build/header_guard)');
content = content.replace(/(#endif)$/,
'$1 // NOLINT(build/header_guard)');
}
if (!content.endsWith('\n')) content += '\n'; // Pacify linter.
return { name, content, path: path.resolve(dir, name) };
});
files.push({
path: path.resolve(dir, 'binding.gyp'),
content: `# ${auto}\n` + JSON.stringify({
targets: [
{
target_name: 'binding',
defines: [ 'V8_DEPRECATION_WARNINGS=1' ],
sources: files.map(function(file) {
return file.name;
})
}
]
})
});
try {
fs.mkdirSync(dir);
} catch (e) {
strictEqual(e.code, 'EEXIST');
}
for (const file of files) {
let content;
try {
content = fs.readFileSync(file.path, 'utf8');
} catch (e) {
strictEqual(e.code, 'ENOENT');
}
// Only update when file content has changed to prevent unneeded rebuilds.
if (content !== file.content) {
fs.writeFileSync(file.path, file.content);
console.log('wrote', file.path);
}
}
}
function boilerplate(name, content) {
return `'use strict';
const common = require('../../common');
${content.replace(
"'./build/Release/binding'",
// eslint-disable-next-line no-template-curly-in-string
'`./build/${common.buildType}/binding`')}
`;
}