@percy/cli-exec 1.0.0 → 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/common.js +10 -0
- package/dist/exec.js +114 -0
- package/dist/index.js +4 -0
- package/dist/ping.js +32 -0
- package/dist/start.js +28 -0
- package/dist/stop.js +39 -0
- package/package.json +4 -4
package/dist/common.js
ADDED
package/dist/exec.js
ADDED
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import command from '@percy/cli-command';
|
|
2
|
+
import * as common from './common.js';
|
|
3
|
+
import start from './start.js';
|
|
4
|
+
import stop from './stop.js';
|
|
5
|
+
import ping from './ping.js';
|
|
6
|
+
export const exec = command('exec', {
|
|
7
|
+
description: 'Start and stop Percy around a supplied command',
|
|
8
|
+
usage: '[options] -- <command>',
|
|
9
|
+
commands: [start, stop, ping],
|
|
10
|
+
flags: [...common.flags, {
|
|
11
|
+
name: 'parallel',
|
|
12
|
+
description: 'Marks the build as one of many parallel builds',
|
|
13
|
+
parse: () => {
|
|
14
|
+
var _process$env;
|
|
15
|
+
|
|
16
|
+
return !!((_process$env = process.env).PERCY_PARALLEL_TOTAL || (_process$env.PERCY_PARALLEL_TOTAL = '-1'));
|
|
17
|
+
}
|
|
18
|
+
}, {
|
|
19
|
+
name: 'partial',
|
|
20
|
+
description: 'Marks the build as a partial build',
|
|
21
|
+
parse: () => {
|
|
22
|
+
var _process$env2;
|
|
23
|
+
|
|
24
|
+
return !!((_process$env2 = process.env).PERCY_PARTIAL_BUILD || (_process$env2.PERCY_PARTIAL_BUILD = '1'));
|
|
25
|
+
}
|
|
26
|
+
}],
|
|
27
|
+
examples: ['$0 -- echo "percy is running around this echo command"', '$0 -- yarn test'],
|
|
28
|
+
loose: ['Warning: Missing command separator (--),', 'some command options may not work as expected'].join(' '),
|
|
29
|
+
percy: {
|
|
30
|
+
server: true
|
|
31
|
+
}
|
|
32
|
+
}, async function* ({
|
|
33
|
+
flags,
|
|
34
|
+
argv,
|
|
35
|
+
env,
|
|
36
|
+
percy,
|
|
37
|
+
log,
|
|
38
|
+
exit
|
|
39
|
+
}) {
|
|
40
|
+
let [command, ...args] = argv; // command is required
|
|
41
|
+
|
|
42
|
+
if (!command) {
|
|
43
|
+
log.error("You must supply a command to run after '--'");
|
|
44
|
+
log.info('Example:');
|
|
45
|
+
log.info(' $ percy exec -- npm test');
|
|
46
|
+
exit(1);
|
|
47
|
+
} // verify the provided command exists
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
let {
|
|
51
|
+
default: which
|
|
52
|
+
} = await import('which');
|
|
53
|
+
|
|
54
|
+
if (!which.sync(command, {
|
|
55
|
+
nothrow: true
|
|
56
|
+
})) {
|
|
57
|
+
exit(127, `Command not found "${command}"`);
|
|
58
|
+
} // attempt to start percy if enabled
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
if (!percy) {
|
|
62
|
+
log.warn('Percy is disabled');
|
|
63
|
+
} else {
|
|
64
|
+
try {
|
|
65
|
+
yield* percy.yield.start();
|
|
66
|
+
} catch (error) {
|
|
67
|
+
if (error.canceled) throw error;
|
|
68
|
+
log.warn('Skipping visual tests');
|
|
69
|
+
log.error(error);
|
|
70
|
+
}
|
|
71
|
+
} // provide SDKs with useful env vars
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
env.PERCY_SERVER_ADDRESS = percy === null || percy === void 0 ? void 0 : percy.address();
|
|
75
|
+
env.PERCY_LOGLEVEL = log.loglevel(); // run the provided command
|
|
76
|
+
|
|
77
|
+
log.info(`Running "${[command, ...args].join(' ')}"`);
|
|
78
|
+
let [status, error] = yield* spawn(command, args); // stop percy if running (force stop if there is an error);
|
|
79
|
+
|
|
80
|
+
await (percy === null || percy === void 0 ? void 0 : percy.stop(!!error)); // forward any returned status code
|
|
81
|
+
|
|
82
|
+
if (status) exit(status, error);
|
|
83
|
+
}); // Spawn a command with cross-spawn and return an array containing the resulting status code along
|
|
84
|
+
// with any error encountered while running. Uses a generator pattern to handle interupt signals.
|
|
85
|
+
|
|
86
|
+
async function* spawn(cmd, args) {
|
|
87
|
+
let {
|
|
88
|
+
default: crossSpawn
|
|
89
|
+
} = await import('cross-spawn');
|
|
90
|
+
let proc, closed, error;
|
|
91
|
+
|
|
92
|
+
try {
|
|
93
|
+
proc = crossSpawn(cmd, args, {
|
|
94
|
+
stdio: 'inherit'
|
|
95
|
+
});
|
|
96
|
+
proc.on('close', code => closed = code);
|
|
97
|
+
proc.on('error', err => error = err); // run until an event is triggered
|
|
98
|
+
|
|
99
|
+
/* eslint-disable-next-line no-unmodified-loop-condition */
|
|
100
|
+
|
|
101
|
+
while (closed == null && error == null) {
|
|
102
|
+
yield new Promise(r => setImmediate(r));
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
if (error) throw error;
|
|
106
|
+
return [closed];
|
|
107
|
+
} catch (err) {
|
|
108
|
+
if (!err.signal) return [1, err];
|
|
109
|
+
proc.kill(err.signal);
|
|
110
|
+
return [0, err];
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
export default exec;
|
package/dist/index.js
ADDED
package/dist/ping.js
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import command from '@percy/cli-command';
|
|
2
|
+
import * as common from './common.js';
|
|
3
|
+
export const ping = command('ping', {
|
|
4
|
+
description: 'Pings a local running Percy snapshot server',
|
|
5
|
+
flags: common.flags,
|
|
6
|
+
percy: true
|
|
7
|
+
}, async ({
|
|
8
|
+
flags,
|
|
9
|
+
percy,
|
|
10
|
+
log,
|
|
11
|
+
exit
|
|
12
|
+
}) => {
|
|
13
|
+
if (!percy) exit(0, 'Percy is disabled');
|
|
14
|
+
let {
|
|
15
|
+
request
|
|
16
|
+
} = await import('@percy/cli-command/utils');
|
|
17
|
+
let ping = `http://localhost:${flags.port}/percy/healthcheck`;
|
|
18
|
+
|
|
19
|
+
try {
|
|
20
|
+
await request(ping, {
|
|
21
|
+
retryNotFound: true,
|
|
22
|
+
noProxy: true
|
|
23
|
+
});
|
|
24
|
+
} catch (err) {
|
|
25
|
+
log.error('Percy is not running');
|
|
26
|
+
log.debug(err);
|
|
27
|
+
exit(1);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
log.info('Percy is running');
|
|
31
|
+
});
|
|
32
|
+
export default ping;
|
package/dist/start.js
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import command from '@percy/cli-command';
|
|
2
|
+
import * as common from './common.js';
|
|
3
|
+
export const start = command('start', {
|
|
4
|
+
description: 'Starts a local Percy snapshot server',
|
|
5
|
+
flags: common.flags,
|
|
6
|
+
examples: ['$0 &> percy.log'],
|
|
7
|
+
percy: {
|
|
8
|
+
server: true
|
|
9
|
+
}
|
|
10
|
+
}, async function* ({
|
|
11
|
+
percy,
|
|
12
|
+
exit
|
|
13
|
+
}) {
|
|
14
|
+
if (!percy) exit(0, 'Percy is disabled'); // start percy
|
|
15
|
+
|
|
16
|
+
yield* percy.yield.start();
|
|
17
|
+
|
|
18
|
+
try {
|
|
19
|
+
// run until stopped or terminated
|
|
20
|
+
while (percy.readyState < 3) {
|
|
21
|
+
yield new Promise(r => setImmediate(r));
|
|
22
|
+
}
|
|
23
|
+
} catch (error) {
|
|
24
|
+
await percy.stop(true);
|
|
25
|
+
throw error;
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
export default start;
|
package/dist/stop.js
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import command from '@percy/cli-command';
|
|
2
|
+
import * as common from './common.js';
|
|
3
|
+
export const stop = command('stop', {
|
|
4
|
+
description: 'Stops a local running Percy snapshot server',
|
|
5
|
+
flags: common.flags,
|
|
6
|
+
percy: true
|
|
7
|
+
}, async ({
|
|
8
|
+
flags,
|
|
9
|
+
percy,
|
|
10
|
+
log,
|
|
11
|
+
exit
|
|
12
|
+
}) => {
|
|
13
|
+
if (!percy) exit(0, 'Percy is disabled');
|
|
14
|
+
let {
|
|
15
|
+
request
|
|
16
|
+
} = await import('@percy/cli-command/utils');
|
|
17
|
+
let stop = `http://localhost:${flags.port}/percy/stop`;
|
|
18
|
+
let ping = `http://localhost:${flags.port}/percy/healthcheck`;
|
|
19
|
+
|
|
20
|
+
try {
|
|
21
|
+
await request(stop, {
|
|
22
|
+
method: 'POST',
|
|
23
|
+
noProxy: true
|
|
24
|
+
});
|
|
25
|
+
} catch (err) {
|
|
26
|
+
log.error('Percy is not running');
|
|
27
|
+
log.debug(err);
|
|
28
|
+
exit(1);
|
|
29
|
+
} // retry heathcheck until it fails
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
await new Promise(function check(resolve) {
|
|
33
|
+
return request(ping, {
|
|
34
|
+
noProxy: true
|
|
35
|
+
}).then(() => setTimeout(check, 100, resolve)).catch(resolve);
|
|
36
|
+
});
|
|
37
|
+
log.info('Percy has stopped');
|
|
38
|
+
});
|
|
39
|
+
export default stop;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@percy/cli-exec",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.3",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
"node": ">=14"
|
|
15
15
|
},
|
|
16
16
|
"files": [
|
|
17
|
-
"
|
|
17
|
+
"dist"
|
|
18
18
|
],
|
|
19
19
|
"main": "./dist/index.js",
|
|
20
20
|
"type": "module",
|
|
@@ -32,9 +32,9 @@
|
|
|
32
32
|
]
|
|
33
33
|
},
|
|
34
34
|
"dependencies": {
|
|
35
|
-
"@percy/cli-command": "1.0.
|
|
35
|
+
"@percy/cli-command": "1.0.3",
|
|
36
36
|
"cross-spawn": "^7.0.3",
|
|
37
37
|
"which": "^2.0.2"
|
|
38
38
|
},
|
|
39
|
-
"gitHead": "
|
|
39
|
+
"gitHead": "a259d5cff0933711bced21a979c577e70765d318"
|
|
40
40
|
}
|