@npmcli/run-script
Advanced tools
Comparing version 4.1.0 to 4.1.1
@@ -5,3 +5,3 @@ 'use strict' | ||
// this code adapted from: https://blogs.msdn.microsoft.com/twistylittlepassagesallalike/2011/04/23/everyone-quotes-command-line-arguments-the-wrong-way/ | ||
const cmd = (input) => { | ||
const cmd = (input, doubleEscape) => { | ||
if (!input.length) { | ||
@@ -41,3 +41,7 @@ return '""' | ||
result = result.replace(/[!^&()<>|"]/g, '^$&') | ||
// except for % which is escaped with another % | ||
if (doubleEscape) { | ||
result = result.replace(/[!^&()<>|"]/g, '^$&') | ||
} | ||
// except for % which is escaped with another %, and only once | ||
result = result.replace(/%/g, '%%') | ||
@@ -44,0 +48,0 @@ |
@@ -6,3 +6,3 @@ /* eslint camelcase: "off" */ | ||
const { tmpdir } = require('os') | ||
const { resolve } = require('path') | ||
const { isAbsolute, resolve } = require('path') | ||
const which = require('which') | ||
@@ -24,15 +24,55 @@ const npm_config_node_gyp = require.resolve('node-gyp/bin/node-gyp.js') | ||
const spawnEnv = setPATH(path, { | ||
// we need to at least save the PATH environment var | ||
...process.env, | ||
...env, | ||
npm_package_json: resolve(path, 'package.json'), | ||
npm_lifecycle_event: event, | ||
npm_lifecycle_script: cmd, | ||
npm_config_node_gyp, | ||
}) | ||
let scriptFile | ||
let script = '' | ||
const isCmd = /(?:^|\\)cmd(?:\.exe)?$/i.test(scriptShell) | ||
if (isCmd) { | ||
let initialCmd = '' | ||
let insideQuotes = false | ||
for (let i = 0; i < cmd.length; ++i) { | ||
const char = cmd.charAt(i) | ||
if (char === ' ' && !insideQuotes) { | ||
break | ||
} | ||
initialCmd += char | ||
if (char === '"' || char === "'") { | ||
insideQuotes = !insideQuotes | ||
} | ||
} | ||
let pathToInitial | ||
try { | ||
pathToInitial = which.sync(initialCmd, { | ||
path: spawnEnv.path, | ||
pathext: spawnEnv.pathext, | ||
}).toLowerCase() | ||
} catch (err) { | ||
pathToInitial = initialCmd.toLowerCase() | ||
} | ||
const doubleEscape = pathToInitial.endsWith('.cmd') || pathToInitial.endsWith('.bat') | ||
scriptFile = resolve(tmpdir(), `${event}-${Date.now()}.cmd`) | ||
script += '@echo off\n' | ||
script += `${cmd} ${args.map((arg) => escape.cmd(arg)).join(' ')}` | ||
script += `${cmd} ${args.map((arg) => escape.cmd(arg, doubleEscape)).join(' ')}` | ||
} else { | ||
const shellPath = which.sync(scriptShell) | ||
const shebang = isAbsolute(scriptShell) | ||
? `#!${scriptShell}` | ||
: `#!/usr/bin/env ${scriptShell}` | ||
scriptFile = resolve(tmpdir(), `${event}-${Date.now()}.sh`) | ||
script += `#!${shellPath}\n` | ||
script += `${shebang}\n` | ||
script += `${cmd} ${args.map((arg) => escape.sh(arg)).join(' ')}` | ||
} | ||
writeFile(scriptFile, script) | ||
@@ -45,11 +85,3 @@ if (!isCmd) { | ||
const spawnOpts = { | ||
env: setPATH(path, { | ||
// we need to at least save the PATH environment var | ||
...process.env, | ||
...env, | ||
npm_package_json: resolve(path, 'package.json'), | ||
npm_lifecycle_event: event, | ||
npm_lifecycle_script: cmd, | ||
npm_config_node_gyp, | ||
}), | ||
env: spawnEnv, | ||
stdioString, | ||
@@ -56,0 +88,0 @@ stdio, |
{ | ||
"name": "@npmcli/run-script", | ||
"version": "4.1.0", | ||
"version": "4.1.1", | ||
"description": "Run a lifecycle script for a package (descendant of npm-lifecycle)", | ||
@@ -5,0 +5,0 @@ "author": "GitHub Inc.", |
@@ -160,2 +160,6 @@ # @npmcli/run-script | ||
In Windows, when the shell is cmd, and when the initial command in the script | ||
is a known batch file (i.e. `something.cmd`) we double escape additional | ||
arguments so that the shim scripts npm installs work correctly. | ||
The actual implementation of the escaping is in `lib/escape.js`. |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
20875
396
165