Skip to content

Commit 06b0103

Browse files
committed
feat(nsis): Change installation directory when not using 'oneClick' with NSIS
Closes #596
1 parent 1bc808e commit 06b0103

File tree

11 files changed

+86
-617
lines changed

11 files changed

+86
-617
lines changed

CONTRIBUTING.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,4 +102,6 @@ Or you can create Node.js run configuration manually:
102102
TEST_APP_TMP_DIR=/tmp/electron-builder-test ./node_modules/.bin/jest --env jest-environment-node-debug -t 'boring' '/TestFileName\.\w+$'
103103
```
104104

105-
where `TEST_APP_TMP_DIR` is specified to easily inspect and use test build, `boring` is the test name and `test/out/nsisTest.js` is the path to test file.
105+
where `TEST_APP_TMP_DIR` is specified to easily inspect and use test build, `boring` is the test name and `test/out/nsisTest.js` is the path to test file.
106+
107+
Do not forget to execute `yarn compile` before run.

docs/Options.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,7 @@ See [NSIS target notes](https://github.com/electron-userland/electron-builder/wi
204204
| oneClick | <a name="NsisOptions-oneClick"></a>One-click installation. Defaults to `true`.
205205
| perMachine | <a name="NsisOptions-perMachine"></a><p>Defaults to <code>false</code>.</p> <p>If <code>oneClick</code> is <code>true</code> (default): Install per all users (per-machine).</p> <p>If <code>oneClick</code> is <code>false</code>: no install mode installer page (choice per-machine or per-user), always install per-machine.</p>
206206
| allowElevation | <a name="NsisOptions-allowElevation"></a>*boring installer only.* Allow requesting for elevation. If false, user will have to restart installer with elevated permissions. Defaults to `true`.
207+
| allowToChangeInstallationDirectory | <a name="NsisOptions-allowToChangeInstallationDirectory"></a>*boring installer only.* Whether to allow user to change installation directory. Defaults to `false`.
207208
| runAfterFinish | <a name="NsisOptions-runAfterFinish"></a>*one-click installer only.* Run application after finish. Defaults to `true`.
208209
| guid | <a name="NsisOptions-guid"></a>See [GUID vs Application Name](https://github.com/electron-userland/electron-builder/wiki/NSIS#guid-vs-application-name).
209210
| installerIcon | <a name="NsisOptions-installerIcon"></a>The path to installer icon. Defaults to `build/installerIcon.ico` or application icon.

package.json

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
"lint": "node test/out/helpers/lint.js",
77
"pretest": "node ./test/vendor/yarn.js compile && node ./test/vendor/yarn.js lint && node ./test/vendor/yarn.js check-deps",
88
"check-deps": "node ./test/out/helpers/checkDeps.js",
9+
"///": "Please see https://github.com/electron-userland/electron-builder/blob/master/CONTRIBUTING.md#run-test-using-cli how to run particular test instead full (and very slow) run",
910
"test": "node ./test/out/helpers/runTests.js",
1011
"test-linux": "docker run --rm -ti -v ${PWD}:/project -v ${PWD##*/}-node-modules:/project/node_modules -v ~/.electron:/root/.electron electronuserland/electron-builder:wine /test.sh",
1112
"semantic-release": "semantic-release pre && npm publish && semantic-release post",
@@ -16,12 +17,10 @@
1617
"test-deps-mac": "brew install rpm dpkg mono lzip gnu-tar graphicsmagick xz && brew install wine --without-x11",
1718
"postinstall": "lerna bootstrap",
1819
"update-deps": "lerna exec -- npm-check-updates --reject 'electron-builder-http,electron-builder-util' -a",
19-
"lerna-publish": "lerna publish --skip-npm --skip-git",
20-
"set-versions": "node test/out/helpers/setVersions.js p",
21-
"set-dep-versions": "node test/out/helpers/setVersions.js"
20+
"lerna-publish": "node test/out/helpers/setVersions.js p && lerna publish --skip-npm --skip-git && node test/out/helpers/setVersions.js && conventional-changelog -p angular -i CHANGELOG.md -s",
21+
"npm-publish": "./packages/npm-publish.sh"
2222
},
2323
"devDependencies": {
24-
"@develar/semantic-release": "^6.3.26",
2524
"@types/electron": "^1.4.30",
2625
"@types/ini": "^1.3.29",
2726
"@types/jest": "^16.0.3",

packages/electron-builder/src/options/winOptions.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,11 @@ export interface NsisOptions {
8585
*/
8686
readonly allowElevation?: boolean
8787

88+
/*
89+
*boring installer only.* Whether to allow user to change installation directory. Defaults to `false`.
90+
*/
91+
readonly allowToChangeInstallationDirectory?: boolean
92+
8893
/*
8994
*one-click installer only.* Run application after finish. Defaults to `true`.
9095
*/

packages/electron-builder/src/targets/nsis.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,13 @@ export default class NsisTarget extends Target {
157157
defines.MULTIUSER_INSTALLMODE_ALLOW_ELEVATION = null
158158
}
159159

160+
if (options.allowToChangeInstallationDirectory) {
161+
if (oneClick) {
162+
throw new Error("allowToChangeInstallationDirectory makes sense only for boring installer (please set oneClick to false)")
163+
}
164+
defines.allowToChangeInstallationDirectory = null
165+
}
166+
160167
// Error: invalid VIProductVersion format, should be X.X.X.X
161168
// so, we must strip beta
162169
const localeId = options.language || "1033"

packages/electron-builder/templates/nsis/boringInstaller.nsh

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
!define MUI_FINISHPAGE_RUN_FUNCTION "StartApp"
2121

2222
!ifdef LICENSE_FILE
23-
2423
Function licensePre
2524
${GetParameters} $R0
2625
${GetOptions} $R0 "--update" $R1
@@ -42,6 +41,9 @@
4241
!define MUI_CUSTOMFUNCTION_GUIINIT GuiInit
4342
!endif
4443

44+
!ifdef allowToChangeInstallationDirectory
45+
!insertmacro MUI_PAGE_DIRECTORY
46+
!endif
4547
!insertmacro MUI_PAGE_INSTFILES
4648
!insertmacro MUI_PAGE_FINISH
4749
!else

packages/npm-publish.sh

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#!/usr/bin/env bash
2+
set -e
3+
4+
npm publish packages/electron-builder-http || true
5+
npm publish packages/electron-builder-core || true
6+
npm publish packages/electron-builder-util || true
7+
npm publish packages/electron-builder || true
8+
npm publish packages/electron-builder-squirrel-windows || true
9+
npm publish packages/electron-auto-updater || true

test/src/helpers/setVersions.ts

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,21 @@ async function main(): Promise<void> {
2222
}
2323

2424
async function setPackageVersions(packages: Array<string>, packageData: Array<any>) {
25-
const versions = await BluebirdPromise.map(packages, it => exec("node", [path.join(rootDir, "test", "vendor", "yarn.js"), "info", "--json", it, "dist-tags"]).then((it: string) => JSON.parse(it).data))
25+
const versions = await BluebirdPromise.map(packages, it => exec("node", [path.join(rootDir, "test", "vendor", "yarn.js"), "info", "--json", it, "dist-tags"])
26+
.then((it: string) => {
27+
if (it === "") {
28+
// {"type":"error","data":"Received invalid response from npm."}
29+
// not yet published to npm
30+
return "0.0.1"
31+
}
32+
33+
try {
34+
return JSON.parse(it).data
35+
}
36+
catch (e) {
37+
throw new Error(`Cannot parse ${it}: ${e.stack || e}`)
38+
}
39+
}))
2640
for (let i = 0; i < packages.length; i++) {
2741
const packageName = packages[i]
2842
const packageJson = packageData[i]
@@ -52,12 +66,12 @@ async function setDepVersions(packages: Array<string>, packageData: Array<any>)
5266
let changed = false
5367
for (let depIndex = 0; depIndex < packages.length; depIndex++) {
5468
const depPackageName = packages[depIndex]
55-
const oldVersion = packageJson.dependencies[depPackageName]
56-
const newVersion = versions[depIndex]
69+
const oldVersion = packageJson.dependencies == null ? null : packageJson.dependencies[depPackageName]
5770
if (oldVersion == null) {
5871
continue
5972
}
6073

74+
const newVersion = versions[depIndex]
6175
if (oldVersion == newVersion) {
6276
console.log(`Skip ${depPackageName} for ${packageName} — version ${newVersion} is actual`)
6377
continue

test/src/linux/fpmTest.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1-
// "apk" is very slow, don't test for now
21
import { Platform } from "electron-builder"
32
import { app } from "../helpers/packTester"
43

4+
// "apk" is very slow, don't test for now
5+
56
test.ifDevOrLinuxCi("targets", app({targets: Platform.LINUX.createTarget(["sh", "freebsd", "pacman", "zip", "7z"])}))
67

78
// https://github.com/electron-userland/electron-builder/issues/460

test/src/windows/nsisTest.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,20 @@ test.ifDevOrLinuxCi("custom script", app({targets: nsisTarget}, {
169169
packed: context => assertThat(path.join(context.projectDir, "build", "customInstallerScript")).isFile(),
170170
}))
171171

172+
test.ifDevOrLinuxCi("allowToChangeInstallationDirectory", app({
173+
targets: nsisTarget,
174+
appMetadata: {
175+
name: "test-custom-inst-dir",
176+
productName: "Test Custom Installation Dir"
177+
},
178+
config: {
179+
nsis: {
180+
allowToChangeInstallationDirectory: true,
181+
oneClick: false,
182+
}
183+
}
184+
}))
185+
172186
test("menuCategory", app({
173187
targets: Platform.WINDOWS.createTarget(["nsis"], Arch.ia32),
174188
appMetadata: {

0 commit comments

Comments
 (0)