Skip to content

Commit

Permalink
feat: extending PATH (#40)
Browse files Browse the repository at this point in the history
  • Loading branch information
zkochan committed Jun 26, 2022
1 parent 1b46073 commit 430bc92
Show file tree
Hide file tree
Showing 4 changed files with 121 additions and 7 deletions.
1 change: 1 addition & 0 deletions README.md
Expand Up @@ -35,6 +35,7 @@ The same as above, but will just continue if the file does not exist.

- `opts.preserveSymlinks` - _Boolean_ - if true, `--preserve-symlinks` is added to the options passed to NodeJS.
- `opts.nodePath` - _String_ - sets the [NODE_PATH](https://nodejs.org/api/cli.html#cli_node_path_path) env variable.
- `opts.prependToPath` - _String_ - prepends the passed path to PATH before executing the Node.js program.
- `opts.nodeExecPath` - _String_ - sets the path to the Node.js executable.
- `opts.createCmdFile` - _Boolean_ - is `true` on Windows by default. If true, creates a cmd file.
- `opts.createPwshFile` - _Boolean_ - is `true` by default. If true, creates a powershell file.
Expand Down
44 changes: 37 additions & 7 deletions src/index.ts
Expand Up @@ -64,6 +64,8 @@ namespace cmdShim {
* Path to the Node.js executable
*/
nodeExecPath?: string

prependToPath?: string
}
}
type Options = cmdShim.Options
Expand Down Expand Up @@ -327,6 +329,7 @@ function generateCmdShim (src: string, to: string, opts: InternalOptions): strin
let prog = opts.prog
let args = opts.args || ''
const nodePath = normalizePathEnvVar(opts.nodePath).win32
const prependToPath = normalizePathEnvVar(opts.prependToPath).win32
if (!prog) {
prog = quotedPathToTarget
args = ''
Expand All @@ -349,6 +352,9 @@ function generateCmdShim (src: string, to: string, opts: InternalOptions): strin
// node "%~dp0\.\node_modules\npm\bin\npm-cli.js" %*
// )
let cmd = '@SETLOCAL\r\n'
if (prependToPath) {
cmd += `@SET "PATH=${prependToPath}:%PATH%"\r\n`
}
if (nodePath) {
cmd += `\
@IF NOT DEFINED NODE_PATH (\r
Expand Down Expand Up @@ -429,6 +435,11 @@ case \`uname\` in
esac
`
if (opts.prependToPath) {
sh += `\
export PATH="${opts.prependToPath}:$PATH"
`
}
if (shNodePath) {
sh += `\
if [ -z "$NODE_PATH" ]; then
Expand Down Expand Up @@ -474,9 +485,12 @@ function generatePwshShim (src: string, to: string, opts: InternalOptions): stri
shTarget = shTarget.split('\\').join('/')
const quotedPathToTarget = path.isAbsolute(shTarget) ? `"${shTarget}"` : `"$basedir/${shTarget}"`
let args = opts.args || ''
let normalizedPathEnvVar = normalizePathEnvVar(opts.nodePath)
const nodePath = normalizedPathEnvVar.win32
const shNodePath = normalizedPathEnvVar.posix
let normalizedNodePathEnvVar = normalizePathEnvVar(opts.nodePath)
const nodePath = normalizedNodePathEnvVar.win32
const shNodePath = normalizedNodePathEnvVar.posix
let normalizedPrependPathEnvVar = normalizePathEnvVar(opts.prependToPath)
const prependPath = normalizedPrependPathEnvVar.win32
const shPrependPath = normalizedPrependPathEnvVar.posix
if (!pwshProg) {
pwshProg = quotedPathToTarget
args = ''
Expand Down Expand Up @@ -524,27 +538,41 @@ function generatePwshShim (src: string, to: string, opts: InternalOptions): stri
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
$exe=""
${(nodePath || prependPath) ? '$pathsep=":"\n' : ''}\
${nodePath ? `\
$pathsep=":"
$env_node_path=$env:NODE_PATH
$new_node_path="${nodePath}"
` : ''}\
${prependPath ? `\
$env_path=$env:PATH
$prepend_path="${prependPath}"
` : ''}\
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
# Fix case when both the Windows and Linux builds of Node
# are installed in the same directory
$exe=".exe"
${nodePath ? ' $pathsep=";"\n' : ''}\
${(nodePath || prependPath) ? ' $pathsep=";"\n' : ''}\
}`
if (shNodePath) {
if (shNodePath || shPrependPath) {
pwsh += `\
else {
$new_node_path="${shNodePath}"
${shNodePath ? ` $new_node_path="${shNodePath}"\n` : ''}\
${shPrependPath ? ` $prepend_path="${shPrependPath}"\n` : ''}\
}
`
}
if (shNodePath) {
pwsh += `\
if ([string]::IsNullOrEmpty($env_node_path)) {
$env:NODE_PATH=$new_node_path
} else {
$env:NODE_PATH="$env_node_path$pathsep$new_node_path"
}
`
}
if (opts.prependToPath) {
pwsh += `
$env:PATH="$prepend_path$pathsep$env:PATH"
`
}
if (pwshLongProg) {
Expand All @@ -568,6 +596,7 @@ if (Test-Path ${pwshLongProg}) {
$ret=$LASTEXITCODE
}
${nodePath ? '$env:NODE_PATH=$env_node_path\n' : ''}\
${prependPath ? '$env:PATH=$env_path\n' : ''}\
exit $ret
`
} else {
Expand All @@ -579,6 +608,7 @@ if ($MyInvocation.ExpectingInput) {
& ${pwshProg} ${args} ${shTarget} ${progArgs}$args
}
${nodePath ? '$env:NODE_PATH=$env_node_path\n' : ''}\
${prependPath ? '$env:PATH=$env_path\n' : ''}\
exit $LASTEXITCODE
`
}
Expand Down
71 changes: 71 additions & 0 deletions test/__snapshots__/test.js.snap
Expand Up @@ -180,6 +180,77 @@ exit $ret
"
`;

exports[`env shebang with PATH extending env.shim 1`] = `
"#!/bin/sh
basedir=$(dirname \\"$(echo \\"$0\\" | sed -e 's,\\\\\\\\,/,g')\\")
case \`uname\` in
*CYGWIN*) basedir=\`cygpath -w \\"$basedir\\"\`;;
esac
export PATH=\\"/add-to-path:$PATH\\"
if [ -x \\"$basedir/node\\" ]; then
exec \\"$basedir/node\\" \\"$basedir/src.env\\" \\"$@\\"
else
exec node \\"$basedir/src.env\\" \\"$@\\"
fi
"
`;

exports[`env shebang with PATH extending env.shim.cmd 1`] = `
"@SETLOCAL
@SET \\"PATH=\\\\add-to-path:%PATH%\\"
@IF EXIST \\"%~dp0\\\\node.exe\\" (
\\"%~dp0\\\\node.exe\\" \\"%~dp0\\\\src.env\\" %*
) ELSE (
@SET PATHEXT=%PATHEXT:;.JS;=;%
node \\"%~dp0\\\\src.env\\" %*
)
"
`;

exports[`env shebang with PATH extending env.shim.ps1 1`] = `
"#!/usr/bin/env pwsh
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
$exe=\\"\\"
$pathsep=\\":\\"
$env_path=$env:PATH
$prepend_path=\\"\\\\add-to-path\\"
if ($PSVersionTable.PSVersion -lt \\"6.0\\" -or $IsWindows) {
# Fix case when both the Windows and Linux builds of Node
# are installed in the same directory
$exe=\\".exe\\"
$pathsep=\\";\\"
} else {
$prepend_path=\\"/add-to-path\\"
}
$env:PATH=\\"$prepend_path$pathsep$env:PATH\\"
$ret=0
if (Test-Path \\"$basedir/node$exe\\") {
# Support pipeline input
if ($MyInvocation.ExpectingInput) {
$input | & \\"$basedir/node$exe\\" \\"$basedir/src.env\\" $args
} else {
& \\"$basedir/node$exe\\" \\"$basedir/src.env\\" $args
}
$ret=$LASTEXITCODE
} else {
# Support pipeline input
if ($MyInvocation.ExpectingInput) {
$input | & \\"node$exe\\" \\"$basedir/src.env\\" $args
} else {
& \\"node$exe\\" \\"$basedir/src.env\\" $args
}
$ret=$LASTEXITCODE
}
$env:PATH=$env_path
exit $ret
"
`;

exports[`env shebang with args env.args.shim 1`] = `
"#!/bin/sh
basedir=$(dirname \\"$(echo \\"$0\\" | sed -e 's,\\\\\\\\,/,g')\\")
Expand Down
12 changes: 12 additions & 0 deletions test/test.js
Expand Up @@ -57,6 +57,18 @@ describe('env shebang', () => {
testFile(`${to}.ps1`)
})

describe('env shebang with PATH extending', () => {
const src = path.resolve(fixtures, 'src.env')
const to = path.resolve(fixtures, 'env.shim')
beforeAll(() => {
return cmdShim(src, to, { prependToPath: '/add-to-path', createCmdFile: true, fs })
})

testFile(to)
testFile(`${to}.cmd`, '\r\n')
testFile(`${to}.ps1`)
})

describe('env shebang with NODE_PATH', () => {
const src = path.resolve(fixtures, 'src.env')
const to = path.resolve(fixtures, 'env.shim')
Expand Down

0 comments on commit 430bc92

Please sign in to comment.