Skip to content

Commit f4398a7

Browse files
committed
fix(dmg): pass -ov flag to overwrite existing dmg
Close #1308
1 parent 3e2798f commit f4398a7

File tree

16 files changed

+166
-233
lines changed

16 files changed

+166
-233
lines changed

.idea/dictionaries/develar.xml

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/Options.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ You can use [file macros](#file-macros) in the `from` and `to` fields as well.
143143
| publish | <a name="Config-publish"></a>See [publish](https://github.com/electron-userland/electron-builder/wiki/Publishing-Artifacts#PublishConfiguration).
144144
| forceCodeSigning | <a name="Config-forceCodeSigning"></a>Whether to fail if application will be not signed (to prevent unsigned app if code signing configuration is not correct).
145145
| electronVersion | <a name="Config-electronVersion"></a>The version of electron you are packaging for. Defaults to version of `electron`, `electron-prebuilt` or `electron-prebuilt-compile` dependency.
146-
| artifactName | <a name="Config-artifactName"></a><p>The [artifact file name pattern](https://github.com/electron-userland/electron-builder/wiki/Options#artifact-file-name-pattern). Defaults to <code>${productName}-${version}.${ext}</code> (some target can have another defaults, see corresponding options).</p> <p>Currently supported only for <code>pkg</code>, <code>dmg</code> and <code>nsis</code>.</p>
146+
| artifactName | <a name="Config-artifactName"></a><p>The [artifact file name pattern](https://github.com/electron-userland/electron-builder/wiki/Options#artifact-file-name-pattern). Defaults to <code>${productName}-${version}.${ext}</code> (some target can have another defaults, see corresponding options).</p> <p>Currently supported only for <code>mas</code>, <code>pkg</code>, <code>dmg</code> and <code>nsis</code>.</p>
147147

148148
<a name="AppXOptions"></a>
149149
### `appx`

package.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
"ajv-keywords": "^2.0.1-beta.0",
3232
"archiver": "^1.3.0",
3333
"asar": "~0.13.0",
34-
"aws-sdk": "^2.20.0",
34+
"aws-sdk": "^2.22.0",
3535
"bluebird-lst": "^1.0.1",
3636
"chalk": "^1.1.3",
3737
"chromium-pickle-js": "^0.2.0",
@@ -62,8 +62,7 @@
6262
"yargs": "^6.6.0"
6363
},
6464
"devDependencies": {
65-
"@develar/typescript-json-schema": "0.9.3",
66-
"@types/electron": "^1.4.32",
65+
"@types/electron": "^1.4.33",
6766
"@types/ini": "^1.3.29",
6867
"@types/jest": "^18.1.1",
6968
"@types/js-yaml": "^3.5.29",
@@ -89,8 +88,9 @@
8988
"path-sort": "^0.1.0",
9089
"source-map-support": "^0.4.11",
9190
"ts-babel": "^1.4.4",
92-
"tslint": "^4.4.2",
91+
"tslint": "^4.5.0",
9392
"typescript": "^2.2.1",
93+
"typescript-json-schema": "0.10.0",
9494
"whitespace": "^2.1.0",
9595
"xml2js": "^0.4.17"
9696
},

packages/electron-builder/src/macPackager.ts

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { exec } from "electron-builder-util"
44
import { deepAssign } from "electron-builder-util/out/deepAssign"
55
import { log, task, warn } from "electron-builder-util/out/log"
66
import { signAsync, SignOptions } from "electron-macos-sign"
7+
import { ensureDir } from "fs-extra-p"
78
import * as path from "path"
89
import { AppInfo } from "./appInfo"
910
import { appleCertificatePrefixes, CodeSigningInfo, createKeychain, findIdentity } from "./codeSign"
@@ -41,7 +42,7 @@ export default class MacPackager extends PlatformPackager<MacOptions> {
4142
if (iconPath != null && !iconPath.endsWith(".icns")) {
4243
iconPath += ".icns"
4344
}
44-
return iconPath == null ? await this.getDefaultIcon("icns") : path.resolve(this.projectDir, iconPath)
45+
return iconPath == null ? await this.getDefaultIcon("icns") : await this.getResource(iconPath)
4546
}
4647

4748
createTargets(targets: Array<string>, mapper: (name: string, factory: (outDir: string) => Target) => void, cleanupTasks: Array<() => Promise<any>>): void {
@@ -77,8 +78,8 @@ export default class MacPackager extends PlatformPackager<MacOptions> {
7778

7879
if (!hasMas || targets.length > 1) {
7980
const appPath = prepackaged == null ? path.join(this.computeAppOutDir(outDir, arch), `${this.appInfo.productFilename}.app`) : prepackaged
80-
nonMasPromise = (prepackaged ? BluebirdPromise.resolve() : this.doPack(outDir, path.dirname(appPath), this.platform.nodeName, arch, this.platformSpecificBuildOptions))
81-
.then(() => this.sign(appPath, null))
81+
nonMasPromise = (prepackaged ? BluebirdPromise.resolve() : this.doPack(outDir, path.dirname(appPath), this.platform.nodeName, arch, this.platformSpecificBuildOptions, targets))
82+
.then(() => this.sign(appPath, null, null))
8283
.then(() => this.packageInDistributableFormat(appPath, Arch.x64, targets, postAsyncTasks))
8384
}
8485

@@ -88,25 +89,28 @@ export default class MacPackager extends PlatformPackager<MacOptions> {
8889
continue
8990
}
9091

91-
const appOutDir = prepackaged || path.join(outDir, targetName)
9292
const masBuildOptions = deepAssign({}, this.platformSpecificBuildOptions, (<any>this.config).mas)
9393
if (targetName === "mas-dev") {
9494
deepAssign(masBuildOptions, (<any>this.config)[targetName])
9595
masBuildOptions.type = "development"
9696
}
9797

98+
const targetOutDir = path.join(outDir, targetName)
9899
if (prepackaged == null) {
99-
await this.doPack(outDir, appOutDir, "mas", arch, masBuildOptions)
100+
await this.doPack(outDir, targetOutDir, "mas", arch, masBuildOptions, [target])
101+
await this.sign(path.join(targetOutDir, `${this.appInfo.productFilename}.app`), targetOutDir, masBuildOptions)
102+
}
103+
else {
104+
await this.sign(prepackaged, targetOutDir, masBuildOptions)
100105
}
101-
await this.sign(path.join(appOutDir, `${this.appInfo.productFilename}.app`), masBuildOptions)
102106
}
103107

104108
if (nonMasPromise != null) {
105109
await nonMasPromise
106110
}
107111
}
108112

109-
private async sign(appPath: string, masOptions: MasBuildOptions | null): Promise<void> {
113+
private async sign(appPath: string, outDir: string | null, masOptions: MasBuildOptions | null): Promise<void> {
110114
if (process.platform !== "darwin") {
111115
warn("macOS application code signing is supported only on macOS, skipping.")
112116
return
@@ -198,12 +202,13 @@ export default class MacPackager extends PlatformPackager<MacOptions> {
198202
await task(`Signing app (identity: ${name})`, this.doSign(signOptions))
199203

200204
if (masOptions != null) {
201-
const pkg = path.join(path.dirname(appPath), `${this.appInfo.productFilename}-${this.appInfo.version}.pkg`)
202205
const certType = "3rd Party Mac Developer Installer"
203206
const masInstallerIdentity = await findIdentity(certType, masOptions.identity, keychainName)
204207
if (masInstallerIdentity == null) {
205208
throw new Error(`Cannot find valid "${certType}" identity to sign MAS installer, please see https://github.com/electron-userland/electron-builder/wiki/Code-Signing`)
206209
}
210+
211+
const pkg = path.join(outDir!, this.expandArtifactNamePattern(masOptions, "pkg"))
207212
await this.doFlat(appPath, pkg, masInstallerIdentity, keychainName)
208213
this.dispatchArtifactCreated(pkg, null, `${this.appInfo.name}-${this.appInfo.version}.pkg`)
209214
}
@@ -216,9 +221,12 @@ export default class MacPackager extends PlatformPackager<MacOptions> {
216221

217222
//noinspection JSMethodCanBeStatic
218223
protected async doFlat(appPath: string, outFile: string, identity: string, keychain: string | n): Promise<any> {
224+
// productbuild doesn't created directory for out file
225+
await ensureDir(path.dirname(outFile))
226+
219227
const args = prepareProductBuildArgs(identity, keychain)
220228
args.push("--component", appPath, "/Applications")
221229
args.push(outFile)
222-
return exec("productbuild", args)
230+
return await exec("productbuild", args)
223231
}
224232
}

packages/electron-builder/src/metadata.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Arch, Platform, TargetSpecificOptions } from "electron-builder-core"
1+
import { Arch, Platform, Target, TargetSpecificOptions } from "electron-builder-core"
22
import { Publish } from "electron-builder-http/out/publishOptions"
33
import { DebOptions, LinuxBuildOptions, SnapOptions } from "./options/linuxOptions"
44
import { DmgOptions, MacOptions, MasBuildOptions, PkgOptions } from "./options/macOptions"
@@ -221,7 +221,7 @@ export interface Config extends PlatformSpecificBuildOptions, TargetSpecificOpti
221221
/**
222222
The [artifact file name pattern](https://github.com/electron-userland/electron-builder/wiki/Options#artifact-file-name-pattern). Defaults to `${productName}-${version}.${ext}` (some target can have another defaults, see corresponding options).
223223
224-
Currently supported only for `pkg`, `dmg` and `nsis`.
224+
Currently supported only for `mas`, `pkg`, `dmg` and `nsis`.
225225
*/
226226
readonly artifactName?: string | null
227227
}
@@ -231,6 +231,7 @@ export interface AfterPackContext {
231231
readonly packager: PlatformPackager<any>
232232
readonly electronPlatformName: string
233233
readonly arch: Arch
234+
readonly targets: Array<Target>
234235
}
235236

236237
export interface BeforeBuildContext {

packages/electron-builder/src/packager.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ export class Packager implements BuildInfo {
5555

5656
readonly tempDirManager = new TmpDir()
5757

58-
private _repositoryInfo = new Lazy<SourceRepositoryInfo>(() => getRepositoryInfo(this.projectDir, this.appInfo.metadata, this.devMetadata))
58+
private _repositoryInfo = new Lazy<SourceRepositoryInfo>(() => getRepositoryInfo(this.projectDir, this.metadata, this.devMetadata))
5959

6060
private readonly afterPackHandlers: Array<(context: AfterPackContext) => Promise<any> | null> = []
6161

@@ -66,7 +66,7 @@ export class Packager implements BuildInfo {
6666
readonly prepackaged?: string | null
6767

6868
//noinspection JSUnusedGlobalSymbols
69-
constructor(readonly options: PackagerOptions, private readonly cancellationToken: CancellationToken) {
69+
constructor(readonly options: PackagerOptions, readonly cancellationToken: CancellationToken) {
7070
this.projectDir = options.projectDir == null ? process.cwd() : path.resolve(options.projectDir)
7171

7272
this.prepackaged = options.prepackaged == null ? null : path.resolve(this.projectDir, options.prepackaged)

packages/electron-builder/src/packagerApi.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { Arch, Platform, Target } from "electron-builder-core"
2+
import { CancellationToken } from "electron-builder-http/out/CancellationToken"
23
import { PublishConfiguration } from "electron-builder-http/out/publishOptions"
34
import { TmpDir } from "electron-builder-util/out/tmp"
45
import { AppInfo } from "./appInfo"
@@ -63,6 +64,8 @@ export interface BuildInfo {
6364

6465
readonly prepackaged?: string | null
6566

67+
readonly cancellationToken: CancellationToken
68+
6669
dispatchArtifactCreated(event: ArtifactCreated): void
6770

6871
afterPack(context: AfterPackContext): Promise<void>

packages/electron-builder/src/platformPackager.ts

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import BluebirdPromise from "bluebird-lst"
22
import { Arch, getArchSuffix, Platform, Target, TargetSpecificOptions } from "electron-builder-core"
3-
import { asArray, debug, isEmptyOrSpaces, use } from "electron-builder-util"
3+
import { asArray, debug, isEmptyOrSpaces, Lazy, use } from "electron-builder-util"
44
import { deepAssign } from "electron-builder-util/out/deepAssign"
55
import { copyDir, statOrNull, unlinkIfExists } from "electron-builder-util/out/fs"
66
import { log, warn } from "electron-builder-util/out/log"
@@ -25,7 +25,19 @@ export abstract class PlatformPackager<DC extends PlatformSpecificBuildOptions>
2525

2626
readonly platformSpecificBuildOptions: DC
2727

28-
readonly resourceList: Promise<Array<string>>
28+
get resourceList(): Promise<Array<string>> {
29+
return this._resourceList.value
30+
}
31+
32+
private readonly _resourceList = new Lazy<Array<string>>(() => {
33+
return readdir(this.buildResourcesDir)
34+
.catch(e => {
35+
if (e.code !== "ENOENT") {
36+
throw e
37+
}
38+
return []
39+
})
40+
})
2941

3042
abstract get platform(): Platform
3143

@@ -39,14 +51,6 @@ export abstract class PlatformPackager<DC extends PlatformSpecificBuildOptions>
3951
this.projectDir = info.projectDir
4052

4153
this.buildResourcesDir = path.resolve(this.projectDir, this.relativeBuildResourcesDirname)
42-
43-
this.resourceList = readdir(this.buildResourcesDir)
44-
.catch(e => {
45-
if (e.code !== "ENOENT") {
46-
throw e
47-
}
48-
return []
49-
})
5054
}
5155

5256
abstract get defaultTarget(): Array<string>
@@ -95,7 +99,7 @@ export abstract class PlatformPackager<DC extends PlatformSpecificBuildOptions>
9599

96100
async pack(outDir: string, arch: Arch, targets: Array<Target>, postAsyncTasks: Array<Promise<any>>): Promise<any> {
97101
const appOutDir = this.computeAppOutDir(outDir, arch)
98-
await this.doPack(outDir, appOutDir, this.platform.nodeName, arch, this.platformSpecificBuildOptions)
102+
await this.doPack(outDir, appOutDir, this.platform.nodeName, arch, this.platformSpecificBuildOptions, targets)
99103
this.packageInDistributableFormat(appOutDir, arch, targets, postAsyncTasks)
100104
}
101105

@@ -135,7 +139,7 @@ export abstract class PlatformPackager<DC extends PlatformSpecificBuildOptions>
135139
return matcher
136140
}
137141

138-
protected async doPack(outDir: string, appOutDir: string, platformName: string, arch: Arch, platformSpecificBuildOptions: DC) {
142+
protected async doPack(outDir: string, appOutDir: string, platformName: string, arch: Arch, platformSpecificBuildOptions: DC, targets: Array<Target>) {
139143
if (this.info.prepackaged != null) {
140144
return
141145
}
@@ -218,11 +222,16 @@ export abstract class PlatformPackager<DC extends PlatformSpecificBuildOptions>
218222
await copyFiles(extraResourceMatchers)
219223
await copyFiles(extraFileMatchers)
220224

225+
if (this.info.cancellationToken.cancelled) {
226+
return
227+
}
228+
221229
await this.info.afterPack({
222230
appOutDir: appOutDir,
223231
packager: this,
224232
electronPlatformName: platformName,
225233
arch: arch,
234+
targets: targets,
226235
})
227236
await this.sanityCheckPackage(appOutDir, asarOptions != null)
228237
}
@@ -517,7 +526,12 @@ export abstract class PlatformPackager<DC extends PlatformSpecificBuildOptions>
517526
}
518527
}
519528
}
520-
else if (!isEmptyOrSpaces(custom)) {
529+
else if (custom != null && !isEmptyOrSpaces(custom)) {
530+
const resourceList = await this.resourceList
531+
if (resourceList.includes(custom)) {
532+
return path.join(this.buildResourcesDir, custom)
533+
}
534+
521535
let p = path.resolve(this.buildResourcesDir, custom)
522536
if (await statOrNull(p) == null) {
523537
p = path.resolve(this.projectDir, custom)

packages/electron-builder/src/publish/PublishManager.ts

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import BluebirdPromise from "bluebird-lst"
22
import { createHash } from "crypto"
3-
import { Arch, Platform } from "electron-builder-core"
3+
import { Arch, Platform, Target } from "electron-builder-core"
44
import { CancellationToken } from "electron-builder-http/out/CancellationToken"
55
import { GenericServerOptions, GithubOptions, githubUrl, PublishConfiguration, PublishProvider, S3Options, s3Url, UpdateInfo, VersionInfo } from "electron-builder-http/out/publishOptions"
66
import { asArray, debug, isEmptyOrSpaces } from "electron-builder-util"
@@ -60,11 +60,21 @@ export class PublishManager implements PublishContext {
6060
}
6161

6262
packager.addAfterPackHandler(async event => {
63-
if (this.cancellationToken.cancelled || !(event.electronPlatformName == "darwin" || event.packager.platform === Platform.WINDOWS)) {
63+
const packager = event.packager
64+
if (event.electronPlatformName === "darwin") {
65+
if (!event.targets.some(it => it.name === "zip")) {
66+
return
67+
}
68+
}
69+
else if (packager.platform === Platform.WINDOWS) {
70+
if (!event.targets.some(it => isSuitableWindowsTarget(it))) {
71+
return
72+
}
73+
}
74+
else {
6475
return
6576
}
6677

67-
const packager = event.packager
6878
const publishConfigs = await getPublishConfigsForUpdateInfo(packager, await getPublishConfigs(packager, null))
6979
if (publishConfigs == null || publishConfigs.length === 0) {
7080
return
@@ -73,12 +83,12 @@ export class PublishManager implements PublishContext {
7383
let publishConfig = publishConfigs[0]
7484
if ((<GenericServerOptions>publishConfig).url != null) {
7585
publishConfig = Object.assign({}, publishConfig, {
76-
url: packager.expandMacro((<GenericServerOptions>publishConfig).url, packager.platform === Platform.WINDOWS ? null : Arch.x64)
86+
url: packager.expandMacro((<GenericServerOptions>publishConfig).url, null)
7787
})
7888
}
7989

8090
if (packager.platform === Platform.WINDOWS) {
81-
let publisherName = await (<WinPackager>packager).computedPublisherName.value
91+
const publisherName = await (<WinPackager>packager).computedPublisherName.value
8292
if (publisherName != null) {
8393
publishConfig = Object.assign({publisherName: publisherName}, publishConfig)
8494
}
@@ -123,7 +133,7 @@ export class PublishManager implements PublishContext {
123133

124134
if (target != null && eventFile != null && !this.cancellationToken.cancelled) {
125135
if ((packager.platform === Platform.MAC && target.name === "zip") ||
126-
(packager.platform === Platform.WINDOWS && (target.name === "nsis" || target.name.startsWith("nsis-")) && eventFile.endsWith(".exe"))) {
136+
(packager.platform === Platform.WINDOWS && isSuitableWindowsTarget(target) && eventFile.endsWith(".exe"))) {
127137
this.addTask(writeUpdateInfo(event, publishConfigs))
128138
}
129139
}
@@ -368,8 +378,12 @@ export async function getPublishConfigs(packager: PlatformPackager<any>, targetS
368378
}
369379
}
370380

381+
if (publishers == null) {
382+
return []
383+
}
384+
371385
debug(`Explicit publish provider: ${JSON.stringify(publishers, null, 2)}`)
372-
return <Promise<Array<PublishConfiguration>>>BluebirdPromise.map(asArray(publishers), it => getResolvedPublishConfig(packager.info, typeof it === "string" ? {provider: it} : it))
386+
return await <Promise<Array<PublishConfiguration>>>BluebirdPromise.map(asArray(publishers), it => getResolvedPublishConfig(packager.info, typeof it === "string" ? {provider: it} : it))
373387
}
374388

375389
function sha256(file: string) {
@@ -397,4 +411,8 @@ function isPullRequest() {
397411
}
398412

399413
return isSet(process.env.TRAVIS_PULL_REQUEST) || isSet(process.env.CI_PULL_REQUEST) || isSet(process.env.CI_PULL_REQUESTS)
414+
}
415+
416+
function isSuitableWindowsTarget(target: Target) {
417+
return target.name === "nsis" || target.name.startsWith("nsis-")
400418
}

0 commit comments

Comments
 (0)