@zkochan/cmd-shim 2.2.3 → 3.1.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/README.md +1 -0
- package/index.d.ts +47 -0
- package/index.js +112 -17
- package/package.json +8 -7
package/README.md
CHANGED
|
@@ -39,6 +39,7 @@ The same as above, but will just continue if the file does not exist.
|
|
|
39
39
|
- `opts.preserveSymlinks` - _Boolean_ - if true, `--preserve-symlinks` is added to the options passed to NodeJS.
|
|
40
40
|
- `opts.nodePath` - _String_ - sets the [NODE_PATH](https://nodejs.org/api/cli.html#cli_node_path_path) env variable.
|
|
41
41
|
- `opts.createCmdFile` - _Boolean_ - is `true` on Windows by default. If true, creates a cmd file.
|
|
42
|
+
- `opts.createPwshFile` - _Boolean_ - is `true` by default. If true, creates a powershell file.
|
|
42
43
|
|
|
43
44
|
```javascript
|
|
44
45
|
const cmdShim = require('@zkochan/cmd-shim')
|
package/index.d.ts
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
|
|
2
|
+
interface Options {
|
|
3
|
+
/**
|
|
4
|
+
* If a PowerShell script should be created.
|
|
5
|
+
*
|
|
6
|
+
* @default true
|
|
7
|
+
*/
|
|
8
|
+
createPwshFile?: boolean;
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* If a Windows Command Prompt script should be created.
|
|
12
|
+
*
|
|
13
|
+
* @default false
|
|
14
|
+
*/
|
|
15
|
+
createCmdFile?: boolean;
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* If symbolic links should be preserved.
|
|
19
|
+
*
|
|
20
|
+
* @default false
|
|
21
|
+
*/
|
|
22
|
+
preserveSymlinks?: boolean;
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* The path to the executable file.
|
|
26
|
+
*/
|
|
27
|
+
prog?: string;
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* The arguments to initialize the `node` process with.
|
|
31
|
+
*/
|
|
32
|
+
args?: string;
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* The value of the $NODE_PATH environment variable.
|
|
36
|
+
*
|
|
37
|
+
* The single `string` format is only kept for legacy compatibility,
|
|
38
|
+
* and the array form should be preferred.
|
|
39
|
+
*/
|
|
40
|
+
nodePath?: string | string[];
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
declare function cmdShim(src: string, to: string, opts: Options): Promise<void>
|
|
44
|
+
declare namespace cmdShim {
|
|
45
|
+
function cmdShimIfExists(src: string, to: string, opts: Options): Promise<void>
|
|
46
|
+
}
|
|
47
|
+
export = cmdShim;
|
package/index.js
CHANGED
|
@@ -19,6 +19,8 @@ const path = require('path')
|
|
|
19
19
|
const isWindows = require('is-windows')
|
|
20
20
|
const shebangExpr = /^#!\s*(?:\/usr\/bin\/env)?\s*([^ \t]+)(.*)$/
|
|
21
21
|
const DEFAULT_OPTIONS = {
|
|
22
|
+
// Create PowerShell file by default if the option hasn't been specified
|
|
23
|
+
createPwshFile: true,
|
|
22
24
|
createCmdFile: isWindows()
|
|
23
25
|
}
|
|
24
26
|
|
|
@@ -42,12 +44,16 @@ function cmdShim (src, to, opts) {
|
|
|
42
44
|
}
|
|
43
45
|
|
|
44
46
|
function cmdShim_ (src, to, opts) {
|
|
45
|
-
return Promise.all([
|
|
47
|
+
return Promise.all([
|
|
48
|
+
rm(to),
|
|
49
|
+
rm(`${to}.ps1`),
|
|
50
|
+
opts.createCmdFile && rm(`${to}.cmd`)
|
|
51
|
+
])
|
|
46
52
|
.then(() => writeShim(src, to, opts))
|
|
47
53
|
}
|
|
48
54
|
|
|
49
55
|
function writeShim (src, to, opts) {
|
|
50
|
-
opts =
|
|
56
|
+
opts = Object.assign({}, DEFAULT_OPTIONS, opts)
|
|
51
57
|
const defaultArgs = opts.preserveSymlinks ? '--preserve-symlinks' : ''
|
|
52
58
|
// make a cmd file and a sh script
|
|
53
59
|
// First, check if the bin is a #! of some sort.
|
|
@@ -61,7 +67,7 @@ function writeShim (src, to, opts) {
|
|
|
61
67
|
const shebang = firstLine.match(shebangExpr)
|
|
62
68
|
if (!shebang) return writeShim_(src, to, Object.assign({}, opts, {args: defaultArgs}))
|
|
63
69
|
const prog = shebang[1]
|
|
64
|
-
const args = shebang[2] && (defaultArgs && (shebang[2] + ' ' + defaultArgs) || shebang[2]) || defaultArgs
|
|
70
|
+
const args = (shebang[2] && ((defaultArgs && (shebang[2] + ' ' + defaultArgs)) || shebang[2])) || defaultArgs
|
|
65
71
|
return writeShim_(src, to, Object.assign({}, opts, {prog, args}))
|
|
66
72
|
})
|
|
67
73
|
.catch(() => writeShim_(src, to, Object.assign({}, opts, {args: defaultArgs})))
|
|
@@ -69,24 +75,32 @@ function writeShim (src, to, opts) {
|
|
|
69
75
|
}
|
|
70
76
|
|
|
71
77
|
function writeShim_ (src, to, opts) {
|
|
72
|
-
opts =
|
|
78
|
+
opts = Object.assign({}, DEFAULT_OPTIONS, opts)
|
|
73
79
|
let shTarget = path.relative(path.dirname(to), src)
|
|
74
80
|
let target = shTarget.split('/').join('\\')
|
|
75
81
|
let longProg
|
|
76
82
|
let prog = opts.prog
|
|
77
83
|
let shProg = prog && prog.split('\\').join('/')
|
|
78
84
|
let shLongProg
|
|
85
|
+
let pwshProg = shProg && `"${shProg}$exe"`
|
|
86
|
+
let pwshLongProg
|
|
79
87
|
shTarget = shTarget.split('\\').join('/')
|
|
80
88
|
let args = opts.args || ''
|
|
89
|
+
let {
|
|
90
|
+
win32: nodePath,
|
|
91
|
+
posix: shNodePath
|
|
92
|
+
} = normalizePathEnvVar(opts.nodePath)
|
|
81
93
|
if (!prog) {
|
|
82
94
|
prog = `"%~dp0\\${target}"`
|
|
83
95
|
shProg = `"$basedir/${shTarget}"`
|
|
96
|
+
pwshProg = shProg
|
|
84
97
|
args = ''
|
|
85
98
|
target = ''
|
|
86
99
|
shTarget = ''
|
|
87
100
|
} else {
|
|
88
101
|
longProg = `"%~dp0\\${prog}.exe"`
|
|
89
102
|
shLongProg = '"$basedir/' + prog + '"'
|
|
103
|
+
pwshLongProg = `"$basedir/${prog}$exe"`
|
|
90
104
|
target = `"%~dp0\\${target}"`
|
|
91
105
|
shTarget = `"$basedir/${shTarget}"`
|
|
92
106
|
}
|
|
@@ -100,7 +114,7 @@ function writeShim_ (src, to, opts) {
|
|
|
100
114
|
// SET PATHEXT=%PATHEXT:;.JS;=;%
|
|
101
115
|
// node "%~dp0\.\node_modules\npm\bin\npm-cli.js" %*
|
|
102
116
|
// )
|
|
103
|
-
cmd =
|
|
117
|
+
cmd = nodePath ? `@SET NODE_PATH=${nodePath}\r\n` : ''
|
|
104
118
|
if (longProg) {
|
|
105
119
|
cmd += '@IF EXIST ' + longProg + ' (\r\n' +
|
|
106
120
|
' ' + longProg + ' ' + args + ' ' + target + ' %*\r\n' +
|
|
@@ -131,17 +145,16 @@ function writeShim_ (src, to, opts) {
|
|
|
131
145
|
// exit $ret
|
|
132
146
|
|
|
133
147
|
let sh = '#!/bin/sh\n'
|
|
134
|
-
|
|
148
|
+
sh = sh +
|
|
149
|
+
"basedir=$(dirname \"$(echo \"$0\" | sed -e 's,\\\\,/,g')\")\n" +
|
|
150
|
+
'\n' +
|
|
151
|
+
'case `uname` in\n' +
|
|
152
|
+
' *CYGWIN*) basedir=`cygpath -w "$basedir"`;;\n' +
|
|
153
|
+
'esac\n' +
|
|
154
|
+
'\n'
|
|
155
|
+
const env = opts.nodePath ? `NODE_PATH="${shNodePath}" ` : ''
|
|
135
156
|
|
|
136
157
|
if (shLongProg) {
|
|
137
|
-
sh = sh +
|
|
138
|
-
"basedir=$(dirname \"$(echo \"$0\" | sed -e 's,\\\\,/,g')\")\n" +
|
|
139
|
-
'\n' +
|
|
140
|
-
'case `uname` in\n' +
|
|
141
|
-
' *CYGWIN*) basedir=`cygpath -w "$basedir"`;;\n' +
|
|
142
|
-
'esac\n' +
|
|
143
|
-
'\n'
|
|
144
|
-
|
|
145
158
|
sh = sh +
|
|
146
159
|
'if [ -x ' + shLongProg + ' ]; then\n' +
|
|
147
160
|
' ' + env + shLongProg + ' ' + args + ' ' + shTarget + ' "$@"\n' +
|
|
@@ -152,20 +165,102 @@ function writeShim_ (src, to, opts) {
|
|
|
152
165
|
'fi\n' +
|
|
153
166
|
'exit $ret\n'
|
|
154
167
|
} else {
|
|
155
|
-
sh = env + shProg + ' ' + args + ' ' + shTarget + ' "$@"\n' +
|
|
168
|
+
sh = sh + env + shProg + ' ' + args + ' ' + shTarget + ' "$@"\n' +
|
|
156
169
|
'exit $?\n'
|
|
157
170
|
}
|
|
158
171
|
|
|
172
|
+
// #!/usr/bin/env pwsh
|
|
173
|
+
// $basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
|
|
174
|
+
//
|
|
175
|
+
// $ret=0
|
|
176
|
+
// $exe = ""
|
|
177
|
+
// if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
|
|
178
|
+
// # Fix case when both the Windows and Linux builds of Node
|
|
179
|
+
// # are installed in the same directory
|
|
180
|
+
// $exe = ".exe"
|
|
181
|
+
// }
|
|
182
|
+
// if (Test-Path "$basedir/node") {
|
|
183
|
+
// & "$basedir/node$exe" "$basedir/node_modules/npm/bin/npm-cli.js" $args
|
|
184
|
+
// $ret=$LASTEXITCODE
|
|
185
|
+
// } else {
|
|
186
|
+
// & "node$exe" "$basedir/node_modules/npm/bin/npm-cli.js" $args
|
|
187
|
+
// $ret=$LASTEXITCODE
|
|
188
|
+
// }
|
|
189
|
+
// exit $ret
|
|
190
|
+
let pwsh = '#!/usr/bin/env pwsh\n' +
|
|
191
|
+
'$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent\n' +
|
|
192
|
+
'\n' +
|
|
193
|
+
'$exe=""\n' +
|
|
194
|
+
(opts.nodePath ? '$env_node_path=$env:NODE_PATH\n' +
|
|
195
|
+
`$env:NODE_PATH="${nodePath}"\n` : '') +
|
|
196
|
+
'if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {\n' +
|
|
197
|
+
' # Fix case when both the Windows and Linux builds of Node\n' +
|
|
198
|
+
' # are installed in the same directory\n' +
|
|
199
|
+
' $exe=".exe"\n' +
|
|
200
|
+
'}'
|
|
201
|
+
if (opts.nodePath) {
|
|
202
|
+
pwsh = pwsh +
|
|
203
|
+
' else {\n' +
|
|
204
|
+
` $env:NODE_PATH="${shNodePath}"\n` +
|
|
205
|
+
'}'
|
|
206
|
+
}
|
|
207
|
+
pwsh += '\n'
|
|
208
|
+
if (shLongProg) {
|
|
209
|
+
pwsh = pwsh +
|
|
210
|
+
'$ret=0\n' +
|
|
211
|
+
`if (Test-Path ${pwshLongProg}) {\n` +
|
|
212
|
+
` & ${pwshLongProg} ${args} ${shTarget} $args\n` +
|
|
213
|
+
' $ret=$LASTEXITCODE\n' +
|
|
214
|
+
'} else {\n' +
|
|
215
|
+
` & ${pwshProg} ${args} ${shTarget} $args\n` +
|
|
216
|
+
' $ret=$LASTEXITCODE\n' +
|
|
217
|
+
'}\n' +
|
|
218
|
+
(opts.nodePath ? '$env:NODE_PATH=$env_node_path\n' : '') +
|
|
219
|
+
'exit $ret\n'
|
|
220
|
+
} else {
|
|
221
|
+
pwsh = pwsh +
|
|
222
|
+
`& ${pwshProg} ${args} ${shTarget} $args\n` +
|
|
223
|
+
(opts.nodePath ? '$env:NODE_PATH=$env_node_path\n' : '') +
|
|
224
|
+
'exit $LASTEXITCODE\n'
|
|
225
|
+
}
|
|
226
|
+
|
|
159
227
|
return Promise.all([
|
|
160
228
|
opts.createCmdFile && fs.writeFile(to + '.cmd', cmd, 'utf8'),
|
|
229
|
+
opts.createPwshFile && fs.writeFile(`${to}.ps1`, pwsh, 'utf8'),
|
|
161
230
|
fs.writeFile(to, sh, 'utf8')
|
|
162
231
|
])
|
|
163
|
-
|
|
232
|
+
.then(() => chmodShim(to, opts))
|
|
164
233
|
}
|
|
165
234
|
|
|
166
|
-
function chmodShim (to, createCmdFile) {
|
|
235
|
+
function chmodShim (to, {createCmdFile, createPwshFile}) {
|
|
167
236
|
return Promise.all([
|
|
168
237
|
fs.chmod(to, 0o755),
|
|
238
|
+
createPwshFile && fs.chmod(`${to}.ps1`, 0o755),
|
|
169
239
|
createCmdFile && fs.chmod(`${to}.cmd`, 0o755)
|
|
170
240
|
])
|
|
171
241
|
}
|
|
242
|
+
|
|
243
|
+
/**
|
|
244
|
+
* @param {string|string[]} nodePath
|
|
245
|
+
* @returns {{win32:string,posix:string}}
|
|
246
|
+
*/
|
|
247
|
+
function normalizePathEnvVar (nodePath) {
|
|
248
|
+
if (!nodePath) {
|
|
249
|
+
return {
|
|
250
|
+
win32: nodePath,
|
|
251
|
+
posix: nodePath
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
let split = (typeof nodePath === 'string' ? nodePath.split(path.delimiter) : Array.from(nodePath))
|
|
255
|
+
let result = {}
|
|
256
|
+
for (let i = 0; i < split.length; i++) {
|
|
257
|
+
const win32 = split[i].split('/').join('\\')
|
|
258
|
+
const posix = isWindows() ? split[i].split('\\').join('/').replace(/^([^:\\/]*):/, (_, $1) => `/mnt/${$1.toLowerCase()}`) : split[i]
|
|
259
|
+
|
|
260
|
+
result.win32 = result.win32 ? `${result.win32};${win32}` : win32
|
|
261
|
+
result.posix = result.posix ? `${result.posix}:${posix}` : posix
|
|
262
|
+
|
|
263
|
+
result[i] = {win32, posix}
|
|
264
|
+
}
|
|
265
|
+
return result
|
|
266
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zkochan/cmd-shim",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.1.0",
|
|
4
4
|
"description": "Used in pnpm for command line application support",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Zoltan Kochan",
|
|
@@ -8,13 +8,15 @@
|
|
|
8
8
|
"url": "http://kochan.io"
|
|
9
9
|
},
|
|
10
10
|
"scripts": {
|
|
11
|
-
"test:unit": "tape test/*.js
|
|
11
|
+
"test:unit": "tape test/*.js",
|
|
12
12
|
"test": "standard && npm run test:unit && mos test",
|
|
13
13
|
"md": "mos"
|
|
14
14
|
},
|
|
15
15
|
"files": [
|
|
16
|
+
"index.d.ts",
|
|
16
17
|
"index.js"
|
|
17
18
|
],
|
|
19
|
+
"types": "index.d.ts",
|
|
18
20
|
"repository": {
|
|
19
21
|
"type": "git",
|
|
20
22
|
"url": "https://github.com/pnpm/cmd-shim.git"
|
|
@@ -28,14 +30,13 @@
|
|
|
28
30
|
"devDependencies": {
|
|
29
31
|
"mos": "^1.3.1",
|
|
30
32
|
"mos-plugin-readme": "^1.0.4",
|
|
31
|
-
"rimraf": "
|
|
32
|
-
"standard": "^
|
|
33
|
-
"tap-diff": "^0.1.1",
|
|
33
|
+
"rimraf": "^2.6.2",
|
|
34
|
+
"standard": "^11.0.1",
|
|
34
35
|
"tape": "^4.6.2",
|
|
35
|
-
"tape-promise": "^
|
|
36
|
+
"tape-promise": "^3.0.0"
|
|
36
37
|
},
|
|
37
38
|
"engines": {
|
|
38
|
-
"node": ">=
|
|
39
|
+
"node": ">=6"
|
|
39
40
|
},
|
|
40
41
|
"mos": {
|
|
41
42
|
"plugins": [
|