1 | var _ = 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 |
|
13 | exports.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 |
|
25 | exports.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 |
|
64 | exports.ensureDirs = function(context, callback) {
|
65 | var config = context.config;
|
66 |
|
67 |
|
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 |
|
83 | exports.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 |
|
98 | exports.loadPackages = function(rootContext, packageName, modules, callback) {
|
99 | if (!callback) {
|
100 | callback = modules;
|
101 | modules = undefined;
|
102 | }
|
103 |
|
104 |
|
105 | if (!_.isArray(modules)) {
|
106 | modules = [modules];
|
107 | } else if (!modules.length) {
|
108 |
|
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;
|
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 |
|
160 | exports.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 |
|
172 | exports.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 |
|
199 | exports.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 |
|
235 | exports.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 |
|
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 |
|
262 | exports.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 | };
|