<commit_before>'use strict'

const downloadFileFromGithub = require('./download-file-from-github')
const electronInstaller = require('electron-winstaller')
const fs = require('fs-extra')
const glob = require('glob')
const os = require('os')
const path = require('path')
const spawnSync = require('./spawn-sync')

const CONFIG = require('../config')

module.exports = function (packagedAppPath, codeSign) {
  const options = {
    appDirectory: packagedAppPath,
    authors: 'GitHub Inc.',
    iconUrl: `https://raw.githubusercontent.com/atom/atom/master/resources/app-icons/${CONFIG.channel}/atom.ico`,
    loadingGif: path.join(CONFIG.repositoryRootPath, 'resources', 'win', 'loading.gif'),
    outputDirectory: CONFIG.buildOutputPath,
    remoteReleases: `https://atom.io/api/updates?version=${CONFIG.appMetadata.version}`,
    setupIcon: path.join(CONFIG.repositoryRootPath, 'resources', 'app-icons', CONFIG.channel, 'atom.ico')
  }

  const certPath = path.join(os.tmpdir(), 'win.p12')
  const signing = codeSign && process.env.WIN_P12KEY_URL

  if (signing) {
    downloadFileFromGithub(process.env.WIN_P12KEY_URL, certPath)
    var signParams = []
    signParams.push(`/f ${certPath}`) // Signing cert file
    signParams.push(`/p ${process.env.WIN_P12KEY_PASSWORD}`) // Signing cert password
    signParams.push('/fd sha256') // File digest algorithm
    signParams.push('/tr http://timestamp.digicert.com') // Time stamp server
    signParams.push('/td sha256') // Times stamp algorithm
    options.signWithParams = signParams.join(' ')
  } else {
    console.log('Skipping code-signing. Specify the --code-sign option and provide a WIN_P12KEY_URL environment variable to perform code-signing'.gray)
  }

  const cleanUp = function () {
    if (fs.existsSync(certPath)) {
      console.log(`Deleting certificate at ${certPath}`)
      fs.removeSync(certPath)
    }

    for (let nupkgPath of glob.sync(`${CONFIG.buildOutputPath}/*.nupkg`)) {
      if (!nupkgPath.includes(CONFIG.appMetadata.version)) {
        console.log(`Deleting downloaded nupkg for previous version at ${nupkgPath} to prevent it from being stored as an artifact`)
        fs.removeSync(nupkgPath)
      }
    }
  }

  // Squirrel signs its own copy of the executables but we need them for the portable ZIP
  const extractSignedExes = function() {
    if (signing) {
      for (let nupkgPath of glob.sync(`${CONFIG.buildOutputPath}/*-full.nupkg`)) {
        if (nupkgPath.includes(CONFIG.appMetadata.version)) {
          console.log(`Extracting signed executables from ${nupkgPath} for use in portable zip`)
          const outPath = path.dirname(nupkgPath)
          const appPath = path.relative(outPath, packagedAppPath)
          spawnSync('7z.exe', ['e', path.relative(outPath, nupkgPath), 'lib\\net45\\*.exe', '-aoa', `-o${appPath}`], { cwd:outPath })
          spawnSync(process.env.COMSPEC, ['/c', `move /y ${path.join(appPath, 'squirrel.exe')} ${path.join(appPath, 'update.exe')}`], { cwd:outPath })
          return
        }
      }
    }
  }

  console.log(`Creating Windows Installer for ${packagedAppPath}`)
  return electronInstaller.createWindowsInstaller(options)
    .then(extractSignedExes, function (error) {
      console.log(`Extracting signed executables failed:\n${error}`)
      cleanUp()
    })
    .then(cleanUp, function (error) {
      console.log(`Windows installer creation failed:\n${error}`)
      cleanUp()
    })
}
<commit_msg>Deal with spaces, paths and other 7z/cmd issues with signed extraction<commit_after>'use strict'

