UNPKG

24.1 kBJavaScriptView Raw
1#!/usr/bin/env node
2"use strict";
3var config_1 = require("./config");
4var task_runner_1 = require("./task.runner");
5var cli_1 = require("./cli");
6var fs_1 = require("fs");
7var index_1 = require("./index");
8var logger_1 = require("./logger");
9var reports = require("./reporter.resolve");
10var file = require("./file.utils");
11var seq = require("./task.sequence");
12var Rx = require("rx");
13var file_utils_1 = require("./file.utils");
14var debug = require("debug")("cb:cli");
15var _ = require('../lodash.custom');
16var parsed = cli_1.default(process.argv.slice(2));
17var defaultReporter = reports.getDefaultReporter();
18var defaultReporterFn = function (input) {
19 var output = defaultReporter(input);
20 if (output.data.length) {
21 output.data.forEach(function (line) { return logger_1.default.info(line); });
22 }
23};
24if (parsed.execute) {
25 runFromCli(parsed, defaultReporterFn);
26}
27else {
28 if (parsed.cli.flags.version) {
29 console.log(parsed.output[0]);
30 }
31 else {
32 if (parsed.output.length) {
33 parsed.output.forEach(function (line) {
34 logger_1.default.info(line);
35 });
36 }
37 }
38}
39function runFromCli(parsed, cliDefaultReporter) {
40 var addReporterIfMissing = function (setup, fn) {
41 return setup.reporters.length > 0
42 ? setup
43 : _.assign({}, setup, { reportFn: fn });
44 };
45 var addSignalFnIfMissing = function (setup, obs) {
46 return setup.config.signalObserver
47 ? setup
48 : _.set(setup, 'config.signalObserver', obs);
49 };
50 var addLoadDefaultsIfUndefined = function (cli) {
51 return typeof cli.flags.loadDefaultInputs === "undefined"
52 ? _.set(cli, 'flags.loadDefaultInputs', true)
53 : cli;
54 };
55 var cliSignalObserver = new Rx.Subject();
56 var killSwitches$ = new Rx.Subject();
57 killSwitches$.subscribe(function () {
58 process.exit(1);
59 });
60 file_utils_1.Right(parsed.cli)
61 .map(function (cli) { return addLoadDefaultsIfUndefined(cli); })
62 .chain(function (cli) { return index_1.getSetup(cli); })
63 .map(function (x) { return addReporterIfMissing(x, cliDefaultReporter); })
64 .map(function (x) { return addSignalFnIfMissing(x, cliSignalObserver); })
65 .fold(function (err) {
66 // todo log input errors
67 cliDefaultReporter(err);
68 killSwitches$.onNext(true);
69 return err;
70 }, function (setup) {
71 setup.reportFn({
72 type: reports.ReportTypes.UsingInputFile, data: { sources: setup.userInput.sources }
73 });
74 if (parsed.cli.command === 'run') {
75 runWithSetup(setup, killSwitches$);
76 }
77 if (parsed.cli.command === 'docs') {
78 docsWithSetup(setup, killSwitches$);
79 }
80 if (parsed.cli.command === 'init') {
81 initWithSetup(setup, killSwitches$);
82 }
83 if (parsed.cli.command === 'tasks' || parsed.cli.command === 'ls') {
84 tasksWithSetup(setup, killSwitches$);
85 }
86 if (parsed.cli.command === 'watch') {
87 watchWithSetup(setup, killSwitches$);
88 }
89 if (parsed.cli.command === 'watchers') {
90 watchersWithSetup(setup, killSwitches$);
91 }
92 });
93}
94function runWithSetup(prepared, killSwitches$) {
95 var setUp$ = new Rx.BehaviorSubject({});
96 var progress$ = new Rx.BehaviorSubject([]);
97 var summaryGiven = false; // todo remove the need for this as it breaks the encapsulation
98 var exitSignal$ = prepared.config.signalObserver
99 .filter(function (x) { return x.type === config_1.SignalTypes.Exit; })
100 .do(function (cbSignal) { return prepared.reportFn({
101 type: reports.ReportTypes.SignalReceived,
102 data: cbSignal.data
103 }); })
104 .withLatestFrom(setUp$, progress$, function (signal, setup, reports) {
105 return { reports: reports, setup: setup, signal: signal };
106 });
107 var exits$ = Rx.Observable.zip(Rx.Observable.just(true).timestamp(prepared.config.scheduler), exitSignal$.timestamp(prepared.config.scheduler), function (begin, signal) {
108 return { begin: begin, signal: signal };
109 }).do(function (incoming) {
110 var signal = incoming.signal, begin = incoming.begin;
111 var setup = signal.value.setup;
112 var reports = signal.value.reports;
113 var startTime = begin.timestamp;
114 var endTime = signal.timestamp;
115 /**
116 * Main summary report, although here it could be partial
117 * (as an exit command could occur at any time)
118 */
119 if ((setup.tasks.valid.length * 2) !== reports.length) {
120 if (!summaryGiven) {
121 summaryGiven = true;
122 handleCompletion(reports, setup, endTime - startTime);
123 }
124 }
125 else {
126 console.log("Exit signal, but summary given from main handler");
127 }
128 });
129 var reports$ = index_1.handleIncoming(prepared)
130 .do(function (x) { return setUp$.onNext(x.setup); }) // first item is the setup
131 .flatMap(function (x) {
132 if (x.setup.errors.length) {
133 killSwitches$.onNext(true);
134 return Rx.Observable.empty();
135 }
136 if (x.setup.tasks.invalid.length) {
137 killSwitches$.onNext(true);
138 return Rx.Observable.empty();
139 }
140 return x.update$;
141 })
142 .do(function (x) { return progress$.onNext(progress$.getValue().concat(x)); })
143 .do(function (report) {
144 prepared.reportFn({
145 type: reports.ReportTypes.TaskReport,
146 data: {
147 report: report,
148 config: prepared.config
149 }
150 });
151 })
152 .takeUntil(exits$)
153 .toArray()
154 .filter(function (reports) { return reports.length > 0; })
155 .timestamp(prepared.config.scheduler)
156 .withLatestFrom(setUp$, function (incoming, setup) {
157 return {
158 setup: setup,
159 reports: incoming.value,
160 timestamp: incoming.timestamp
161 };
162 });
163 Rx.Observable.zip(Rx.Observable.just(true).timestamp(prepared.config.scheduler), reports$, function (begin, result) {
164 return { begin: begin, result: result };
165 }).subscribe(function (incoming) {
166 if (!summaryGiven) {
167 summaryGiven = true;
168 handleCompletion(incoming.result.reports, incoming.result.setup, incoming.result.timestamp - incoming.begin.timestamp);
169 }
170 });
171 /**
172 * Handle file-writes
173 * @type {Rx.Observable<CBSignal<FileWriteSignal>>|Rx.Observable<T>}
174 */
175 prepared.config.signalObserver
176 .filter(function (x) { return x.type === config_1.SignalTypes.FileWrite; })
177 .do(function (x) {
178 if (prepared.config.dryRun) {
179 }
180 else {
181 file.writeFileToDisk(x.data.file, x.data.content);
182 }
183 }).subscribe();
184 /**
185 * Because errors are handled by reports, task executions ALWAYS complete
186 * and we handle that here.
187 */
188 function handleCompletion(taskReports, setup, runtime) {
189 /**
190 * Merge sequence tree with Task Reports
191 */
192 var decoratedSequence = seq.decorateSequenceWithReports(setup.sequence, taskReports);
193 /**
194 * Push a 'Completion report' onto the $complete Observable.
195 * This means consumers will get everything when they call
196 */
197 var errors = taskReports.filter(function (x) { return x.type === task_runner_1.TaskReportType.error; });
198 var completeData = {
199 errors: errors,
200 runtime: runtime,
201 taskErrors: errors,
202 sequence: decoratedSequence,
203 cli: prepared.cli,
204 config: prepared.config
205 };
206 /**
207 * Main summary report
208 */
209 prepared.reportFn({
210 type: reports.ReportTypes.Summary,
211 data: completeData
212 });
213 require("./command.run.post-execution").postCliExecution(completeData);
214 }
215}
216function docsWithSetup(prepared, killSwitches$) {
217 index_1.handleIncoming(prepared)
218 .pluck("setup")
219 .subscribe(function (setup) {
220 if (setup.errors.length) {
221 return killSwitches$.onNext(true);
222 }
223 if (setup.output) {
224 setup.output.forEach(function (outputItem) {
225 file.writeFileToDisk(outputItem.file, outputItem.content);
226 });
227 }
228 });
229}
230function initWithSetup(prepared, killSwitches$) {
231 index_1.handleIncoming(prepared)
232 .pluck("setup")
233 .subscribe(function (setup) {
234 if (setup.errors.length) {
235 return killSwitches$.onNext(true);
236 }
237 fs_1.writeFileSync(setup.outputFilePath, fs_1.readFileSync(setup.templateFilePath));
238 });
239}
240function tasksWithSetup(prepared, killSwitches$) {
241 index_1.handleIncoming(prepared)
242 .subscribe(function (x) {
243 var _a = x.setup, groups = _a.groups, tasks = _a.tasks;
244 var invalid = groups.reduce(function (acc, group) { return acc.concat(group.tasks.invalid); }, []);
245 if (invalid.length || prepared.config.verbose === 1 /* Verbose */) {
246 return prepared.reportFn({
247 type: reports.ReportTypes.TaskTree,
248 data: {
249 tasks: tasks,
250 config: prepared.config,
251 title: invalid.length ? "Errors found:" : "Available Tasks:"
252 }
253 });
254 }
255 if (!groups.length) {
256 return prepared.reportFn({ type: reports.ReportTypes.NoTasksAvailable });
257 }
258 prepared.reportFn({
259 type: reports.ReportTypes.SimpleTaskList,
260 data: { setup: x.setup }
261 });
262 });
263}
264function watchWithSetup(prepared, killSwitches$) {
265 index_1.handleIncoming(prepared)
266 .flatMap(function (x) {
267 if (x.setup.errors.length) {
268 killSwitches$.onNext(true);
269 return Rx.Observable.empty();
270 }
271 return x.update$; // start the watchers
272 })
273 .subscribe();
274}
275function watchersWithSetup(prepared, killSwitches$) {
276 index_1.handleIncoming(prepared)
277 .pluck("setup")
278 .subscribe(function (setup) {
279 if (setup.errors.length) {
280 return killSwitches$.onNext(true);
281 }
282 prepared.reportFn({
283 type: reports.ReportTypes.WatcherNames,
284 data: { setup: setup }
285 });
286 });
287}
288//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2IuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvY2IudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFLQSxtQ0FBNEU7QUFHNUUsNkNBQXlEO0FBS3pELDZCQUF3QjtBQUN4Qix5QkFBK0M7QUFDL0MsaUNBQWdFO0FBQ2hFLG1DQUE4QjtBQUc5Qiw0Q0FBOEM7QUFDOUMsbUNBQXFDO0FBQ3JDLHFDQUF1QztBQUV2Qyx1QkFBMEI7QUFDMUIsMkNBQW1DO0FBRW5DLElBQU0sS0FBSyxHQUFHLE9BQU8sQ0FBQyxPQUFPLENBQUMsQ0FBQyxRQUFRLENBQUMsQ0FBQztBQUN6QyxJQUFNLENBQUMsR0FBRyxPQUFPLENBQUMsa0JBQWtCLENBQUMsQ0FBQztBQUN0QyxJQUFNLE1BQU0sR0FBRyxhQUFHLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUUxQyxJQUFNLGVBQWUsR0FBRyxPQUFPLENBQUMsa0JBQWtCLEVBQUUsQ0FBQztBQUNyRCxJQUFNLGlCQUFpQixHQUFHLFVBQUMsS0FBSztJQUM1QixJQUFNLE1BQU0sR0FBRyxlQUFlLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDdEMsRUFBRSxDQUFDLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDO1FBQ3JCLE1BQU0sQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLFVBQUEsSUFBSSxJQUFJLE9BQUEsZ0JBQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEVBQWpCLENBQWlCLENBQUMsQ0FBQztJQUNuRCxDQUFDO0FBQ0wsQ0FBQyxDQUFDO0FBRUYsRUFBRSxDQUFDLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUM7SUFDakIsVUFBVSxDQUFDLE1BQU0sRUFBRSxpQkFBaUIsQ0FBQyxDQUFDO0FBQzFDLENBQUM7QUFBQyxJQUFJLENBQUMsQ0FBQztJQUNKLEVBQUUsQ0FBQyxDQUFDLE1BQU0s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
\No newline at end of file