forked from microsoft/vscode-python
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathgenerator.ts
More file actions
99 lines (93 loc) · 4.04 KB
/
generator.ts
File metadata and controls
99 lines (93 loc) · 4.04 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
import * as path from 'path';
import { Disposable, OutputChannel, Uri } from 'vscode';
import { IApplicationShell } from '../common/application/types';
import { IFileSystem } from '../common/platform/types';
import { IProcessServiceFactory } from '../common/process/types';
import { IConfigurationService, IPythonSettings } from '../common/types';
import { EXTENSION_ROOT_DIR } from '../constants';
import { captureTelemetry } from '../telemetry';
import { EventName } from '../telemetry/constants';
export class Generator implements Disposable {
private optionsFile: string;
private disposables: Disposable[];
private pythonSettings: IPythonSettings;
public get tagFilePath(): string {
return this.pythonSettings.workspaceSymbols.tagFilePath;
}
public get enabled(): boolean {
return this.pythonSettings.workspaceSymbols.enabled;
}
constructor(
public readonly workspaceFolder: Uri,
private readonly output: OutputChannel,
private readonly appShell: IApplicationShell,
private readonly fs: IFileSystem,
private readonly processServiceFactory: IProcessServiceFactory,
configurationService: IConfigurationService
) {
this.disposables = [];
this.optionsFile = path.join(EXTENSION_ROOT_DIR, 'resources', 'ctagOptions');
this.pythonSettings = configurationService.getSettings(workspaceFolder);
}
public dispose() {
this.disposables.forEach(d => d.dispose());
}
public async generateWorkspaceTags(): Promise<void> {
if (!this.pythonSettings.workspaceSymbols.enabled) {
return;
}
return this.generateTags({ directory: this.workspaceFolder.fsPath });
}
private buildCmdArgs(): string[] {
const exclusions = this.pythonSettings.workspaceSymbols.exclusionPatterns;
const excludes = exclusions.length === 0 ? [] : exclusions.map(pattern => `--exclude=${pattern}`);
return [`--options=${this.optionsFile}`, '--languages=Python'].concat(excludes);
}
@captureTelemetry(EventName.WORKSPACE_SYMBOLS_BUILD)
private async generateTags(source: { directory?: string; file?: string }): Promise<void> {
const tagFile = path.normalize(this.pythonSettings.workspaceSymbols.tagFilePath);
const cmd = this.pythonSettings.workspaceSymbols.ctagsPath;
const args = this.buildCmdArgs();
let outputFile = tagFile;
if (source.file && source.file.length > 0) {
source.directory = path.dirname(source.file);
}
if (path.dirname(outputFile) === source.directory) {
outputFile = path.basename(outputFile);
}
const outputDir = path.dirname(outputFile);
if (!(await this.fs.directoryExists(outputDir))) {
await this.fs.createDirectory(outputDir);
}
args.push('-o', outputFile, '.');
this.output.appendLine(`${'-'.repeat(10)}Generating Tags${'-'.repeat(10)}`);
this.output.appendLine(`${cmd} ${args.join(' ')}`);
const promise = new Promise<void>(async (resolve, reject) => {
try {
const processService = await this.processServiceFactory.create();
const result = processService.execObservable(cmd, args, { cwd: source.directory });
let errorMsg = '';
result.out.subscribe(
output => {
if (output.source === 'stderr') {
errorMsg += output.out;
}
this.output.append(output.out);
},
reject,
() => {
if (errorMsg.length > 0) {
reject(new Error(errorMsg));
} else {
resolve();
}
}
);
} catch (ex) {
reject(ex);
}
});
this.appShell.setStatusBarMessage('Generating Tags', promise);
await promise;
}
}