const downloadFileFromGithub = require('./download-file-from-github')
const electronInstaller = require('electron-winstaller')
const fs = require('fs-extra')
const glob = require('glob')
const os = require('os')
const path = require('path')
const spawnSync = require('./spawn-sync')

const CONFIG = require('../config')

module.exports = function (packagedAppPath, codeSign) {
  const options = {
    appDirectory: packagedAppPath,
    authors: 'GitHub Inc.',
    iconUrl: `https://raw.githubusercontent.com/atom/atom/master/resources/app-icons/${CONFIG.channel}/atom.ico`,
    loadingGif: path.join(CONFIG.repositoryRootPath, 'resources', 'win', 'loading.gif'),
    outputDirectory: CONFIG.buildOutputPath,
    remoteReleases: `https://atom.io/api/updates?version=${CONFIG.appMetadata.version}`,
    setupIcon: path.join(CONFIG.repositoryRootPath, 'resources', 'app-icons', CONFIG.channel, 'atom.ico')
  }

  const certPath = path.join(os.tmpdir(), 'win.p12')
  const signing = codeSign && process.env.WIN_P12KEY_URL

  if (signing) {
    downloadFileFromGithub(process.env.WIN_P12KEY_URL, certPath)
    var signParams = []
    signParams.push(`/f ${certPath}`) // Signing cert file
    signParams.push(`/p ${process.env.WIN_P12KEY_PASSWORD}`) // Signing cert password
    signParams.push('/fd sha256') // File digest algorithm
    signParams.push('/tr http://timestamp.digicert.com') // Time stamp server
    signParams.push('/td sha256') // Times stamp algorithm
    options.signWithParams = signParams.join(' ')
  } else {
    console.log('Skipping code-signing. Specify the --code-sign option and provide a WIN_P12KEY_URL environment variable to perform code-signing'.gray)
  }

  const cleanUp = function () {
    if (fs.existsSync(certPath)) {
      console.log(`Deleting certificate at ${certPath}`)
      fs.removeSync(certPath)
    }

    for (let nupkgPath of glob.sync(`${CONFIG.buildOutputPath}/*.nupkg`)) {
      if (!nupkgPath.includes(CONFIG.appMetadata.version)) {
        console.log(`Deleting downloaded nupkg for previous version at ${nupkgPath} to prevent it from being stored as an artifact`)
        fs.removeSync(nupkgPath)
      }
    }
  }

  // Squirrel signs its own copy of the executables but we need them for the portable ZIP
  const extractSignedExes = function() {
    if (signing) {
      for (let nupkgPath of glob.sync(`${CONFIG.buildOutputPath}/*-full.nupkg`)) {
        if (nupkgPath.includes(CONFIG.appMetadata.version)) {
          nupkgPath = path.resolve(nupkgPath) // Switch from forward-slash notation
          console.log(`Extracting signed executables from ${nupkgPath} for use in portable zip`)
          spawnSync('7z.exe', ['e', nupkgPath, 'lib\\net45\\*.exe', '-aoa', `-o${packagedAppPath}`])
          spawnSync(process.env.COMSPEC, ['/c', 'move', '/y', path.join(packagedAppPath, 'squirrel.exe'), path.join(packagedAppPath, 'update.exe')])
          return
        }
      }
    }
  }

  console.log(`Creating Windows Installer for ${packagedAppPath}`)
  return electronInstaller.createWindowsInstaller(options)
    .then(extractSignedExes, function (error) {
      console.log(`Extracting signed executables failed:\n${error}`)
      cleanUp()
    })
    .then(cleanUp, function (error) {
      console.log(`Windows installer creation failed:\n${error}`)
      cleanUp()
    })
}

{'fraction_non_alphanumeric': 0.142129764329357, 'fraction_numerical': 0.005673552516729706, 'mean_word_length': 3.7709923664122136, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 4, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 8, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2123830', 'n_tokens_mistral': 2175, 'n_tokens_neox': 2126, 'n_words': 470}