#!/usr/bin/env node /* eslint-disable no-console */ /** * Dependencies. */ const chalk = require('chalk') const exists = require('fs').existsSync const Metalsmith = require('..') const program = require('commander') const 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. */ const dir = process.cwd() const config = program.config const path = resolve(dir, config) if (!exists(path)) fatal('could not find a ' + config + ' configuration file.') let json try { json = require(path) } catch (e) { fatal('it seems like ' + config + ' is malformed.') } /** * Metalsmith. */ const 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) if (json.ignore != null) metalsmith.ignore(json.ignore) /** * Plugins. */ normalize(json.plugins).forEach(function(plugin){ for (const name in plugin) { const opts = plugin[name] let mod try { const local = resolve(dir, name) const 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() // eslint-disable-next-line no-process-exit 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 const ret = [] for (const key in obj) { const plugin = {} plugin[key] = obj[key] ret.push(plugin) } return ret }