forked from DonJayamanne/pythonVSCode
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Expand file tree
/
Copy pathtestConfigurationManager.ts
More file actions
78 lines (72 loc) · 3.74 KB
/
testConfigurationManager.ts
File metadata and controls
78 lines (72 loc) · 3.74 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
import * as path from 'path';
import { QuickPickItem, Uri } from 'vscode';
import { IFileSystem } from '../../../common/platform/types';
import { Product } from '../../../common/types';
import { IServiceContainer } from '../../../ioc/types';
import { IApplicationShell } from '../../../common/application/types';
import { TestConfigurationManager } from '../../common/testConfigurationManager';
import { ITestConfigSettingsService } from '../../common/types';
import { PytestInstallationHelper } from '../pytestInstallationHelper';
import { traceInfo } from '../../../logging';
export class ConfigurationManager extends TestConfigurationManager {
private readonly pytestInstallationHelper: PytestInstallationHelper;
constructor(workspace: Uri, serviceContainer: IServiceContainer, cfg?: ITestConfigSettingsService) {
super(workspace, Product.pytest, serviceContainer, cfg);
const appShell = serviceContainer.get<IApplicationShell>(IApplicationShell);
this.pytestInstallationHelper = new PytestInstallationHelper(appShell);
}
public async requiresUserToConfigure(wkspace: Uri): Promise<boolean> {
const configFiles = await this.getConfigFiles(wkspace.fsPath);
// If a config file exits, there's nothing to be configured.
if (configFiles.length > 0 && configFiles.length !== 1 && configFiles[0] !== 'setup.cfg') {
return false;
}
return true;
}
public async configure(wkspace: Uri): Promise<void> {
const args: string[] = [];
const configFileOptionLabel = 'Use existing config file';
const options: QuickPickItem[] = [];
const configFiles = await this.getConfigFiles(wkspace.fsPath);
// If a config file exits, there's nothing to be configured.
if (configFiles.length > 0 && configFiles.length !== 1 && configFiles[0] !== 'setup.cfg') {
return;
}
if (configFiles.length === 1 && configFiles[0] === 'setup.cfg') {
options.push({
label: configFileOptionLabel,
description: 'setup.cfg',
});
}
const subDirs = await this.getTestDirs(wkspace.fsPath);
const testDir = await this.selectTestDir(wkspace.fsPath, subDirs, options);
if (typeof testDir === 'string' && testDir !== configFileOptionLabel) {
args.push(testDir);
}
const installed = await this.installer.isInstalled(Product.pytest);
await this.testConfigSettingsService.updateTestArgs(wkspace.fsPath, Product.pytest, args);
if (!installed) {
// Check if Python Environments extension is available for enhanced installation flow
if (this.pytestInstallationHelper.isEnvExtensionAvailable()) {
traceInfo('pytest not installed, prompting user with environment extension integration');
const installAttempted = await this.pytestInstallationHelper.promptToInstallPytest(wkspace);
if (!installAttempted) {
// User chose to ignore or installation failed
return;
}
} else {
// Fall back to traditional installer
traceInfo('pytest not installed, falling back to traditional installer');
await this.installer.install(Product.pytest);
}
}
}
private async getConfigFiles(rootDir: string): Promise<string[]> {
const fs = this.serviceContainer.get<IFileSystem>(IFileSystem);
const promises = ['pytest.ini', 'tox.ini', 'setup.cfg'].map(async (cfg) =>
(await fs.fileExists(path.join(rootDir, cfg))) ? cfg : '',
);
const values = await Promise.all(promises);
return values.filter((exists) => exists.length > 0);
}
}