diff --git a/.idea/dictionaries/develar.xml b/.idea/dictionaries/develar.xml
index 68739d4e80f..f3868690f1c 100644
--- a/.idea/dictionaries/develar.xml
+++ b/.idea/dictionaries/develar.xml
@@ -66,6 +66,7 @@
makensis
minimatch
mkdirp
+ mkdtemp
mpass
multilib
multiuser
diff --git a/.idea/runConfigurations/BuildTest.xml b/.idea/runConfigurations/BuildTest.xml
index a8e2d4f3070..84eb02dad06 100644
--- a/.idea/runConfigurations/BuildTest.xml
+++ b/.idea/runConfigurations/BuildTest.xml
@@ -3,6 +3,12 @@
-
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/runConfigurations/CodeSignTest.xml b/.idea/runConfigurations/CodeSignTest.xml
index f0946aeda3c..4322aa815c4 100644
--- a/.idea/runConfigurations/CodeSignTest.xml
+++ b/.idea/runConfigurations/CodeSignTest.xml
@@ -1,5 +1,5 @@
-
+
@@ -9,6 +9,8 @@
-
+
+
+
\ No newline at end of file
diff --git a/.idea/runConfigurations/linuxPackagerTest.xml b/.idea/runConfigurations/linuxPackagerTest.xml
index 66f9cec4093..dc6fad857b3 100644
--- a/.idea/runConfigurations/linuxPackagerTest.xml
+++ b/.idea/runConfigurations/linuxPackagerTest.xml
@@ -1,5 +1,5 @@
-
+
@@ -7,6 +7,8 @@
-
+
+
+
\ No newline at end of file
diff --git a/.idea/runConfigurations/osxPackagerTest.xml b/.idea/runConfigurations/osxPackagerTest.xml
deleted file mode 100644
index 4a823a86878..00000000000
--- a/.idea/runConfigurations/osxPackagerTest.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 9b75ae864f8..7243f5716be 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -88,6 +88,7 @@ Only IntelliJ Platform IDEs (IntelliJ IDEA, WebStorm) support debug. [Forked ver
Use one of the shared run configurations as a template and:
+* Ensure that `Before launch` contains `Compile TypeScript`.
* Set `Node interpreter` to NodeJS 7. Yes — NodeJS 7 is required to debug. Download [nightly build](https://nodejs.org/download/nightly/).
* Set `Node parameters` to `--inspect`.
* Set `Application Parameters` to `--match="test name" relative-test-file-name` if you want to debug particular test. E.g.
diff --git a/src/codeSign.ts b/src/codeSign.ts
index 623f870239c..c804ce3aa7a 100644
--- a/src/codeSign.ts
+++ b/src/codeSign.ts
@@ -1,12 +1,12 @@
import { exec, getTempName, isEmptyOrSpaces } from "./util/util"
import { deleteFile, outputFile, copy, rename } from "fs-extra-p"
import { download } from "./util/httpRequest"
-import { tmpdir } from "os"
import * as path from "path"
import { executeFinally, all } from "./util/promise"
import { Promise as BluebirdPromise } from "bluebird"
import { randomBytes } from "crypto"
import { homedir } from "os"
+import { TmpDir } from "./util/tmp"
//noinspection JSUnusedLocalSymbols
const __awaiter = require("./util/awaiter")
@@ -19,23 +19,13 @@ export interface CodeSigningInfo {
keychainName?: string | null
}
-export function generateKeychainName(): string {
- return path.join(tmpdir(), getTempName("csc") + ".keychain")
-}
-
-export function downloadCertificate(urlOrBase64: string): BluebirdPromise {
- const tempFile = path.join(tmpdir(), `${getTempName()}.p12`)
- if (urlOrBase64.startsWith("https://")) {
- return download(urlOrBase64, tempFile)
- .thenReturn(tempFile)
- }
- else if (urlOrBase64.startsWith("file://")) {
+export function downloadCertificate(urlOrBase64: string, tmpDir: TmpDir): BluebirdPromise {
+ if (urlOrBase64.startsWith("file://")) {
return BluebirdPromise.resolve(urlOrBase64.substring("file://".length))
}
- else {
- return outputFile(tempFile, new Buffer(urlOrBase64, "base64"))
- .thenReturn(tempFile)
- }
+
+ return tmpDir.getTempFile(".p12")
+ .then(tempFile => (urlOrBase64.startsWith("https://") ? download(urlOrBase64, tempFile) : outputFile(tempFile, new Buffer(urlOrBase64, "base64"))).thenReturn(tempFile))
}
let bundledCertKeychainAdded: Promise | null = null
@@ -66,12 +56,14 @@ async function createCustomCertKeychain() {
}
}
-export async function createKeychain(keychainName: string, cscLink: string, cscKeyPassword: string, cscILink?: string | null, cscIKeyPassword?: string | null): Promise {
+export async function createKeychain(tmpDir: TmpDir, cscLink: string, cscKeyPassword: string, cscILink?: string | null, cscIKeyPassword?: string | null): Promise {
if (bundledCertKeychainAdded == null) {
bundledCertKeychainAdded = createCustomCertKeychain()
}
await bundledCertKeychainAdded
+ const keychainName = await tmpDir.getTempFile(".keychain")
+
const certLinks = [cscLink]
if (cscILink != null) {
certLinks.push(cscILink)
@@ -80,7 +72,7 @@ export async function createKeychain(keychainName: string, cscLink: string, cscK
const certPaths = new Array(certLinks.length)
const keychainPassword = randomBytes(8).toString("hex")
return await executeFinally(BluebirdPromise.all([
- BluebirdPromise.map(certLinks, (link, i) => downloadCertificate(link).then(it => certPaths[i] = it)),
+ BluebirdPromise.map(certLinks, (link, i) => downloadCertificate(link, tmpDir).then(it => certPaths[i] = it)),
BluebirdPromise.mapSeries([
["create-keychain", "-p", keychainPassword, keychainName],
["unlock-keychain", "-p", keychainPassword, keychainName],
@@ -88,13 +80,7 @@ export async function createKeychain(keychainName: string, cscLink: string, cscK
], it => exec("security", it))
])
.then(() => importCerts(keychainName, certPaths, >[cscKeyPassword, cscIKeyPassword].filter(it => it != null))),
- errorOccurred => {
- const tasks = certPaths.map((it, index) => certLinks[index].startsWith("https://") ? deleteFile(it, true) : BluebirdPromise.resolve())
- if (errorOccurred) {
- tasks.push(deleteKeychain(keychainName))
- }
- return all(tasks)
- })
+ () => all(certPaths.map((it, index) => certLinks[index].startsWith("https://") ? deleteFile(it, true) : BluebirdPromise.resolve())))
}
async function importCerts(keychainName: string, paths: Array, keyPasswords: Array): Promise {
@@ -115,20 +101,6 @@ export function sign(path: string, name: string, keychain: string): BluebirdProm
return exec("codesign", args)
}
-export function deleteKeychain(keychainName: string, ignoreNotFound: boolean = true): BluebirdPromise {
- const result = exec("security", ["delete-keychain", keychainName])
- if (ignoreNotFound) {
- return result.catch(error => {
- if (!error.message.includes("The specified keychain could not be found.")) {
- throw error
- }
- })
- }
- else {
- return result
- }
-}
-
export let findIdentityRawResult: Promise> | null = null
async function getValidIdentities(keychain?: string | null): Promise> {
diff --git a/src/linuxPackager.ts b/src/linuxPackager.ts
index 1d8bc4ec6d5..0c29b7ef03a 100755
--- a/src/linuxPackager.ts
+++ b/src/linuxPackager.ts
@@ -36,7 +36,7 @@ export class LinuxPackager extends PlatformPackager {
let helper: LinuxTargetHelper | null
const getHelper = () => {
if (helper == null) {
- helper = new LinuxTargetHelper(this, cleanupTasks)
+ helper = new LinuxTargetHelper(this)
}
return helper
}
diff --git a/src/macPackager.ts b/src/macPackager.ts
index 11710908fb0..1b07ef2fea0 100644
--- a/src/macPackager.ts
+++ b/src/macPackager.ts
@@ -3,7 +3,7 @@ import { Platform, MasBuildOptions, Arch, MacOptions } from "./metadata"
import * as path from "path"
import { Promise as BluebirdPromise } from "bluebird"
import { log, warn, task } from "./util/log"
-import { createKeychain, deleteKeychain, CodeSigningInfo, generateKeychainName, findIdentity } from "./codeSign"
+import { createKeychain, CodeSigningInfo, findIdentity } from "./codeSign"
import { deepAssign } from "./util/deepAssign"
import { signAsync, flatAsync, BaseSignOptions, SignOptions, FlatOptions } from "electron-osx-sign"
import { DmgTarget } from "./targets/dmg"
@@ -16,16 +16,14 @@ const __awaiter = require("./util/awaiter")
export default class MacPackager extends PlatformPackager {
codeSigningInfo: Promise
- constructor(info: BuildInfo, cleanupTasks: Array<() => Promise>) {
+ constructor(info: BuildInfo) {
super(info)
if (this.options.cscLink == null) {
this.codeSigningInfo = BluebirdPromise.resolve({})
}
else {
- const keychainName = generateKeychainName()
- cleanupTasks.push(() => deleteKeychain(keychainName))
- this.codeSigningInfo = createKeychain(keychainName, this.options.cscLink, this.getCscPassword(), this.options.cscInstallerLink, this.options.cscInstallerKeyPassword)
+ this.codeSigningInfo = createKeychain(info.tempDirManager, this.options.cscLink!, this.getCscPassword(), this.options.cscInstallerLink, this.options.cscInstallerKeyPassword)
}
}
diff --git a/src/packager.ts b/src/packager.ts
index 3f65da5ce33..15b8be863ad 100644
--- a/src/packager.ts
+++ b/src/packager.ts
@@ -18,6 +18,7 @@ import { AppInfo } from "./appInfo"
import MacPackager from "./macPackager"
import { createTargets } from "./targets/targetFactory"
import { readPackageJson } from "./util/readPackageJson"
+import { TmpDir } from "./util/tmp"
//noinspection JSUnusedLocalSymbols
const __awaiter = require("./util/awaiter")
@@ -41,6 +42,8 @@ export class Packager implements BuildInfo {
appInfo: AppInfo
+ readonly tempDirManager = new TmpDir()
+
//noinspection JSUnusedGlobalSymbols
constructor(public options: PackagerOptions) {
this.projectDir = options.projectDir == null ? process.cwd() : path.resolve(options.projectDir)
@@ -91,7 +94,7 @@ export class Packager implements BuildInfo {
this.appInfo = new AppInfo(this.metadata, this.devMetadata)
const cleanupTasks: Array<() => Promise> = []
- return executeFinally(this.doBuild(cleanupTasks), () => all(cleanupTasks.map(it => it())))
+ return executeFinally(this.doBuild(cleanupTasks), () => all(cleanupTasks.map(it => it()).concat(this.tempDirManager.cleanup())))
}
private async doBuild(cleanupTasks: Array<() => Promise>): Promise