Skip to content

Commit 9a31bf3

Browse files
authored
chore: support macOS config (#32)
* chore: support macOS config * chore: bump version
1 parent d44ef35 commit 9a31bf3

3 files changed

Lines changed: 297 additions & 4 deletions

File tree

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@vscode/gulp-electron",
3-
"version": "1.38.2",
3+
"version": "1.39.0",
44
"description": "gulp plugin for packaging Electron into VS Code",
55
"main": "src/index.js",
66
"scripts": {

src/darwin.js

Lines changed: 294 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,22 @@ function getOriginalAppName(opts) {
1212
return semver.gte(opts.version, "0.24.0") ? "Electron" : "Atom";
1313
}
1414

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+
1531
function getOriginalAppFullName(opts) {
1632
return getOriginalAppName(opts) + ".app";
1733
}
@@ -281,6 +297,177 @@ function patchHelperInfoPlist(opts) {
281297
return es.duplex(input, es.merge(output, icons));
282298
}
283299

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+
284471
function addCredits(opts) {
285472
if (!opts.darwinCredits) {
286473
return es.through();
@@ -395,6 +582,107 @@ function renameAppHelper(opts) {
395582
});
396583
}
397584

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+
398686
exports.patch = function (opts) {
399687
var pass = es.through();
400688

@@ -403,11 +691,16 @@ exports.patch = function (opts) {
403691
.pipe(patchIcon(opts))
404692
.pipe(patchInfoPlist(opts))
405693
.pipe(patchHelperInfoPlist(opts))
694+
.pipe(patchMiniAppInfoPlist(opts))
695+
.pipe(patchMiniAppHelperInfoPlist(opts))
696+
.pipe(patchMiniAppIcon(opts))
406697
.pipe(createEntitlementsPlist(opts))
407698
.pipe(addCredits(opts))
408699
.pipe(moveChromiumLicense(opts))
409700
.pipe(renameApp(opts))
410-
.pipe(renameAppHelper(opts));
701+
.pipe(renameAppHelper(opts))
702+
.pipe(renameMiniApp(opts))
703+
.pipe(renameMiniAppHelper(opts));
411704

412705
return es.duplex(pass, src);
413706
};

0 commit comments

Comments
 (0)