1 | 'use strict';
|
2 |
|
3 | Object.defineProperty(exports, '__esModule', {
|
4 | value: true
|
5 | });
|
6 |
|
7 | const execa = require('execa');
|
8 |
|
9 | const mergeWith = require('lodash/mergeWith');
|
10 |
|
11 | const common = require('@boost/common');
|
12 |
|
13 | const event = require('@boost/event');
|
14 |
|
15 | const plugin = require('@boost/plugin');
|
16 |
|
17 | const constants = require('./constants.js');
|
18 |
|
19 | const isClassInstance = require('./helpers/isClassInstance.js');
|
20 |
|
21 | function _interopDefault(e) {
|
22 | return e && e.__esModule ? e : {
|
23 | 'default': e
|
24 | };
|
25 | }
|
26 |
|
27 | const execa__default = _interopDefault(execa);
|
28 |
|
29 | const mergeWith__default = _interopDefault(mergeWith);
|
30 |
|
31 | class Driver extends plugin.Plugin {
|
32 | constructor(...args) {
|
33 | super(...args);
|
34 | this.commands = [];
|
35 | this.config = void 0;
|
36 | this.metadata = void 0;
|
37 | this.tool = void 0;
|
38 | this.output = {
|
39 | stderr: '',
|
40 | stdout: ''
|
41 | };
|
42 | this.onLoadProviderConfig = new event.Event('load-provider-config');
|
43 | this.onLoadConsumerConfig = new event.Event('load-consumer-config');
|
44 | this.onMergeConfig = new event.Event('merge-config');
|
45 | this.onCreateConfigFile = new event.Event('create-config-file');
|
46 | this.onCopyConfigFile = new event.Event('copy-config-file');
|
47 | this.onReferenceConfigFile = new event.Event('reference-config-file');
|
48 | this.onTemplateConfigFile = new event.Event('template-config-file');
|
49 | this.onDeleteConfigFile = new event.Event('delete-config-file');
|
50 | this.onBeforeExecute = new event.ConcurrentEvent('before-execute');
|
51 | this.onAfterExecute = new event.ConcurrentEvent('after-execute');
|
52 | this.onFailedExecute = new event.ConcurrentEvent('failed-execute');
|
53 | }
|
54 |
|
55 | static validate(driver) {
|
56 | const name = isClassInstance.isClassInstance(driver) && driver.constructor.name || 'Driver';
|
57 |
|
58 | if (!common.isObject(driver.options)) {
|
59 | throw new Error(`\`${name}\` requires an options object.`);
|
60 | }
|
61 | }
|
62 |
|
63 | blueprint({
|
64 | array,
|
65 | object,
|
66 | string,
|
67 | bool
|
68 | }) {
|
69 | return {
|
70 | args: array(string()),
|
71 | configStrategy: string(constants.STRATEGY_NATIVE).oneOf([constants.STRATEGY_NATIVE, constants.STRATEGY_CREATE, constants.STRATEGY_REFERENCE, constants.STRATEGY_TEMPLATE, constants.STRATEGY_COPY, constants.STRATEGY_NONE]),
|
72 | dependencies: array(string()),
|
73 | env: object(string()),
|
74 | expandGlobs: bool(true),
|
75 | outputStrategy: string(constants.STRATEGY_BUFFER).oneOf([constants.STRATEGY_BUFFER, constants.STRATEGY_PIPE, constants.STRATEGY_STREAM, constants.STRATEGY_NONE]),
|
76 | template: string()
|
77 | };
|
78 | }
|
79 |
|
80 | bootstrap() {}
|
81 |
|
82 | startup(tool) {
|
83 | this.tool = tool;
|
84 | this.bootstrap();
|
85 | }
|
86 | |
87 |
|
88 |
|
89 |
|
90 |
|
91 | doMerge(prevValue, nextValue) {
|
92 | if (Array.isArray(prevValue) && Array.isArray(nextValue)) {
|
93 |
|
94 | return [...new Set([...prevValue, ...nextValue])];
|
95 | }
|
96 |
|
97 | return undefined;
|
98 | }
|
99 | |
100 |
|
101 |
|
102 |
|
103 |
|
104 | extractErrorMessage(error) {
|
105 | return error.message.split('\n', 1)[0] || '';
|
106 | }
|
107 | |
108 |
|
109 |
|
110 |
|
111 |
|
112 | formatConfig(data) {
|
113 | const content = JSON.stringify(data, null, 2);
|
114 |
|
115 | if (this.metadata.configName.endsWith('.js')) {
|
116 | return `module.exports = ${content};`;
|
117 | }
|
118 |
|
119 | return content;
|
120 | }
|
121 | |
122 |
|
123 |
|
124 |
|
125 |
|
126 | getName() {
|
127 | return this.name.split('-').pop();
|
128 | }
|
129 | |
130 |
|
131 |
|
132 |
|
133 |
|
134 | getArgs() {
|
135 | return common.toArray(this.options.args);
|
136 | }
|
137 | |
138 |
|
139 |
|
140 |
|
141 |
|
142 | getDependencies() {
|
143 | return [
|
144 | ...this.metadata.dependencies,
|
145 | ...common.toArray(this.options.dependencies)];
|
146 | }
|
147 | |
148 |
|
149 |
|
150 |
|
151 |
|
152 | getOutputStrategy() {
|
153 | var _ref;
|
154 |
|
155 | return (_ref = this.tool.config.execute.output || this.options.outputStrategy) !== null && _ref !== void 0 ? _ref : constants.STRATEGY_BUFFER;
|
156 | }
|
157 | |
158 |
|
159 |
|
160 |
|
161 |
|
162 | getSupportedOptions() {
|
163 | return [];
|
164 | }
|
165 | |
166 |
|
167 |
|
168 |
|
169 |
|
170 | getVersion() {
|
171 | var _execa__default$defau;
|
172 |
|
173 | const _this$metadata = this.metadata,
|
174 | bin = _this$metadata.bin,
|
175 | versionOption = _this$metadata.versionOption;
|
176 | const version = (((_execa__default$defau = execa__default['default'].sync(bin, [versionOption], {
|
177 | preferLocal: true
|
178 | })) === null || _execa__default$defau === void 0 ? void 0 : _execa__default$defau.stdout) || '').trim();
|
179 | const match = version.match(/(\d+)\.(\d+)\.(\d+)/u);
|
180 | return match ? match[0] : '0.0.0';
|
181 | }
|
182 | |
183 |
|
184 |
|
185 |
|
186 |
|
187 | mergeConfig(prev, next) {
|
188 | return mergeWith__default['default'](prev, next, this.doMerge);
|
189 | }
|
190 | |
191 |
|
192 |
|
193 |
|
194 |
|
195 | processFailure(error) {
|
196 | const _error$stderr = error.stderr,
|
197 | stderr = _error$stderr === void 0 ? '' : _error$stderr,
|
198 | _error$stdout = error.stdout,
|
199 | stdout = _error$stdout === void 0 ? '' : _error$stdout;
|
200 | const out = (stderr || stdout).trim();
|
201 |
|
202 | if (out) {
|
203 | this.setOutput('stderr', out);
|
204 | }
|
205 | }
|
206 | |
207 |
|
208 |
|
209 |
|
210 |
|
211 | processSuccess(response) {
|
212 | const _response$stderr = response.stderr,
|
213 | stderr = _response$stderr === void 0 ? '' : _response$stderr,
|
214 | _response$stdout = response.stdout,
|
215 | stdout = _response$stdout === void 0 ? '' : _response$stdout;
|
216 | this.setOutput('stderr', stderr.trim());
|
217 | this.setOutput('stdout', stdout.trim());
|
218 | }
|
219 | |
220 |
|
221 |
|
222 |
|
223 |
|
224 | registerCommand(path, config, runner) {
|
225 | this.commands.push({
|
226 | config,
|
227 | path,
|
228 | runner
|
229 | });
|
230 | return this;
|
231 | }
|
232 | |
233 |
|
234 |
|
235 |
|
236 |
|
237 | setMetadata(metadata) {
|
238 | const _common$predicates = common.predicates,
|
239 | array = _common$predicates.array,
|
240 | bool = _common$predicates.bool,
|
241 | string = _common$predicates.string,
|
242 | object = _common$predicates.object,
|
243 | shape = _common$predicates.shape;
|
244 | this.metadata = common.optimal(metadata, {
|
245 | bin: string().match(/^[a-z]{1}[a-zA-Z0-9-]+$/u).required(),
|
246 | commandOptions: object(shape({
|
247 | description: string().required(),
|
248 | type: string().oneOf(['string', 'number', 'boolean'])
|
249 | })),
|
250 | configName: string().required(),
|
251 | configOption: string('--config'),
|
252 | configStrategy: string(constants.STRATEGY_CREATE).oneOf([constants.STRATEGY_CREATE, constants.STRATEGY_REFERENCE, constants.STRATEGY_COPY]),
|
253 | dependencies: array(string()),
|
254 | description: string(),
|
255 | filterOptions: bool(true),
|
256 | helpOption: string('--help'),
|
257 | title: string().required(),
|
258 | useConfigOption: bool(),
|
259 | versionOption: string('--version'),
|
260 | watchOptions: array(string()),
|
261 | workspaceStrategy: string(constants.STRATEGY_REFERENCE).oneOf([constants.STRATEGY_REFERENCE, constants.STRATEGY_COPY])
|
262 | }, {
|
263 | name: this.constructor.name
|
264 | });
|
265 | return this;
|
266 | }
|
267 | |
268 |
|
269 |
|
270 |
|
271 |
|
272 | setOutput(type, value) {
|
273 | this.output[type] = value.trim();
|
274 | return this;
|
275 | }
|
276 |
|
277 | }
|
278 |
|
279 | exports.Driver = Driver;
|
280 |
|