generator-nsis 0.8.10 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,535 +1,233 @@
1
- const Generator = require('yeoman-generator');
2
- const pkg = require('../../package.json');
3
1
 
4
- const globby = require('globby');
5
- const languageData = require('@nsis/language-data').meta;
6
- const semver = require('semver');
7
- const slugify = require('@sindresorhus/slugify');
8
- const spdxLicenseList = require('spdx-license-list/full');
9
- const terminalLink = require('terminal-link');
10
- const updateNotifier = require('update-notifier');
11
- const { nsisDir } = require('makensis');
12
- const { basename, extname, resolve } = require('path');
13
-
14
- // Is there a newer version of this generator?
15
- updateNotifier({ pkg: pkg }).notify();
16
-
17
- // Create array of license choices
18
- const spdxCodes = Object.getOwnPropertyNames(spdxLicenseList).sort();
19
- const licenseChoices = spdxCodes.map(obj => {
20
- const licenses = {};
21
- licenses['name'] = terminalLink(obj, `https://spdx.org/licenses/${obj}.html`, {
22
- fallback() {
23
- return obj;
24
- }
25
- });
26
- licenses['value'] = obj;
27
-
28
- return licenses;
29
- });
30
-
31
- const docsURL = 'https://github.com/NSIS-Dev/Documentation/tree/master';
32
-
33
- const bundledLibraries = [
34
- {
35
- name: 'Colors.nsh',
36
- value: 'Colors',
37
- checked: false
38
- },
39
- {
40
- name: terminalLink('FileFunc.nsh', `${docsURL}/Includes/FileFunc`, {
41
- fallback() {
42
- return 'FileFunc.nsh';
43
- }
44
- }),
45
- value: 'FileFunc',
46
- checked: false
47
- },
48
- {
49
- name: 'InstallOptions.nsh',
50
- value: 'InstallOptions',
51
- checked: false
52
- },
53
- {
54
- name: 'Integration.nsh',
55
- value: 'Integration',
56
- checked: false
57
- },
58
- {
59
- name: 'LangFile.nsh',
60
- value: 'LangFile',
61
- checked: false
62
- },
63
- {
64
- name: 'Library.nsh',
65
- value: 'Library',
66
- checked: false
67
- },
68
- {
69
- name: terminalLink('LogicLib.nsh', `${docsURL}/Includes/LogicLib`, {
70
- fallback() {
71
- return 'LogicLib.nsh';
72
- }
73
- }),
74
- value: 'LogicLib',
75
- checked: false
76
- },
77
- {
78
- name: terminalLink('Memento.nsh', `${docsURL}/Includes/Memento`, {
79
- fallback() {
80
- return 'Memento.nsh';
81
- }
82
- }),
83
- value: 'Memento',
84
- checked: false
85
- },
86
- {
87
- name: 'MUI2.nsh',
88
- value: 'MUI2',
89
- checked: false
90
- },
91
- {
92
- name: 'MultiUser.nsh',
93
- value: 'MultiUser',
94
- checked: false
95
- },
96
- {
97
- name: 'nsDialogs.nsh',
98
- value: 'nsDialogs',
99
- checked: false
100
- },
101
- {
102
- name: 'Sections.nsh',
103
- value: 'Sections',
104
- checked: false
105
- },
106
- {
107
- name: terminalLink('StrFunc.nsh', `${docsURL}/Includes/StrFunc`, {
108
- fallback() {
109
- return 'StrFunc.nsh';
110
- }
111
- }),
112
- value: 'StrFunc',
113
- checked: false
114
- },
115
- {
116
- name: terminalLink('TextFunc.nsh', `${docsURL}/Includes/TextFunc`, {
117
- fallback() {
118
- return 'TextFunc.nsh';
119
- }
120
- }),
121
- value: 'TextFunc',
122
- checked: false
123
- },
124
- {
125
- name: 'UpgradeDLL.nsh',
126
- value: 'UpgradeDLL',
127
- checked: false
128
- },
129
- {
130
- name: 'Util.nsh',
131
- value: 'Util',
132
- checked: false
133
- },
134
- {
135
- name: 'VB6RunTime.nsh',
136
- value: 'VB6RunTime',
137
- checked: false
138
- },
139
- {
140
- name: 'VPatchLib.nsh',
141
- value: 'VPatchLib',
142
- checked: false
143
- },
144
- {
145
- name: 'WinCore.nsh',
146
- value: 'WinCore',
147
- checked: false
148
- },
149
- {
150
- name: 'WinMessages.nsh',
151
- value: 'WinMessages',
152
- checked: false
153
- },
154
- {
155
- name: terminalLink('WinVer.nsh', `${docsURL}/Includes/WinVer`, {
156
- fallback() {
157
- return 'WinVer.nsh';
158
- }
159
- }),
160
- value: 'WinVer',
161
- checked: false
162
- },
163
- {
164
- name: terminalLink('WordFunc.nsh', `${docsURL}/Includes/WordFunc`, {
165
- fallback() {
166
- return 'WordFunc.nsh';
167
- }
168
- }),
169
- value: 'WordFunc',
170
- checked: false
171
- },
172
- {
173
- name: terminalLink('x64.nsh', `${docsURL}/Includes/x64`, {
174
- fallback() {
175
- return 'x64.nsh';
176
- }
177
- }),
178
- value: 'x64',
179
- checked: false
180
- }
181
- ];
182
-
183
- const getAllLibraries = async () => {
184
- const nsisPath = await nsisDir();
185
- const includeDir = resolve(nsisPath, 'Include')
186
-
187
- const excludedFiles = bundledLibraries.map(excludedFiles => {
188
- return `!${includeDir}/${excludedFiles.value}.nsh`;
189
- });
190
-
191
- const headerFiles = globby.sync([`${includeDir}/*.nsh`,`!${includeDir}/MUI.nsh`, ...excludedFiles]);
192
-
193
- const customHeaders = headerFiles.map(headerFile => {
194
- return {
195
- name: `${basename(headerFile)} [3rd party]`,
196
- value: basename(headerFile, extname(headerFile)),
197
- checked: false
198
- }
199
- });
200
-
201
- const allLibraries = [...bundledLibraries, ...customHeaders];
202
-
203
- return allLibraries.sort((a,b) => a.value.localeCompare(b.value));
204
- };
205
-
206
- module.exports = class extends Generator {
207
- constructor(args, opts) {
208
- super(args, opts);
209
-
210
- this.option('first-party', { desc: 'Limits library inclusion to first-party', default: false });
211
- this.option('loose-version', { desc: `Doesn't enforce semantic versioning`, default: false });
212
- this.option('unlock-all', { desc: 'Unlocks all disabled features', default: false });
213
-
214
- this.looseVersion = (this.options.looseVersion ? true : false);
215
- this.disabled = (this.options.unlockAll ? false : true);
216
- this.firstParty = (this.options.firstParty ? true : false);
217
- }
218
-
219
- languageChoices() {
220
- const languageChoices = Object.entries(languageData).map(([key, value]) => {
221
- const isDisabled = (key === 'English') ? this.disabled : false;
222
-
223
- // Use long names
224
- return {
225
- name: value.english || key,
226
- value: key,
227
- disabled: isDisabled
228
- };
229
- });
230
-
231
- // Sort names
232
- languageChoices.sort((a, b) => {
233
- if (a.name < b.name) {
234
- return -1;
235
- }
236
- if (a.name > b.name) {
237
- return 1;
238
- }
239
-
240
- return 0;
241
- });
242
-
243
- return languageChoices;
244
- }
245
-
246
- languageDialog(isUnicode) {
247
- const languageDialog = Object.entries(languageData).map(([key, value]) => {
248
- if (key === 'English') return;
249
-
250
- return {
251
- constant: `$\{LANG_${key.toUpperCase()}}`,
252
- string: (isUnicode) ? value.native : (value.long || key)
253
- };
254
- });
255
-
256
- return languageDialog;
257
- }
258
-
259
- inquirer() {
260
- return this.prompt([
261
- {
262
- name: 'name',
263
- message: `Application name`,
264
- default: slugify(this.appname),
265
- store: true
266
- },
267
- {
268
- name: 'version',
269
- message: `Application version`,
270
- default: '0.0.0',
271
- store: true,
272
- validate: version => (this.looseVersion === true || semver.valid(version) !== null) ? true : `Not a valid ${terminalLink('semantic version', 'https://semver.org', {
273
- fallback() {
274
- return 'semantic version';
275
- }
276
- })}`
277
- },
278
- {
279
- name: 'unicode',
280
- message: 'Unicode installer',
281
- type: 'confirm',
282
- default: 'true',
283
- store: true
284
- },
285
- {
286
- name: 'elevation',
287
- message: 'Requested execution level',
288
- type: 'list',
289
- default: 'user',
290
- store: true,
291
- choices: [ 'user', 'highest', 'admin', 'none' ]
292
- },
293
- {
294
- name: 'compression',
295
- message: 'Set compression',
296
- type: 'list',
297
- default: 'lzma',
298
- store: true,
299
- choices: [ 'zlib', 'bzip2', 'lzma' ]
300
- },
301
- {
302
- name: 'pages',
303
- message: 'Installer pages',
304
- type: 'checkbox',
305
- store: true,
306
- choices: [
307
- {
308
- name: 'license',
309
- value: 'license',
310
- },
311
- {
312
- name: 'components',
313
- value: 'components',
314
- },
315
- {
316
- name: 'directory',
317
- value: 'directory',
318
- },
319
- {
320
- name: 'instfiles',
321
- value: 'instfiles',
322
- checked: true
323
- }
324
- ]
325
- },
326
- {
327
- name: 'spdxQuestion',
328
- message: `Choose a license from ${terminalLink('SPDX License List', 'https://spdx.org/licenses/', {
329
- fallback() {
330
- return 'SPDX License List'
331
- }
332
- })}`,
333
- type: 'confirm',
334
- default: true,
335
- store: true,
336
- when: answers => answers.pages.includes('license') ? true : false
337
- },
338
- {
339
- name: 'spdxLicense',
340
- message: 'Choose a license',
341
- type: 'list',
342
- default: 'MIT',
343
- choices: licenseChoices,
344
- store: true,
345
- when: answers => (answers.pages.includes('license') && answers.spdxQuestion) ? true : false
346
- },
347
- {
348
- name: 'sections',
349
- message: 'Number of sections',
350
- default: 1,
351
- store: true,
352
- validate: number => (Number.isInteger(parseInt(number)) && parseInt(number) > 0) ? true : 'Not a valid integer'
353
- },
354
- {
355
- name: 'callbacks',
356
- message: 'Add callback functions',
357
- type: 'checkbox',
358
- store: true,
359
- choices: [
360
- {
361
- name: terminalLink('.onInit', 'https://github.com/NSIS-Dev/Documentation/blob/master/Callbacks/onInit.md', {
362
- fallback() {
363
- return '.onInit';
364
- }
365
- }),
366
- value: '.onInit'
367
- },
368
- {
369
- name: terminalLink('.onGUIInit', 'https://github.com/NSIS-Dev/Documentation/blob/master/Callbacks/onGUIInit.md', {
370
- fallback() {
371
- return '.onGUIInit';
372
- }
373
- }),
374
- value: '.onGUIInit'
375
- },
376
- {
377
- name: terminalLink('.onGUIEnd', 'https://github.com/NSIS-Dev/Documentation/blob/master/Callbacks/onGUIEnd.md', {
378
- fallback() {
379
- return '.onGUIEnd';
380
- }
381
- }),
382
- value: '.onGUIEnd'
383
- },
384
- {
385
- name: terminalLink('.onInstSuccess', 'https://github.com/NSIS-Dev/Documentation/blob/master/Callbacks/onInstSuccess.md', {
386
- fallback() {
387
- return '.onInstSuccess';
388
- }
389
- }),
390
- value: '.onInstSuccess'
391
- },
392
- {
393
- name: terminalLink('.onInstFailed', 'https://github.com/NSIS-Dev/Documentation/blob/master/Callbacks/onInstFailed.md', {
394
- fallback() {
395
- return '.onInstFailed';
396
- }
397
- }),
398
- value: '.onInstFailed'
399
- },
400
- {
401
- name: terminalLink('.onUserAbort', 'https://github.com/NSIS-Dev/Documentation/blob/master/Callbacks/onUserAbort.md', {
402
- fallback() {
403
- return '.onUserAbort';
404
- }
405
- }),
406
- value: '.onUserAbort'
407
- },
408
- {
409
- name: terminalLink('.onVerifyInstDir', 'https://github.com/NSIS-Dev/Documentation/blob/master/Callbacks/onVerifyInstDir.md', {
410
- fallback() {
411
- return '.onVerifyInstDir';
412
- }
413
- }),
414
- value: '.onVerifyInstDir'
415
- },
416
- {
417
- name: terminalLink('.onRebootFailed', 'https://github.com/NSIS-Dev/Documentation/blob/master/Callbacks/onRebootFailed.md', {
418
- fallback() {
419
- return '.onRebootFailed';
420
- }
421
- }),
422
- value: '.onRebootFailed'
423
- },
424
- {
425
- name: terminalLink('.onSelChange', 'https://github.com/NSIS-Dev/Documentation/blob/master/Callbacks/onSelChange.md', {
426
- fallback() {
427
- return '.onSelChange';
428
- }
429
- }),
430
- value: '.onSelChange'
431
- },
432
- {
433
- name: terminalLink('.onMouseOverSection', 'https://github.com/NSIS-Dev/Documentation/blob/master/Callbacks/onMouseOverSection.md', {
434
- fallback() {
435
- return '.onMouseOverSection';
436
- }
437
- }),
438
- value: '.onMouseOverSection'
439
- },
440
- ] },
441
- {
442
- name: 'includes',
443
- message: 'Add libraries',
444
- type: 'checkbox',
445
- store: true,
446
- choices: async () => this.firstParty ? bundledLibraries : await getAllLibraries()
447
- },
448
- {
449
- name: 'languages',
450
- message: (this.disabled === true) ? 'Add languages other than English' : 'Add languages',
451
- type: 'checkbox',
452
- store: true,
453
- choices: this.languageChoices()
454
- },
455
- {
456
- name: 'languageDialog',
457
- message: 'Add language dialog',
458
- type: 'confirm',
459
- default: 'true',
460
- store: true,
461
- when: answers => {
462
- switch (true) {
463
- case (this.options['unlock-all'] === true && answers.languages.length > 1):
464
- case (this.options['unlock-all'] === false && answers.languages.length > 0):
465
- return true;
466
- default:
467
- return false;
468
- }
469
- }
470
- },
471
- {
472
- name: 'editInstallerScript',
473
- message: 'Edit installer script',
474
- type: 'confirm',
475
- default: 'true',
476
- store: true,
477
- when: () => {
478
- return (process.env.EDITOR) ? true : false;
479
- }
480
- },
481
- ]).then(props => {
482
-
483
- if (typeof props.spdxLicense !== 'undefined') {
484
- props.licenseText = spdxLicenseList[props.spdxLicense].licenseText.replace(/\n{3,}/g, '\n\n');
485
- }
486
-
487
- if (props.name.includes('&')) {
488
- props.ampersand_name = props.name.replace('&', '&&');
489
- }
490
-
491
- props.outfile = props.version ? `${slugify(props.name)}-${props.version}-setup` : `${slugify(props.name)}-setup`;
492
-
493
- if (props.languageDialog) {
494
- if (!props.callbacks.includes('.onInit')) {
495
- props.callbacks.unshift('.onInit');
496
- }
497
- }
498
-
499
- if (props.includes.includes('MUI2')) {
500
- const indexOfonGUIInit = props.callbacks.indexOf('.onGUIInit');
501
- const indexOfonUserAbort = props.callbacks.indexOf('.onUserAbort');
502
- if (indexOfonGUIInit !== -1) {
503
- props.callbacks.splice(indexOfonGUIInit, 1, '"custom.onGUIInit"');
504
- }
505
- if (indexOfonUserAbort !== -1) {
506
- props.callbacks.splice(indexOfonUserAbort, 1, '"custom.onUserAbort"');
507
- }
508
- }
509
-
510
- this.fs.copyTpl(
511
- this.templatePath('installer.nsi.ejs'),
512
- this.destinationPath('installer.nsi'),
513
- {
514
- languageData: languageData,
515
- pkg: props,
516
- unlockAll: this.options['unlock-all']
517
- }
518
- );
519
-
520
- if (typeof props.spdxLicense !== 'undefined') {
521
- this.fs.copyTpl(
522
- this.templatePath('license.txt.ejs'),
523
- this.destinationPath('license.txt'),
524
- {
525
- licenseText: props.licenseText
526
- }
527
- );
528
- }
529
-
530
- if (props.editInstallerScript === true) {
531
- this.spawnCommand(process.env.EDITOR, [ 'installer.nsi' ]);
532
- }
533
- });
534
- }
535
- };
2
+ import { meta as languageData } from '@nsis/language-data';
3
+
4
+ import { getAllLibraries, getLanguageChoices, licenseChoices } from '../lib/helpers.js';
5
+ import * as choices from '../lib/choices.js';
6
+ import Generator from 'yeoman-generator';
7
+ import semver from 'semver';
8
+ import slugify from '@sindresorhus/slugify';
9
+ import spdxLicenseList from 'spdx-license-list/full.js';
10
+ import terminalLink from 'terminal-link';
11
+
12
+ export default class extends Generator {
13
+ constructor(args, opts) {
14
+ super(args, opts);
15
+
16
+ this.option('first-party', { desc: 'Limits library inclusion to first-party', default: false });
17
+ this.option('loose-version', { desc: `Doesn't enforce semantic versioning`, default: false });
18
+ this.option('unlock-all', { desc: 'Unlocks all disabled features', default: false });
19
+ this.option('debug', { desc: 'Prints debug messages', default: false });
20
+
21
+ this.looseVersion = (this.options.looseVersion ? true : false);
22
+ this.disabled = (this.options.unlockAll ? false : true);
23
+ this.firstParty = (this.options.firstParty ? true : false);
24
+ this.debug = (this.options.debug ? true : false);
25
+ }
26
+
27
+ // languageDialog(isUnicode) {
28
+ // const languageDialog = Object.entries(languageData).map(([key, value]) => {
29
+ // if (key === 'English') return;
30
+
31
+ // return {
32
+ // constant: `$\{LANG_${key.toUpperCase()}}`,
33
+ // string: (isUnicode) ? value.native : (value.long || key)
34
+ // };
35
+ // });
36
+
37
+ // return languageDialog;
38
+ // }
39
+
40
+ inquirer() {
41
+ return this.prompt([
42
+ {
43
+ name: 'name',
44
+ message: `Application name`,
45
+ default: slugify(this.appname),
46
+ store: true,
47
+ validate: name => (name.trim().length > 0) ? true : 'Not a valid name'
48
+ },
49
+ {
50
+ name: 'version',
51
+ message: `Application version`,
52
+ default: '0.0.0',
53
+ store: true,
54
+ validate: version => (this.looseVersion === true || semver.valid(version) !== null) ? true : `Not a valid ${terminalLink('semantic version', 'https://semver.org', {
55
+ fallback() {
56
+ return 'semantic version';
57
+ }
58
+ })}`
59
+ },
60
+ {
61
+ name: 'unicode',
62
+ message: 'Unicode installer',
63
+ type: 'confirm',
64
+ default: 'true',
65
+ store: true
66
+ },
67
+ {
68
+ name: 'elevation',
69
+ message: 'Requested execution level',
70
+ type: 'list',
71
+ default: 'user',
72
+ store: true,
73
+ choices: choices.elevation
74
+ },
75
+ {
76
+ name: 'compression',
77
+ message: 'Set compression',
78
+ type: 'list',
79
+ default: 'lzma',
80
+ store: true,
81
+ choices: choices.compression
82
+ },
83
+ {
84
+ name: 'pages',
85
+ message: 'Installer pages',
86
+ type: 'checkbox',
87
+ store: true,
88
+ default: [ 'instfiles' ],
89
+ choices: choices.pages
90
+ },
91
+ {
92
+ name: 'spdxQuestion',
93
+ message: `Choose a license from ${terminalLink('SPDX License List', 'https://spdx.org/licenses/', {
94
+ fallback() {
95
+ return 'SPDX License List'
96
+ }
97
+ })}`,
98
+ type: 'confirm',
99
+ default: true,
100
+ store: true,
101
+ when: answers => answers.pages?.includes('license') ? true : false
102
+ },
103
+ {
104
+ name: 'spdxLicense',
105
+ message: 'Choose a license',
106
+ type: 'list',
107
+ default: 'MIT',
108
+ choices: licenseChoices,
109
+ store: true,
110
+ when: answers => answers.pages?.includes('license') && answers.spdxQuestion ? true : false
111
+ },
112
+ {
113
+ name: 'sections',
114
+ message: 'Number of sections',
115
+ default: 1,
116
+ store: true,
117
+ validate: number => (Number.isInteger(parseInt(number)) && parseInt(number) > 0) ? true : 'Not a valid integer'
118
+ },
119
+ {
120
+ name: 'callbacks',
121
+ message: 'Add callback functions',
122
+ type: 'checkbox',
123
+ store: true,
124
+ default: [],
125
+ choices: choices.callbacks
126
+ },
127
+ {
128
+ name: 'includes',
129
+ message: 'Add libraries',
130
+ type: 'checkbox',
131
+ store: true,
132
+ default: [],
133
+ choices: async () => this.firstParty ? choices.includes : await getAllLibraries(),
134
+ validate: callbacks => (callbacks.includes('MUI') && callbacks.includes('MUI2')) ? 'Don\'t mix MUI versions' : true
135
+ },
136
+ {
137
+ name: 'languages',
138
+ message: (this.disabled === true) ? 'Add languages other than English' : 'Add languages',
139
+ type: 'checkbox',
140
+ store: true,
141
+ default: [],
142
+ choices: getLanguageChoices(this.disabled)
143
+ },
144
+ {
145
+ name: 'languageDialog',
146
+ message: 'Add language dialog',
147
+ type: 'confirm',
148
+ default: 'true',
149
+ store: true,
150
+ when: answers => {
151
+ switch (true) {
152
+ case (this.options['unlock-all'] === true && answers.languages?.length > 1):
153
+ case (this.options['unlock-all'] === false && answers.languages?.length > 0):
154
+ return true;
155
+
156
+ default:
157
+ return false;
158
+ }
159
+ }
160
+ },
161
+ {
162
+ name: 'editInstallerScript',
163
+ message: 'Edit installer script',
164
+ type: 'confirm',
165
+ default: 'true',
166
+ store: true,
167
+ when: () => {
168
+ return (process.env.EDITOR) ? true : false;
169
+ }
170
+ },
171
+ ]).then(async props => {
172
+
173
+ if (this.options.debug) {
174
+ console.log(props);
175
+ }
176
+
177
+ if (typeof props.spdxLicense !== 'undefined') {
178
+ props.licenseText = spdxLicenseList[props.spdxLicense].licenseText.replace(/\n{3,}/g, '\n\n');
179
+ }
180
+
181
+ if (props.name.includes('&')) {
182
+ props.ampersand_name = props.name.replace('&', '&&');
183
+ }
184
+
185
+ props.outfile = props.version ? `${slugify(props.name)}-${props.version}-setup` : `${slugify(props.name)}-setup`;
186
+
187
+ if (props.languageDialog) {
188
+ if (!props.callbacks.includes('.onInit')) {
189
+ props.callbacks.unshift('.onInit');
190
+ }
191
+ }
192
+
193
+ if (props.includes?.includes('MUI2')) {
194
+ const includesOnGUIInit = props.callbacks.indexOf('.onGUIInit');
195
+
196
+ if (includesOnGUIInit !== -1) {
197
+ props.callbacks.splice(includesOnGUIInit, 1, 'MUI.onGUIInit');
198
+ }
199
+
200
+ const includesOnUserAbort = props.callbacks.indexOf('.onUserAbort');
201
+
202
+ if (includesOnUserAbort !== -1) {
203
+ props.callbacks.splice(includesOnUserAbort, 1, 'MUI.onUserAbort');
204
+ }
205
+ }
206
+
207
+ await this.fs.copyTplAsync(
208
+ this.templatePath('installer.nsi.ejs'),
209
+ this.destinationPath('installer.nsi'),
210
+ {
211
+ languageData: languageData,
212
+ pkg: props,
213
+ unlockAll: this.options['unlock-all'],
214
+ debug: this.options.debug
215
+ }
216
+ );
217
+
218
+ if (typeof props.spdxLicense !== 'undefined') {
219
+ await this.fs.copyTplAsync(
220
+ this.templatePath('license.txt.ejs'),
221
+ this.destinationPath('license.txt'),
222
+ {
223
+ licenseText: props.licenseText
224
+ }
225
+ );
226
+ }
227
+
228
+ if (props.editInstallerScript === true) {
229
+ this.spawnCommand(process.env.EDITOR, [ 'installer.nsi' ]);
230
+ }
231
+ });
232
+ }
233
+ }