Skip to content

Commit

Permalink
feat: allow custom makensis and nsis logging (#6024)
Browse files Browse the repository at this point in the history
* feat: allowing a custom nsis binary to be specified. This will indirectly enable debugger logs for nsis installers (user specifies download url to nsis dev bundler). implements #5119
* update makensis to 3.0.4.2
  • Loading branch information
mmaietta committed Aug 9, 2021
1 parent 1497411 commit a99a7c8
Show file tree
Hide file tree
Showing 10 changed files with 187 additions and 5 deletions.
5 changes: 5 additions & 0 deletions .changeset/old-planes-look.md
@@ -0,0 +1,5 @@
---
"app-builder-lib": minor
---

feat: allowing custom makensis url to be specified and adding flag to enable debug logging for NSIS scripts
66 changes: 65 additions & 1 deletion packages/app-builder-lib/scheme.json
Expand Up @@ -3447,6 +3447,38 @@
"description": "Whether to create start menu shortcut.",
"type": "boolean"
},
"customNsisBinary": {
"description": "Allows providing the URL configuration for `makensis`.",
"type": [
"null",
"object"
],
"properties": {
"url": {
"description": "URL to download from",
"type": "string"
},
"checksum": {
"description": "SHA256 to validate downloaded `makensis`",
"type": [
"null",
"string"
]
},
"version": {
"description": "Version of `makensis` (used for caching)",
"type": [
"null",
"string"
]
}
}
},
"debugLogging": {
"default": false,
"description": "Enables `LogText` to be used in `nsh` scripts",
"type": "boolean"
},
"deleteAppDataOnUninstall": {
"default": false,
"description": "*one-click installer only.* Whether to delete app data on uninstall.",
Expand Down Expand Up @@ -3748,6 +3780,38 @@
"description": "Whether to create start menu shortcut.",
"type": "boolean"
},
"customNsisBinary": {
"description": "Allows providing the URL configuration for `makensis`.",
"type": [
"null",
"object"
],
"properties": {
"url": {
"description": "URL to download from",
"type": "string"
},
"checksum": {
"description": "SHA256 to validate downloaded `makensis`",
"type": [
"null",
"string"
]
},
"version": {
"description": "Version of `makensis` (used for caching)",
"type": [
"null",
"string"
]
}
}
},
"debugLogging": {
"default": false,
"description": "Enables `LogText` to be used in `nsh` scripts",
"type": "boolean"
},
"deleteAppDataOnUninstall": {
"default": false,
"description": "*one-click installer only.* Whether to delete app data on uninstall.",
Expand Down Expand Up @@ -6581,4 +6645,4 @@
}
},
"type": "object"
}
}
5 changes: 5 additions & 0 deletions packages/app-builder-lib/src/binDownload.ts
Expand Up @@ -10,6 +10,11 @@ export function download(url: string, output: string, checksum?: string | null):
return executeAppBuilder(args) as Promise<any>
}

export function getBinFromCustomLoc(name: string, version: string, binariesLocUrl: string, checksum: string): Promise<string> {
const dirName = `${name}-${version}`
return getBin(dirName, binariesLocUrl, checksum)
}

