<commit_before>import * as vscode from 'vscode';
import * as path from 'path';
import * as fs from 'fs';
import * as child_process from 'child_process';
import { PythonSettings } from '../common/configSettings';

const pythonSettings = PythonSettings.getInstance();

export class Generator implements vscode.Disposable {
    private optionsFile: string;
    private disposables: vscode.Disposable[];

    constructor(private output: vscode.OutputChannel) {
        this.disposables = [];
        this.optionsFile = path.join(__dirname, '..', '..', '..', 'resources', 'ctagOptions');
    }

    dispose() {
        this.disposables.forEach(d => d.dispose());
    }

    private buildCmdArgsg(): string[] {
        const optionsFile = this.optionsFile.indexOf(' ') > 0 ? `"${this.optionsFile}"` : this.optionsFile;
        const exclusions = pythonSettings.workspaceSymbols.exclusionPatterns;
        const excludes = exclusions.length === 0 ? [] : exclusions.map(pattern => `--exclude=${pattern}`);

        return [`--options=${optionsFile}`, '--languages=Python'].concat(excludes);
    }

    generateWorkspaceTags(): Promise<any> {
        const tagFile = path.normalize(pythonSettings.workspaceSymbols.tagFilePath);
        return this.generateTags(tagFile, { directory: vscode.workspace.rootPath });
    }

    private generateTags(outputFile: string, source: { directory?: string, file?: string }): Promise<any> {
        const cmd = pythonSettings.workspaceSymbols.ctagsPath;
        const args = this.buildCmdArgsg();
        if (source.file && source.file.length > 0) {
            source.directory = path.dirname(source.file);
        }

        if (path.dirname(outputFile) === source.directory) {
            outputFile = path.basename(outputFile);
        }
        outputFile = outputFile.indexOf(' ') > 0 ? `"${outputFile}"` : outputFile;
        const outputDir = path.dirname(outputFile);
        if (!fs.existsSync(outputDir)){
            fs.mkdirSync(outputDir);
        }
        args.push(`-o ${outputFile}`, '.');
        this.output.appendLine('-'.repeat(10) + 'Generating Tags' + '-'.repeat(10));
        this.output.appendLine(`${cmd} ${args.join(' ')}`);
        const promise = new Promise<any>((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);<commit_msg>fix typo<commit_after>import * as vscode from 'vscode';
import * as path from 'path';
import * as fs from 'fs';
import * as child_process from 'child_process';
import { PythonSettings } from '../common/configSettings';

const pythonSettings = PythonSettings.getInstance();

export class Generator implements vscode.Disposable {
    private optionsFile: string;
    private disposables: vscode.Disposable[];

    constructor(private output: vscode.OutputChannel) {
        this.disposables = [];
        this.optionsFile = path.join(__dirname, '..', '..', '..', 'resources', 'ctagOptions');
    }

    dispose() {
        this.disposables.forEach(d => d.dispose());
    }

    private buildCmdArgs(): string[] {
        const optionsFile = this.optionsFile.indexOf(' ') > 0 ? `"${this.optionsFile}"` : this.optionsFile;
        const exclusions = pythonSettings.workspaceSymbols.exclusionPatterns;
        const excludes = exclusions.length === 0 ? [] : exclusions.map(pattern => `--exclude=${pattern}`);

        return [`--options=${optionsFile}`, '--languages=Python'].concat(excludes);
    }

    generateWorkspaceTags(): Promise<any> {
        const tagFile = path.normalize(pythonSettings.workspaceSymbols.tagFilePath);
        return this.generateTags(tagFile, { directory: vscode.workspace.rootPath });
    }

    private generateTags(outputFile: string, source: { directory?: string, file?: string }): Promise<any> {
        const cmd = pythonSettings.workspaceSymbols.ctagsPath;
        const args = this.buildCmdArgs();
        if (source.file && source.file.length > 0) {
            source.directory = path.dirname(source.file);
        }

        if (path.dirname(outputFile) === source.directory) {
            outputFile = path.basename(outputFile);
        }
        outputFile = outputFile.indexOf(' ') > 0 ? `"${outputFile}"` : outputFile;
        const outputDir = path.dirname(outputFile);
        if (!fs.existsSync(outputDir)){
            fs.mkdirSync(outputDir);
        }
        args.push(`-o ${outputFile}`, '.');
        this.output.appendLine('-'.repeat(10) + 'Generating Tags' + '-'.repeat(10));
        this.output.appendLine(`${cmd} ${args.join(' ')}`);
        const promise = new Promise<any>((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);
{'fraction_non_alphanumeric': 0.14862075436291988, 'fraction_numerical': 0.0037530493525989865, 'mean_word_length': 2.7855113636363638, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 23, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4656410', 'n_tokens_mistral': 1527, 'n_tokens_neox': 1492, 'n_words': 300}