1 | 'use strict';
|
2 |
|
3 | Object.defineProperty(exports, "__esModule", {
|
4 | value: true
|
5 | });
|
6 |
|
7 | var _promise = require('babel-runtime/core-js/promise');
|
8 |
|
9 | var _promise2 = _interopRequireDefault(_promise);
|
10 |
|
11 | var _extends2 = require('babel-runtime/helpers/extends');
|
12 |
|
13 | var _extends3 = _interopRequireDefault(_extends2);
|
14 |
|
15 | var _assign = require('babel-runtime/core-js/object/assign');
|
16 |
|
17 | var _assign2 = _interopRequireDefault(_assign);
|
18 |
|
19 | var _asyncToGenerator2 = require('babel-runtime/helpers/asyncToGenerator');
|
20 |
|
21 | var _asyncToGenerator3 = _interopRequireDefault(_asyncToGenerator2);
|
22 |
|
23 | var _from = require('babel-runtime/core-js/array/from');
|
24 |
|
25 | var _from2 = _interopRequireDefault(_from);
|
26 |
|
27 | var _keys = require('babel-runtime/core-js/object/keys');
|
28 |
|
29 | var _keys2 = _interopRequireDefault(_keys);
|
30 |
|
31 | var _set = require('babel-runtime/core-js/set');
|
32 |
|
33 | var _set2 = _interopRequireDefault(_set);
|
34 |
|
35 | var _child_process = require('child_process');
|
36 |
|
37 | var _child_process2 = _interopRequireDefault(_child_process);
|
38 |
|
39 | var _treeKill = require('tree-kill');
|
40 |
|
41 | var _treeKill2 = _interopRequireDefault(_treeKill);
|
42 |
|
43 | var _fastGlob = require('fast-glob');
|
44 |
|
45 | var _fastGlob2 = _interopRequireDefault(_fastGlob);
|
46 |
|
47 | var _path = require('path');
|
48 |
|
49 | var _path2 = _interopRequireDefault(_path);
|
50 |
|
51 | var _State = require('./State');
|
52 |
|
53 | var _State2 = _interopRequireDefault(_State);
|
54 |
|
55 | var _File = require('./File');
|
56 |
|
57 | var _File2 = _interopRequireDefault(_File);
|
58 |
|
59 | var _Rule = require('./Rule');
|
60 |
|
61 | var _Rule2 = _interopRequireDefault(_Rule);
|
62 |
|
63 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
64 |
|
65 | const VARIABLE_PATTERN = /\$\{?(\w+)\}?/g;
|
66 |
|
67 | class StateConsumer {
|
68 |
|
69 | constructor(state, options) {
|
70 | this.consumerOptions = {};
|
71 |
|
72 | this.state = state;
|
73 | this.options = new Proxy(options, {
|
74 | get: (target, key) => {
|
75 | return key in this.consumerOptions ? this.consumerOptions[key] : target[key];
|
76 | },
|
77 | set: (target, key, value) => {
|
78 | this.setOption(this.consumerOptions, key, value);
|
79 | return true;
|
80 | },
|
81 | ownKeys: target => {
|
82 | const keys = new _set2.default((0, _keys2.default)(this.consumerOptions));
|
83 |
|
84 | (0, _keys2.default)(target).forEach(key => keys.add(key));
|
85 |
|
86 | return (0, _from2.default)(keys.values());
|
87 | }
|
88 | });
|
89 | this.env = {
|
90 | OUTDIR: this.options.outputDirectory || '.',
|
91 |
|
92 | OUTEXT: `.${this.options.outputFormat}`,
|
93 | JOB: this.options.jobName || this.state.env.NAME
|
94 | };
|
95 | }
|
96 |
|
97 | addTarget(filePath) {
|
98 | this.state.targets.add(filePath);
|
99 | }
|
100 |
|
101 | removeTarget(filePath) {
|
102 | this.state.targets.delete(filePath);
|
103 | }
|
104 |
|
105 | addResolvedTarget(filePath) {
|
106 | this.state.targets.add(this.resolvePath(filePath));
|
107 | }
|
108 |
|
109 | replaceResolvedTarget(oldFilePath, newFilePath) {
|
110 | var _this = this;
|
111 |
|
112 | return (0, _asyncToGenerator3.default)(function* () {
|
113 | const x = _this.resolvePath(oldFilePath);
|
114 | if (_this.state.targets.has(x)) {
|
115 | yield _this.addResolvedTarget(newFilePath);
|
116 | }
|
117 | })();
|
118 | }
|
119 |
|
120 | addResolvedTargets(filePaths) {
|
121 | for (const filePath of filePaths) {
|
122 | this.addResolvedTarget(filePath);
|
123 | }
|
124 | }
|
125 |
|
126 | get killToken() {
|
127 | return this.state.killToken;
|
128 | }
|
129 |
|
130 | set killToken(value) {
|
131 | this.state.killToken = value;
|
132 | }
|
133 |
|
134 | assignOptions(options) {
|
135 | for (const name in options) {
|
136 | const value = options[name];
|
137 |
|
138 | if (name === 'jobs') {
|
139 | let jobs = this.state.options.jobs;
|
140 |
|
141 | if (!jobs) {
|
142 | this.state.options.jobs = jobs = {};
|
143 | }
|
144 |
|
145 | for (const jobName in value) {
|
146 | const subOptions = value[jobName];
|
147 | let jobOptions = jobs[jobName];
|
148 |
|
149 | if (!jobOptions) {
|
150 | jobs[jobName] = jobOptions = {};
|
151 | }
|
152 |
|
153 | for (const jobOptionName in subOptions) {
|
154 | this.setOption(jobOptions, jobOptionName, subOptions[jobOptionName]);
|
155 | }
|
156 | }
|
157 | } else {
|
158 | this.setOption(this.state.options, name, value);
|
159 | }
|
160 | }
|
161 | }
|
162 |
|
163 | setOption(store, name, value) {
|
164 | const schema = this.state.optionSchema.get(name);
|
165 | if (schema) {
|
166 | let invalidType = false;
|
167 |
|
168 | switch (schema.type) {
|
169 | case 'string':
|
170 | invalidType = typeof value !== 'string';
|
171 | break;
|
172 | case 'strings':
|
173 | invalidType = !Array.isArray(value) || value.some(x => typeof x !== 'string');
|
174 | break;
|
175 | case 'number':
|
176 | invalidType = typeof value !== 'number';
|
177 | break;
|
178 | case 'boolean':
|
179 | invalidType = typeof value !== 'boolean';
|
180 | break;
|
181 | case 'variable':
|
182 | invalidType = !(typeof value === 'string' || Array.isArray(value) && value.every(x => typeof x === 'string'));
|
183 | break;
|
184 | }
|
185 |
|
186 | if (invalidType || schema.values && !schema.values.includes(value)) {
|
187 | this.error(`Ignoring attempt to set \`${name}\` to a invalid value of \`${value.toString()}\``);
|
188 | } else {
|
189 | store[schema.name] = value;
|
190 | }
|
191 | } else if (name.startsWith('$')) {
|
192 |
|
193 | store[name] = value;
|
194 | } else {
|
195 | this.error(`Ignoring attempt to set unknown option \`${name}\` to a value of \`${value.toString()}\``);
|
196 | }
|
197 | }
|
198 |
|
199 | checkForKill() {
|
200 | if (this.state.killToken && this.state.killToken.error) throw this.state.killToken.error;
|
201 | }
|
202 |
|
203 | get ruleClasses() {
|
204 | return this.state.ruleClasses;
|
205 | }
|
206 |
|
207 | get filePath() {
|
208 | return this.state.filePath;
|
209 | }
|
210 |
|
211 | get rootPath() {
|
212 | return this.state.rootPath;
|
213 | }
|
214 |
|
215 | get files() {
|
216 | return this.state.files.values();
|
217 | }
|
218 |
|
219 | get rules() {
|
220 | return this.state.rules.values();
|
221 | }
|
222 |
|
223 | get targets() {
|
224 | const targets = new _set2.default();
|
225 |
|
226 | for (const rule of this.rules) {
|
227 | for (const file of rule.outputs) {
|
228 | const ext = _path2.default.extname(file.filePath);
|
229 | if (ext === `.${this.options.outputFormat}` || ext === '.xdv' && this.options.outputFormat === 'dvi') {
|
230 | targets.add(file.filePath);
|
231 | }
|
232 | }
|
233 | }
|
234 |
|
235 | return (0, _from2.default)(targets.values());
|
236 | }
|
237 |
|
238 | getTargetPaths() {
|
239 | return this.state.getTargetPaths();
|
240 | }
|
241 |
|
242 | getTargetFiles() {
|
243 | return this.state.getTargetFiles();
|
244 | }
|
245 |
|
246 | addRule(rule) {
|
247 | var _this2 = this;
|
248 |
|
249 | return (0, _asyncToGenerator3.default)(function* () {
|
250 | yield _this2.state.addRule(rule);
|
251 | })();
|
252 | }
|
253 |
|
254 | normalizePath(filePath) {
|
255 | return this.state.normalizePath(filePath);
|
256 | }
|
257 |
|
258 | resolvePath(filePath) {
|
259 | return _path2.default.normalize(this.expandVariables(filePath));
|
260 | }
|
261 |
|
262 | expandVariables(value, additionalProperties = {}) {
|
263 | const properties = (0, _assign2.default)({}, this.state.env, this.env, additionalProperties);
|
264 |
|
265 | return value.replace(VARIABLE_PATTERN, (match, name) => properties[name] || match[0]);
|
266 | }
|
267 |
|
268 | globPath(pattern, { types = 'all', ignorePattern } = {}) {
|
269 | var _this3 = this;
|
270 |
|
271 | return (0, _asyncToGenerator3.default)(function* () {
|
272 | try {
|
273 | return yield (0, _fastGlob2.default)(_this3.expandVariables(pattern), {
|
274 | cwd: _this3.rootPath,
|
275 | bashNative: [],
|
276 | onlyFiles: types === 'files',
|
277 | onlyDirs: types === 'directories',
|
278 | ignore: ignorePattern
|
279 | });
|
280 | } catch (error) {}
|
281 |
|
282 | return [];
|
283 | })();
|
284 | }
|
285 |
|
286 | getFile(filePath) {
|
287 | var _this4 = this;
|
288 |
|
289 | return (0, _asyncToGenerator3.default)(function* () {
|
290 | const file = yield _this4.state.getFile(filePath);
|
291 | if (file && _this4.options.jobName) file.jobNames.add(_this4.options.jobName);
|
292 | return file;
|
293 | })();
|
294 | }
|
295 |
|
296 | getFiles(filePaths) {
|
297 | var _this5 = this;
|
298 |
|
299 | return (0, _asyncToGenerator3.default)(function* () {
|
300 | const files = [];
|
301 | for (const filePath of filePaths) {
|
302 | const file = yield _this5.getFile(filePath);
|
303 | if (file) files.push(file);
|
304 | }
|
305 | return files;
|
306 | })();
|
307 | }
|
308 |
|
309 | getGlobbedFiles(pattern) {
|
310 | var _this6 = this;
|
311 |
|
312 | return (0, _asyncToGenerator3.default)(function* () {
|
313 | const files = [];
|
314 | for (const filePath of yield _this6.globPath(pattern)) {
|
315 | const file = yield _this6.getFile(filePath);
|
316 | if (file) files.push(file);
|
317 | }
|
318 | return files;
|
319 | })();
|
320 | }
|
321 |
|
322 | error(text, name = 'DiCy') {
|
323 | this.log({ severity: 'error', name, text });
|
324 | }
|
325 |
|
326 | warning(text, name = 'DiCy') {
|
327 | this.log({ severity: 'warning', name, text });
|
328 | }
|
329 |
|
330 | info(text, name = 'DiCy') {
|
331 | this.log({ severity: 'info', name, text });
|
332 | }
|
333 |
|
334 | log(message) {
|
335 | const severity = this.options.severity || 'warning';
|
336 | if (severity === 'warning' && message.severity === 'info' || severity === 'error' && message.severity !== 'error') return;
|
337 | this.emit('log', (0, _extends3.default)({ type: 'log' }, message));
|
338 | }
|
339 |
|
340 | get components() {
|
341 | return this.state.components;
|
342 | }
|
343 |
|
344 | addNode(x) {
|
345 | this.state.addNode(x);
|
346 | }
|
347 |
|
348 | removeNode(x) {
|
349 | this.state.addNode(x);
|
350 | }
|
351 |
|
352 | hasEdge(x, y) {
|
353 | return this.state.hasEdge(x, y);
|
354 | }
|
355 |
|
356 | addEdge(x, y) {
|
357 | this.state.addEdge(x, y);
|
358 | }
|
359 |
|
360 | removeEdge(x, y) {
|
361 | this.state.removeEdge(x, y);
|
362 | }
|
363 |
|
364 | isGrandparentOf(x, y) {
|
365 | return this.state.isGrandparentOf(x, y);
|
366 | }
|
367 |
|
368 | getResolvedFile(filePath) {
|
369 | var _this7 = this;
|
370 |
|
371 | return (0, _asyncToGenerator3.default)(function* () {
|
372 | return _this7.getFile(_this7.resolvePath(filePath));
|
373 | })();
|
374 | }
|
375 |
|
376 |
|
377 | addListener(eventName, listener) {
|
378 | return this.state.addListener(eventName, listener);
|
379 | }
|
380 |
|
381 | emit(eventName, ...args) {
|
382 | return this.state.emit(eventName, ...args);
|
383 | }
|
384 |
|
385 | eventNames() {
|
386 | return this.state.eventNames();
|
387 | }
|
388 |
|
389 | getMaxListeners() {
|
390 | return this.state.eventNames();
|
391 | }
|
392 |
|
393 | listenerCount(eventName) {
|
394 | return this.state.listenerCount(eventName);
|
395 | }
|
396 |
|
397 | listeners(eventName) {
|
398 | return this.state.listeners(eventName);
|
399 | }
|
400 |
|
401 | on(eventName, listener) {
|
402 | return this.state.on(eventName, listener);
|
403 | }
|
404 |
|
405 | once(eventName, listener) {
|
406 | return this.state.once(eventName, listener);
|
407 | }
|
408 |
|
409 | prependListener(eventName, listener) {
|
410 | return this.state.prependListener(eventName, listener);
|
411 | }
|
412 |
|
413 | prependOnceListener(eventName, listener) {
|
414 | return this.state.prependOnceListener(eventName, listener);
|
415 | }
|
416 |
|
417 | removeAllListeners(eventName) {
|
418 | return this.state.removeAllListeners(eventName);
|
419 | }
|
420 |
|
421 | removeListener(eventName, listener) {
|
422 | return this.state.removeListener(eventName, listener);
|
423 | }
|
424 |
|
425 | setMaxListeners(n) {
|
426 | return this.state.setMaxListeners(n);
|
427 | }
|
428 |
|
429 | executeChildProcess(command, options) {
|
430 | return new _promise2.default((resolve, reject) => {
|
431 | let stdout;
|
432 | let stderr;
|
433 | let exited = false;
|
434 | const handleExit = error => {
|
435 | if (exited) return;
|
436 | exited = true;
|
437 |
|
438 | if (child.pid) this.state.processes.delete(child.pid);
|
439 | if (error) {
|
440 | reject(error);
|
441 | } else {
|
442 | resolve({ stdout, stderr });
|
443 | }
|
444 | };
|
445 | const child = _child_process2.default.spawn(command, options);
|
446 |
|
447 | if (child.pid) this.state.processes.add(child.pid);
|
448 | child.on('error', handleExit);
|
449 | child.on('close', (code, signal) => {
|
450 | let error;
|
451 | if (code !== 0 || signal !== null) {
|
452 | error = new Error(`Command failed: \`${command}\`\n${stderr || ''}`.trim());
|
453 |
|
454 | error.code = code;
|
455 |
|
456 | error.signal = signal;
|
457 | }
|
458 | handleExit(error);
|
459 | });
|
460 | if (child.stdout) {
|
461 | child.stdout.setEncoding('utf8');
|
462 | child.stdout.on('data', data => {
|
463 | stdout = `${stdout || ''}${data}`;
|
464 | });
|
465 | }
|
466 | if (child.stderr) {
|
467 | child.stderr.setEncoding('utf8');
|
468 | child.stderr.on('data', data => {
|
469 | stderr = `${stderr || ''}${data}`;
|
470 | });
|
471 | }
|
472 | });
|
473 | }
|
474 |
|
475 | killChildProcesses() {
|
476 | for (const pid of this.state.processes.values()) {
|
477 | (0, _treeKill2.default)(pid);
|
478 | }
|
479 | this.state.processes.clear();
|
480 | }
|
481 |
|
482 | isOutputOf(file, ruleId) {
|
483 | return this.state.isOutputOf(file, ruleId);
|
484 | }
|
485 | }
|
486 | exports.default = StateConsumer; |
\ | No newline at end of file |