@vscode/gulp-electron 1.38.2 → 1.40.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.
Files changed (3) hide show
  1. package/package.json +1 -1
  2. package/src/darwin.js +294 -1
  3. package/src/win32.js +107 -62
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vscode/gulp-electron",
3
- "version": "1.38.2",
3
+ "version": "1.40.0",
4
4
  "description": "gulp plugin for packaging Electron into VS Code",
5
5
  "main": "src/index.js",
6
6
  "scripts": {
package/src/darwin.js CHANGED
@@ -12,6 +12,22 @@ function getOriginalAppName(opts) {
12
12
  return semver.gte(opts.version, "0.24.0") ? "Electron" : "Atom";
13
13
  }
14
14
 
15
+ function getOriginalMiniAppName(opts) {
16
+ return getOriginalAppName(opts) + " MiniApp";
17
+ }
18
+
19
+ function getOriginalMiniAppFullName(opts) {
20
+ return getOriginalMiniAppName(opts) + ".app";
21
+ }
22
+
23
+ function getMiniAppName(opts) {
24
+ return opts.darwinMiniAppName || opts.productName + " MiniApp";
25
+ }
26
+
27
+ function getMiniAppFullName(opts) {
28
+ return getMiniAppName(opts) + ".app";
29
+ }
30
+
15
31
  function getOriginalAppFullName(opts) {
16
32
  return getOriginalAppName(opts) + ".app";
17
33
  }
@@ -281,6 +297,177 @@ function patchHelperInfoPlist(opts) {
281
297
  return es.duplex(input, es.merge(output, icons));
282
298
  }
283
299
 
300
+ function patchMiniAppInfoPlist(opts) {
301
+ if (!opts.darwinMiniAppName) {
302
+ return es.through();
303
+ }
304
+
305
+ var input = es.through();
306
+ var output = input.pipe(
307
+ es.map(function (f, cb) {
308
+ // Match MiniApp's Info.plist at Contents/Applications/*/Contents/Info.plist
309
+ const match = /Contents\/Applications\/[^\/]+\.app\/Contents\/Info.plist$/i.exec(
310
+ f.relative);
311
+ if (!match) {
312
+ return cb(null, f);
313
+ }
314
+
315
+ var contents = "";
316
+
317
+ f.contents.on("error", function (err) {
318
+ cb(err);
319
+ });
320
+
321
+ f.contents.on("data", function (d) {
322
+ contents += d;
323
+ });
324
+
325
+ f.contents.on("end", function () {
326
+ var infoPlist = plist.parse(contents.toString("utf8"));
327
+
328
+ var miniAppName = getMiniAppName(opts);
329
+
330
+ // Bundle identifier
331
+ if (opts.darwinMiniAppBundleIdentifier) {
332
+ infoPlist["CFBundleIdentifier"] = opts.darwinMiniAppBundleIdentifier;
333
+ } else if (opts.darwinBundleIdentifier) {
334
+ infoPlist["CFBundleIdentifier"] = opts.darwinBundleIdentifier + ".miniapp";
335
+ }
336
+
337
+ // Name and display name
338
+ infoPlist["CFBundleName"] = miniAppName;
339
+ infoPlist["CFBundleDisplayName"] = opts.darwinMiniAppDisplayName || miniAppName;
340
+
341
+ // Executable name
342
+ infoPlist["CFBundleExecutable"] = miniAppName;
343
+
344
+ // Version info
345
+ infoPlist["CFBundleVersion"] = opts.productVersion;
346
+ infoPlist["CFBundleShortVersionString"] = opts.productVersion;
347
+
348
+ // Icon file
349
+ if (opts.darwinMiniAppIcon) {
350
+ infoPlist["CFBundleIconFile"] = path.basename(opts.darwinMiniAppIcon);
351
+ }
352
+
353
+ // Copyright
354
+ if (opts.copyright) {
355
+ infoPlist["NSHumanReadableCopyright"] = opts.copyright;
356
+ }
357
+
358
+ // Update host bundle reference
359
+ if (opts.darwinBundleIdentifier) {
360
+ infoPlist["ElectronHostBundleId"] = opts.darwinBundleIdentifier;
361
+ }
362
+
363
+ f.contents = Buffer.from(plist.build(infoPlist), "utf8");
364
+ cb(null, f);
365
+ });
366
+ })
367
+ );
368
+
369
+ return es.duplex(input, output);
370
+ }
371
+
372
+ function patchMiniAppHelperInfoPlist(opts) {
373
+ if (!opts.darwinMiniAppName) {
374
+ return es.through();
375
+ }
376
+
377
+ var input = es.through();
378
+ var output = input.pipe(
379
+ es.map(function (f, cb) {
380
+ // Match MiniApp Helper's Info.plist at Contents/Applications/*/Contents/Frameworks/Helper*.app/Contents/Info.plist
381
+ const match = /Contents\/Applications\/[^\/]+\.app\/Contents\/Frameworks\/[^\/]+\ Helper( \(\w+\))?\.app\/Contents\/Info.plist$/i.exec(
382
+ f.relative);
383
+ if (!match) {
384
+ return cb(null, f);
385
+ }
386
+
387
+ var contents = "";
388
+
389
+ f.contents.on("error", function (err) {
390
+ cb(err);
391
+ });
392
+
393
+ f.contents.on("data", function (d) {
394
+ contents += d;
395
+ });
396
+
397
+ f.contents.on("end", function () {
398
+ var infoPlist = plist.parse(contents.toString("utf8"));
399
+ var suffix = match[1] ?? "";
400
+
401
+ var miniAppName = getMiniAppName(opts);
402
+ var helperName = miniAppName + " Helper" + suffix;
403
+
404
+ // Bundle identifier
405
+ if (opts.darwinMiniAppBundleIdentifier) {
406
+ infoPlist["CFBundleIdentifier"] = opts.darwinMiniAppBundleIdentifier + ".helper";
407
+ } else if (opts.darwinBundleIdentifier) {
408
+ infoPlist["CFBundleIdentifier"] = opts.darwinBundleIdentifier + ".miniapp.helper";
409
+ }
410
+
411
+ infoPlist["CFBundleName"] = helperName;
412
+
413
+ if (infoPlist["CFBundleDisplayName"]) {
414
+ infoPlist["CFBundleDisplayName"] = helperName;
415
+ }
416
+
417
+ if (infoPlist["CFBundleExecutable"]) {
418
+ infoPlist["CFBundleExecutable"] = helperName;
419
+ }
420
+
421
+ f.contents = Buffer.from(plist.build(infoPlist), "utf8");
422
+ cb(null, f);
423
+ });
424
+ })
425
+ );
426
+
427
+ return es.duplex(input, output);
428
+ }
429
+
430
+ function patchMiniAppIcon(opts) {
431
+ if (!opts.darwinMiniAppName || !opts.darwinMiniAppIcon) {
432
+ return es.through();
433
+ }
434
+
435
+ var originalIconPath = path.join(
436
+ getOriginalAppFullName(opts),
437
+ "Contents",
438
+ "Applications",
439
+ getOriginalMiniAppFullName(opts),
440
+ "Contents",
441
+ "Resources",
442
+ "miniapp.icns"
443
+ );
444
+ var iconPath = path.join(
445
+ getOriginalAppFullName(opts),
446
+ "Contents",
447
+ "Applications",
448
+ getOriginalMiniAppFullName(opts),
449
+ "Contents",
450
+ "Resources",
451
+ path.basename(opts.darwinMiniAppIcon)
452
+ );
453
+
454
+ var pass = es.through();
455
+
456
+ // filter out original icon
457
+ var src = pass.pipe(
458
+ es.mapSync(function (f) {
459
+ if (f.relative !== originalIconPath) {
460
+ return f;
461
+ }
462
+ })
463
+ );
464
+
465
+ // add custom icon
466
+ var icon = vfs.src(opts.darwinMiniAppIcon).pipe(rename(iconPath));
467
+
468
+ return es.duplex(pass, es.merge(src, icon));
469
+ }
470
+
284
471
  function addCredits(opts) {
285
472
  if (!opts.darwinCredits) {
286
473
  return es.through();
@@ -395,6 +582,107 @@ function renameAppHelper(opts) {
395
582
  });
396
583
  }
397
584
 
585
+ function renameMiniApp(opts) {
586
+ if (!opts.darwinMiniAppName) {
587
+ return es.through();
588
+ }
589
+
590
+ var originalMiniAppName = getOriginalMiniAppName(opts);
591
+ var originalMiniAppFullName = getOriginalMiniAppFullName(opts);
592
+ var miniAppName = getMiniAppName(opts);
593
+ var miniAppFullName = getMiniAppFullName(opts);
594
+
595
+ return rename(function (path) {
596
+ // Check if this is inside the Applications folder
597
+ if (!/Contents\/Applications/.test(path.dirname) &&
598
+ !(path.dirname === "." && path.basename === originalMiniAppName && /Contents\/Applications$/.test(path.dirname))) {
599
+ // Not a miniapp path, but check if dirname contains Applications
600
+ if (!path.dirname.includes("Contents/Applications")) {
601
+ return;
602
+ }
603
+ }
604
+
605
+ // Rename the MiniApp.app folder itself
606
+ if (
607
+ /Contents\/Applications$/.test(path.dirname) &&
608
+ path.basename === originalMiniAppName &&
609
+ path.extname === ".app"
610
+ ) {
611
+ path.basename = miniAppName;
612
+ return;
613
+ }
614
+
615
+ // Rename paths inside MiniApp.app
616
+ if (path.dirname.includes(originalMiniAppFullName)) {
617
+ path.dirname = path.dirname.replace(
618
+ originalMiniAppFullName,
619
+ miniAppFullName
620
+ );
621
+ }
622
+
623
+ // Rename the MiniApp executable in MacOS folder
624
+ if (
625
+ /Contents\/Applications\/[^\/]+\.app\/Contents\/MacOS$/.test(path.dirname) &&
626
+ path.basename === originalMiniAppName &&
627
+ path.extname === ""
628
+ ) {
629
+ path.basename = miniAppName;
630
+ }
631
+ });
632
+ }
633
+
634
+ function renameMiniAppHelper(opts) {
635
+ if (!opts.darwinMiniAppName) {
636
+ return es.through();
637
+ }
638
+
639
+ var originalMiniAppHelperName = getOriginalMiniAppName(opts) + " Helper";
640
+ var miniAppName = getMiniAppName(opts);
641
+
642
+ return rename(function (path) {
643
+ // Only process paths inside MiniApp's Frameworks
644
+ if (!/Contents\/Applications\/[^\/]+\.app\/Contents\/Frameworks/.test(path.dirname) &&
645
+ !/Contents\/Applications\/[^\/]+\.app\/Contents\/Frameworks$/.test(path.dirname + "/" + path.basename)) {
646
+ // Check if the path is the helper app folder itself
647
+ if (!/Contents\/Applications/.test(path.dirname)) {
648
+ return;
649
+ }
650
+ }
651
+
652
+ // Rename the helper .app folder
653
+ if (
654
+ /Contents\/Applications\/[^\/]+\.app\/Contents\/Frameworks$/.test(path.dirname) &&
655
+ path.extname === ".app"
656
+ ) {
657
+ var basenameMatch = /^Electron MiniApp Helper( \(\w+\))?$/.exec(path.basename);
658
+ if (basenameMatch) {
659
+ var suffix = basenameMatch[1] || "";
660
+ path.basename = miniAppName + " Helper" + suffix;
661
+ return;
662
+ }
663
+ }
664
+
665
+ // Rename paths inside MiniApp Helper.app
666
+ var helperDirMatch = /Electron\ MiniApp\ Helper( \(\w+\))?\.app/.exec(path.dirname);
667
+ if (helperDirMatch) {
668
+ var suffix = helperDirMatch[1] || "";
669
+ path.dirname = path.dirname.replace(
670
+ /Electron\ MiniApp\ Helper( \(\w+\))?\.app/,
671
+ miniAppName + " Helper$1.app"
672
+ );
673
+
674
+ // Rename the helper executable
675
+ var execMatch = /Contents\/Applications\/[^\/]+\.app\/Contents\/Frameworks\/[^\/]+\.app\/Contents\/MacOS$/.test(path.dirname);
676
+ if (execMatch) {
677
+ var execNameMatch = /^Electron MiniApp Helper( \(\w+\))?$/.exec(path.basename);
678
+ if (execNameMatch && path.extname === "") {
679
+ path.basename = miniAppName + " Helper" + (execNameMatch[1] || "");
680
+ }
681
+ }
682
+ }
683
+ });
684
+ }
685
+
398
686
  exports.patch = function (opts) {
399
687
  var pass = es.through();
400
688
 
@@ -403,11 +691,16 @@ exports.patch = function (opts) {
403
691
  .pipe(patchIcon(opts))
404
692
  .pipe(patchInfoPlist(opts))
405
693
  .pipe(patchHelperInfoPlist(opts))
694
+ .pipe(patchMiniAppInfoPlist(opts))
695
+ .pipe(patchMiniAppHelperInfoPlist(opts))
696
+ .pipe(patchMiniAppIcon(opts))
406
697
  .pipe(createEntitlementsPlist(opts))
407
698
  .pipe(addCredits(opts))
408
699
  .pipe(moveChromiumLicense(opts))
409
700
  .pipe(renameApp(opts))
410
- .pipe(renameAppHelper(opts));
701
+ .pipe(renameAppHelper(opts))
702
+ .pipe(renameMiniApp(opts))
703
+ .pipe(renameMiniAppHelper(opts));
411
704
 
412
705
  return es.duplex(pass, src);
413
706
  };
package/src/win32.js CHANGED
@@ -60,76 +60,113 @@ exports.getAppPath = function (opts) {
60
60
  return path.join("resources", "app");
61
61
  };
62
62
 
63
+ function applyRcedit(f, patch, cb) {
64
+ var tempPath = temp.path();
65
+ var ostream = fs.createWriteStream(tempPath);
66
+
67
+ f.contents.pipe(ostream);
68
+ ostream.on("close", function () {
69
+ // Remove codesignature before editing exe file
70
+ const signToolPath = getSignTool();
71
+ const {error} = spawnSync(signToolPath, ["remove", "/s", tempPath]);
72
+ if (error) {
73
+ return cb(error);
74
+ }
75
+
76
+ rcedit(tempPath, patch).then(() => {
77
+ fs.readFile(tempPath, function (err, data) {
78
+ if (err) {
79
+ return cb(err);
80
+ }
81
+
82
+ f.contents = data;
83
+
84
+ fs.unlink(tempPath, function (err) {
85
+ if (err) {
86
+ return cb(err);
87
+ }
88
+
89
+ cb(null, f);
90
+ });
91
+ });
92
+ }).catch(err => {
93
+ if (err) {
94
+ return cb(err);
95
+ }
96
+ });
97
+ });
98
+ }
99
+
63
100
  function patchExecutable(opts) {
64
101
  return es.map(function (f, cb) {
65
- if (
66
- f.relative !== getOriginalAppFullName(opts) ||
67
- process.platform !== "win32"
68
- ) {
102
+ if (process.platform !== "win32") {
69
103
  return cb(null, f);
70
104
  }
71
105
 
72
- var patch = {
73
- "version-string": {
74
- CompanyName: opts.companyName || "GitHub, Inc.",
75
- FileDescription: opts.productAppName || opts.productName,
76
- LegalCopyright:
77
- opts.copyright ||
78
- "Copyright (C) 2014 GitHub, Inc. All rights reserved",
79
- ProductName: opts.productAppName || opts.productName,
80
- ProductVersion: opts.productVersion,
81
- },
82
- "file-version": opts.productVersion,
83
- "product-version": opts.productVersion,
84
- };
85
-
86
- if (opts.createVersionedResources) {
87
- if (!opts.productVersionString) {
88
- throw new Error("productVersionString must be defined.");
89
- }
90
- patch["resource-string"] = {
91
- 2: opts.productVersionString
106
+ if (f.relative === getOriginalAppFullName(opts)) {
107
+ var patch = {
108
+ "version-string": {
109
+ CompanyName: opts.companyName || "GitHub, Inc.",
110
+ FileDescription: opts.productAppName || opts.productName,
111
+ LegalCopyright:
112
+ opts.copyright ||
113
+ "Copyright (C) 2014 GitHub, Inc. All rights reserved",
114
+ ProductName: opts.productAppName || opts.productName,
115
+ ProductVersion: opts.productVersion,
116
+ },
117
+ "file-version": opts.productVersion,
118
+ "product-version": opts.productVersion,
92
119
  };
93
- }
94
120
 
95
- if (opts.winIcon) {
96
- patch.icon = opts.winIcon;
121
+ if (opts.createVersionedResources) {
122
+ if (!opts.productVersionString) {
123
+ throw new Error("productVersionString must be defined.");
124
+ }
125
+ patch["resource-string"] = {
126
+ 2: opts.productVersionString
127
+ };
128
+ }
129
+
130
+ if (opts.winIcon) {
131
+ patch.icon = opts.winIcon;
132
+ }
133
+
134
+ return applyRcedit(f, patch, cb);
97
135
  }
98
136
 
99
- var tempPath = temp.path();
100
- var ostream = fs.createWriteStream(tempPath);
137
+ if (opts.win32ProxyAppName && f.relative === "electron_proxy.exe") {
138
+ var patch = {
139
+ "version-string": {
140
+ CompanyName: opts.companyName || "GitHub, Inc.",
141
+ FileDescription: opts.win32ProxyAppName,
142
+ LegalCopyright:
143
+ opts.copyright ||
144
+ "Copyright (C) 2014 GitHub, Inc. All rights reserved",
145
+ ProductName: opts.win32ProxyAppName,
146
+ ProductVersion: opts.productVersion,
147
+ },
148
+ "file-version": opts.productVersion,
149
+ "product-version": opts.productVersion,
150
+ "resource-string": {
151
+ 3: `${opts.productName}.exe`
152
+ },
153
+ };
101
154
 
102
- f.contents.pipe(ostream);
103
- ostream.on("close", function () {
104
- // Remove codesignature before editing exe file
105
- const signToolPath = getSignTool();
106
- const {error} = spawnSync(signToolPath, ["remove", "/s", tempPath]);
107
- if (error) {
108
- return cb(error);
155
+ if (opts.createVersionedResources) {
156
+ if (!opts.productVersionString) {
157
+ throw new Error("productVersionString must be defined.");
158
+ }
159
+ patch["resource-string"][2] = opts.productVersionString;
109
160
  }
110
161
 
111
- rcedit(tempPath, patch).then(() => {
112
- fs.readFile(tempPath, function (err, data) {
113
- if (err) {
114
- return cb(err);
115
- }
116
-
117
- f.contents = data;
162
+ if (opts.win32ProxyIcon) {
163
+ patch.icon = opts.win32ProxyIcon;
164
+ }
118
165
 
119
- fs.unlink(tempPath, function (err) {
120
- if (err) {
121
- return cb(err);
122
- }
166
+ return applyRcedit(f, patch, cb);
167
+ }
123
168
 
124
- cb(null, f);
125
- });
126
- });
127
- }).catch(err => {
128
- if (err) {
129
- return cb(err);
130
- }
131
- });
132
- });
169
+ return cb(null, f);
133
170
  });
134
171
  }
135
172
 
@@ -145,12 +182,12 @@ function removeDefaultApp() {
145
182
 
146
183
  function renameApp(opts) {
147
184
  return rename(function (path) {
148
- if (
149
- path.dirname === "." &&
150
- path.basename === getOriginalAppName(opts) &&
151
- path.extname === ".exe"
152
- ) {
153
- path.basename = opts.productName;
185
+ if (path.dirname === "." && path.extname === ".exe") {
186
+ if (path.basename === getOriginalAppName(opts)) {
187
+ path.basename = opts.productName;
188
+ } else if (opts.win32ProxyAppName && path.basename === "electron_proxy") {
189
+ path.basename = opts.win32ProxyAppName;
190
+ }
154
191
  }
155
192
  });
156
193
  }
@@ -168,6 +205,14 @@ function moveFilesExceptExecutable(opts) {
168
205
  return f;
169
206
  }
170
207
 
208
+ // Skip if the file is the renamed proxy executable
209
+ if (
210
+ opts.win32ProxyAppName &&
211
+ f.relative === `${opts.win32ProxyAppName}.exe`
212
+ ) {
213
+ return f;
214
+ }
215
+
171
216
  // Move other files to version subfolder
172
217
  if (f.path && f.base) {
173
218
  const relativePath = path.relative(f.base, f.path);