UNPKG

4.42 kBJavaScriptView Raw
1'use strict'
2
3let clone = require('clone')
4let debug = require('debug')
5let empty = require('is-empty')
6let fs = require('mz/fs')
7let glob = require('globby')
8let merge = require('merge-array')
9let path = require('path')
10let Promise = require('bluebird')
11let resolve = require('resolve').sync
12let utils = require('mako-utils')
13
14// single export
15exports = module.exports = Promise.coroutine(load)
16exports.sync = loadSync
17
18/**
19 * Loads a mako configuration file.
20 *
21 * @param {String} file The absolute pathname to the config file to load.
22 * @param {Array} [overrides] User-supplied entries. (overrides config)
23 * @return {Object}
24 */
25function * load (file, overrides) {
26 debug('loading %s', utils.relative(file))
27 let config = JSON.parse(yield fs.readFile(file, 'utf8'))
28 let dir = path.dirname(file)
29 let env = process.env.NODE_ENV || 'development'
30
31 if (env in config) {
32 debug('merging env %s', env)
33 let envConf = config[env]
34 if (envConf.entries) merge(config.entries, envConf.entries)
35 if (envConf.plugins) merge(config.plugins, envConf.plugins)
36 }
37
38 let result = {
39 entries: yield normalizeEntries(overrides, config.entries, dir),
40 plugins: normalizePlugins(config.plugins, dir)
41 }
42 if (config.root) result.root = path.resolve(dir, config.root)
43 if (config.concurrency) result.concurrency = config.concurrency
44 debug('final config: %j', result)
45 return result
46}
47
48/**
49 * Synchronous version of load.
50 *
51 * @param {String} file The absolute pathname to the config file to load.
52 * @param {Array} [overrides] User-supplied entries. (overrides config)
53 * @return {Object}
54 */
55function loadSync (file, overrides) {
56 debug('loading %s (sync)', utils.relative(file))
57 let config = JSON.parse(fs.readFileSync(file, 'utf8'))
58 let dir = path.dirname(file)
59 let env = process.env.NODE_ENV || 'development'
60
61 if (env in config) {
62 debug('merging env %s', env)
63 let envConf = config[env]
64 if (envConf.entries) merge(config.entries, envConf.entries)
65 if (envConf.plugins) merge(config.plugins, envConf.plugins)
66 }
67
68 let result = {
69 entries: normalizeEntriesSync(overrides, config.entries, dir),
70 plugins: normalizePlugins(config.plugins, dir)
71 }
72 if (config.root) result.root = path.resolve(dir, config.root)
73 if (config.concurrency) result.concurrency = config.concurrency
74 debug('final config: %j', result)
75 return result
76}
77
78/**
79 * Normalizes the list of entries. By default, the config file will contain a
80 * complete list of entries. If the user passes a list of entries via the CLI,
81 * that list will be used instead.
82 *
83 * It will return a flattened array of absolute file paths, with any globs
84 * already expanded.
85 *
86 * @param {Array} input The input list from the user. (if specified)
87 * @param {Array} config The list specified in the config file.
88 * @param {String} dir The location of the config file.
89 * @return {Array}
90 */
91function normalizeEntries (input, config, dir) {
92 let list = !empty(input) ? input : config
93 return glob(list, { cwd: dir, realpath: true })
94}
95
96/**
97 * Synchronous version of normalizeEntries.
98 *
99 * @param {Array} input The input list from the user. (if specified)
100 * @param {Array} config The list specified in the config file.
101 * @param {String} dir The location of the config file.
102 * @return {Array}
103 */
104function normalizeEntriesSync (input, config, dir) {
105 let list = !empty(input) ? input : config
106 return glob.sync(list, { cwd: dir, realpath: true })
107}
108
109/**
110 * Normalizes the list of plugins. For each plugin specified in the config,
111 * it will initialize. (with arguments if supplied) The return value is a flat
112 * list of plugin functions.
113 *
114 * When a plugin is specified only as a string, it will be initialized without
115 * arguments. (basically accepting the defaults)
116 *
117 * When a plugin is specified as an array, the first item is the plugin name,
118 * all other items will be forwarded as arguments.
119 *
120 * @param {Array} config The list of plugins specified in the config.
121 * @param {String} root The location of the config file.
122 * @return {Array}
123 */
124function normalizePlugins (config, root) {
125 if (!config) return []
126 return config
127 .map(plugin => {
128 if (typeof plugin === 'string') return [ plugin ]
129 return clone(plugin)
130 })
131 .map(plugin => {
132 let fn = require(resolve(plugin[0], { basedir: root }))
133 return fn.apply(null, plugin.slice(1))
134 })
135}