From a26f8a577589a587bc8f1efda4071aaaf5018570 Mon Sep 17 00:00:00 2001 From: Nate Fischer Date: Thu, 16 Oct 2025 21:33:18 -0700 Subject: [PATCH 1/2] fix: don't wrap first part of command in quotes It seems as though some Windows systems don't allow the first part of the command to be wrapped in quotes. We couldn't detect this issue on CI, but this was reported by a user. Fixes #7 --- index.js | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/index.js b/index.js index cc48b97..5861832 100644 --- a/index.js +++ b/index.js @@ -4,10 +4,14 @@ const { cmdArrayAttr } = require('./common'); const proxyifyCmd = (t, ...cmdStart) => { // Create the target (or use the one passed in) t = t || function _t(...args) { - // Wrap all the arguments in quotes - const newArgs = cmdStart + let newArgs = []; + // The first segment of the command should not be wrapped in quotes + newArgs.push(cmdStart[0]); + + // Wrap all subsequent arguments in quotes + newArgs = newArgs.concat(cmdStart.slice(1) .concat(args) - .map((x) => JSON.stringify(x)); + .map((x) => JSON.stringify(x))); // Run this command in the shell return origShell.exec.call(this.stdout, newArgs.join(' ')); }; From 9ec178895638ff615771abaaf034076b65fab083 Mon Sep 17 00:00:00 2001 From: Nate Fischer Date: Thu, 16 Oct 2025 21:47:04 -0700 Subject: [PATCH 2/2] refactor: switch to using shell.cmd() This swaps the internal implementation to use the new shell.cmd() API. This avoids the need for wrapping with double quotes which should also mean better compatibility on Windows. --- index.js | 19 ++++++++++++++----- test/test.js | 20 ++++++++++++++++++++ 2 files changed, 34 insertions(+), 5 deletions(-) diff --git a/index.js b/index.js index 5861832..ad83865 100644 --- a/index.js +++ b/index.js @@ -9,11 +9,20 @@ const proxyifyCmd = (t, ...cmdStart) => { newArgs.push(cmdStart[0]); // Wrap all subsequent arguments in quotes - newArgs = newArgs.concat(cmdStart.slice(1) - .concat(args) - .map((x) => JSON.stringify(x))); - // Run this command in the shell - return origShell.exec.call(this.stdout, newArgs.join(' ')); + newArgs = newArgs + .concat(cmdStart.slice(1)) + .concat(args); + // Run this command in the shell with globbing temporarily disabled. + // 'noglob' is part of ShellJS internals, but hopefully this will stay + // around. We cannot achieve the same with `set('-f')` because we need to + // know the previous state in order to reset globbing back the way it was. + const oldGlob = origShell.config.noglob; + try { + origShell.config.noglob = true; + return origShell.cmd.call(this.stdout, newArgs); + } finally { + origShell.config.noglob = oldGlob; + } }; // Store the list of commands, in case we have a subcommand chain t[cmdArrayAttr] = cmdStart; diff --git a/test/test.js b/test/test.js index e7ccb2c..37f7389 100644 --- a/test/test.js +++ b/test/test.js @@ -289,6 +289,26 @@ describe('proxy', function describeproxy() { done(); }); + it('other shelljs commands can still glob', (done) => { + const fa = 'a.txt'; + const fglob = '*.txt'; + shell.exec('echo hello world').to(fa); + shell.exec('echo hello world').to(fglob); + + if (unix()) { + shell.__native.rm(fglob); + } else { + shell.del(fglob); + } + fs.existsSync(fglob).should.equal(false); + fs.existsSync(fa).should.equal(true); + + shell.rm('*.txt'); + fs.existsSync(fglob).should.equal(false); + fs.existsSync(fa).should.equal(false); + done(); + }); + it('escapes quotes', (done) => { if (!unix()) { // Windows doesn't support `"` as a character in a filename, see