@zkochan/cmd-shim 5.2.1 → 5.3.1
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/LICENSE +27 -27
- package/README.md +52 -51
- package/index.d.ts +73 -72
- package/index.d.ts.map +1 -1
- package/index.js +455 -406
- package/index.js.map +1 -1
- package/package.json +8 -7
package/index.js
CHANGED
|
@@ -1,244 +1,269 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
cmdShim.ifExists = cmdShimIfExists;
|
|
3
|
-
const util_1 = require("util");
|
|
4
|
-
const path = require("path");
|
|
5
|
-
const isWindows = require("is-windows");
|
|
6
|
-
const CMD_EXTENSION = require("cmd-extension");
|
|
7
|
-
const shebangExpr = /^#!\s*(?:\/usr\/bin\/env)?\s*([^ \t]+)(.*)$/;
|
|
8
|
-
const DEFAULT_OPTIONS = {
|
|
9
|
-
// Create PowerShell file by default if the option hasn't been specified
|
|
10
|
-
createPwshFile: true,
|
|
11
|
-
createCmdFile: isWindows(),
|
|
12
|
-
fs: require('fs')
|
|
13
|
-
};
|
|
14
|
-
/**
|
|
15
|
-
* Map from extensions of files that this module is frequently used for to their runtime.
|
|
16
|
-
* @type {Map<string, string>}
|
|
17
|
-
*/
|
|
18
|
-
const extensionToProgramMap = new Map([
|
|
19
|
-
['.js', 'node'],
|
|
20
|
-
['.cjs', 'node'],
|
|
21
|
-
['.mjs', 'node'],
|
|
22
|
-
['.cmd', 'cmd'],
|
|
23
|
-
['.bat', 'cmd'],
|
|
24
|
-
['.ps1', 'pwsh'],
|
|
25
|
-
['.sh', 'sh']
|
|
26
|
-
]);
|
|
27
|
-
function ingestOptions(opts) {
|
|
28
|
-
const opts_ = { ...DEFAULT_OPTIONS, ...opts };
|
|
29
|
-
const fs = opts_.fs;
|
|
30
|
-
opts_.fs_ = {
|
|
31
|
-
chmod: fs.chmod ? util_1.promisify(fs.chmod) : (async () => { }),
|
|
32
|
-
mkdir: util_1.promisify(fs.mkdir),
|
|
33
|
-
readFile: util_1.promisify(fs.readFile),
|
|
34
|
-
stat: util_1.promisify(fs.stat),
|
|
35
|
-
unlink: util_1.promisify(fs.unlink),
|
|
36
|
-
writeFile: util_1.promisify(fs.writeFile)
|
|
37
|
-
};
|
|
38
|
-
return opts_;
|
|
39
|
-
}
|
|
40
|
-
/**
|
|
41
|
-
* Try to create shims.
|
|
42
|
-
*
|
|
43
|
-
* @param src Path to program (executable or script).
|
|
44
|
-
* @param to Path to shims.
|
|
45
|
-
* Don't add an extension if you will create multiple types of shims.
|
|
46
|
-
* @param opts Options.
|
|
47
|
-
* @throws If `src` is missing.
|
|
48
|
-
*/
|
|
49
|
-
async function cmdShim(src, to, opts) {
|
|
50
|
-
const opts_ = ingestOptions(opts);
|
|
51
|
-
await
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
*
|
|
56
|
-
*
|
|
57
|
-
*
|
|
58
|
-
*
|
|
59
|
-
* @param
|
|
60
|
-
*
|
|
61
|
-
*
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
*
|
|
69
|
-
*
|
|
70
|
-
*
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
*
|
|
78
|
-
*
|
|
79
|
-
* @param
|
|
80
|
-
*
|
|
81
|
-
*
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
//
|
|
87
|
-
//
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
*
|
|
94
|
-
*
|
|
95
|
-
*
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
*
|
|
103
|
-
*
|
|
104
|
-
*
|
|
105
|
-
*
|
|
106
|
-
* @param
|
|
107
|
-
*
|
|
108
|
-
*
|
|
109
|
-
* @param
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
const
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
*
|
|
125
|
-
*
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
*
|
|
133
|
-
*
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
//
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
*
|
|
143
|
-
*
|
|
144
|
-
*
|
|
145
|
-
* @
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
*
|
|
194
|
-
*
|
|
195
|
-
* @param
|
|
196
|
-
* @param
|
|
197
|
-
*
|
|
198
|
-
* @param opts
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
// `
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
if (
|
|
1
|
+
'use strict';
|
|
2
|
+
cmdShim.ifExists = cmdShimIfExists;
|
|
3
|
+
const util_1 = require("util");
|
|
4
|
+
const path = require("path");
|
|
5
|
+
const isWindows = require("is-windows");
|
|
6
|
+
const CMD_EXTENSION = require("cmd-extension");
|
|
7
|
+
const shebangExpr = /^#!\s*(?:\/usr\/bin\/env)?\s*([^ \t]+)(.*)$/;
|
|
8
|
+
const DEFAULT_OPTIONS = {
|
|
9
|
+
// Create PowerShell file by default if the option hasn't been specified
|
|
10
|
+
createPwshFile: true,
|
|
11
|
+
createCmdFile: isWindows(),
|
|
12
|
+
fs: require('fs')
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* Map from extensions of files that this module is frequently used for to their runtime.
|
|
16
|
+
* @type {Map<string, string>}
|
|
17
|
+
*/
|
|
18
|
+
const extensionToProgramMap = new Map([
|
|
19
|
+
['.js', 'node'],
|
|
20
|
+
['.cjs', 'node'],
|
|
21
|
+
['.mjs', 'node'],
|
|
22
|
+
['.cmd', 'cmd'],
|
|
23
|
+
['.bat', 'cmd'],
|
|
24
|
+
['.ps1', 'pwsh'],
|
|
25
|
+
['.sh', 'sh']
|
|
26
|
+
]);
|
|
27
|
+
function ingestOptions(opts) {
|
|
28
|
+
const opts_ = { ...DEFAULT_OPTIONS, ...opts };
|
|
29
|
+
const fs = opts_.fs;
|
|
30
|
+
opts_.fs_ = {
|
|
31
|
+
chmod: fs.chmod ? (0, util_1.promisify)(fs.chmod) : (async () => { }),
|
|
32
|
+
mkdir: (0, util_1.promisify)(fs.mkdir),
|
|
33
|
+
readFile: (0, util_1.promisify)(fs.readFile),
|
|
34
|
+
stat: (0, util_1.promisify)(fs.stat),
|
|
35
|
+
unlink: (0, util_1.promisify)(fs.unlink),
|
|
36
|
+
writeFile: (0, util_1.promisify)(fs.writeFile)
|
|
37
|
+
};
|
|
38
|
+
return opts_;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Try to create shims.
|
|
42
|
+
*
|
|
43
|
+
* @param src Path to program (executable or script).
|
|
44
|
+
* @param to Path to shims.
|
|
45
|
+
* Don't add an extension if you will create multiple types of shims.
|
|
46
|
+
* @param opts Options.
|
|
47
|
+
* @throws If `src` is missing.
|
|
48
|
+
*/
|
|
49
|
+
async function cmdShim(src, to, opts) {
|
|
50
|
+
const opts_ = ingestOptions(opts);
|
|
51
|
+
await cmdShim_(src, to, opts_);
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Try to create shims.
|
|
55
|
+
*
|
|
56
|
+
* Does nothing if `src` doesn't exist.
|
|
57
|
+
*
|
|
58
|
+
* @param src Path to program (executable or script).
|
|
59
|
+
* @param to Path to shims.
|
|
60
|
+
* Don't add an extension if you will create multiple types of shims.
|
|
61
|
+
* @param opts Options.
|
|
62
|
+
*/
|
|
63
|
+
function cmdShimIfExists(src, to, opts) {
|
|
64
|
+
return cmdShim(src, to, opts).catch(() => { });
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Try to unlink, but ignore errors.
|
|
68
|
+
* Any problems will surface later.
|
|
69
|
+
*
|
|
70
|
+
* @param path File to be removed.
|
|
71
|
+
*/
|
|
72
|
+
function rm(path, opts) {
|
|
73
|
+
return opts.fs_.unlink(path).catch(() => { });
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Try to create shims **even if `src` is missing**.
|
|
77
|
+
*
|
|
78
|
+
* @param src Path to program (executable or script).
|
|
79
|
+
* @param to Path to shims.
|
|
80
|
+
* Don't add an extension if you will create multiple types of shims.
|
|
81
|
+
* @param opts Options.
|
|
82
|
+
*/
|
|
83
|
+
async function cmdShim_(src, to, opts) {
|
|
84
|
+
const srcRuntimeInfo = await searchScriptRuntime(src, opts);
|
|
85
|
+
// Always tries to create all types of shims by calling `writeAllShims` as of now.
|
|
86
|
+
// Append your code here to change the behavior in response to `srcRuntimeInfo`.
|
|
87
|
+
// Create 3 shims for (Ba)sh in Cygwin / MSYS, no extension) & CMD (.cmd) & PowerShell (.ps1)
|
|
88
|
+
await writeShimsPreCommon(to, opts);
|
|
89
|
+
return writeAllShims(src, to, srcRuntimeInfo, opts);
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Do processes before **all** shims are created.
|
|
93
|
+
* This must be called **only once** for one call of `cmdShim(IfExists)`.
|
|
94
|
+
*
|
|
95
|
+
* @param target Path of shims that are going to be created.
|
|
96
|
+
*/
|
|
97
|
+
function writeShimsPreCommon(target, opts) {
|
|
98
|
+
return opts.fs_.mkdir(path.dirname(target), { recursive: true });
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Write all types (sh & cmd & pwsh) of shims to files.
|
|
102
|
+
* Extensions (`.cmd` and `.ps1`) are appended to cmd and pwsh shims.
|
|
103
|
+
*
|
|
104
|
+
*
|
|
105
|
+
* @param src Path to program (executable or script).
|
|
106
|
+
* @param to Path to shims **without extensions**.
|
|
107
|
+
* Extensions are added for CMD and PowerShell shims.
|
|
108
|
+
* @param srcRuntimeInfo Return value of `await searchScriptRuntime(src)`.
|
|
109
|
+
* @param opts Options.
|
|
110
|
+
*/
|
|
111
|
+
function writeAllShims(src, to, srcRuntimeInfo, opts) {
|
|
112
|
+
const opts_ = ingestOptions(opts);
|
|
113
|
+
const generatorAndExts = [{ generator: generateShShim, extension: '' }];
|
|
114
|
+
if (opts_.createCmdFile) {
|
|
115
|
+
generatorAndExts.push({ generator: generateCmdShim, extension: CMD_EXTENSION });
|
|
116
|
+
}
|
|
117
|
+
if (opts_.createPwshFile) {
|
|
118
|
+
generatorAndExts.push({ generator: generatePwshShim, extension: '.ps1' });
|
|
119
|
+
}
|
|
120
|
+
return Promise.all(generatorAndExts.map((generatorAndExt) => writeShim(src, to + generatorAndExt.extension, srcRuntimeInfo, generatorAndExt.generator, opts_)));
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Do processes before writing shim.
|
|
124
|
+
*
|
|
125
|
+
* @param target Path to shim that is going to be created.
|
|
126
|
+
*/
|
|
127
|
+
function writeShimPre(target, opts) {
|
|
128
|
+
return rm(target, opts);
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Do processes after writing the shim.
|
|
132
|
+
*
|
|
133
|
+
* @param target Path to just created shim.
|
|
134
|
+
*/
|
|
135
|
+
function writeShimPost(target, opts) {
|
|
136
|
+
// Only chmoding shims as of now.
|
|
137
|
+
// Some other processes may be appended.
|
|
138
|
+
return chmodShim(target, opts);
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Look into runtime (e.g. `node` & `sh` & `pwsh`) and its arguments
|
|
142
|
+
* of the target program (script or executable).
|
|
143
|
+
*
|
|
144
|
+
* @param target Path to the executable or script.
|
|
145
|
+
* @return Promise of infomation of runtime of `target`.
|
|
146
|
+
*/
|
|
147
|
+
async function searchScriptRuntime(target, opts) {
|
|
148
|
+
try {
|
|
149
|
+
const data = await opts.fs_.readFile(target, 'utf8');
|
|
150
|
+
// First, check if the bin is a #! of some sort.
|
|
151
|
+
const firstLine = data.trim().split(/\r*\n/)[0];
|
|
152
|
+
const shebang = firstLine.match(shebangExpr);
|
|
153
|
+
if (!shebang) {
|
|
154
|
+
// If not, infer script type from its extension.
|
|
155
|
+
// If the inference fails, it's something that'll be compiled, or some other
|
|
156
|
+
// sort of script, and just call it directly.
|
|
157
|
+
const targetExtension = path.extname(target).toLowerCase();
|
|
158
|
+
return {
|
|
159
|
+
// undefined if extension is unknown but it's converted to null.
|
|
160
|
+
program: extensionToProgramMap.get(targetExtension) || null,
|
|
161
|
+
additionalArgs: ''
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
return {
|
|
165
|
+
program: shebang[1],
|
|
166
|
+
additionalArgs: shebang[2]
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
catch (err) {
|
|
170
|
+
if (!isWindows() || err.code !== 'ENOENT')
|
|
171
|
+
throw err;
|
|
172
|
+
if (await opts.fs_.stat(`${target}${getExeExtension()}`)) {
|
|
173
|
+
return {
|
|
174
|
+
program: null,
|
|
175
|
+
additionalArgs: '',
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
throw err;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
function getExeExtension() {
|
|
182
|
+
let cmdExtension;
|
|
183
|
+
if (process.env.PATHEXT) {
|
|
184
|
+
cmdExtension = process.env.PATHEXT
|
|
185
|
+
.split(path.delimiter)
|
|
186
|
+
.find(ext => ext.toLowerCase() === '.exe');
|
|
187
|
+
}
|
|
188
|
+
return cmdExtension || '.exe';
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* Write shim to the file system while executing the pre- and post-processes
|
|
192
|
+
* defined in `WriteShimPre` and `WriteShimPost`.
|
|
193
|
+
*
|
|
194
|
+
* @param src Path to the executable or script.
|
|
195
|
+
* @param to Path to the (sh) shim(s) that is going to be created.
|
|
196
|
+
* @param srcRuntimeInfo Result of `await searchScriptRuntime(src)`.
|
|
197
|
+
* @param generateShimScript Generator of shim script.
|
|
198
|
+
* @param opts Other options.
|
|
199
|
+
*/
|
|
200
|
+
async function writeShim(src, to, srcRuntimeInfo, generateShimScript, opts) {
|
|
201
|
+
const defaultArgs = opts.preserveSymlinks ? '--preserve-symlinks' : '';
|
|
202
|
+
// `Array.prototype.filter` removes ''.
|
|
203
|
+
// ['--foo', '--bar'].join(' ') and [].join(' ') returns '--foo --bar' and '' respectively.
|
|
204
|
+
const args = [srcRuntimeInfo.additionalArgs, defaultArgs].filter(arg => arg).join(' ');
|
|
205
|
+
opts = Object.assign({}, opts, {
|
|
206
|
+
prog: srcRuntimeInfo.program,
|
|
207
|
+
args: args
|
|
208
|
+
});
|
|
209
|
+
await writeShimPre(to, opts);
|
|
210
|
+
await opts.fs_.writeFile(to, generateShimScript(src, to, opts), 'utf8');
|
|
211
|
+
return writeShimPost(to, opts);
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Generate the content of a shim for CMD.
|
|
215
|
+
*
|
|
216
|
+
* @param src Path to the executable or script.
|
|
217
|
+
* @param to Path to the shim to be created.
|
|
218
|
+
* It is highly recommended to end with `.cmd` (or `.bat`).
|
|
219
|
+
* @param opts Options.
|
|
220
|
+
* @return The content of shim.
|
|
221
|
+
*/
|
|
222
|
+
function generateCmdShim(src, to, opts) {
|
|
223
|
+
// `shTarget` is not used to generate the content.
|
|
224
|
+
const shTarget = path.relative(path.dirname(to), src);
|
|
225
|
+
let target = shTarget.split('/').join('\\');
|
|
226
|
+
const quotedPathToTarget = path.isAbsolute(target) ? `"${target}"` : `"%~dp0\\${target}"`;
|
|
227
|
+
let longProg;
|
|
228
|
+
let prog = opts.prog;
|
|
229
|
+
let args = opts.args || '';
|
|
230
|
+
const nodePath = normalizePathEnvVar(opts.nodePath).win32;
|
|
231
|
+
const prependToPath = normalizePathEnvVar(opts.prependToPath).win32;
|
|
232
|
+
if (!prog) {
|
|
233
|
+
prog = quotedPathToTarget;
|
|
234
|
+
args = '';
|
|
235
|
+
target = '';
|
|
236
|
+
}
|
|
237
|
+
else if (prog === 'node' && opts.nodeExecPath) {
|
|
238
|
+
prog = `"${opts.nodeExecPath}"`;
|
|
239
|
+
target = quotedPathToTarget;
|
|
240
|
+
}
|
|
241
|
+
else {
|
|
242
|
+
longProg = `"%~dp0\\${prog}.exe"`;
|
|
243
|
+
target = quotedPathToTarget;
|
|
244
|
+
}
|
|
245
|
+
let progArgs = opts.progArgs ? `${opts.progArgs.join(` `)} ` : '';
|
|
246
|
+
// @IF EXIST "%~dp0\node.exe" (
|
|
247
|
+
// "%~dp0\node.exe" "%~dp0\.\node_modules\npm\bin\npm-cli.js" %*
|
|
248
|
+
// ) ELSE (
|
|
249
|
+
// SETLOCAL
|
|
250
|
+
// SET PATHEXT=%PATHEXT:;.JS;=;%
|
|
251
|
+
// node "%~dp0\.\node_modules\npm\bin\npm-cli.js" %*
|
|
252
|
+
// )
|
|
253
|
+
let cmd = '@SETLOCAL\r\n';
|
|
254
|
+
if (prependToPath) {
|
|
255
|
+
cmd += `@SET "PATH=${prependToPath}:%PATH%"\r\n`;
|
|
256
|
+
}
|
|
257
|
+
if (nodePath) {
|
|
233
258
|
cmd += `\
|
|
234
259
|
@IF NOT DEFINED NODE_PATH (\r
|
|
235
260
|
@SET "NODE_PATH=${nodePath}"\r
|
|
236
261
|
) ELSE (\r
|
|
237
262
|
@SET "NODE_PATH=%NODE_PATH%;${nodePath}"\r
|
|
238
263
|
)\r
|
|
239
|
-
`;
|
|
240
|
-
}
|
|
241
|
-
if (longProg) {
|
|
264
|
+
`;
|
|
265
|
+
}
|
|
266
|
+
if (longProg) {
|
|
242
267
|
cmd += `\
|
|
243
268
|
@IF EXIST ${longProg} (\r
|
|
244
269
|
${longProg} ${args} ${target} ${progArgs}%*\r
|
|
@@ -246,58 +271,58 @@ function generateCmdShim(src, to, opts) {
|
|
|
246
271
|
@SET PATHEXT=%PATHEXT:;.JS;=;%\r
|
|
247
272
|
${prog} ${args} ${target} ${progArgs}%*\r
|
|
248
273
|
)\r
|
|
249
|
-
`;
|
|
250
|
-
}
|
|
251
|
-
else {
|
|
252
|
-
cmd += `@${prog} ${args} ${target} ${progArgs}%*\r\n`;
|
|
253
|
-
}
|
|
254
|
-
return cmd;
|
|
255
|
-
}
|
|
256
|
-
/**
|
|
257
|
-
* Generate the content of a shim for (Ba)sh in, for example, Cygwin and MSYS(2).
|
|
258
|
-
*
|
|
259
|
-
* @param src Path to the executable or script.
|
|
260
|
-
* @param to Path to the shim to be created.
|
|
261
|
-
* It is highly recommended to end with `.sh` or to contain no extension.
|
|
262
|
-
* @param opts Options.
|
|
263
|
-
* @return The content of shim.
|
|
264
|
-
*/
|
|
265
|
-
function generateShShim(src, to, opts) {
|
|
266
|
-
let shTarget = path.relative(path.dirname(to), src);
|
|
267
|
-
let shProg = opts.prog && opts.prog.split('\\').join('/');
|
|
268
|
-
let shLongProg;
|
|
269
|
-
shTarget = shTarget.split('\\').join('/');
|
|
270
|
-
const quotedPathToTarget = path.isAbsolute(shTarget) ? `"${shTarget}"` : `"$basedir/${shTarget}"`;
|
|
271
|
-
let args = opts.args || '';
|
|
272
|
-
const shNodePath = normalizePathEnvVar(opts.nodePath).posix;
|
|
273
|
-
if (!shProg) {
|
|
274
|
-
shProg = quotedPathToTarget;
|
|
275
|
-
args = '';
|
|
276
|
-
shTarget = '';
|
|
277
|
-
}
|
|
278
|
-
else if (opts.prog === 'node' && opts.nodeExecPath) {
|
|
279
|
-
shProg = `"${opts.nodeExecPath}"`;
|
|
280
|
-
shTarget = quotedPathToTarget;
|
|
281
|
-
}
|
|
282
|
-
else {
|
|
283
|
-
shLongProg = `"$basedir/${opts.prog}"`;
|
|
284
|
-
shTarget = quotedPathToTarget;
|
|
285
|
-
}
|
|
286
|
-
let progArgs = opts.progArgs ? `${opts.progArgs.join(` `)} ` : '';
|
|
287
|
-
// #!/bin/sh
|
|
288
|
-
// basedir=`dirname "$0"`
|
|
289
|
-
//
|
|
290
|
-
// case `uname` in
|
|
291
|
-
// *CYGWIN*) basedir=`cygpath -w "$basedir"`;;
|
|
292
|
-
// esac
|
|
293
|
-
//
|
|
294
|
-
// export NODE_PATH="<nodepath>"
|
|
295
|
-
//
|
|
296
|
-
// if [ -x "$basedir/node.exe" ]; then
|
|
297
|
-
// exec "$basedir/node.exe" "$basedir/node_modules/npm/bin/npm-cli.js" "$@"
|
|
298
|
-
// else
|
|
299
|
-
// exec node "$basedir/node_modules/npm/bin/npm-cli.js" "$@"
|
|
300
|
-
// fi
|
|
274
|
+
`;
|
|
275
|
+
}
|
|
276
|
+
else {
|
|
277
|
+
cmd += `@${prog} ${args} ${target} ${progArgs}%*\r\n`;
|
|
278
|
+
}
|
|
279
|
+
return cmd;
|
|
280
|
+
}
|
|
281
|
+
/**
|
|
282
|
+
* Generate the content of a shim for (Ba)sh in, for example, Cygwin and MSYS(2).
|
|
283
|
+
*
|
|
284
|
+
* @param src Path to the executable or script.
|
|
285
|
+
* @param to Path to the shim to be created.
|
|
286
|
+
* It is highly recommended to end with `.sh` or to contain no extension.
|
|
287
|
+
* @param opts Options.
|
|
288
|
+
* @return The content of shim.
|
|
289
|
+
*/
|
|
290
|
+
function generateShShim(src, to, opts) {
|
|
291
|
+
let shTarget = path.relative(path.dirname(to), src);
|
|
292
|
+
let shProg = opts.prog && opts.prog.split('\\').join('/');
|
|
293
|
+
let shLongProg;
|
|
294
|
+
shTarget = shTarget.split('\\').join('/');
|
|
295
|
+
const quotedPathToTarget = path.isAbsolute(shTarget) ? `"${shTarget}"` : `"$basedir/${shTarget}"`;
|
|
296
|
+
let args = opts.args || '';
|
|
297
|
+
const shNodePath = normalizePathEnvVar(opts.nodePath).posix;
|
|
298
|
+
if (!shProg) {
|
|
299
|
+
shProg = quotedPathToTarget;
|
|
300
|
+
args = '';
|
|
301
|
+
shTarget = '';
|
|
302
|
+
}
|
|
303
|
+
else if (opts.prog === 'node' && opts.nodeExecPath) {
|
|
304
|
+
shProg = `"${opts.nodeExecPath}"`;
|
|
305
|
+
shTarget = quotedPathToTarget;
|
|
306
|
+
}
|
|
307
|
+
else {
|
|
308
|
+
shLongProg = `"$basedir/${opts.prog}"`;
|
|
309
|
+
shTarget = quotedPathToTarget;
|
|
310
|
+
}
|
|
311
|
+
let progArgs = opts.progArgs ? `${opts.progArgs.join(` `)} ` : '';
|
|
312
|
+
// #!/bin/sh
|
|
313
|
+
// basedir=`dirname "$0"`
|
|
314
|
+
//
|
|
315
|
+
// case `uname` in
|
|
316
|
+
// *CYGWIN*) basedir=`cygpath -w "$basedir"`;;
|
|
317
|
+
// esac
|
|
318
|
+
//
|
|
319
|
+
// export NODE_PATH="<nodepath>"
|
|
320
|
+
//
|
|
321
|
+
// if [ -x "$basedir/node.exe" ]; then
|
|
322
|
+
// exec "$basedir/node.exe" "$basedir/node_modules/npm/bin/npm-cli.js" "$@"
|
|
323
|
+
// else
|
|
324
|
+
// exec node "$basedir/node_modules/npm/bin/npm-cli.js" "$@"
|
|
325
|
+
// fi
|
|
301
326
|
let sh = `\
|
|
302
327
|
#!/bin/sh
|
|
303
328
|
basedir=$(dirname "$(echo "$0" | sed -e 's,\\\\,/,g')")
|
|
@@ -306,124 +331,146 @@ case \`uname\` in
|
|
|
306
331
|
*CYGWIN*) basedir=\`cygpath -w "$basedir"\`;;
|
|
307
332
|
esac
|
|
308
333
|
|
|
309
|
-
`;
|
|
310
|
-
if (opts.
|
|
334
|
+
`;
|
|
335
|
+
if (opts.prependToPath) {
|
|
336
|
+
sh += `\
|
|
337
|
+
export PATH="${opts.prependToPath}:$PATH"
|
|
338
|
+
`;
|
|
339
|
+
}
|
|
340
|
+
if (shNodePath) {
|
|
311
341
|
sh += `\
|
|
312
342
|
if [ -z "$NODE_PATH" ]; then
|
|
313
343
|
export NODE_PATH="${shNodePath}"
|
|
314
344
|
else
|
|
315
345
|
export NODE_PATH="$NODE_PATH:${shNodePath}"
|
|
316
346
|
fi
|
|
317
|
-
`;
|
|
318
|
-
}
|
|
319
|
-
if (shLongProg) {
|
|
347
|
+
`;
|
|
348
|
+
}
|
|
349
|
+
if (shLongProg) {
|
|
320
350
|
sh += `\
|
|
321
351
|
if [ -x ${shLongProg} ]; then
|
|
322
352
|
exec ${shLongProg} ${args} ${shTarget} ${progArgs}"$@"
|
|
323
353
|
else
|
|
324
354
|
exec ${shProg} ${args} ${shTarget} ${progArgs}"$@"
|
|
325
355
|
fi
|
|
326
|
-
`;
|
|
327
|
-
}
|
|
328
|
-
else {
|
|
356
|
+
`;
|
|
357
|
+
}
|
|
358
|
+
else {
|
|
329
359
|
sh += `\
|
|
330
360
|
${shProg} ${args} ${shTarget} ${progArgs}"$@"
|
|
331
361
|
exit $?
|
|
332
|
-
`;
|
|
333
|
-
}
|
|
334
|
-
return sh;
|
|
335
|
-
}
|
|
336
|
-
/**
|
|
337
|
-
* Generate the content of a shim for PowerShell.
|
|
338
|
-
*
|
|
339
|
-
* @param src Path to the executable or script.
|
|
340
|
-
* @param to Path to the shim to be created.
|
|
341
|
-
* It is highly recommended to end with `.ps1`.
|
|
342
|
-
* @param opts Options.
|
|
343
|
-
* @return The content of shim.
|
|
344
|
-
*/
|
|
345
|
-
function generatePwshShim(src, to, opts) {
|
|
346
|
-
let shTarget = path.relative(path.dirname(to), src);
|
|
347
|
-
const shProg = opts.prog && opts.prog.split('\\').join('/');
|
|
348
|
-
let pwshProg = shProg && `"${shProg}$exe"`;
|
|
349
|
-
let pwshLongProg;
|
|
350
|
-
shTarget = shTarget.split('\\').join('/');
|
|
351
|
-
const quotedPathToTarget = path.isAbsolute(shTarget) ? `"${shTarget}"` : `"$basedir/${shTarget}"`;
|
|
352
|
-
let args = opts.args || '';
|
|
353
|
-
let
|
|
354
|
-
const nodePath =
|
|
355
|
-
const shNodePath =
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
//
|
|
374
|
-
// $
|
|
375
|
-
//
|
|
376
|
-
//
|
|
377
|
-
//
|
|
378
|
-
//
|
|
379
|
-
//
|
|
380
|
-
//
|
|
381
|
-
//
|
|
382
|
-
//
|
|
383
|
-
//
|
|
384
|
-
//
|
|
385
|
-
//
|
|
386
|
-
//
|
|
387
|
-
//
|
|
388
|
-
//
|
|
389
|
-
//
|
|
390
|
-
//
|
|
391
|
-
//
|
|
392
|
-
//
|
|
393
|
-
//
|
|
394
|
-
//
|
|
395
|
-
//
|
|
396
|
-
//
|
|
397
|
-
//
|
|
362
|
+
`;
|
|
363
|
+
}
|
|
364
|
+
return sh;
|
|
365
|
+
}
|
|
366
|
+
/**
|
|
367
|
+
* Generate the content of a shim for PowerShell.
|
|
368
|
+
*
|
|
369
|
+
* @param src Path to the executable or script.
|
|
370
|
+
* @param to Path to the shim to be created.
|
|
371
|
+
* It is highly recommended to end with `.ps1`.
|
|
372
|
+
* @param opts Options.
|
|
373
|
+
* @return The content of shim.
|
|
374
|
+
*/
|
|
375
|
+
function generatePwshShim(src, to, opts) {
|
|
376
|
+
let shTarget = path.relative(path.dirname(to), src);
|
|
377
|
+
const shProg = opts.prog && opts.prog.split('\\').join('/');
|
|
378
|
+
let pwshProg = shProg && `"${shProg}$exe"`;
|
|
379
|
+
let pwshLongProg;
|
|
380
|
+
shTarget = shTarget.split('\\').join('/');
|
|
381
|
+
const quotedPathToTarget = path.isAbsolute(shTarget) ? `"${shTarget}"` : `"$basedir/${shTarget}"`;
|
|
382
|
+
let args = opts.args || '';
|
|
383
|
+
let normalizedNodePathEnvVar = normalizePathEnvVar(opts.nodePath);
|
|
384
|
+
const nodePath = normalizedNodePathEnvVar.win32;
|
|
385
|
+
const shNodePath = normalizedNodePathEnvVar.posix;
|
|
386
|
+
let normalizedPrependPathEnvVar = normalizePathEnvVar(opts.prependToPath);
|
|
387
|
+
const prependPath = normalizedPrependPathEnvVar.win32;
|
|
388
|
+
const shPrependPath = normalizedPrependPathEnvVar.posix;
|
|
389
|
+
if (!pwshProg) {
|
|
390
|
+
pwshProg = quotedPathToTarget;
|
|
391
|
+
args = '';
|
|
392
|
+
shTarget = '';
|
|
393
|
+
}
|
|
394
|
+
else if (opts.prog === 'node' && opts.nodeExecPath) {
|
|
395
|
+
pwshProg = `"${opts.nodeExecPath}"`;
|
|
396
|
+
shTarget = quotedPathToTarget;
|
|
397
|
+
}
|
|
398
|
+
else {
|
|
399
|
+
pwshLongProg = `"$basedir/${opts.prog}$exe"`;
|
|
400
|
+
shTarget = quotedPathToTarget;
|
|
401
|
+
}
|
|
402
|
+
let progArgs = opts.progArgs ? `${opts.progArgs.join(` `)} ` : '';
|
|
403
|
+
// #!/usr/bin/env pwsh
|
|
404
|
+
// $basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
|
|
405
|
+
//
|
|
406
|
+
// $ret=0
|
|
407
|
+
// $exe = ""
|
|
408
|
+
// if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
|
|
409
|
+
// # Fix case when both the Windows and Linux builds of Node
|
|
410
|
+
// # are installed in the same directory
|
|
411
|
+
// $exe = ".exe"
|
|
412
|
+
// }
|
|
413
|
+
// if (Test-Path "$basedir/node") {
|
|
414
|
+
// # Support pipeline input
|
|
415
|
+
// if ($MyInvocation.ExpectingInput) {
|
|
416
|
+
// $input | & "$basedir/node$exe" "$basedir/node_modules/npm/bin/npm-cli.js" $args
|
|
417
|
+
// } else {
|
|
418
|
+
// & "$basedir/node$exe" "$basedir/node_modules/npm/bin/npm-cli.js" $args
|
|
419
|
+
// }
|
|
420
|
+
// $ret=$LASTEXITCODE
|
|
421
|
+
// } else {
|
|
422
|
+
// # Support pipeline input
|
|
423
|
+
// if ($MyInvocation.ExpectingInput) {
|
|
424
|
+
// $input | & "node$exe" "$basedir/node_modules/npm/bin/npm-cli.js" $args
|
|
425
|
+
// } else {
|
|
426
|
+
// & "node$exe" "$basedir/node_modules/npm/bin/npm-cli.js" $args
|
|
427
|
+
// }
|
|
428
|
+
// $ret=$LASTEXITCODE
|
|
429
|
+
// }
|
|
430
|
+
// exit $ret
|
|
398
431
|
let pwsh = `\
|
|
399
432
|
#!/usr/bin/env pwsh
|
|
400
433
|
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
|
|
401
434
|
|
|
402
435
|
$exe=""
|
|
403
|
-
${
|
|
404
|
-
$
|
|
436
|
+
${(nodePath || prependPath) ? '$pathsep=":"\n' : ''}\
|
|
437
|
+
${nodePath ? `\
|
|
405
438
|
$env_node_path=$env:NODE_PATH
|
|
406
439
|
$new_node_path="${nodePath}"
|
|
407
440
|
` : ''}\
|
|
441
|
+
${prependPath ? `\
|
|
442
|
+
$env_path=$env:PATH
|
|
443
|
+
$prepend_path="${prependPath}"
|
|
444
|
+
` : ''}\
|
|
408
445
|
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
|
|
409
446
|
# Fix case when both the Windows and Linux builds of Node
|
|
410
447
|
# are installed in the same directory
|
|
411
448
|
$exe=".exe"
|
|
412
|
-
${
|
|
413
|
-
}`;
|
|
414
|
-
if (
|
|
449
|
+
${(nodePath || prependPath) ? ' $pathsep=";"\n' : ''}\
|
|
450
|
+
}`;
|
|
451
|
+
if (shNodePath || shPrependPath) {
|
|
415
452
|
pwsh += `\
|
|
416
453
|
else {
|
|
417
|
-
$new_node_path="${shNodePath}"
|
|
454
|
+
${shNodePath ? ` $new_node_path="${shNodePath}"\n` : ''}\
|
|
455
|
+
${shPrependPath ? ` $prepend_path="${shPrependPath}"\n` : ''}\
|
|
418
456
|
}
|
|
457
|
+
`;
|
|
458
|
+
}
|
|
459
|
+
if (shNodePath) {
|
|
460
|
+
pwsh += `\
|
|
419
461
|
if ([string]::IsNullOrEmpty($env_node_path)) {
|
|
420
462
|
$env:NODE_PATH=$new_node_path
|
|
421
463
|
} else {
|
|
422
464
|
$env:NODE_PATH="$env_node_path$pathsep$new_node_path"
|
|
423
465
|
}
|
|
424
|
-
`;
|
|
425
|
-
}
|
|
426
|
-
if (
|
|
466
|
+
`;
|
|
467
|
+
}
|
|
468
|
+
if (opts.prependToPath) {
|
|
469
|
+
pwsh += `
|
|
470
|
+
$env:PATH="$prepend_path$pathsep$env:PATH"
|
|
471
|
+
`;
|
|
472
|
+
}
|
|
473
|
+
if (pwshLongProg) {
|
|
427
474
|
pwsh += `
|
|
428
475
|
$ret=0
|
|
429
476
|
if (Test-Path ${pwshLongProg}) {
|
|
@@ -443,11 +490,12 @@ if (Test-Path ${pwshLongProg}) {
|
|
|
443
490
|
}
|
|
444
491
|
$ret=$LASTEXITCODE
|
|
445
492
|
}
|
|
446
|
-
${
|
|
493
|
+
${nodePath ? '$env:NODE_PATH=$env_node_path\n' : ''}\
|
|
494
|
+
${prependPath ? '$env:PATH=$env_path\n' : ''}\
|
|
447
495
|
exit $ret
|
|
448
|
-
`;
|
|
449
|
-
}
|
|
450
|
-
else {
|
|
496
|
+
`;
|
|
497
|
+
}
|
|
498
|
+
else {
|
|
451
499
|
pwsh += `
|
|
452
500
|
# Support pipeline input
|
|
453
501
|
if ($MyInvocation.ExpectingInput) {
|
|
@@ -455,37 +503,38 @@ if ($MyInvocation.ExpectingInput) {
|
|
|
455
503
|
} else {
|
|
456
504
|
& ${pwshProg} ${args} ${shTarget} ${progArgs}$args
|
|
457
505
|
}
|
|
458
|
-
${
|
|
506
|
+
${nodePath ? '$env:NODE_PATH=$env_node_path\n' : ''}\
|
|
507
|
+
${prependPath ? '$env:PATH=$env_path\n' : ''}\
|
|
459
508
|
exit $LASTEXITCODE
|
|
460
|
-
`;
|
|
461
|
-
}
|
|
462
|
-
return pwsh;
|
|
463
|
-
}
|
|
464
|
-
/**
|
|
465
|
-
* Chmod just created shim and make it executable
|
|
466
|
-
*
|
|
467
|
-
* @param to Path to shim.
|
|
468
|
-
*/
|
|
469
|
-
function chmodShim(to, opts) {
|
|
470
|
-
return opts.fs_.chmod(to, 0o755);
|
|
471
|
-
}
|
|
472
|
-
function normalizePathEnvVar(nodePath) {
|
|
473
|
-
if (!nodePath) {
|
|
474
|
-
return {
|
|
475
|
-
win32: '',
|
|
476
|
-
posix: ''
|
|
477
|
-
};
|
|
478
|
-
}
|
|
479
|
-
let split = (typeof nodePath === 'string' ? nodePath.split(path.delimiter) : Array.from(nodePath));
|
|
480
|
-
let result = {};
|
|
481
|
-
for (let i = 0; i < split.length; i++) {
|
|
482
|
-
const win32 = split[i].split('/').join('\\');
|
|
483
|
-
const posix = isWindows() ? split[i].split('\\').join('/').replace(/^([^:\\/]*):/, (_, $1) => `/mnt/${$1.toLowerCase()}`) : split[i];
|
|
484
|
-
result.win32 = result.win32 ? `${result.win32};${win32}` : win32;
|
|
485
|
-
result.posix = result.posix ? `${result.posix}:${posix}` : posix;
|
|
486
|
-
result[i] = { win32, posix };
|
|
487
|
-
}
|
|
488
|
-
return result;
|
|
489
|
-
}
|
|
490
|
-
module.exports = cmdShim;
|
|
509
|
+
`;
|
|
510
|
+
}
|
|
511
|
+
return pwsh;
|
|
512
|
+
}
|
|
513
|
+
/**
|
|
514
|
+
* Chmod just created shim and make it executable
|
|
515
|
+
*
|
|
516
|
+
* @param to Path to shim.
|
|
517
|
+
*/
|
|
518
|
+
function chmodShim(to, opts) {
|
|
519
|
+
return opts.fs_.chmod(to, 0o755);
|
|
520
|
+
}
|
|
521
|
+
function normalizePathEnvVar(nodePath) {
|
|
522
|
+
if (!nodePath || !nodePath.length) {
|
|
523
|
+
return {
|
|
524
|
+
win32: '',
|
|
525
|
+
posix: ''
|
|
526
|
+
};
|
|
527
|
+
}
|
|
528
|
+
let split = (typeof nodePath === 'string' ? nodePath.split(path.delimiter) : Array.from(nodePath));
|
|
529
|
+
let result = {};
|
|
530
|
+
for (let i = 0; i < split.length; i++) {
|
|
531
|
+
const win32 = split[i].split('/').join('\\');
|
|
532
|
+
const posix = isWindows() ? split[i].split('\\').join('/').replace(/^([^:\\/]*):/, (_, $1) => `/mnt/${$1.toLowerCase()}`) : split[i];
|
|
533
|
+
result.win32 = result.win32 ? `${result.win32};${win32}` : win32;
|
|
534
|
+
result.posix = result.posix ? `${result.posix}:${posix}` : posix;
|
|
535
|
+
result[i] = { win32, posix };
|
|
536
|
+
}
|
|
537
|
+
return result;
|
|
538
|
+
}
|
|
539
|
+
module.exports = cmdShim;
|
|
491
540
|
//# sourceMappingURL=index.js.map
|