export function getBinFromUrl(name: string, version: string, checksum: string): Promise<string> {
const dirName = `${name}-${version}`
let url: string
Expand Down
7 changes: 6 additions & 1 deletion packages/app-builder-lib/src/targets/nsis/NsisTarget.ts
Expand Up @@ -23,7 +23,7 @@ import { addCustomMessageFileInclude, createAddLangsMacro, LangConfigurator } fr
import { computeLicensePage } from "./nsisLicense"
import { NsisOptions, PortableOptions } from "./nsisOptions"
import { NsisScriptGenerator } from "./nsisScriptGenerator"
import { AppPackageHelper, nsisTemplatesDir, NSIS_PATH, UninstallerReader } from "./nsisUtil"
import { AppPackageHelper, nsisTemplatesDir, NSIS_PATH, UninstallerReader, NsisTargetOptions } from "./nsisUtil"

const debug = _debug("electron-builder:nsis")

Expand Down Expand Up @@ -62,6 +62,8 @@ export class NsisTarget extends Target {
if (deps != null && deps["electron-squirrel-startup"] != null) {
log.warn('"electron-squirrel-startup" dependency is not required for NSIS')
}

NsisTargetOptions.resolve(this.options)
}

build(appOutDir: string, arch: Arch) {
Expand Down Expand Up @@ -189,6 +191,9 @@ export class NsisTarget extends Target {

APP_PACKAGE_NAME: appInfo.name,
}
if (options.debugLogging) {
defines.ENABLE_LOGGING = null
}
if (uninstallAppKey !== guid) {
defines.UNINSTALL_REGISTRY_KEY_2 = `Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\${guid}`
}
Expand Down
36 changes: 36 additions & 0 deletions packages/app-builder-lib/src/targets/nsis/nsisOptions.ts
@@ -1,6 +1,28 @@
import { TargetSpecificOptions } from "../../core"
import { CommonWindowsInstallerConfiguration } from "../.."

interface CustomNsisBinary {
/**
* @private
* @default https://github.com/electron-userland/electron-builder-binaries/releases/download
*/

readonly url: string | null

/**
* @private
* @default o+YZsXHp8LNihhuk7JsCDhdIgx0MKKK+1b3sGD+4zX5djZULe4/4QMcAsfQ+0r+a8FnwBt7BVBHkIkJHjKQ0sg==
*/

readonly checksum?: string | null

/**
* @private
* @default 3.0.4.2
*/

readonly version?: string | null
}
export interface CommonNsisOptions {
/**
* Whether to create [Unicode installer](http://nsis.sourceforge.net/Docs/Chapter1.html#intro-unicode).
Expand All @@ -24,6 +46,20 @@ export interface CommonNsisOptions {
* @default false
*/
readonly useZip?: boolean

/**
* @private
*/
readonly customNsisBinary?: CustomNsisBinary | null

/**
* Whether or not to enable NSIS logging for debugging.
* Note: Requires a debug-enabled NSIS build.
* electron-builder's included `makensis` only supports building debug-enabled NSIS installers on Windows currently
* https://github.com/electron-userland/electron-builder/issues/5119#issuecomment-811353612
* @private
*/
readonly debugLogging?: boolean | null
}

export interface NsisOptions extends CommonNsisOptions, CommonWindowsInstallerConfiguration, TargetSpecificOptions {
Expand Down
25 changes: 22 additions & 3 deletions packages/app-builder-lib/src/targets/nsis/nsisUtil.ts
@@ -1,22 +1,41 @@
import { Arch, log } from "builder-util"
import { PackageFileInfo } from "builder-util-runtime"
import { getBinFromUrl } from "../../binDownload"
import { getBinFromUrl, getBinFromCustomLoc } from "../../binDownload"
import { copyFile } from "builder-util/out/fs"
import * as path from "path"
import { getTemplatePath } from "../../util/pathManager"
import { NsisTarget } from "./NsisTarget"
import * as fs from "fs/promises"
import * as zlib from "zlib"
import { NsisOptions } from "./nsisOptions"

export const nsisTemplatesDir = getTemplatePath("nsis")

export const NsisTargetOptions = (() => {
let _resolve: (options: NsisOptions) => any
const promise = new Promise<NsisOptions>(resolve => (_resolve = resolve))
return {
then: (callback: (options: NsisOptions) => any): Promise<string> => promise.then(callback),
resolve: (options: NsisOptions): any => _resolve(options),
}
})()

export const NSIS_PATH = () => {
const custom = process.env.ELECTRON_BUILDER_NSIS_DIR
if (custom != null && custom.length > 0) {
return Promise.resolve(custom.trim())
}
// noinspection SpellCheckingInspection
return getBinFromUrl("nsis", "3.0.4.1", "VKMiizYdmNdJOWpRGz4trl4lD++BvYP2irAXpMilheUP0pc93iKlWAoP843Vlraj8YG19CVn0j+dCo/hURz9+Q==")
return NsisTargetOptions.then((options: NsisOptions) => {
if (options.customNsisBinary) {
const { checksum, url, version } = options.customNsisBinary
if (checksum && url) {
const binaryVersion = version || checksum.substr(0, 8)
return getBinFromCustomLoc("nsis", binaryVersion, url, checksum)
}
}
// noinspection SpellCheckingInspection
return getBinFromUrl("nsis", "3.0.4.2", "o+YZsXHp8LNihhuk7JsCDhdIgx0MKKK+1b3sGD+4zX5djZULe4/4QMcAsfQ+0r+a8FnwBt7BVBHkIkJHjKQ0sg==")
})
}

export class AppPackageHelper {
Expand Down
14 changes: 14 additions & 0 deletions packages/app-builder-lib/templates/nsis/common.nsh
Expand Up @@ -99,3 +99,17 @@ Name "${PRODUCT_NAME}"

${StdUtils.ExecShellAsUser} $0 "$launchLink" "open" "$startAppArgs"
!macroend

!define LogSet "!insertmacro LogSetMacro"
!macro LogSetMacro SETTING
!ifdef ENABLE_LOGGING
LogSet ${SETTING}
!endif
!macroend

!define LogText "!insertmacro LogTextMacro"
!macro LogTextMacro INPUT_TEXT
!ifdef ENABLE_LOGGING
LogText ${INPUT_TEXT}
!endif
!macroend
3 changes: 3 additions & 0 deletions packages/app-builder-lib/templates/nsis/installer.nsi
Expand Up @@ -40,6 +40,9 @@ Var oldMenuDirectory
!endif

Function .onInit
SetOutPath $INSTDIR
${LogSet} on

!ifmacrodef preInit
!insertmacro preInit
!endif
Expand Down
3 changes: 3 additions & 0 deletions packages/app-builder-lib/templates/nsis/uninstaller.nsh
Expand Up @@ -3,6 +3,9 @@ Function un.checkAppRunning
FunctionEnd

Function un.onInit
SetOutPath $INSTDIR
${LogSet} on

!insertmacro check64BitAndSetRegView

${If} ${Silent}
Expand Down
28 changes: 28 additions & 0 deletions test/src/windows/assistedInstallerTest.ts
Expand Up @@ -117,6 +117,34 @@ test.ifAll.ifNotCiMac("assisted, MUI_HEADER as option", () => {
)
})

test.ifNotCiMac(
"custom makensis.exe",
app({
targets: nsisTarget,
config: {
nsis: {
customNsisBinary: {
url: "https://github.com/electron-userland/electron-builder-binaries/releases/download/nsis-3.0.4.1/nsis-3.0.4.1.7z",
version: "3.0.4.1",
checksum: "VKMiizYdmNdJOWpRGz4trl4lD++BvYP2irAXpMilheUP0pc93iKlWAoP843Vlraj8YG19CVn0j+dCo/hURz9+Q==",
},
},
},
})
)

test.ifNotCiMac(
"debug logging enabled",
app({
targets: nsisTarget,
config: {
nsis: {
debugLogging: true,
},
},
})
)

test.ifNotCiMac(
"assisted, only perMachine",
app({
Expand Down

0 comments on commit a99a7c8

Please sign in to comment.