<commit_before>import spawn from "../os/spawn";

import butler from "../util/butler";

import { join } from "path";

import { devNull } from "../logger";
import {
  IInstallManager,
  IInstallOpts,
  IInstallResult,
  IUninstallOpts,
  IUninstallResult,
} from "./common/core";

import getBlessing from "./common/get-blessing";
import findUninstallers from "./common/find-uninstallers";
import saveAngels from "./common/save-angels";
import { formatExitCode } from "../format/exit-code";

// NSIS docs: http://nsis.sourceforge.net/Docs/Chapter3.html
// When ran without elevate, some NSIS installers will silently fail.
// So, we run them with elevate all the time.

async function install(opts: IInstallOpts): Promise<IInstallResult> {
  const { ctx } = opts;
  const logger = opts.logger.child({ name: "nsis/install" });

  await getBlessing(opts, "install");
  ctx.emitProgress({ progress: -1 });

  const result = await saveAngels(opts, async () => {
    let removeAfterUsage = false;

    const { archivePath, destPath } = opts;
    let installerPath = archivePath;

    /*
     * FIXME: change downloads directory structure, instead of having:
     * - downloads/
     *   - 123.zip
     *   - 456
     * 
     * let's have:
     * - downloads/
     *   - 123/
     *     - Complete filename.zip
     *   - 456/
     *     - Another file.exe
     * 
     * and then we won't need that at all.
     */
    if (!/\.exe$/i.test(installerPath)) {
      // copy to temporary file, otherwise windows will refuse to open them
      // cf. https://github.com/itchio/itch/issues/322
      installerPath += ".exe";
      await butler.ditto(opts.archivePath, installerPath, {
        ctx,
        logger: devNull,
      });
      removeAfterUsage = true;
    }

    const code = await spawn({
      command: "butler.exe",
      args: [
        "elevate",
        "--",
        installerPath,
        "/S", // run the installer silently
        "/NCRC", // disable CRC-check, we do hash checking ourselves
        `/D=${destPath}`,
      ],
      onToken: tok => logger.info(`${installerPath}: ${tok}`),
      ctx,
      logger,
    });

    // FIXME: remove that too then
    if (removeAfterUsage) {
      await butler.wipe(installerPath, {
        ctx,
        logger: devNull,
      });
    }

    if (code !== 0) {
      // TODO: standardize those errors so we can have dialogs for them
      // and have them be reported.
      throw new Error(`NSIS Installer exit code: ${formatExitCode(code)}`);
    }

    logger.info("elevate/nsis installer completed successfully");
  });

  return {
    files: result.files,
  };
}

async function uninstall(opts: IUninstallOpts): Promise<IUninstallResult> {
  const { ctx } = opts;

  const logger = opts.logger.child({ name: "nsis/uninstall" });
  ctx.emitProgress({ progress: -1 });<commit_msg>Remove workaround for nsis installers<commit_after>import spawn from "../os/spawn";

import butler from "../util/butler";

import { join } from "path";

import { devNull } from "../logger";
import {
  IInstallManager,
  IInstallOpts,
  IInstallResult,
  IUninstallOpts,
  IUninstallResult,
} from "./common/core";

import getBlessing from "./common/get-blessing";
import findUninstallers from "./common/find-uninstallers";
import saveAngels from "./common/save-angels";
import { formatExitCode } from "../format/exit-code";

// NSIS docs: http://nsis.sourceforge.net/Docs/Chapter3.html
// When ran without elevate, some NSIS installers will silently fail.
// So, we run them with elevate all the time.

async function install(opts: IInstallOpts): Promise<IInstallResult> {
  const { ctx } = opts;
  const logger = opts.logger.child({ name: "nsis/install" });

  await getBlessing(opts, "install");
  ctx.emitProgress({ progress: -1 });

  const result = await saveAngels(opts, async () => {
    const { archivePath, destPath } = opts;

    const code = await spawn({
      command: "butler.exe",
      args: [
        "elevate",
        "--",
        archivePath,
        "/S", // run the installer silently
        "/NCRC", // disable CRC-check, we do hash checking ourselves
        `/D=${destPath}`,
      ],
      onToken: tok => logger.info(`${archivePath}: ${tok}`),
      ctx,
      logger,
    });

    if (code !== 0) {
      // TODO: standardize those errors so we can have dialogs for them
      // and have them be reported.
      throw new Error(`NSIS Installer exit code: ${formatExitCode(code)}`);
    }

    logger.info("elevate/nsis installer completed successfully");
  });

  return {
    files: result.files,
  };
}

async function uninstall(opts: IUninstallOpts): Promise<IUninstallResult> {
  const { ctx } = opts;

  const logger = opts.logger.child({ name: "nsis/uninstall" });
  ctx.emitProgress({ progress: -1 });
{'fraction_non_alphanumeric': 0.13929618768328444, 'fraction_numerical': 0.004817762882279012, 'mean_word_length': 2.6901081916537866, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 11, 'https://': 1, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 3, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6173974', 'n_tokens_mistral': 1504, 'n_tokens_neox': 1452, 'n_words': 411}