#!/usr/bin/env node /** * Dependencies. */ var chalk = require('chalk'); var exists = require('fs').existsSync; var Metalsmith = require('..'); var program = require('commander'); var resolve = require('path').resolve; /** * Usage. */ program .version(require('../package.json').version) .option('-c, --config ', 'configuration file location', 'metalsmith.json'); /** * Examples. */ program.on('--help', function(){ console.log(' Examples:'); console.log(); console.log(' # build from metalsmith.json:'); console.log(' $ metalsmith'); console.log(); console.log(' # build from lib/config.json:'); console.log(' $ metalsmith --config lib/config.json'); console.log(); }); /** * Parse. */ program.parse(process.argv); /** * Config. */ var dir = process.cwd(); var config = program.config; var path = resolve(dir, config); if (!exists(path)) fatal('could not find a ' + config + ' configuration file.'); try { var json = require(path); } catch (e) { fatal('it seems like ' + config + ' is malformed.'); } /** * Metalsmith. */ var metalsmith = new Metalsmith(dir); if (json.source) metalsmith.source(json.source); if (json.destination) metalsmith.destination(json.destination); if (json.concurrency) metalsmith.concurrency(json.concurrency); if (json.metadata) metalsmith.metadata(json.metadata); if (json.clean != null) metalsmith.clean(json.clean); if (json.frontmatter != null) metalsmith.frontmatter(json.frontmatter); /** * Plugins. */ normalize(json.plugins).forEach(function(plugin){ for (var name in plugin) { var opts = plugin[name]; var mod; try { var local = resolve(dir, name); var npm = resolve(dir, 'node_modules', name); if (exists(local) || exists(local + '.js')) { mod = require(local); } else if (exists(npm)) { mod = require(npm); } else { mod = require(name); } } catch (e) { fatal('failed to require plugin "' + name + '".'); } try { metalsmith.use(mod(opts)); } catch (e) { fatal('error using plugin "' + name + '"...', e.message + '\n\n' + e.stack); } } }); /** * Build. */ metalsmith.build(function(err){ if (err) return fatal(err.message, err.stack); log('successfully built to ' + metalsmith.destination()); }); /** * Log an error and then exit the process. * * @param {String} msg * @param {String} [stack] Optional stack trace to print. */ function fatal(msg, stack){ console.error(); console.error(chalk.red(' Metalsmith') + chalk.gray(' · ') + msg); if (stack) { console.error(); console.error(chalk.gray(stack)); } console.error(); process.exit(1); } /** * Log a `message`. * * @param {String} message */ function log(message){ console.log(); console.log(chalk.gray(' Metalsmith · ') + message); console.log(); } /** * Normalize an `obj` of plugins. * * @param {Array or Object} obj * @return {Array} */ function normalize(obj){ if (obj instanceof Array) return obj; var ret = []; for (var key in obj) { var plugin = {}; plugin[key] = obj[key]; ret.push(plugin); } return ret; }