<commit_before>/*
 * Copyright 2018 <NAME> <<EMAIL>>
 *
 * This source code is licensed under the MIT license which is detailed in the LICENSE.txt file.
 */
import * as constants from 'constants';
import * as fs from 'fs';
import * as path from 'path';
import * as _ from 'lodash';
import { ExtensionContext, Logger, Pty, SessionConfiguration, SessionBackend, CreateSessionOptions } from '@extraterm/extraterm-extension-api';
import { ShellStringParser } from 'extraterm-shell-string-parser';

import { WindowsConsolePty, PtyOptions } from './WindowsConsolePty';

interface WindowsConsoleSessionConfiguration extends SessionConfiguration {
  exe?: string;
}

const WINDOWS_CONSOLE_TYPE = "windows-console";

class WindowsConsoleBackend implements SessionBackend {

  constructor(private _log: Logger) {
  }

  defaultSessionConfigurations(): SessionConfiguration[] {
    const defaultSessions: WindowsConsoleSessionConfiguration[] = [];

    const cmdSessionConfig: WindowsConsoleSessionConfiguration = {
      uuid: "",
      name: "CMD",
      type: WINDOWS_CONSOLE_TYPE,
      exe: "cmd.exe",
      args: ""
    };
    defaultSessions.push(cmdSessionConfig);

    if (this._validateExe("powershell.exe")) {
      const powershellSessionConfig: WindowsConsoleSessionConfiguration = {
        uuid: "",
        name: "PowerShell",
        type: WINDOWS_CONSOLE_TYPE,
        exe: "powershell.exe",
        args: ""
      };
      defaultSessions.push(powershellSessionConfig);
    }

    if (this._validateExe("pwsh.exe")) {
      const powershellCoreSessionConfig: WindowsConsoleSessionConfiguration = {
        uuid: "",
        name: "PowerShell Core",
        type: WINDOWS_CONSOLE_TYPE,
        exe: "pwsh.exe",
        args: ""
      };
      defaultSessions.push(powershellCoreSessionConfig);
    }

    return defaultSessions;
  }

  createSession(sessionConfiguration: SessionConfiguration, sessionOptions: CreateSessionOptions): Pty {
    const sessionConfig = <WindowsConsoleSessionConfiguration> sessionConfiguration;

    let exe = sessionConfig.exe;
    let preMessage = "";
    const args = ShellStringParser(sessionConfig.args);

    if ( ! this._validateExe(exe)) {
      preMessage = `\x0a\x0d\x0a\x0d*** Program '${exe}' couldn't be executed, falling back to 'cmd.exe' ***\x0a\x0d\x0a\x0d\x0a\x0d`;
      exe = "cmd.exe";
    }

    const ptyEnv = _.cloneDeep(process.env);
    let prop: string;
    for (prop in sessionOptions.extraEnv) {
      ptyEnv[prop] = sessionOptions.extraEnv[prop];
    }

    let cwd: string = null;

    if (sessionConfig.initialDirectory != null && sessionConfig.initialDirectory !== "") {
      const dirError = this._validateDirectoryPath(cwd);
      if (dirError != null) {
        preMessage += `\x0a\x0d\x0a\x0d*** Initial directory '${cwd}' couldn't be found. ***\x0a\x0d\x0a\x0d\x0a\x0d`;
      } else {
        cwd = sessionConfig.initialDirectory;
      }
    }

    if (cwd == null && sessionOptions.workingDirectory != null && sessionOptions.workingDirectory !== "") {
      const dirError = this._validateDirectoryPath(sessionOptions.workingDirectory);
      if (dirError == null) {
        cwd = sessionOptions.workingDirectory;
      }
    }

    if (cwd == null) {
      cwd = process.env.HOME;
    }

    const dirError = this._validateDirectoryPath(cwd);
    if (dirError != null) {
      preMessage += `\x0a\x0d\x0a\x0d*** Initial directory '${cwd}' couldn't be found. ***\x0a\x0d\x0a\x0d\x0a\x0d`;
    }

    const options: PtyOptions = {
      exe: exe,
      args: args,
      env: ptyEnv,
      cols: sessionOptions.cols,
      rows: sessionOptions.rows,
      cwd,
      preMessage
    };
    return new WindowsConsolePty(this._log, options);
  }

