1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 | 'use strict';
|
7 |
|
8 | const util = require('util');
|
9 | const fs = require('fs');
|
10 | const path = require('path');
|
11 | const spawn = require('cross-spawn');
|
12 | const debug = require('debug')('loopback:build');
|
13 |
|
14 |
|
15 |
|
16 |
|
17 | function getRootDir() {
|
18 | return path.resolve(__dirname, '..');
|
19 | }
|
20 |
|
21 |
|
22 |
|
23 |
|
24 | function getPackageDir() {
|
25 | return process.cwd();
|
26 | }
|
27 |
|
28 |
|
29 |
|
30 |
|
31 |
|
32 |
|
33 | function getConfigFile(name, defaultName) {
|
34 | const dir = getPackageDir();
|
35 | let configFile = path.join(dir, name);
|
36 | if (!fs.existsSync(configFile)) {
|
37 | debug('%s does not exist', configFile);
|
38 | if (defaultName) {
|
39 | configFile = path.join(dir, defaultName);
|
40 | if (!fs.existsSync(configFile)) {
|
41 | debug('%s does not exist', configFile);
|
42 | configFile = path.join(getRootDir(), 'config/' + name);
|
43 | } else {
|
44 | debug('%s found', configFile);
|
45 | }
|
46 | } else {
|
47 |
|
48 | configFile = path.join(getRootDir(), 'config/' + name);
|
49 | debug('%s found', configFile);
|
50 | }
|
51 | } else {
|
52 | debug('%s found', configFile);
|
53 | }
|
54 | return configFile;
|
55 | }
|
56 |
|
57 |
|
58 |
|
59 |
|
60 |
|
61 |
|
62 |
|
63 |
|
64 | function resolveCLI(cli, options = {resolveFromProjectFirst: true}) {
|
65 | const {resolveFromProjectFirst = true} = options;
|
66 | if (resolveFromProjectFirst === false) {
|
67 | return require.resolve(cli);
|
68 | }
|
69 | try {
|
70 | const pkgDir = getPackageDir();
|
71 | const resolved = resolveCLIFromProject(cli, pkgDir);
|
72 | if (resolved != null) return resolved;
|
73 | } catch (e) {
|
74 |
|
75 | }
|
76 | return require.resolve(cli);
|
77 | }
|
78 |
|
79 |
|
80 |
|
81 |
|
82 |
|
83 | function getPackageName(cli) {
|
84 | const paths = cli.split('/');
|
85 | if (paths[0].startsWith('@')) {
|
86 |
|
87 | return `${paths[0]}/${paths[1]}`;
|
88 | } else {
|
89 |
|
90 | return paths[0];
|
91 | }
|
92 | }
|
93 |
|
94 |
|
95 |
|
96 |
|
97 |
|
98 |
|
99 | function resolveCLIFromProject(cli, projectRootDir = getPackageDir()) {
|
100 | const cliPkg = getPackageName(cli);
|
101 | debug(`Trying to resolve CLI module '%s' from %s`, cliPkg, projectRootDir);
|
102 |
|
103 | const pkg = require(path.join(projectRootDir, 'package.json'));
|
104 | if (
|
105 | (pkg.devDependencies && pkg.devDependencies[cliPkg]) ||
|
106 | (pkg.dependencies && pkg.dependencies[cliPkg])
|
107 | ) {
|
108 |
|
109 | const modulePath = './node_modules/' + cli;
|
110 | const cliModule = require.resolve(path.join(projectRootDir, modulePath));
|
111 | debug(`Resolved CLI module '%s': %s`, cliPkg, cliModule);
|
112 | return cliModule;
|
113 | } else {
|
114 | debug(`CLI module '%s' is not found in dependencies`, cliPkg);
|
115 | }
|
116 | }
|
117 |
|
118 |
|
119 |
|
120 |
|
121 |
|
122 |
|
123 |
|
124 |
|
125 |
|
126 |
|
127 | function runCLI(cli, args, options) {
|
128 | cli = resolveCLI(cli, options && options.resolveFromProjectFirst);
|
129 | args = [cli].concat(args);
|
130 | debug('%s', args.join(' '));
|
131 |
|
132 | if (typeof options === 'boolean') options = {dryRun: options};
|
133 | options = options || {};
|
134 | if (options.dryRun) {
|
135 | return util.format('%s %s', process.execPath, args.join(' '));
|
136 | }
|
137 | if (options.nodeArgs) {
|
138 | debug('node args: %s', options.nodeArgs.join(' '));
|
139 |
|
140 | args = options.nodeArgs.concat(args);
|
141 | }
|
142 | debug('Spawn %s %s', process.execPath, args.join(' '));
|
143 | const child = spawn(
|
144 | process.execPath,
|
145 | args,
|
146 | Object.assign(
|
147 | {
|
148 | stdio: 'inherit',
|
149 | env: Object.create(process.env),
|
150 | },
|
151 | options,
|
152 | ),
|
153 | );
|
154 | child.on('close', (code, signal) => {
|
155 | debug('%s exits: %d', cli, code);
|
156 | process.exitCode = code;
|
157 | });
|
158 | return child;
|
159 | }
|
160 |
|
161 |
|
162 |
|
163 |
|
164 |
|
165 |
|
166 |
|
167 |
|
168 |
|
169 | function runShell(command, args, options) {
|
170 | args = args.map(a => JSON.stringify(a));
|
171 | debug('%s %s', command, args.join(' '));
|
172 |
|
173 | if (typeof options === 'boolean') options = {dryRun: options};
|
174 | options = options || {};
|
175 | if (options.dryRun) {
|
176 | return util.format('%s %s', command, args.join(' '));
|
177 | }
|
178 | const child = spawn(
|
179 | command,
|
180 | args,
|
181 | Object.assign(
|
182 | {
|
183 | stdio: 'inherit',
|
184 | env: Object.create(process.env),
|
185 |
|
186 |
|
187 |
|
188 | shell: true,
|
189 | },
|
190 | options,
|
191 | ),
|
192 | );
|
193 | child.on('close', (code, signal) => {
|
194 | debug('%s exits: %d', command, code);
|
195 | if (code > 0 || signal) {
|
196 | console.warn(
|
197 | 'Command aborts (code %d signal %s): %s %s.',
|
198 | code,
|
199 | signal,
|
200 | command,
|
201 | args.join(' '),
|
202 | );
|
203 | }
|
204 | if (signal === 'SIGKILL' && code === 0) {
|
205 |
|
206 | code = 128;
|
207 | }
|
208 | process.exitCode = code;
|
209 | });
|
210 | return child;
|
211 | }
|
212 |
|
213 |
|
214 |
|
215 |
|
216 |
|
217 |
|
218 | function isOptionSet(opts, ...optionNames) {
|
219 | return opts.some(opt =>
|
220 |
|
221 | optionNames.some(name => name === opt || opt.startsWith(`${name}=`)),
|
222 | );
|
223 | }
|
224 |
|
225 | function mochaConfiguredForProject() {
|
226 | const configFiles = [
|
227 | '.mocharc.js',
|
228 | '.mocharc.json',
|
229 | '.mocharc.yaml',
|
230 | '.mocharc.yml',
|
231 | ];
|
232 | return configFiles.some(f => {
|
233 | const configFile = path.join(getPackageDir(), f);
|
234 | return fs.existsSync(configFile);
|
235 | });
|
236 | }
|
237 |
|
238 | exports.getRootDir = getRootDir;
|
239 | exports.getPackageDir = getPackageDir;
|
240 | exports.getConfigFile = getConfigFile;
|
241 | exports.resolveCLI = resolveCLI;
|
242 | exports.runCLI = runCLI;
|
243 | exports.runShell = runShell;
|
244 | exports.isOptionSet = isOptionSet;
|
245 | exports.mochaConfiguredForProject = mochaConfiguredForProject;
|
246 | exports.resolveCLIFromProject = resolveCLIFromProject;
|
247 | exports.getPackageName = getPackageName;
|