forked from DonJayamanne/pythonVSCode
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Expand file tree
/
Copy pathutils.ts
More file actions
117 lines (110 loc) · 4.42 KB
/
utils.ts
File metadata and controls
117 lines (110 loc) · 4.42 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
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
import { CancellationError, CancellationToken, Uri, workspace } from 'vscode';
import { IDiscoveryAPI } from '../pythonEnvironments/base/locator';
import { PythonExtension, ResolvedEnvironment } from '../api/types';
import { ITerminalHelper, TerminalShellType } from '../common/terminal/types';
import { TerminalCodeExecutionProvider } from '../terminals/codeExecution/terminalCodeExecution';
import { Conda } from '../pythonEnvironments/common/environmentManagers/conda';
export function resolveFilePath(filepath?: string): Uri | undefined {
if (!filepath) {
return workspace.workspaceFolders ? workspace.workspaceFolders[0].uri : undefined;
}
// starts with a scheme
try {
return Uri.parse(filepath);
} catch (e) {
return Uri.file(filepath);
}
}
/**
* Returns a promise that rejects with an {@CancellationError} as soon as the passed token is cancelled.
* @see {@link raceCancellation}
*/
export function raceCancellationError<T>(promise: Promise<T>, token: CancellationToken): Promise<T> {
return new Promise((resolve, reject) => {
const ref = token.onCancellationRequested(() => {
ref.dispose();
reject(new CancellationError());
});
promise.then(resolve, reject).finally(() => ref.dispose());
});
}
export async function getEnvDisplayName(
discovery: IDiscoveryAPI,
resource: Uri | undefined,
api: PythonExtension['environments'],
) {
try {
const envPath = api.getActiveEnvironmentPath(resource);
const env = await discovery.resolveEnv(envPath.path);
return env?.display || env?.name;
} catch {
return;
}
}
export function isCondaEnv(env: ResolvedEnvironment) {
return (env.environment?.type || '').toLowerCase() === 'conda';
}
export async function getEnvironmentDetails(
resourcePath: Uri | undefined,
api: PythonExtension['environments'],
terminalExecutionService: TerminalCodeExecutionProvider,
terminalHelper: ITerminalHelper,
packages: string | undefined,
token: CancellationToken,
): Promise<string> {
// environment
const envPath = api.getActiveEnvironmentPath(resourcePath);
const environment = await raceCancellationError(api.resolveEnvironment(envPath), token);
if (!environment || !environment.version) {
throw new Error('No environment found for the provided resource path: ' + resourcePath?.fsPath);
}
const runCommand = await raceCancellationError(
getTerminalCommand(environment, resourcePath, terminalExecutionService, terminalHelper),
token,
);
const message = [
`Following is the information about the Python environment:`,
`1. Environment Type: ${environment.environment?.type || 'unknown'}`,
`2. Version: ${environment.version.sysVersion || 'unknown'}`,
'',
`3. Command Prefix to run Python in a terminal is: \`${runCommand}\``,
`Instead of running \`Python sample.py\` in the terminal, you will now run: \`${runCommand} sample.py\``,
`Similarly instead of running \`Python -c "import sys;...."\` in the terminal, you will now run: \`${runCommand} -c "import sys;...."\``,
packages ? `4. ${packages}` : '',
];
return message.join('\n');
}
export async function getTerminalCommand(
environment: ResolvedEnvironment,
resource: Uri | undefined,
terminalExecutionService: TerminalCodeExecutionProvider,
terminalHelper: ITerminalHelper,
): Promise<string> {
let cmd: { command: string; args: string[] };
if (isCondaEnv(environment)) {
cmd = (await getCondaRunCommand(environment)) || (await terminalExecutionService.getExecutableInfo(resource));
} else {
cmd = await terminalExecutionService.getExecutableInfo(resource);
}
return terminalHelper.buildCommandForTerminal(TerminalShellType.other, cmd.command, cmd.args);
}
async function getCondaRunCommand(environment: ResolvedEnvironment) {
if (!environment.executable.uri) {
return;
}
const conda = await Conda.getConda();
if (!conda) {
return;
}
const condaEnv = await conda.getCondaEnvironment(environment.executable.uri?.fsPath);
if (!condaEnv) {
return;
}
const cmd = await conda.getRunPythonArgs(condaEnv, true, false);
if (!cmd) {
return;
}
return { command: cmd[0], args: cmd.slice(1) };
}