Code coverage report for lib/commands/build.js

Statements: 100% (42 / 42)      Branches: 100% (28 / 28)      Functions: 100% (8 / 8)      Lines: 100% (42 / 42)      Ignored: none     

All files » lib/commands/ » build.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121    24           24 24   24 13                               12 1 1                       24 15 15 15 15             15   24 18 2 1   1     16     24 16 5     16 6 10 6 4 3   1       15 14 3 3     24 5     24 5 7           24 24 17                                    
'use strict';
 
var streamArray = require('stream-array'),
  fs = require('fs'),
  vfs = require('vinyl-fs'),
  chokidar = require('chokidar'),
  debounce = require('debounce');
 
module.exports = build;
module.exports.description = 'build documentation';
 
module.exports.parseArgs = function (yargs) {
  var argv = addOutputArgs(yargs)
  .option('format', {
    alias: 'f',
    default: 'json',
    choices: ['json', 'md', 'html']
  })
  .option('output', {
    describe: 'output location. omit for stdout, otherwise is a filename ' +
      'for single-file outputs and a directory name for multi-file outputs like html',
    default: 'stdout',
    alias: 'o'
  })
  .example('$0 build foo.js -f md > API.md', 'parse documentation in a ' +
    'file and generate API documentation as Markdown')
  .argv;
 
  if (argv.f === 'html' && argv.o === 'stdout') {
    yargs.showHelp();
    throw new Error('The HTML output mode requires a destination directory set with -o');
  }
};
 
/*
 * The `build` command.  Requires either `--output` or the `callback` argument.
 * If the callback is provided, it is called with (error, formattedResult);
 * otherwise, formatted results are outputted based on the value of `--output`.
 *
 * The former case, with the callback, is used by the `serve` command, which is
 * just a thin wrapper around this one.
 */
function build(documentation, parsedArgs, callback) {
  var inputs = parsedArgs.inputs;
  var buildOptions = parsedArgs.commandOptions;
  var options = parsedArgs.options;
  var formatterOptions = {
    name: buildOptions.name || (options.package || {}).name,
    version: buildOptions['project-version'] || (options.package || {}).version,
    theme: buildOptions.theme,
    hljs: options.hljs || {}
  };
 
  var generator = documentation.bind(null, inputs, options, onDocumented);
 
  function onDocumented(err, comments) {
    if (err) {
      if (typeof callback === 'function') {
        return callback(err);
      }
      throw err;
    }
 
    documentation.formats[buildOptions.format](comments, formatterOptions, onFormatted);
  }
 
  function onFormatted(err, output) {
    if (buildOptions.watch) {
      updateWatcher();
    }
 
    if (typeof callback === 'function') {
      callback(null, output);
    } else if (buildOptions.output === 'stdout') {
      process.stdout.write(output);
    } else if (Array.isArray(output)) {
      streamArray(output).pipe(vfs.dest(buildOptions.output));
    } else {
      fs.writeFileSync(buildOptions.output, output);
    }
  }
 
  generator();
  if (buildOptions.watch) {
    var watcher = chokidar.watch(inputs);
    watcher.on('all', debounce(generator, 300));
  }
 
  function updateWatcher() {
    documentation.expandInputs(inputs, options, addNewFiles);
  }
 
  function addNewFiles(err, files) {
    watcher.add(files.map(function (data) {
      return data.file;
    }));
  }
}
 
// export this so `serve` can use it also
module.exports.addOutputArgs = addOutputArgs;
function addOutputArgs(yargs) {
  return yargs.option('theme', {
    describe: 'specify a theme: this must be a valid theme module',
    alias: 't'
  })
  .option('name', {
    describe: 'project name. by default, inferred from package.json'
  })
  .option('watch', {
    describe: 'watch input files and rebuild documentation when they change',
    alias: 'w',
    type: 'boolean'
  })
  .option('project-version', {
    describe: 'project version. by default, inferred from package.json'
  })
  .help('help');
}