  private _validateExe(exe: string): boolean {
    if (path.isAbsolute(exe)) {
      return this._validateExePath(exe);
    }

    const searchPaths: string[] = process.env.PATH.split(";");<commit_msg>Fix up the initial directory for windows console sessions.<commit_after>/*
 * Copyright 2018 <NAME> <<EMAIL>>
 *
 * This source code is licensed under the MIT license which is detailed in the LICENSE.txt file.
 */
import * as constants from 'constants';
import * as fs from 'fs';
import * as path from 'path';
import * as _ from 'lodash';
import { ExtensionContext, Logger, Pty, SessionConfiguration, SessionBackend, CreateSessionOptions } from '@extraterm/extraterm-extension-api';
import { ShellStringParser } from 'extraterm-shell-string-parser';

import { WindowsConsolePty, PtyOptions } from './WindowsConsolePty';

interface WindowsConsoleSessionConfiguration extends SessionConfiguration {
  exe?: string;
}

const WINDOWS_CONSOLE_TYPE = "windows-console";

class WindowsConsoleBackend implements SessionBackend {

  constructor(private _log: Logger) {
  }

  defaultSessionConfigurations(): SessionConfiguration[] {
    const defaultSessions: WindowsConsoleSessionConfiguration[] = [];

    const cmdSessionConfig: WindowsConsoleSessionConfiguration = {
      uuid: "",
      name: "CMD",
      type: WINDOWS_CONSOLE_TYPE,
      exe: "cmd.exe",
      args: ""
    };
    defaultSessions.push(cmdSessionConfig);

    if (this._validateExe("powershell.exe")) {
      const powershellSessionConfig: WindowsConsoleSessionConfiguration = {
        uuid: "",
        name: "PowerShell",
        type: WINDOWS_CONSOLE_TYPE,
        exe: "powershell.exe",
        args: ""
      };
      defaultSessions.push(powershellSessionConfig);
    }

    if (this._validateExe("pwsh.exe")) {
      const powershellCoreSessionConfig: WindowsConsoleSessionConfiguration = {
        uuid: "",
        name: "PowerShell Core",
        type: WINDOWS_CONSOLE_TYPE,
        exe: "pwsh.exe",
        args: ""
      };
      defaultSessions.push(powershellCoreSessionConfig);
    }

    return defaultSessions;
  }

  createSession(sessionConfiguration: SessionConfiguration, sessionOptions: CreateSessionOptions): Pty {
    const sessionConfig = <WindowsConsoleSessionConfiguration> sessionConfiguration;

    let exe = sessionConfig.exe;
    let preMessage = "";
    const args = ShellStringParser(sessionConfig.args);

    if ( ! this._validateExe(exe)) {
      preMessage = `\x0a\x0d\x0a\x0d*** Program '${exe}' couldn't be executed, falling back to 'cmd.exe'. ***\x0a\x0d\x0a\x0d\x0a\x0d`;
      this._log.warn(`Program '${exe}' couldn't be executed, falling back to 'cmd.exe'.`);
      exe = "cmd.exe";
    }

    const ptyEnv = _.cloneDeep(process.env);
    let prop: string;
    for (prop in sessionOptions.extraEnv) {
      ptyEnv[prop] = sessionOptions.extraEnv[prop];
    }

    let cwd: string = null;

    if (sessionConfig.initialDirectory != null && sessionConfig.initialDirectory !== "") {
      const dirError = this._validateDirectoryPath(sessionConfig.initialDirectory);
      if (dirError != null) {
        preMessage += `\x0a\x0d\x0a\x0d*** Initial directory '${sessionConfig.initialDirectory}' couldn't be found. ***\x0a\x0d\x0a\x0d\x0a\x0d`;
        this._log.warn(`Initial directory '${sessionConfig.initialDirectory}' couldn't be found.`);
      } else {
        cwd = sessionConfig.initialDirectory;
      }
    }

    if (cwd == null && sessionOptions.workingDirectory != null && sessionOptions.workingDirectory !== "") {
      const dirError = this._validateDirectoryPath(sessionOptions.workingDirectory);
      if (dirError == null) {
        cwd = sessionOptions.workingDirectory;
      }
    }

    if (cwd == null) {
      cwd = process.env.HOME;
    }

    const dirError = this._validateDirectoryPath(cwd);
    if (dirError != null) {
      preMessage += `\x0a\x0d\x0a\x0d*** Initial directory '${cwd}' couldn't be found. ***\x0a\x0d\x0a\x0d\x0a\x0d`;
      this._log.warn(`Initial directory '${cwd}' couldn't be found.`);
    }

    const options: PtyOptions = {
      exe: exe,
      args: args,
      env: ptyEnv,
      cols: sessionOptions.cols,
      rows: sessionOptions.rows,
      cwd,
      preMessage
    };
    return new WindowsConsolePty(this._log, options);
  }

  private _validateExe(exe: string): boolean {
    if (path.isAbsolute(exe)) {
      return this._validateExePath(exe);
    }

    const searchPaths: string[] = process.env.PATH.split(";");
{'fraction_non_alphanumeric': 0.12323256947830327, 'fraction_numerical': 0.008288639687957094, 'mean_word_length': 3.316149395055234, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 11, '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': '423034', 'n_tokens_mistral': 2560, 'n_tokens_neox': 2465, 'n_words': 544}