just-scripts 2.5.0 → 2.6.0
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/CHANGELOG.json +48 -1
- package/CHANGELOG.md +18 -2
- package/lib/tasks/eslintTask.d.ts.map +1 -1
- package/lib/tasks/eslintTask.js +4 -5
- package/lib/tasks/eslintTask.js.map +1 -1
- package/lib/tasks/jestTask.d.ts +8 -0
- package/lib/tasks/jestTask.d.ts.map +1 -1
- package/lib/tasks/jestTask.js +8 -9
- package/lib/tasks/jestTask.js.map +1 -1
- package/lib/tasks/nodeExecTask.d.ts +22 -8
- package/lib/tasks/nodeExecTask.d.ts.map +1 -1
- package/lib/tasks/nodeExecTask.js +16 -10
- package/lib/tasks/nodeExecTask.js.map +1 -1
- package/lib/tasks/prettierTask.d.ts +1 -0
- package/lib/tasks/prettierTask.d.ts.map +1 -1
- package/lib/tasks/prettierTask.js +7 -21
- package/lib/tasks/prettierTask.js.map +1 -1
- package/lib/tasks/tscTask.d.ts.map +1 -1
- package/lib/tasks/tscTask.js +20 -38
- package/lib/tasks/tscTask.js.map +1 -1
- package/lib/tasks/tslintTask.d.ts.map +1 -1
- package/lib/tasks/tslintTask.js +7 -8
- package/lib/tasks/tslintTask.js.map +1 -1
- package/lib/tasks/webpackCliInitTask.js +2 -1
- package/lib/tasks/webpackCliInitTask.js.map +1 -1
- package/lib/tasks/webpackCliTask.js +1 -1
- package/lib/tasks/webpackCliTask.js.map +1 -1
- package/lib/tasks/webpackDevServerTask.d.ts.map +1 -1
- package/lib/tasks/webpackDevServerTask.js +1 -1
- package/lib/tasks/webpackDevServerTask.js.map +1 -1
- package/lib/utils/exec.d.ts +20 -31
- package/lib/utils/exec.d.ts.map +1 -1
- package/lib/utils/exec.js +53 -61
- package/lib/utils/exec.js.map +1 -1
- package/package.json +4 -2
- package/src/tasks/eslintTask.ts +7 -6
- package/src/tasks/jestTask.ts +18 -9
- package/src/tasks/nodeExecTask.ts +33 -17
- package/src/tasks/prettierTask.ts +9 -26
- package/src/tasks/tscTask.ts +21 -44
- package/src/tasks/tslintTask.ts +8 -7
- package/src/tasks/webpackCliInitTask.ts +1 -1
- package/src/tasks/webpackCliTask.ts +2 -2
- package/src/tasks/webpackDevServerTask.ts +3 -3
- package/src/utils/exec.ts +52 -66
package/src/tasks/tslintTask.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { resolve, logger, resolveCwd, TaskFunction } from 'just-task';
|
|
2
|
-
import { exec, encodeArgs } from '../utils';
|
|
3
2
|
import * as path from 'path';
|
|
4
3
|
import * as fs from 'fs';
|
|
4
|
+
import { logNodeCommand, spawn } from '../utils';
|
|
5
5
|
|
|
6
6
|
export interface TsLintTaskOptions {
|
|
7
7
|
config?: string;
|
|
@@ -12,7 +12,7 @@ export interface TsLintTaskOptions {
|
|
|
12
12
|
export function tslintTask(options: TsLintTaskOptions = {}): TaskFunction {
|
|
13
13
|
const projectFile = options.project || resolveCwd('./tsconfig.json');
|
|
14
14
|
|
|
15
|
-
return function tslint() {
|
|
15
|
+
return async function tslint() {
|
|
16
16
|
const tslintCmd = resolve('tslint/lib/tslintCli.js');
|
|
17
17
|
|
|
18
18
|
if (projectFile && tslintCmd && fs.existsSync(projectFile)) {
|
|
@@ -31,11 +31,12 @@ export function tslintTask(options: TsLintTaskOptions = {}): TaskFunction {
|
|
|
31
31
|
args.push('--fix');
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
-
const
|
|
35
|
-
|
|
36
|
-
return
|
|
37
|
-
} else {
|
|
38
|
-
return Promise.resolve();
|
|
34
|
+
const allArgs = [tslintCmd, ...args];
|
|
35
|
+
logNodeCommand(allArgs);
|
|
36
|
+
return spawn(process.execPath, allArgs, { stdio: 'inherit' });
|
|
39
37
|
}
|
|
38
|
+
|
|
39
|
+
// undertaker apparently requires returning a promise, async function, or function that calls done()
|
|
40
|
+
return Promise.resolve();
|
|
40
41
|
};
|
|
41
42
|
}
|
|
@@ -9,7 +9,7 @@ import { tryRequire } from '../tryRequire';
|
|
|
9
9
|
*/
|
|
10
10
|
export function webpackCliInitTask(customScaffold?: string, auto = false): TaskFunction {
|
|
11
11
|
return function webpackCli() {
|
|
12
|
-
const init = tryRequire('@webpack-cli/init')
|
|
12
|
+
const init = tryRequire('@webpack-cli/init')?.default;
|
|
13
13
|
if (!init) {
|
|
14
14
|
logger.warn('webpack-cli init requires three dependencies: @webpack-cli/init (preferred - as a devDependency)');
|
|
15
15
|
return;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { logger, TaskFunction, resolve } from 'just-task';
|
|
2
|
-
import { spawn } from '../utils';
|
|
2
|
+
import { logNodeCommand, spawn } from '../utils';
|
|
3
3
|
import { getTsNodeEnv } from '../typescript/getTsNodeEnv';
|
|
4
4
|
import { findWebpackConfig } from '../webpack/findWebpackConfig';
|
|
5
5
|
|
|
@@ -67,7 +67,7 @@ export function webpackCliTask(options: WebpackCliTaskOptions = {}): TaskFunctio
|
|
|
67
67
|
}
|
|
68
68
|
}
|
|
69
69
|
|
|
70
|
-
|
|
70
|
+
logNodeCommand(args);
|
|
71
71
|
|
|
72
72
|
return spawn(process.execPath, args, { stdio: 'inherit', env: options.env });
|
|
73
73
|
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// // WARNING: Careful about add more imports - only import types from webpack
|
|
2
2
|
import { Configuration } from 'webpack';
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
3
|
+
import { logNodeCommand, spawn } from '../utils';
|
|
4
|
+
import { resolve, resolveCwd, TaskFunction } from 'just-task';
|
|
5
5
|
import * as fs from 'fs';
|
|
6
6
|
import * as path from 'path';
|
|
7
7
|
import { WebpackCliTaskOptions } from './webpackCliTask';
|
|
@@ -93,7 +93,7 @@ export function webpackDevServerTask(options: WebpackDevServerTaskOptions = {}):
|
|
|
93
93
|
args = [...args, ...options.webpackCliArgs];
|
|
94
94
|
}
|
|
95
95
|
|
|
96
|
-
|
|
96
|
+
logNodeCommand(args);
|
|
97
97
|
return spawn(process.execPath, args, { stdio: 'inherit', env: options.env });
|
|
98
98
|
};
|
|
99
99
|
}
|
package/src/utils/exec.ts
CHANGED
|
@@ -1,52 +1,25 @@
|
|
|
1
1
|
import * as cp from 'child_process';
|
|
2
|
-
import {
|
|
2
|
+
import { spawn as crossSpawn } from 'cross-spawn';
|
|
3
|
+
import { logger } from 'just-task';
|
|
3
4
|
|
|
4
|
-
|
|
5
|
-
stdout?: string;
|
|
6
|
-
stderr?: string;
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
const SEPARATOR = process.platform === 'win32' ? ';' : ':';
|
|
5
|
+
// `exec` and `execSync` were removed due to security issues (keeping filename for history)
|
|
10
6
|
|
|
11
7
|
/**
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
* @param opts Normal exec options plus stdout/stderr for piping output. Can pass `process` for this param.
|
|
16
|
-
* @returns Promise which will settle when the command completes. If output was not piped, it will be
|
|
17
|
-
* returned as the promise's value. If the promise was rejected, the error will be of type `ExecError`.
|
|
8
|
+
* @deprecated This prevents issues from spaces in args, but does NOT escape shell metacharacters.
|
|
9
|
+
* For full escaping, consider a library such as `shell-quote` instead. (Note that `spawn` and tasks
|
|
10
|
+
* from this package now use `cross-spawn` which escapes spaces internally.)
|
|
18
11
|
*/
|
|
19
|
-
export function
|
|
20
|
-
|
|
21
|
-
opts: cp.ExecOptions & { stdout?: NodeJS.WritableStream; stderr?: NodeJS.WritableStream } = {},
|
|
22
|
-
): Promise<string | undefined> {
|
|
23
|
-
return new Promise((resolve, reject) => {
|
|
24
|
-
const child = cp.exec(cmd, opts, (error: ExecError | null, stdout?: string, stderr?: string) => {
|
|
25
|
-
if (error) {
|
|
26
|
-
error.stdout = stdout;
|
|
27
|
-
error.stderr = stderr;
|
|
28
|
-
reject(error);
|
|
29
|
-
} else {
|
|
30
|
-
resolve(stdout);
|
|
31
|
-
}
|
|
32
|
-
});
|
|
33
|
-
|
|
34
|
-
if (opts.stdout) {
|
|
35
|
-
child.stdout?.pipe(opts.stdout);
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
if (opts.stderr) {
|
|
39
|
-
child.stderr?.pipe(opts.stderr);
|
|
40
|
-
}
|
|
41
|
-
});
|
|
12
|
+
export function encodeArgs(cmdArgs: string[]): string[] {
|
|
13
|
+
return quoteSpaces(cmdArgs);
|
|
42
14
|
}
|
|
43
15
|
|
|
44
16
|
/**
|
|
45
|
-
*
|
|
46
|
-
*
|
|
47
|
-
*
|
|
17
|
+
* Quote arguments containing spaces. Note that this does NOT do any other escaping!
|
|
18
|
+
* For more complete escaping, consider a library such as `shell-quote`, or use safer APIs which
|
|
19
|
+
* don't require escaping. (Note that `spawn` from this package now uses `cross-spawn` which
|
|
20
|
+
* escapes spaces internally.)
|
|
48
21
|
*/
|
|
49
|
-
|
|
22
|
+
function quoteSpaces(cmdArgs: string[]): string[] {
|
|
50
23
|
// Taken from https://github.com/xxorax/node-shell-escape/blob/master/shell-escape.js
|
|
51
24
|
// However, we needed to use double quotes because that's the norm in more platforms
|
|
52
25
|
if (!cmdArgs) {
|
|
@@ -64,36 +37,31 @@ export function encodeArgs(cmdArgs: string[]): string[] {
|
|
|
64
37
|
}
|
|
65
38
|
|
|
66
39
|
/**
|
|
67
|
-
*
|
|
68
|
-
*
|
|
69
|
-
* @param cmd Command to execute
|
|
70
|
-
* @param cwd Working directory in which to run the command (default: `process.cwd()`)
|
|
71
|
-
* @param returnOutput If true, return the command's output. If false/unspecified,
|
|
72
|
-
* inherit stdio from the parent process (so the child's output goes to the console).
|
|
73
|
-
* @returns If `returnOutput` is true, returns the command's output. Otherwise returns undefined.
|
|
40
|
+
* Log `Running: <process.execPath> <...args>`
|
|
74
41
|
*/
|
|
75
|
-
export function
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
const env = { ...process.env };
|
|
79
|
-
env.PATH = resolve('./node_modules/.bin') + SEPARATOR + env.PATH;
|
|
80
|
-
|
|
81
|
-
const output = cp.execSync(cmd, {
|
|
82
|
-
cwd,
|
|
83
|
-
env,
|
|
84
|
-
stdio: returnOutput ? undefined : 'inherit',
|
|
85
|
-
});
|
|
86
|
-
return returnOutput ? (output || '').toString('utf8') : undefined;
|
|
42
|
+
export function logNodeCommand(...args: (string | string[])[]): void {
|
|
43
|
+
logger.info(`Running: ${process.execPath} ${quoteSpaces(args.flat()).join(' ')}`);
|
|
87
44
|
}
|
|
88
45
|
|
|
89
46
|
/**
|
|
90
|
-
* Execute a command in a new process.
|
|
47
|
+
* Execute a command in a new process. Uses `cross-spawn` to avoid issues with spaces in arguments,
|
|
48
|
+
* but does not do any additional escaping. (For further enhancements, consider using the `execa`
|
|
49
|
+
* library instead.)
|
|
50
|
+
*
|
|
51
|
+
* **WARNING: If the `shell` option is enabled, do not pass unsanitized user input to this function.
|
|
52
|
+
* Any input containing shell metacharacters may be used to trigger arbitrary command execution.**
|
|
91
53
|
*
|
|
92
54
|
* @param cmd Command to execute
|
|
93
|
-
* @param args Args for the command
|
|
94
|
-
* @param opts Normal spawn options plus stdout/stderr for piping output.
|
|
55
|
+
* @param args Args for the command. Quoting spaces is handled internally by `cross-spawn`.
|
|
56
|
+
* @param opts Normal spawn options plus stdout/stderr for piping output. (To inherit stdio from the
|
|
57
|
+
* parent process, just use `stdio: 'inherit'` instead.)
|
|
58
|
+
*
|
|
95
59
|
* @returns Promise which will settle when the command completes. If the promise is rejected, the error will
|
|
96
|
-
* include the child process's exit code.
|
|
60
|
+
* include the child process's exit code (`error.code`) or signal (`error.signal`) if relevant.
|
|
61
|
+
* The returned promise also has a `child` property with the spawned `ChildProcess` instance.
|
|
62
|
+
*
|
|
63
|
+
* @deprecated This function is not recommended for use outside the `just-scripts` package.
|
|
64
|
+
* Instead, consider a more mature, purpose-specific library such as `execa` or `nano-spawn`.
|
|
97
65
|
*/
|
|
98
66
|
export function spawn(
|
|
99
67
|
cmd: string,
|
|
@@ -101,8 +69,16 @@ export function spawn(
|
|
|
101
69
|
opts: cp.SpawnOptions & { stdout?: NodeJS.WritableStream; stderr?: NodeJS.WritableStream } = {},
|
|
102
70
|
): Promise<void> {
|
|
103
71
|
return new Promise((resolve, reject) => {
|
|
104
|
-
|
|
105
|
-
|
|
72
|
+
let child: cp.ChildProcess;
|
|
73
|
+
try {
|
|
74
|
+
child = crossSpawn(cmd, args, opts);
|
|
75
|
+
} catch (error) {
|
|
76
|
+
reject(error);
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const onExit = (code: number | null, signal: NodeJS.Signals | null): void => {
|
|
81
|
+
child.off('error', onError);
|
|
106
82
|
if (code) {
|
|
107
83
|
const error = new Error('Command failed: ' + [cmd, ...args].join(' '));
|
|
108
84
|
(error as any).code = code;
|
|
@@ -114,7 +90,17 @@ export function spawn(
|
|
|
114
90
|
} else {
|
|
115
91
|
resolve();
|
|
116
92
|
}
|
|
117
|
-
}
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
// Some error circumstances may fire 'error' rather than 'exit'
|
|
96
|
+
// https://nodejs.org/docs/latest/api/child_process.html#event-error
|
|
97
|
+
const onError = (error: Error): void => {
|
|
98
|
+
reject(error);
|
|
99
|
+
child.off('exit', onExit);
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
child.on('exit', onExit);
|
|
103
|
+
child.on('error', onError);
|
|
118
104
|
|
|
119
105
|
if (opts.stdout) {
|
|
120
106
|
child.stdout?.pipe(opts.stdout);
|