Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add MemoLazy to fix codeSigningInfo not responding to changed args #8291

Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 32 additions & 20 deletions packages/app-builder-lib/src/macPackager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import * as path from "path"
import { copyFile, statOrNull, unlinkIfExists } from "builder-util/out/fs"
import { orIfFileNotExist } from "builder-util/out/promise"
import { AppInfo } from "./appInfo"
import { CertType, CodeSigningInfo, createKeychain, findIdentity, Identity, isSignAllowed, removeKeychain, reportError, sign } from "./codeSign/macCodeSign"
import { CertType, CodeSigningInfo, createKeychain, CreateKeychainOptions, findIdentity, Identity, isSignAllowed, removeKeychain, reportError, sign } from "./codeSign/macCodeSign"
import { DIR_TARGET, Platform, Target } from "./core"
import { AfterPackContext, ElectronPlatformName } from "./index"
import { MacConfiguration, MasConfiguration, NotarizeNotaryOptions } from "./options/macOptions"
Expand All @@ -21,32 +21,44 @@ import { getTemplatePath } from "./util/pathManager"
import * as fs from "fs/promises"
import { notarize } from "@electron/notarize"
import { NotarizeOptionsNotaryTool, NotaryToolKeychainCredentials } from "@electron/notarize/lib/types"
import { MemoLazy } from "./util/MemoLazy"

export type CustomMacSignOptions = SignOptions
export type CustomMacSign = (configuration: CustomMacSignOptions, packager: MacPackager) => Promise<void>

export class MacPackager extends PlatformPackager<MacConfiguration> {
readonly codeSigningInfo = new Lazy<CodeSigningInfo>(() => {
const cscLink = this.getCscLink()
if (cscLink == null || process.platform !== "darwin") {
return Promise.resolve({ keychainFile: process.env.CSC_KEYCHAIN || null })
}
readonly codeSigningInfo = new MemoLazy<CreateKeychainOptions | null, CodeSigningInfo>(
() => {
const cscLink = this.getCscLink()
if (cscLink == null || process.platform !== "darwin") {
return null
}

return createKeychain({
tmpDir: this.info.tempDirManager,
cscLink,
cscKeyPassword: this.getCscPassword(),
cscILink: chooseNotNull(this.platformSpecificBuildOptions.cscInstallerLink, process.env.CSC_INSTALLER_LINK),
cscIKeyPassword: chooseNotNull(this.platformSpecificBuildOptions.cscInstallerKeyPassword, process.env.CSC_INSTALLER_KEY_PASSWORD),
currentDir: this.projectDir,
}).then(result => {
const keychainFile = result.keychainFile
if (keychainFile != null) {
this.info.disposeOnBuildFinish(() => removeKeychain(keychainFile))
const selected = {
tmpDir: this.info.tempDirManager,
cscLink,
cscKeyPassword: this.getCscPassword(),
cscILink: chooseNotNull(this.platformSpecificBuildOptions.cscInstallerLink, process.env.CSC_INSTALLER_LINK),
cscIKeyPassword: chooseNotNull(this.platformSpecificBuildOptions.cscInstallerKeyPassword, process.env.CSC_INSTALLER_KEY_PASSWORD),
currentDir: this.projectDir,
}
return result
})
})

return selected
},
async selected => {
if (selected) {
return createKeychain(selected).then(result => {
const keychainFile = result.keychainFile
if (keychainFile != null) {
this.info.disposeOnBuildFinish(() => removeKeychain(keychainFile))
}
return result
})
}

return Promise.resolve({ keychainFile: process.env.CSC_KEYCHAIN || null })
}
)

private _iconPath = new Lazy(() => this.getOrConvertIcon("icns"))

Expand Down
36 changes: 36 additions & 0 deletions packages/app-builder-lib/src/util/MemoLazy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/**
* A reworked implementation of lazy-val (https://github.com/develar/lazy-val/blob/master/src/main.ts)
* that re-calculates the lazy `value` if the provided argument has changed.
*/

export class MemoLazy<S, V> {
private selected: S | undefined = undefined
private _value: Promise<V> | undefined = undefined

constructor(
private selector: () => S,
private creator: (selected: S) => Promise<V>
) {}

get hasValue() {
return this._value !== undefined
}

get value(): Promise<V> {
const selected = this.selector()
if (this._value !== undefined && JSON.stringify(this.selected) === JSON.stringify(selected)) {
mmaietta marked this conversation as resolved.
Show resolved Hide resolved
// value exists and selected hasn't changed, so return the cached value
return this._value
}

this.selected = selected
const result = this.creator(selected)
this.value = result

return result
}

set value(value: Promise<V>) {
this._value = value
}
}
Loading