start-command 0.24.6 → 0.24.7
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.md +16 -0
- package/package.json +1 -1
- package/src/lib/isolation.js +8 -24
- package/src/lib/shell-utils.js +47 -0
- package/test/regression-91.test.js +36 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# start-command
|
|
2
2
|
|
|
3
|
+
## 0.24.7
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 1eef620: fix: display `bash -c "..."` commands with quotes in command line output (issue #91)
|
|
8
|
+
|
|
9
|
+
When a command like `bash -i -c nvm --version` was passed to Docker isolation,
|
|
10
|
+
the displayed command line was missing quotes around the `-c` script argument,
|
|
11
|
+
making the output misleading (showing `bash -i -c nvm --version` instead of
|
|
12
|
+
`bash -i -c "nvm --version"`).
|
|
13
|
+
|
|
14
|
+
A new `buildDisplayCommand()` helper is added in `shell-utils.js` that quotes
|
|
15
|
+
any space-containing `-c` script arguments so the displayed command accurately
|
|
16
|
+
reflects how it was interpreted. Shell command helpers are extracted from
|
|
17
|
+
`isolation.js` into a new `shell-utils.js` module to keep file sizes within limits.
|
|
18
|
+
|
|
3
19
|
## 0.24.6
|
|
4
20
|
|
|
5
21
|
### Patch Changes
|
package/package.json
CHANGED
package/src/lib/isolation.js
CHANGED
|
@@ -214,29 +214,12 @@ function getShellInteractiveFlag(shellPath) {
|
|
|
214
214
|
const shellName = shellPath.split('/').pop();
|
|
215
215
|
return shellName === 'bash' || shellName === 'zsh' ? '-i' : null;
|
|
216
216
|
}
|
|
217
|
-
const
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
}
|
|
223
|
-
/** True if command is a shell invocation with -c (e.g. `bash -i -c "cmd"`); avoids double-wrapping (issue #91). */
|
|
224
|
-
function isShellInvocationWithArgs(command) {
|
|
225
|
-
const parts = command.trim().split(/\s+/);
|
|
226
|
-
return SHELL_NAMES.includes(path.basename(parts[0])) && parts.includes('-c');
|
|
227
|
-
}
|
|
228
|
-
/** Build argv for shell-with-c command; everything after -c is one argument (reverses commandArgs.join(' ')). */
|
|
229
|
-
function buildShellWithArgsCmdArgs(command) {
|
|
230
|
-
const parts = command.trim().split(/\s+/);
|
|
231
|
-
const cIdx = parts.indexOf('-c');
|
|
232
|
-
if (cIdx === -1) {
|
|
233
|
-
return parts;
|
|
234
|
-
}
|
|
235
|
-
const scriptArg = parts.slice(cIdx + 1).join(' ');
|
|
236
|
-
return scriptArg.length > 0
|
|
237
|
-
? [...parts.slice(0, cIdx + 1), scriptArg]
|
|
238
|
-
: parts.slice(0, cIdx + 1);
|
|
239
|
-
}
|
|
217
|
+
const {
|
|
218
|
+
isInteractiveShellCommand,
|
|
219
|
+
isShellInvocationWithArgs,
|
|
220
|
+
buildShellWithArgsCmdArgs,
|
|
221
|
+
buildDisplayCommand,
|
|
222
|
+
} = require('./shell-utils');
|
|
240
223
|
|
|
241
224
|
/** Returns true if the current process has a TTY attached. */
|
|
242
225
|
function hasTTY() {
|
|
@@ -764,7 +747,7 @@ function runInDocker(command, options = {}) {
|
|
|
764
747
|
: detectShellInEnvironment('docker', options, options.shell);
|
|
765
748
|
const shellInteractiveFlag = getShellInteractiveFlag(shellToUse);
|
|
766
749
|
|
|
767
|
-
console.log(outputBlocks.createCommandLine(command));
|
|
750
|
+
console.log(outputBlocks.createCommandLine(buildDisplayCommand(command)));
|
|
768
751
|
console.log();
|
|
769
752
|
|
|
770
753
|
try {
|
|
@@ -974,6 +957,7 @@ module.exports = {
|
|
|
974
957
|
isInteractiveShellCommand,
|
|
975
958
|
isShellInvocationWithArgs,
|
|
976
959
|
buildShellWithArgsCmdArgs,
|
|
960
|
+
buildDisplayCommand,
|
|
977
961
|
detectShellInEnvironment,
|
|
978
962
|
runInScreen,
|
|
979
963
|
runInTmux,
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/** Shell command detection and argument-building utilities for start-command */
|
|
2
|
+
|
|
3
|
+
const path = require('path');
|
|
4
|
+
|
|
5
|
+
const SHELL_NAMES = ['bash', 'zsh', 'sh', 'fish', 'ksh', 'csh', 'tcsh', 'dash'];
|
|
6
|
+
|
|
7
|
+
/** True if command is a bare shell invocation (no -c); avoids bash-inside-bash (issue #84). */
|
|
8
|
+
function isInteractiveShellCommand(command) {
|
|
9
|
+
const parts = command.trim().split(/\s+/);
|
|
10
|
+
return SHELL_NAMES.includes(path.basename(parts[0])) && !parts.includes('-c');
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/** True if command is a shell invocation with -c (e.g. `bash -i -c "cmd"`); avoids double-wrapping (issue #91). */
|
|
14
|
+
function isShellInvocationWithArgs(command) {
|
|
15
|
+
const parts = command.trim().split(/\s+/);
|
|
16
|
+
return SHELL_NAMES.includes(path.basename(parts[0])) && parts.includes('-c');
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/** Build argv for shell-with-c command; everything after -c is one argument (reverses commandArgs.join(' ')). */
|
|
20
|
+
function buildShellWithArgsCmdArgs(command) {
|
|
21
|
+
const parts = command.trim().split(/\s+/);
|
|
22
|
+
const cIdx = parts.indexOf('-c');
|
|
23
|
+
if (cIdx === -1) {
|
|
24
|
+
return parts;
|
|
25
|
+
}
|
|
26
|
+
const scriptArg = parts.slice(cIdx + 1).join(' ');
|
|
27
|
+
return scriptArg.length > 0
|
|
28
|
+
? [...parts.slice(0, cIdx + 1), scriptArg]
|
|
29
|
+
: parts.slice(0, cIdx + 1);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/** Build a display string for a command, quoting arguments that contain spaces (issue #91). */
|
|
33
|
+
function buildDisplayCommand(command) {
|
|
34
|
+
if (!isShellInvocationWithArgs(command)) {
|
|
35
|
+
return command;
|
|
36
|
+
}
|
|
37
|
+
const argv = buildShellWithArgsCmdArgs(command);
|
|
38
|
+
return argv.map((arg) => (arg.includes(' ') ? `"${arg}"` : arg)).join(' ');
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
module.exports = {
|
|
42
|
+
SHELL_NAMES,
|
|
43
|
+
isInteractiveShellCommand,
|
|
44
|
+
isShellInvocationWithArgs,
|
|
45
|
+
buildShellWithArgsCmdArgs,
|
|
46
|
+
buildDisplayCommand,
|
|
47
|
+
};
|
|
@@ -34,6 +34,7 @@ const {
|
|
|
34
34
|
isInteractiveShellCommand,
|
|
35
35
|
isShellInvocationWithArgs,
|
|
36
36
|
buildShellWithArgsCmdArgs,
|
|
37
|
+
buildDisplayCommand,
|
|
37
38
|
} = require('../src/lib/isolation');
|
|
38
39
|
|
|
39
40
|
// Helper: mirrors the attached-mode command-args construction logic in runInDocker.
|
|
@@ -258,3 +259,38 @@ describe('isShellInvocationWithArgs is mutually exclusive with isInteractiveShel
|
|
|
258
259
|
});
|
|
259
260
|
}
|
|
260
261
|
});
|
|
262
|
+
|
|
263
|
+
describe('buildDisplayCommand (issue #91 display fix)', () => {
|
|
264
|
+
it('should quote the -c script argument when it contains spaces', () => {
|
|
265
|
+
assert.strictEqual(
|
|
266
|
+
buildDisplayCommand('bash -i -c nvm --version'),
|
|
267
|
+
'bash -i -c "nvm --version"'
|
|
268
|
+
);
|
|
269
|
+
});
|
|
270
|
+
|
|
271
|
+
it('should quote the -c script argument for plain "bash -c echo hello"', () => {
|
|
272
|
+
assert.strictEqual(
|
|
273
|
+
buildDisplayCommand('bash -c echo hello'),
|
|
274
|
+
'bash -c "echo hello"'
|
|
275
|
+
);
|
|
276
|
+
});
|
|
277
|
+
|
|
278
|
+
it('should not double-quote if script has no spaces', () => {
|
|
279
|
+
assert.strictEqual(buildDisplayCommand('bash -c ls'), 'bash -c ls');
|
|
280
|
+
});
|
|
281
|
+
|
|
282
|
+
it('should return command unchanged for non-shell-with-args commands', () => {
|
|
283
|
+
assert.strictEqual(buildDisplayCommand('nvm --version'), 'nvm --version');
|
|
284
|
+
});
|
|
285
|
+
|
|
286
|
+
it('should return command unchanged for bare shell invocations', () => {
|
|
287
|
+
assert.strictEqual(buildDisplayCommand('bash -i'), 'bash -i');
|
|
288
|
+
});
|
|
289
|
+
|
|
290
|
+
it('should handle zsh -c with spaces', () => {
|
|
291
|
+
assert.strictEqual(
|
|
292
|
+
buildDisplayCommand('zsh -c echo hello world'),
|
|
293
|
+
'zsh -c "echo hello world"'
|
|
294
|
+
);
|
|
295
|
+
});
|
|
296
|
+
});
|