forked from microsoft/vscode-node-debug2
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathutils.ts
More file actions
108 lines (90 loc) · 3.26 KB
/
Copy pathutils.ts
File metadata and controls
108 lines (90 loc) · 3.26 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
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
107
108
/*---------------------------------------------------------
* Copyright (C) Microsoft Corporation. All rights reserved.
*--------------------------------------------------------*/
import * as path from 'path';
import * as fs from 'fs';
import * as cp from 'child_process';
import * as match from 'minimatch';
const NODE_SHEBANG_MATCHER = new RegExp('#! */usr/bin/env +node');
/**
* Checks whether a file is a loadable JavaScript file.
*/
export class JavaScriptDeterminant {
private static readonly defaultPatterns = ['*.js', '*.es6', '*.jsx', '*.mjs'];
private customPatterns: ReadonlyArray<string> = [];
public updatePatterns(patterns: ReadonlyArray<string>) {
this.customPatterns = patterns;
}
public isJavaScript(aPath: string) {
const basename = path.basename(aPath);
const matchesPattern = [
...JavaScriptDeterminant.defaultPatterns,
...this.customPatterns,
].some(pattern => match(basename, pattern, { nocase: true }));
return matchesPattern || this.isShebang(aPath);
}
private isShebang(aPath: string) {
try {
const buffer = Buffer.alloc(30);
const fd = fs.openSync(aPath, 'r');
fs.readSync(fd, buffer, 0, buffer.length, 0);
fs.closeSync(fd);
const line = buffer.toString();
return NODE_SHEBANG_MATCHER.test(line);
} catch (e) {
return false;
}
}
}
export function random(low: number, high: number): number {
return Math.floor(Math.random() * (high - low) + low);
}
export function killTree(processId: number): void {
if (process.platform === 'win32') {
const windir = process.env['WINDIR'] || 'C:\\Windows';
const TASK_KILL = path.join(windir, 'System32', 'taskkill.exe');
// when killing a process in Windows its child processes are *not* killed but become root processes.
// Therefore we use TASKKILL.EXE
try {
cp.execSync(`${TASK_KILL} /F /T /PID ${processId}`);
} catch (err) {
}
} else {
// on linux and OS X we kill all direct and indirect child processes as well
try {
const cmd = path.join(__dirname, './terminateProcess.sh');
cp.spawnSync(cmd, [ processId.toString() ]);
} catch (err) {
}
}
}
export function trimLastNewline(msg: string): string {
return msg.replace(/(\n|\r\n)$/, '');
}
export function extendObject<T>(toObject: T, fromObject: T): T {
for (let key in fromObject) {
if (fromObject.hasOwnProperty(key)) {
toObject[key] = fromObject[key];
}
}
return toObject;
}
export function stripBOM(s: string): string {
if (s && s[0] === '\uFEFF') {
s = s.substr(1);
}
return s;
}
const semverRegex = /v?(\d+)\.(\d+)\.(\d+)/;
export function compareSemver(a: string, b: string): number {
const aNum = versionStringToNumber(a);
const bNum = versionStringToNumber(b);
return aNum - bNum;
}
function versionStringToNumber(str: string): number {
const match = str.match(semverRegex);
if (!match) {
throw new Error('Invalid node version string: ' + str);
}
return parseInt(match[1], 10) * 10000 + parseInt(match[2], 10) * 100 + parseInt(match[3], 10);
}