UNPKG

documentation

Version:
105 lines (94 loc) 3.22 kB
'use strict'; const fs = require('fs'); const remark = require('remark'); const path = require('path'); const documentation = require('../'); const sharedOptions = require('./shared_options'); const inject = require('mdast-util-inject'); const chalk = require('chalk'); const disparity = require('disparity'); module.exports.command = 'readme [input..]'; module.exports.description = 'inject documentation into your README.md'; /** * Add yargs parsing for the readme command * @param {Object} yargs module instance * @returns {Object} yargs with options * @private */ module.exports.builder = Object.assign({}, sharedOptions.sharedOutputOptions, sharedOptions.sharedInputOptions, { 'readme-file': { describe: 'The markdown file into which to inject documentation', default: 'README.md' }, section: { alias: 's', describe: 'The section heading after which to inject generated documentation', required: true }, 'diff-only': { alias: 'd', describe: 'Instead of updating the given README with the generated documentation,' + ' just check if its contents match, exiting nonzero if not.', default: false }, quiet: { alias: 'q', describe: 'Quiet mode: do not print messages or README diff to stdout.', default: false } }); /** * Insert API documentation into a Markdown readme * @private * @param {Object} argv args from the CLI option parser * @returns {undefined} has the side-effect of writing a file or printing to stdout */ module.exports.handler = function readme(argv) { argv._handled = true; if (!argv.input.length) { try { argv.input = [JSON.parse(fs.readFileSync(path.resolve('package.json'), 'utf8')).main || 'index.js']; } catch (e) { throw new Error('documentation was given no files and was not run in a module directory'); } } argv.noReferenceLinks = true; argv.format = 'remark'; /* eslint no-console: 0 */ const log = (...data) => { if (!argv.q) { console.log.apply(console, data); } }; const readmeContent = fs.readFileSync(argv.readmeFile, 'utf8'); documentation.build(argv.input, argv).then(comments => documentation.formats.remark(comments, argv)).then(docsAst => remark().use(plugin, { section: argv.section, toInject: JSON.parse(docsAst) }).process(readmeContent)).then(file => { const diffOutput = disparity.unified(readmeContent, file.contents, { paths: [argv.readmeFile, argv.readmeFile] }); if (!diffOutput.length) { log(`${argv.readmeFile} is up to date.`); process.exit(0); } if (argv.d) { log(chalk.bold(`${argv.readmeFile} needs the following updates:`), `\n${diffOutput}`); process.exit(1); } else { log(chalk.bold(`Updating ${argv.readmeFile}`), `\n${diffOutput}`); } fs.writeFileSync(argv.readmeFile, file.contents); }).catch(err => { console.error(err); process.exit(1); }); }; // wrap the inject utility as an remark plugin function plugin(options) { return function transform(targetAst, file, next) { if (!inject(options.section, targetAst, options.toInject)) { return next(new Error(`Heading ${options.section} not found.`)); } next(); }; }