UNPKG

3.76 kBJavaScriptView Raw
1'use strict';
2
3var VM = require('vm'),
4 Q = require('q'),
5 QFS = require('q-io/fs'),
6 INHERIT = require('inherit'),
7 APW = require('apw'),
8 PATH = require('./path'),
9 UTIL = require('util'),
10 BEMUTIL = require('./util'),
11 REGISTRY = require('./nodesregistry'),
12 LOGGER = require('./logger'),
13 reqf = require('reqf');
14
15exports.DEFAULT_WORKERS = 10;
16
17exports.APW = INHERIT(APW, {
18
19 findAndProcess: function(targets) {
20 if (!Array.isArray(targets)) targets = [targets];
21
22 // Strip trailing slashes from target names
23 // See https://github.com/bem/bem-tools/issues/252
24 var re = new RegExp(PATH.dirSep + '$');
25 targets = targets.map(function(t) {
26 return t.replace(re, '');
27 });
28
29 var _this = this,
30 foundNodes = targets.map(function(t) {
31 return _this.findNode(t);
32 });
33 return Q.all(foundNodes)
34 .fail(function(err) {
35 if (typeof err === 'string') return;
36 return Q.reject(err);
37 })
38 .then(function() {
39 return _this.process(targets);
40 });
41 },
42
43 // TODO: move node introspection logic to the node in arch
44 findNode: function(id, head, tail) {
45 head = head || '';
46 tail = tail || id;
47
48 if (this.arch.hasNode(id)) return Q.resolve(id);
49 if (head === id) return Q.reject(UTIL.format('Node "%s" not found', id));
50
51 var parts = tail.split(PATH.dirSep),
52 p = parts.shift();
53 head = (head? [head, p] : [p]).join(PATH.dirSep);
54 tail = parts.join(PATH.dirSep);
55
56 var _this = this,
57 magicHead = head + '*';
58 if (!this.arch.hasNode(magicHead)) {
59 return this.findNode(id, head, tail);
60 }
61
62 return this.process(magicHead).then(function() {
63 return _this.findNode(id, head, tail);
64 });
65 }
66
67}, {
68
69 Workers: INHERIT(APW.Workers, {
70
71 start: function(plan) {
72 /* jshint -W109 */
73 LOGGER.finfo("[i] Going to build '%s' [%s]", plan.getTargets().join("', '"), plan.getId());
74 /* jshint +W109 */
75 return this.__base(plan);
76 }
77
78 })
79
80});
81
82exports.createArch = function(opts) {
83
84 var arch = new APW.Arch(),
85 DefaultArch = require('./default-arch'),
86 rootMakefile = PATH.join(opts.root, '.bem', 'make.js');
87
88 return QFS.exists(rootMakefile)
89 .then(function(exists) {
90
91 /* jshint -W109 */
92 LOGGER.fsilly("File '%s' %s", rootMakefile, exists? 'exists' : "doesn't exist");
93 /* jshint +W109 */
94 if (exists) return include(rootMakefile);
95
96 })
97 .then(function() {
98 return new (DefaultArch.Arch)(arch, opts).alterArch();
99 });
100
101};
102
103function getPathResolver(base) {
104
105 return function(path) {
106 return path.match(/^\./)? PATH.resolve(PATH.dirname(base), path) : path;
107 };
108
109}
110
111function getIncludeFunc(resolvePath) {
112
113 return function(path) {
114 return include(resolvePath(path));
115 };
116
117}
118
119function include(path) {
120 return evalConfig(require('fs').readFileSync(path, 'utf8'), path);
121}
122
123function evalConfig(content, path) {
124
125 /* jshint -W109 */
126 LOGGER.fsilly("File '%s' read, evaling", path);
127
128 var resolvePath = getPathResolver(path);
129
130 VM.runInNewContext(
131 content,
132 BEMUTIL.extend({}, global, {
133 MAKE: REGISTRY,
134 module: null,
135 __filename: path,
136 __dirname: PATH.dirname(path),
137 require: reqf(path, module),
138 include: getIncludeFunc(resolvePath)
139 }),
140 path);
141
142 LOGGER.fsilly("File '%s' evaled", path);
143 /* jshint +W109 */
144
145}