-
Notifications
You must be signed in to change notification settings - Fork 41
Expand file tree
/
Copy pathshellUtils.ts
More file actions
125 lines (111 loc) · 4.61 KB
/
shellUtils.ts
File metadata and controls
125 lines (111 loc) · 4.61 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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
import { PythonCommandRunConfiguration, PythonEnvironment } from '../../../../api';
import { traceInfo } from '../../../../common/logging';
import { sleep } from '../../../../common/utils/asyncUtils';
import { isWindows } from '../../../../common/utils/platformUtils';
import { activeTerminalShellIntegration } from '../../../../common/window.apis';
import { ShellConstants } from '../../../common/shellConstants';
import { quoteArgs } from '../../../execution/execUtils';
import { SHELL_INTEGRATION_POLL_INTERVAL, SHELL_INTEGRATION_TIMEOUT } from '../../utils';
function getCommandAsString(command: PythonCommandRunConfiguration[], shell: string, delimiter: string): string {
const parts = [];
for (const cmd of command) {
const args = cmd.args ?? [];
parts.push(quoteArgs([normalizeShellPath(cmd.executable, shell), ...args]).join(' '));
}
if (shell === ShellConstants.PWSH) {
if (parts.length === 1) {
return parts[0];
}
return parts.map((p) => `(${p})`).join(` ${delimiter} `);
}
return parts.join(` ${delimiter} `);
}
export function getShellCommandAsString(shell: string, command: PythonCommandRunConfiguration[]): string {
switch (shell) {
case ShellConstants.PWSH:
return getCommandAsString(command, shell, ';');
case ShellConstants.NU:
return getCommandAsString(command, shell, ';');
case ShellConstants.FISH:
return getCommandAsString(command, shell, '; and');
case ShellConstants.BASH:
case ShellConstants.SH:
case ShellConstants.ZSH:
case ShellConstants.CMD:
case ShellConstants.GITBASH:
default:
return getCommandAsString(command, shell, '&&');
}
}
export function normalizeShellPath(filePath: string, shellType?: string): string {
if (isWindows() && shellType) {
if (shellType.toLowerCase() === ShellConstants.GITBASH || shellType.toLowerCase() === 'git-bash') {
return filePath.replace(/\\/g, '/').replace(/^\/([a-zA-Z])/, '$1:');
}
}
return filePath;
}
export function getShellActivationCommand(
shell: string,
environment: PythonEnvironment,
): PythonCommandRunConfiguration[] | undefined {
let activation: PythonCommandRunConfiguration[] | undefined;
if (environment.execInfo?.shellActivation) {
activation = environment.execInfo.shellActivation.get(shell);
if (!activation) {
activation = environment.execInfo.shellActivation.get('unknown');
}
}
if (!activation) {
activation = environment.execInfo?.activation;
}
return activation;
}
export function getShellDeactivationCommand(
shell: string,
environment: PythonEnvironment,
): PythonCommandRunConfiguration[] | undefined {
let deactivation: PythonCommandRunConfiguration[] | undefined;
if (environment.execInfo?.shellDeactivation) {
deactivation = environment.execInfo.shellDeactivation.get(shell);
if (!deactivation) {
deactivation = environment.execInfo.shellDeactivation.get('unknown');
}
}
if (!deactivation) {
deactivation = environment.execInfo?.deactivation;
}
return deactivation;
}
export const PROFILE_TAG_START = '###PATH_START###';
export const PROFILE_TAG_END = '###PATH_END###';
export function extractProfilePath(content: string): string | undefined {
// Extract only the part between the tags
const profilePathRegex = new RegExp(`${PROFILE_TAG_START}\\r?\\n(.*?)\\r?\\n${PROFILE_TAG_END}`, 's');
const match = content?.match(profilePathRegex);
if (match && match[1]) {
const extractedPath = match[1].trim();
return extractedPath;
}
return undefined;
}
export async function shellIntegrationForActiveTerminal(name: string, profile?: string): Promise<boolean> {
let hasShellIntegration = activeTerminalShellIntegration();
let timeout = 0;
while (!hasShellIntegration && timeout < SHELL_INTEGRATION_TIMEOUT) {
await sleep(SHELL_INTEGRATION_POLL_INTERVAL);
timeout += SHELL_INTEGRATION_POLL_INTERVAL;
hasShellIntegration = activeTerminalShellIntegration();
}
if (hasShellIntegration) {
traceInfo(
`SHELL: Shell integration is available on your active terminal, with name ${name} and profile ${profile}. Python activate scripts will be evaluated at shell integration level, except in WSL.`,
);
return true;
}
return false;
}
export function isWsl(): boolean {
// WSL sets these environment variables
return !!(process.env.WSL_DISTRO_NAME || process.env.WSL_INTEROP || process.env.WSLENV);
}