1 | var _ = require('underscore'),
|
2 | async = require('async'),
|
3 | fs = require('fs'),
|
4 | fu = require('./fileUtil'),
|
5 | resources = require('./util/resources');
|
6 |
|
7 | function Context(options, config, plugins, libraries, event) {
|
8 | this._package = options.package;
|
9 | this._platform = options.platform;
|
10 | this._plugins = plugins;
|
11 | this.mode = options.mode;
|
12 | this.module = options.module;
|
13 | this.fileConfig = options.fileConfig;
|
14 | this.resource = options.resource;
|
15 | this.config = config;
|
16 | this.libraries = libraries || options.libraries;
|
17 | this.event = event || options.event;
|
18 | }
|
19 | Context.prototype = {
|
20 | fileUtil: fu,
|
21 |
|
22 | clone: function(options) {
|
23 | var ret = new Context(this, this.config);
|
24 | ret.parent = this;
|
25 | var prototype = Object.keys(Context.prototype);
|
26 | for (var name in this) {
|
27 | if (this.hasOwnProperty(name) && prototype.indexOf(name) === -1) {
|
28 | ret[name] = this[name];
|
29 | }
|
30 | }
|
31 | if (options) {
|
32 | _.extend(ret, options);
|
33 | ret._package = options.package || this._package;
|
34 | ret._platform = options.platform || this._platform;
|
35 | }
|
36 | return ret;
|
37 | },
|
38 |
|
39 | fileNamesForModule: function(mode, moduleName, callback) {
|
40 | var context = this.clone();
|
41 | context.mode = mode;
|
42 | context.module = moduleName && this.config.module(moduleName);
|
43 | if (moduleName && !context.module) {
|
44 | return callback(new Error('Unknown module "' + moduleName + '"'));
|
45 | }
|
46 |
|
47 | this.plugins.outputConfigs(context, function(err, configs) {
|
48 | if (err) {
|
49 | return callback(err);
|
50 | }
|
51 |
|
52 | async.map(configs, function(config, callback) {
|
53 | var fileContext = context.clone();
|
54 | fileContext.fileConfig = config;
|
55 | fileContext._plugins.fileName(fileContext, function(err, fileName) {
|
56 | config.fileName = fileName;
|
57 | callback(err, config);
|
58 | });
|
59 | },
|
60 | callback);
|
61 | });
|
62 | },
|
63 |
|
64 | loadResource: function(resource, callback) {
|
65 | if (!callback) {
|
66 |
|
67 | resource = this.resource;
|
68 | callback = resource;
|
69 | }
|
70 |
|
71 | var fileInfo = {name: resource.hasOwnProperty('sourceFile') ? resource.sourceFile : resource.src};
|
72 |
|
73 | function loaded(err, data) {
|
74 |
|
75 | if (err) {
|
76 | if (!err.resourceLoadError) {
|
77 | var json = '';
|
78 | try {
|
79 |
|
80 | resource = _.clone(resource.originalResource || resource);
|
81 | delete resource.library;
|
82 | delete resource.enoent;
|
83 | json = '\n\t' + JSON.stringify(resource);
|
84 | } catch (err) { }
|
85 |
|
86 | var errorWrapper = new Error('Failed to load resource "' + fileInfo.name + '"' + json + '\n\t' + (err.stack || err));
|
87 | errorWrapper.stack = errorWrapper.message + ' ' + (err.stack || err);
|
88 | errorWrapper.source = err;
|
89 | errorWrapper.code = err.code;
|
90 | errorWrapper.resourceLoadError = true;
|
91 | err = errorWrapper;
|
92 | }
|
93 | callback(err);
|
94 | return;
|
95 | }
|
96 | fileInfo.inputs = data.inputs;
|
97 | fileInfo.generated = data.generated;
|
98 | fileInfo.noSeparator = data.noSeparator;
|
99 | fileInfo.ignoreWarnings = data.ignoreWarnings || resource.ignoreWarnings;
|
100 | fileInfo.content = data.data != null ? data.data : data;
|
101 |
|
102 |
|
103 | _.defer(function() {
|
104 | callback(err, fileInfo);
|
105 | });
|
106 | }
|
107 |
|
108 | if (typeof resource === 'function') {
|
109 | resource(this, loaded);
|
110 | } else if (resource.src) {
|
111 |
|
112 | fu.readFile(resource.src, loaded);
|
113 | } else {
|
114 | loaded(undefined, {data: '', noSeparator: true, inputs: resource.dir ? [resource.dir] : []});
|
115 | }
|
116 |
|
117 | return fileInfo;
|
118 | },
|
119 |
|
120 | outputFile: function(writer, callback) {
|
121 | var context = this;
|
122 | context.plugins.file(context, function(err) {
|
123 | if (err) {
|
124 | return callback(err);
|
125 | }
|
126 |
|
127 | context.plugins.fileName(context, function(err, fileName) {
|
128 | if (err) {
|
129 | return callback(err);
|
130 | }
|
131 |
|
132 | context.buildPath = (fileName.root ? '' : context.platformPath) + fileName.path + '.' + fileName.extension;
|
133 | context.fileName = context.outdir + '/' + context.buildPath;
|
134 | writer(function(err, data) {
|
135 | data = _.defaults({
|
136 | fileConfig: context.fileConfig,
|
137 | platform: context.platform,
|
138 | package: context.package,
|
139 | mode: context.mode
|
140 | }, data);
|
141 |
|
142 | if (err) {
|
143 | fs.unlink(context.fileName, function() { });
|
144 | data.error = err;
|
145 | }
|
146 | context.event.emit('output', data);
|
147 |
|
148 | context.fileCache = undefined;
|
149 | callback(err, data);
|
150 | });
|
151 | });
|
152 | });
|
153 | },
|
154 |
|
155 | get description() {
|
156 | var ret = 'package:' + this.package + '_platform:' + this.platform;
|
157 | if (this.mode) {
|
158 | ret += '_mode:' + this.mode;
|
159 | }
|
160 | if (this.fileName) {
|
161 | ret += '_config:' + this.fileName;
|
162 | }
|
163 | if (this.module) {
|
164 | ret += '_module:' + (this.module.name || this.module);
|
165 | }
|
166 | if (this.resource) {
|
167 |
|
168 | ret += '_resource:' + resources.source(this.resource);
|
169 | }
|
170 | return ret;
|
171 | },
|
172 |
|
173 | get plugins() { return this._plugins; },
|
174 |
|
175 | get package() { return this._package; },
|
176 | get platform() { return this._platform; },
|
177 | get platformPath() {
|
178 | return this.platform ? this.platform + '/' : '';
|
179 | },
|
180 |
|
181 | get combined() {
|
182 | return this.config.combineModules(this.package);
|
183 | },
|
184 | get baseName() {
|
185 | if (!this.combined) {
|
186 | return this.module.name;
|
187 | } else {
|
188 | return (this.config.attributes.packages[this.package] || {}).name || this.package;
|
189 | }
|
190 | },
|
191 |
|
192 | get resources() {
|
193 | if (this.parent) {
|
194 | return this.parent.resources;
|
195 | } else {
|
196 | return this._resources;
|
197 | }
|
198 | },
|
199 | set resources(value) {
|
200 | if (this.parent) {
|
201 | delete this.parent;
|
202 | }
|
203 | this._resources = value;
|
204 | }
|
205 | };
|
206 |
|
207 | module.exports = Context;
|