UNPKG

4.69 kBJavaScriptView Raw
1'use strict';
2
3const CoreObject = require('core-object');
4const chalk = require('chalk');
5const debug = require('debug')('ember-try:task:try-each');
6const runCommand = require('./../utils/run-command');
7
8module.exports = CoreObject.extend({
9 async run(scenarios, options) {
10 // Required lazily to improve startup speed.
11 let ScenarioManager = require('./../utils/scenario-manager');
12 let DependencyManagerAdapterFactory = require('./../utils/dependency-manager-adapter-factory');
13 this.ResultSummary = require('./../utils/result-summary');
14
15 let dependencyManagerAdapters =
16 this.dependencyManagerAdapters ||
17 DependencyManagerAdapterFactory.generateFromConfig(this.config, this.project.root);
18 debug(
19 'DependencyManagerAdapters: %s',
20 dependencyManagerAdapters.map((item) => {
21 return item.configKey;
22 })
23 );
24 this.ScenarioManager = new ScenarioManager({
25 ui: this.ui,
26 dependencyManagerAdapters,
27 });
28
29 this._canceling = false;
30 this._on('SIGINT', () => {
31 this._canceling = true;
32 this.ui.writeLine('\nGracefully shutting down from SIGINT (Ctrl-C)');
33 return this.ScenarioManager.cleanup();
34 });
35
36 try {
37 await this.ScenarioManager.setup();
38 debug('Scenario Manager setup');
39
40 let results = [];
41 for (let scenario of scenarios) {
42 results.push(await this._runCommandForThisScenario(scenario));
43 }
44
45 await this._optionallyCleanup(options);
46
47 debug('Output results');
48 this._printResults(results);
49
50 return this._exitAsAppropriate(results);
51 } catch (err) {
52 this.ui.writeLine(chalk.red('Error!'));
53
54 if (err) {
55 this.ui.writeLine(chalk.red(err));
56 this.ui.writeLine(chalk.red(err.stack));
57 }
58
59 return 1; // Signifies exit code
60 }
61 },
62
63 async _runCommandForThisScenario(scenario) {
64 if (this._canceling) {
65 return;
66 }
67
68 let scenarioDependencyState = await this.ScenarioManager.changeTo(scenario);
69
70 if (this._canceling) {
71 return;
72 }
73
74 process.env.EMBER_TRY_CURRENT_SCENARIO = scenario.name;
75 this._writeHeader(`Scenario: ${scenario.name}`);
76
77 let command = this._determineCommandFor(scenario);
78 let runResults = {
79 scenario: scenario.name,
80 allowedToFail: !!scenario.allowedToFail,
81 dependencyState: scenarioDependencyState,
82 envState: scenario.env,
83 command: command.join(' '),
84 };
85
86 debug('With:\n', runResults);
87
88 let result = await this._runCommand({
89 commandArgs: command,
90 commandOptions: this._commandOptions(scenario.env),
91 });
92
93 if (this._canceling) {
94 return;
95 }
96
97 runResults.result = result;
98 this._writeFooter(`Result: ${result}`);
99
100 return runResults;
101 },
102
103 _writeHeader(text) {
104 let count = 75 - text.length;
105 let separator = new Array(count + 1).join('=');
106 this.ui.writeLine(chalk.blue(`\n=== ${text} ${separator}\n`));
107 },
108
109 _writeFooter(text) {
110 this.ui.writeLine(chalk.blue(`\n${text}`));
111 this.ui.writeLine(chalk.blue('---\n'));
112 },
113
114 _determineCommandFor(scenario) {
115 if (this.commandArgs && this.commandArgs.length) {
116 return this.commandArgs;
117 }
118
119 if (scenario.command) {
120 return scenario.command.split(' ');
121 }
122
123 if (this.config.command) {
124 return this.config.command.split(' ');
125 }
126
127 return this._defaultCommandArgs();
128 },
129
130 _runCommand(options) {
131 return runCommand(this.project.root, options.commandArgs, options.commandOptions);
132 },
133
134 _commandOptions(env) {
135 let options = this.commandOptions || {};
136 if (env) {
137 options.env = Object.assign({}, process.env, env);
138 }
139 return options;
140 },
141
142 _defaultCommandArgs() {
143 return ['ember', 'test'];
144 },
145
146 _printResults(results) {
147 new this.ResultSummary({ ui: this.ui, results }).print();
148 },
149
150 _exitAsAppropriate(results) {
151 let outcomes = results.map((result) => {
152 return result.result || result.allowedToFail;
153 });
154
155 return this._exitBasedOnCondition(outcomes.indexOf(false) > -1);
156 },
157
158 async _optionallyCleanup(options) {
159 debug('Cleanup');
160 delete process.env.EMBER_TRY_CURRENT_SCENARIO;
161
162 if (options && options.skipCleanup) {
163 // Create a fake promise for consistency
164 debug('Skip ScenarioManager cleanup');
165 } else {
166 debug('Cleanup ScenarioManager');
167 return await this.ScenarioManager.cleanup();
168 }
169 },
170
171 _exitBasedOnCondition(condition) {
172 let exitCode = condition ? 1 : 0;
173 debug('Exit %s', exitCode);
174 return exitCode;
175 },
176
177 _exit(code) {
178 debug('Exit %s', code);
179 process.exit(code);
180 },
181
182 _on(signal, fn) {
183 process.on(signal, fn);
184 },
185});