forked from DonJayamanne/pythonVSCode
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathgenerator.ts
More file actions
99 lines (89 loc) · 3.8 KB
/
generator.ts
File metadata and controls
99 lines (89 loc) · 3.8 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 child_process from 'child_process';
import * as fs from 'fs';
import * as path from 'path';
import * as vscode from 'vscode';
import { IPythonSettings, PythonSettings } from '../common/configSettings';
import { captureTelemetry } from '../telemetry';
import { WORKSPACE_SYMBOLS_BUILD } from '../telemetry/constants';
export class Generator implements vscode.Disposable {
private optionsFile: string;
private disposables: vscode.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: vscode.Uri, private output: vscode.OutputChannel) {
this.disposables = [];
this.optionsFile = path.join(__dirname, '..', '..', '..', 'resources', 'ctagOptions');
this.pythonSettings = PythonSettings.getInstance(workspaceFolder);
}
public dispose() {
this.disposables.forEach(d => d.dispose());
}
private buildCmdArgs(): string[] {
const optionsFile = this.optionsFile.indexOf(' ') > 0 ? `"${this.optionsFile}"` : this.optionsFile;
const exclusions = this.pythonSettings.workspaceSymbols.exclusionPatterns;
const excludes = exclusions.length === 0 ? [] : exclusions.map(pattern => `--exclude=${pattern}`);
return [`--options=${optionsFile}`, '--languages=Python'].concat(excludes);
}
public async generateWorkspaceTags(): Promise<void> {
if (!this.pythonSettings.workspaceSymbols.enabled) {
return;
}
return await this.generateTags({ directory: this.workspaceFolder.fsPath });
}
@captureTelemetry(WORKSPACE_SYMBOLS_BUILD)
private 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 (!fs.existsSync(outputDir)) {
fs.mkdirSync(outputDir);
}
outputFile = outputFile.indexOf(' ') > 0 ? `"${outputFile}"` : outputFile;
args.push(`-o ${outputFile}`, '.');
this.output.appendLine('-'.repeat(10) + 'Generating Tags' + '-'.repeat(10));
this.output.appendLine(`${cmd} ${args.join(' ')}`);
const promise = new Promise<void>((resolve, reject) => {
let options: child_process.SpawnOptions = {
cwd: source.directory
};
let hasErrors = false;
let errorMsg = '';
const proc = child_process.spawn(cmd, args, options);
proc.stderr.setEncoding('utf8');
proc.stdout.setEncoding('utf8');
proc.on('error', (error: Error) => {
reject(error);
});
proc.stderr.on('data', (data: string) => {
errorMsg += data;
this.output.append(data);
});
proc.stdout.on('data', (data: string) => {
this.output.append(data);
});
proc.on('exit', () => {
if (hasErrors) {
reject(errorMsg);
}
else {
resolve();
}
});
});
vscode.window.setStatusBarMessage('Generating Tags', promise);
return promise;
}
}