UNPKG

7.49 kBJavaScriptView Raw
1var _ = require('underscore'),
2 async = require('async'),
3 build = require('./build'),
4 combine = require('./jsCombine'),
5 configLoader = require('./config'),
6 Context = require('./context'),
7 fs = require('fs'),
8 fu = require('./fileUtil'),
9 Libraries = require('./libraries'),
10 plugin = require('./plugin'),
11 WatchManager = require('./watch-manager');
12
13exports.loadAndInitDir = function(path, event, options, callback) {
14 exports.loadConfig(path, event, options, function(err, context) {
15 if (err) {
16 return callback(err);
17 }
18
19 exports.ensureDirs(context, function(err) {
20 return callback(err, context);
21 });
22 });
23};
24
25exports.loadConfig = function(path, event, options, callback) {
26 try {
27 fu.resetCache();
28
29 var config = _.isString(path) ? configLoader.load(path) : configLoader.create(path);
30
31 var plugins = plugin.create(options);
32 plugins.initialize(config);
33
34 config.outdir = options.outdir = options.outdir || config.attributes.output;
35
36 var libraries = new Libraries(options);
37 var context = new Context(options, config, plugins, libraries, event);
38 context.options = options;
39 context.configCache = {};
40
41 libraries.initialize(context, function(err) {
42 if (err) {
43 return callback(err);
44 }
45
46 plugins.loadConfig(context, function(err) {
47 if (err) {
48 return callback(err);
49 }
50
51 event.emit('config', context.config);
52 if (options.verbose) {
53 event.emit('log', 'Finalized config ' + JSON.stringify(context.config.serialize(), undefined, 2));
54 }
55
56 callback(undefined, context);
57 });
58 });
59 } catch (err) {
60 callback(err);
61 }
62};
63
64exports.ensureDirs = function(context, callback) {
65 var config = context.config;
66
67 // Ensure that we have the proper build output
68 if (!config.outdir) {
69 return callback(new Error('Output must be defined on the command line or config file.'));
70 }
71 context.outdir = config.outdir;
72
73 fu.ensureDirs(config.outdir + '/.', function() {
74 var stat = fs.statSync(config.outdir);
75 if (!stat.isDirectory()) {
76 callback(new Error('Output must be a directory'));
77 } else {
78 callback();
79 }
80 });
81};
82
83exports.buildPackages = function(rootContext, packageName, modules, callback) {
84 if (!callback) {
85 callback = modules;
86 modules = undefined;
87 }
88
89 exports.loadPackages(rootContext, packageName, modules, function(err, contexts) {
90 if (err) {
91 return callback(err);
92 }
93
94 exports.buildContexts(contexts, callback);
95 });
96};
97
98exports.loadPackages = function(rootContext, packageName, modules, callback) {
99 if (!callback) {
100 callback = modules;
101 modules = undefined;
102 }
103
104 // Allow a string or a list as modules input
105 if (!_.isArray(modules)) {
106 modules = [modules];
107 } else if (!modules.length) {
108 // Special case empty array input to build all
109 modules = [undefined];
110 }
111
112 var options = {};
113 if (typeof packageName === 'object') {
114 options = packageName;
115 packageName = options.package;
116 }
117
118 var packages = rootContext.config.packageList();
119 if (packageName && !_.contains(packages, packageName)) {
120 return callback(undefined, {});
121 }
122
123 var packageNames = packageName ? [packageName] : packages,
124 contexts = [];
125
126 packageNames.forEach(function(pkg) {
127 modules.forEach(function(module) {
128 options.package = pkg;
129 options.module = module || undefined; // '' -> undefined
130
131 rootContext.event.emit('debug', 'Load package: ' + pkg);
132
133 var platforms = rootContext.config.platformList(pkg);
134 platforms.forEach(function(platform) {
135 options.platform = platform;
136
137 var newContext = rootContext.clone(options);
138 contexts.push(newContext);
139 });
140 });
141 });
142
143 var ret = {};
144 async.forEach(
145 contexts,
146 function(context, callback) {
147 exports.loadPlatform(context, function(err, contexts) {
148 if (!err) {
149 var pkg = ret[context.package] = ret[context.package] || {};
150 pkg[context.platform] = _.flatten(contexts);
151 }
152 return callback(err);
153 });
154 },
155 function(err) {
156 callback(err, ret);
157 });
158};
159
160exports.loadPlatform = function(context, callback) {
161 context.event.emit('debug', 'Load platform: ' + context.description);
162 var modes = context.mode ? [context.mode] : context.plugins.modes();
163
164 async.map(modes, function(mode, callback) {
165 exports.loadMode(mode, context, callback);
166 },
167 function(err, contexts) {
168 callback(err, contexts && _.flatten(contexts));
169 });
170};
171
172exports.loadMode = function(mode, context, callback) {
173 context.event.emit('debug', 'Load mode: ' + context.description);
174
175 context = context.clone();
176 context.mode = mode;
177 context.modeCache = {};
178
179 if (context.fileConfig) {
180 callback(undefined, [processFileConfig(context.fileConfig)]);
181 } else {
182 context.plugins.outputConfigs(context, function(err, configs) {
183 if (err) {
184 return callback(err);
185 }
186
187 callback(undefined, _.map(configs, processFileConfig));
188 });
189 }
190
191 function processFileConfig(fileConfig) {
192 var fileContext = context.clone(true);
193 fileContext.fileConfig = fileConfig;
194
195 return fileContext;
196 }
197};
198
199exports.buildContexts = function(configContexts, callback) {
200 if (configContexts instanceof Context) {
201 configContexts = [configContexts];
202 } else if (!_.isArray(configContexts)) {
203 configContexts = _.map(configContexts, function(package) {
204 return _.values(package);
205 });
206 configContexts = _.flatten(configContexts);
207 }
208
209 async.forEach(
210 configContexts,
211 function(fileContext, callback) {
212 var modules = fileContext.module ? [fileContext.module] : fileContext.config.moduleList(fileContext.package);
213
214 fileContext.resources = [];
215 fileContext.combineResources = {};
216 fileContext.fileCache = fileContext.combined ? {} : undefined;
217
218 async.forEach(modules, function(module, callback) {
219 var moduleContext = fileContext.clone();
220 moduleContext.module = module;
221
222 exports.buildModule(moduleContext, callback);
223 },
224 function(err) {
225 if (err) {
226 return callback(err);
227 }
228
229 fileContext.plugins.modeComplete(fileContext, callback);
230 });
231 },
232 callback);
233};
234
235exports.buildModule = function(context, callback) {
236 context.event.emit('debug', 'Build module: ' + context.description);
237
238 var module = context.config.module(context.module);
239 if (!module) {
240 return callback(new Error('Unable to find module "' + context.module + '"'));
241 }
242
243 context.module = module;
244 context.moduleCache = {};
245 context.fileCache = context.combined ? context.fileCache : {};
246
247 var resource = context.resource;
248 if (resource) {
249 resource = resource.originalResource || resource;
250 exports.processResources(context, [resource], callback);
251 } else {
252 // Load all resources associated with this module
253 build.loadResources(context, function(err, resources) {
254 if (err) {
255 return callback(err);
256 }
257 exports.processResources(context, resources, callback);
258 });
259 }
260};
261
262exports.processResources = function(context, resources, callback) {
263 build.processResources(resources, context, function(err, resources) {
264 if (err) {
265 return callback(err);
266 }
267
268 context.moduleResources = resources;
269 context.plugins.module(context, callback);
270 });
271};