@zenbujs/core 0.0.13 → 0.0.15
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.
package/dist/launcher.mjs
CHANGED
|
@@ -6070,7 +6070,7 @@ var require_isomorphic_git = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
|
6070
6070
|
var pako = _interopDefault(require_pako());
|
|
6071
6071
|
var crypto$1$1 = __require("crypto");
|
|
6072
6072
|
var pify = _interopDefault(require_pify());
|
|
6073
|
-
|
|
6073
|
+
_interopDefault(require_ignore());
|
|
6074
6074
|
var cleanGitRef = _interopDefault(require_lib());
|
|
6075
6075
|
_interopDefault(require_diff3());
|
|
6076
6076
|
/**
|
|
@@ -9964,54 +9964,6 @@ ${obj.gpgsig ? obj.gpgsig : ""}`;
|
|
|
9964
9964
|
});
|
|
9965
9965
|
else return dotgit;
|
|
9966
9966
|
}
|
|
9967
|
-
var GitIgnoreManager = class {
|
|
9968
|
-
/**
|
|
9969
|
-
* Determines whether a given file is ignored based on `.gitignore` rules and exclusion files.
|
|
9970
|
-
*
|
|
9971
|
-
* @param {Object} args
|
|
9972
|
-
* @param {FSClient} args.fs - A file system implementation.
|
|
9973
|
-
* @param {string} args.dir - The working directory.
|
|
9974
|
-
* @param {string} [args.gitdir=join(dir, '.git')] - [required] The [git directory](dir-vs-gitdir.md) path
|
|
9975
|
-
* @param {string} args.filepath - The path of the file to check.
|
|
9976
|
-
* @returns {Promise<boolean>} - `true` if the file is ignored, `false` otherwise.
|
|
9977
|
-
*/
|
|
9978
|
-
static async isIgnored({ fs, dir, gitdir = join(dir, ".git"), filepath }) {
|
|
9979
|
-
if (basename(filepath) === ".git") return true;
|
|
9980
|
-
if (filepath === ".") return false;
|
|
9981
|
-
let excludes = "";
|
|
9982
|
-
const excludesFile = join(gitdir, "info", "exclude");
|
|
9983
|
-
if (await fs.exists(excludesFile)) excludes = await fs.read(excludesFile, "utf8");
|
|
9984
|
-
const pairs = [{
|
|
9985
|
-
gitignore: join(dir, ".gitignore"),
|
|
9986
|
-
filepath
|
|
9987
|
-
}];
|
|
9988
|
-
const pieces = filepath.split("/").filter(Boolean);
|
|
9989
|
-
for (let i = 1; i < pieces.length; i++) {
|
|
9990
|
-
const folder = pieces.slice(0, i).join("/");
|
|
9991
|
-
const file = pieces.slice(i).join("/");
|
|
9992
|
-
pairs.push({
|
|
9993
|
-
gitignore: join(dir, folder, ".gitignore"),
|
|
9994
|
-
filepath: file
|
|
9995
|
-
});
|
|
9996
|
-
}
|
|
9997
|
-
let ignoredStatus = false;
|
|
9998
|
-
for (const p of pairs) {
|
|
9999
|
-
let file;
|
|
10000
|
-
try {
|
|
10001
|
-
file = await fs.read(p.gitignore, "utf8");
|
|
10002
|
-
} catch (err) {
|
|
10003
|
-
if (err.code === "NOENT") continue;
|
|
10004
|
-
}
|
|
10005
|
-
const ign = ignore().add(excludes);
|
|
10006
|
-
ign.add(file);
|
|
10007
|
-
const parentdir = dirname(p.filepath);
|
|
10008
|
-
if (parentdir !== "." && ign.ignores(parentdir)) return true;
|
|
10009
|
-
if (ignoredStatus) ignoredStatus = !ign.test(p.filepath).unignored;
|
|
10010
|
-
else ignoredStatus = ign.test(p.filepath).ignored;
|
|
10011
|
-
}
|
|
10012
|
-
return ignoredStatus;
|
|
10013
|
-
}
|
|
10014
|
-
};
|
|
10015
9967
|
async function resolveCommit({ fs, cache, gitdir, oid }) {
|
|
10016
9968
|
const { type, object } = await _readObject({
|
|
10017
9969
|
fs,
|
|
@@ -12347,225 +12299,12 @@ ${obj.gpgsig ? obj.gpgsig : ""}`;
|
|
|
12347
12299
|
throw err;
|
|
12348
12300
|
}
|
|
12349
12301
|
}
|
|
12350
|
-
/**
|
|
12351
|
-
* Efficiently get the status of multiple files at once.
|
|
12352
|
-
*
|
|
12353
|
-
* The returned `StatusMatrix` is admittedly not the easiest format to read.
|
|
12354
|
-
* However it conveys a large amount of information in dense format that should make it easy to create reports about the current state of the repository;
|
|
12355
|
-
* without having to do multiple, time-consuming isomorphic-git calls.
|
|
12356
|
-
* My hope is that the speed and flexibility of the function will make up for the learning curve of interpreting the return value.
|
|
12357
|
-
*
|
|
12358
|
-
* ```js live
|
|
12359
|
-
* // get the status of all the files in 'src'
|
|
12360
|
-
* let status = await git.statusMatrix({
|
|
12361
|
-
* fs,
|
|
12362
|
-
* dir: '/tutorial',
|
|
12363
|
-
* filter: f => f.startsWith('src/')
|
|
12364
|
-
* })
|
|
12365
|
-
* console.log(status)
|
|
12366
|
-
* ```
|
|
12367
|
-
*
|
|
12368
|
-
* ```js live
|
|
12369
|
-
* // get the status of all the JSON and Markdown files
|
|
12370
|
-
* let status = await git.statusMatrix({
|
|
12371
|
-
* fs,
|
|
12372
|
-
* dir: '/tutorial',
|
|
12373
|
-
* filter: f => f.endsWith('.json') || f.endsWith('.md')
|
|
12374
|
-
* })
|
|
12375
|
-
* console.log(status)
|
|
12376
|
-
* ```
|
|
12377
|
-
*
|
|
12378
|
-
* The result is returned as a 2D array.
|
|
12379
|
-
* The outer array represents the files and/or blobs in the repo, in alphabetical order.
|
|
12380
|
-
* The inner arrays describe the status of the file:
|
|
12381
|
-
* the first value is the filepath, and the next three are integers
|
|
12382
|
-
* representing the HEAD status, WORKDIR status, and STAGE status of the entry.
|
|
12383
|
-
*
|
|
12384
|
-
* ```js
|
|
12385
|
-
* // example StatusMatrix
|
|
12386
|
-
* [
|
|
12387
|
-
* ["a.txt", 0, 2, 0], // new, untracked
|
|
12388
|
-
* ["b.txt", 0, 2, 2], // added, staged
|
|
12389
|
-
* ["c.txt", 0, 2, 3], // added, staged, with unstaged changes
|
|
12390
|
-
* ["d.txt", 1, 1, 1], // unmodified
|
|
12391
|
-
* ["e.txt", 1, 2, 1], // modified, unstaged
|
|
12392
|
-
* ["f.txt", 1, 2, 2], // modified, staged
|
|
12393
|
-
* ["g.txt", 1, 2, 3], // modified, staged, with unstaged changes
|
|
12394
|
-
* ["h.txt", 1, 0, 1], // deleted, unstaged
|
|
12395
|
-
* ["i.txt", 1, 0, 0], // deleted, staged
|
|
12396
|
-
* ["j.txt", 1, 2, 0], // deleted, staged, with unstaged-modified changes (new file of the same name)
|
|
12397
|
-
* ["k.txt", 1, 1, 0], // deleted, staged, with unstaged changes (new file of the same name)
|
|
12398
|
-
* ]
|
|
12399
|
-
* ```
|
|
12400
|
-
*
|
|
12401
|
-
* - The HEAD status is either absent (0) or present (1).
|
|
12402
|
-
* - The WORKDIR status is either absent (0), identical to HEAD (1), or different from HEAD (2).
|
|
12403
|
-
* - The STAGE status is either absent (0), identical to HEAD (1), identical to WORKDIR (2), or different from WORKDIR (3).
|
|
12404
|
-
*
|
|
12405
|
-
* ```ts
|
|
12406
|
-
* type Filename = string
|
|
12407
|
-
* type HeadStatus = 0 | 1
|
|
12408
|
-
* type WorkdirStatus = 0 | 1 | 2
|
|
12409
|
-
* type StageStatus = 0 | 1 | 2 | 3
|
|
12410
|
-
*
|
|
12411
|
-
* type StatusRow = [Filename, HeadStatus, WorkdirStatus, StageStatus]
|
|
12412
|
-
*
|
|
12413
|
-
* type StatusMatrix = StatusRow[]
|
|
12414
|
-
* ```
|
|
12415
|
-
*
|
|
12416
|
-
* > Think of the natural progression of file modifications as being from HEAD (previous) -> WORKDIR (current) -> STAGE (next).
|
|
12417
|
-
* > Then HEAD is "version 1", WORKDIR is "version 2", and STAGE is "version 3".
|
|
12418
|
-
* > Then, imagine a "version 0" which is before the file was created.
|
|
12419
|
-
* > Then the status value in each column corresponds to the oldest version of the file it is identical to.
|
|
12420
|
-
* > (For a file to be identical to "version 0" means the file is deleted.)
|
|
12421
|
-
*
|
|
12422
|
-
* Here are some examples of queries you can answer using the result:
|
|
12423
|
-
*
|
|
12424
|
-
* #### Q: What files have been deleted?
|
|
12425
|
-
* ```js
|
|
12426
|
-
* const FILE = 0, WORKDIR = 2
|
|
12427
|
-
*
|
|
12428
|
-
* const filenames = (await statusMatrix({ dir }))
|
|
12429
|
-
* .filter(row => row[WORKDIR] === 0)
|
|
12430
|
-
* .map(row => row[FILE])
|
|
12431
|
-
* ```
|
|
12432
|
-
*
|
|
12433
|
-
* #### Q: What files have unstaged changes?
|
|
12434
|
-
* ```js
|
|
12435
|
-
* const FILE = 0, WORKDIR = 2, STAGE = 3
|
|
12436
|
-
*
|
|
12437
|
-
* const filenames = (await statusMatrix({ dir }))
|
|
12438
|
-
* .filter(row => row[WORKDIR] !== row[STAGE])
|
|
12439
|
-
* .map(row => row[FILE])
|
|
12440
|
-
* ```
|
|
12441
|
-
*
|
|
12442
|
-
* #### Q: What files have been modified since the last commit?
|
|
12443
|
-
* ```js
|
|
12444
|
-
* const FILE = 0, HEAD = 1, WORKDIR = 2
|
|
12445
|
-
*
|
|
12446
|
-
* const filenames = (await statusMatrix({ dir }))
|
|
12447
|
-
* .filter(row => row[HEAD] !== row[WORKDIR])
|
|
12448
|
-
* .map(row => row[FILE])
|
|
12449
|
-
* ```
|
|
12450
|
-
*
|
|
12451
|
-
* #### Q: What files will NOT be changed if I commit right now?
|
|
12452
|
-
* ```js
|
|
12453
|
-
* const FILE = 0, HEAD = 1, STAGE = 3
|
|
12454
|
-
*
|
|
12455
|
-
* const filenames = (await statusMatrix({ dir }))
|
|
12456
|
-
* .filter(row => row[HEAD] === row[STAGE])
|
|
12457
|
-
* .map(row => row[FILE])
|
|
12458
|
-
* ```
|
|
12459
|
-
*
|
|
12460
|
-
* For reference, here are all possible combinations:
|
|
12461
|
-
*
|
|
12462
|
-
* | HEAD | WORKDIR | STAGE | `git status --short` equivalent |
|
|
12463
|
-
* | ---- | ------- | ----- | ------------------------------- |
|
|
12464
|
-
* | 0 | 0 | 0 | `` |
|
|
12465
|
-
* | 0 | 0 | 3 | `AD` |
|
|
12466
|
-
* | 0 | 2 | 0 | `??` |
|
|
12467
|
-
* | 0 | 2 | 2 | `A ` |
|
|
12468
|
-
* | 0 | 2 | 3 | `AM` |
|
|
12469
|
-
* | 1 | 0 | 0 | `D ` |
|
|
12470
|
-
* | 1 | 0 | 1 | ` D` |
|
|
12471
|
-
* | 1 | 0 | 3 | `MD` |
|
|
12472
|
-
* | 1 | 1 | 0 | `D ` + `??` |
|
|
12473
|
-
* | 1 | 1 | 1 | `` |
|
|
12474
|
-
* | 1 | 1 | 3 | `MM` |
|
|
12475
|
-
* | 1 | 2 | 0 | `D ` + `??` |
|
|
12476
|
-
* | 1 | 2 | 1 | ` M` |
|
|
12477
|
-
* | 1 | 2 | 2 | `M ` |
|
|
12478
|
-
* | 1 | 2 | 3 | `MM` |
|
|
12479
|
-
*
|
|
12480
|
-
* @param {object} args
|
|
12481
|
-
* @param {FsClient} args.fs - a file system client
|
|
12482
|
-
* @param {string} args.dir - The [working tree](dir-vs-gitdir.md) directory path
|
|
12483
|
-
* @param {string} [args.gitdir=join(dir, '.git')] - [required] The [git directory](dir-vs-gitdir.md) path
|
|
12484
|
-
* @param {string} [args.ref = 'HEAD'] - Optionally specify a different commit to compare against the workdir and stage instead of the HEAD
|
|
12485
|
-
* @param {string[]} [args.filepaths = ['.']] - Limit the query to the given files and directories
|
|
12486
|
-
* @param {function(string): boolean} [args.filter] - Filter the results to only those whose filepath matches a function.
|
|
12487
|
-
* @param {object} [args.cache] - a [cache](cache.md) object
|
|
12488
|
-
* @param {boolean} [args.ignored = false] - include ignored files in the result
|
|
12489
|
-
*
|
|
12490
|
-
* @returns {Promise<Array<StatusRow>>} Resolves with a status matrix, described below.
|
|
12491
|
-
* @see StatusRow
|
|
12492
|
-
*/
|
|
12493
|
-
async function statusMatrix({ fs: _fs, dir, gitdir = join(dir, ".git"), ref = "HEAD", filepaths = ["."], filter, cache = {}, ignored: shouldIgnore = false }) {
|
|
12494
|
-
try {
|
|
12495
|
-
assertParameter("fs", _fs);
|
|
12496
|
-
assertParameter("gitdir", gitdir);
|
|
12497
|
-
assertParameter("ref", ref);
|
|
12498
|
-
const fs = new FileSystem(_fs);
|
|
12499
|
-
return await _walk({
|
|
12500
|
-
fs,
|
|
12501
|
-
cache,
|
|
12502
|
-
dir,
|
|
12503
|
-
gitdir: await discoverGitdir({
|
|
12504
|
-
fsp: fs,
|
|
12505
|
-
dotgit: gitdir
|
|
12506
|
-
}),
|
|
12507
|
-
trees: [
|
|
12508
|
-
TREE({ ref }),
|
|
12509
|
-
WORKDIR(),
|
|
12510
|
-
STAGE()
|
|
12511
|
-
],
|
|
12512
|
-
map: async function(filepath, [head, workdir, stage]) {
|
|
12513
|
-
if (!head && !stage && workdir) {
|
|
12514
|
-
if (!shouldIgnore) {
|
|
12515
|
-
if (await GitIgnoreManager.isIgnored({
|
|
12516
|
-
fs,
|
|
12517
|
-
dir,
|
|
12518
|
-
filepath
|
|
12519
|
-
})) return null;
|
|
12520
|
-
}
|
|
12521
|
-
}
|
|
12522
|
-
if (!filepaths.some((base) => worthWalking(filepath, base))) return null;
|
|
12523
|
-
if (filter) {
|
|
12524
|
-
if (!filter(filepath)) return;
|
|
12525
|
-
}
|
|
12526
|
-
const [headType, workdirType, stageType] = await Promise.all([
|
|
12527
|
-
head && head.type(),
|
|
12528
|
-
workdir && workdir.type(),
|
|
12529
|
-
stage && stage.type()
|
|
12530
|
-
]);
|
|
12531
|
-
const isBlob = [
|
|
12532
|
-
headType,
|
|
12533
|
-
workdirType,
|
|
12534
|
-
stageType
|
|
12535
|
-
].includes("blob");
|
|
12536
|
-
if ((headType === "tree" || headType === "special") && !isBlob) return;
|
|
12537
|
-
if (headType === "commit") return null;
|
|
12538
|
-
if ((workdirType === "tree" || workdirType === "special") && !isBlob) return;
|
|
12539
|
-
if (stageType === "commit") return null;
|
|
12540
|
-
if ((stageType === "tree" || stageType === "special") && !isBlob) return;
|
|
12541
|
-
const headOid = headType === "blob" ? await head.oid() : void 0;
|
|
12542
|
-
const stageOid = stageType === "blob" ? await stage.oid() : void 0;
|
|
12543
|
-
let workdirOid;
|
|
12544
|
-
if (headType !== "blob" && workdirType === "blob" && stageType !== "blob") workdirOid = "42";
|
|
12545
|
-
else if (workdirType === "blob") workdirOid = await workdir.oid();
|
|
12546
|
-
const entry = [
|
|
12547
|
-
void 0,
|
|
12548
|
-
headOid,
|
|
12549
|
-
workdirOid,
|
|
12550
|
-
stageOid
|
|
12551
|
-
];
|
|
12552
|
-
const result = entry.map((value) => entry.indexOf(value));
|
|
12553
|
-
result.shift();
|
|
12554
|
-
return [filepath, ...result];
|
|
12555
|
-
}
|
|
12556
|
-
});
|
|
12557
|
-
} catch (err) {
|
|
12558
|
-
err.caller = "git.statusMatrix";
|
|
12559
|
-
throw err;
|
|
12560
|
-
}
|
|
12561
|
-
}
|
|
12562
12302
|
exports.checkout = checkout;
|
|
12563
12303
|
exports.clone = clone;
|
|
12564
12304
|
exports.fetch = fetch;
|
|
12565
12305
|
exports.log = log;
|
|
12566
12306
|
exports.readBlob = readBlob;
|
|
12567
12307
|
exports.resolveRef = resolveRef;
|
|
12568
|
-
exports.statusMatrix = statusMatrix;
|
|
12569
12308
|
}));
|
|
12570
12309
|
//#endregion
|
|
12571
12310
|
//#region ../../node_modules/.pnpm/simple-concat@1.0.1/node_modules/simple-concat/index.js
|
|
@@ -18545,10 +18284,42 @@ function electronTargetVersion(appsDir) {
|
|
|
18545
18284
|
return "42.0.0";
|
|
18546
18285
|
}
|
|
18547
18286
|
}
|
|
18548
|
-
|
|
18287
|
+
/**
|
|
18288
|
+
* Build the env used to spawn `pnpm install` (and friends) on first
|
|
18289
|
+
* launch. The bundled toolchain (`<resourcesPath>/toolchain/`) holds
|
|
18290
|
+
* `node` and `bun` binaries; we prepend that dir to PATH so dependency
|
|
18291
|
+
* install hooks with `#!/usr/bin/env node` shebangs (`@parcel/watcher`,
|
|
18292
|
+
* `dugite`, etc.) resolve to the bundled node regardless of how the
|
|
18293
|
+
* .app was launched.
|
|
18294
|
+
*
|
|
18295
|
+
* GUI launches (Finder, Raycast, Spotlight, `open <app>`) inherit a
|
|
18296
|
+
* stripped PATH like `/usr/bin:/bin:/usr/sbin:/sbin`, so without this
|
|
18297
|
+
* prepend the lifecycle scripts crash with `node: command not found`.
|
|
18298
|
+
* We also baseline-merge the standard system bin dirs in case the
|
|
18299
|
+
* inherited PATH lacks them entirely.
|
|
18300
|
+
*/
|
|
18301
|
+
function buildInstallEnv(appsDir, resourcesPath) {
|
|
18549
18302
|
const target = electronTargetVersion(appsDir);
|
|
18303
|
+
const sep = process.platform === "win32" ? ";" : ":";
|
|
18304
|
+
const baselinePath = process.env.PATH ?? process.env.Path ?? "";
|
|
18305
|
+
const toolchainDir = resourcesPath ? path.join(resourcesPath, "toolchain") : null;
|
|
18306
|
+
const systemDirs = process.platform === "win32" ? [] : [
|
|
18307
|
+
"/usr/local/bin",
|
|
18308
|
+
"/usr/bin",
|
|
18309
|
+
"/bin",
|
|
18310
|
+
"/usr/sbin",
|
|
18311
|
+
"/sbin"
|
|
18312
|
+
];
|
|
18313
|
+
const segments = [];
|
|
18314
|
+
if (toolchainDir) segments.push(toolchainDir);
|
|
18315
|
+
if (baselinePath) segments.push(...baselinePath.split(sep));
|
|
18316
|
+
segments.push(...systemDirs);
|
|
18317
|
+
const seen = /* @__PURE__ */ new Set();
|
|
18318
|
+
const PATH = segments.filter((s) => s && !seen.has(s) && seen.add(s)).join(sep);
|
|
18550
18319
|
return {
|
|
18551
18320
|
...process.env,
|
|
18321
|
+
PATH,
|
|
18322
|
+
Path: PATH,
|
|
18552
18323
|
CI: "true",
|
|
18553
18324
|
HOME: path.join(appsDir, ".zenbu", ".node-gyp"),
|
|
18554
18325
|
npm_config_runtime: "electron",
|
|
@@ -18659,7 +18430,7 @@ function spawnInstall(args) {
|
|
|
18659
18430
|
}
|
|
18660
18431
|
async function runInstall(opts) {
|
|
18661
18432
|
const { appsDir, resourcesPath, pm, reporter = null, signal } = opts;
|
|
18662
|
-
const env = buildInstallEnv(appsDir);
|
|
18433
|
+
const env = buildInstallEnv(appsDir, resourcesPath);
|
|
18663
18434
|
const entry = bundledPmEntry(pm, resourcesPath);
|
|
18664
18435
|
switch (pm.type) {
|
|
18665
18436
|
case "pnpm": {
|
|
@@ -20656,20 +20427,6 @@ function resolveMirror(cfg) {
|
|
|
20656
20427
|
function isExistingClone(dir) {
|
|
20657
20428
|
return existsSync(path.join(dir, ".git", "HEAD"));
|
|
20658
20429
|
}
|
|
20659
|
-
/**
|
|
20660
|
-
* True if the working tree has uncommitted modifications. We use this as a
|
|
20661
|
-
* "respect the user's edits" guard before fast-forwarding from origin.
|
|
20662
|
-
*/
|
|
20663
|
-
async function hasLocalModifications(dir) {
|
|
20664
|
-
try {
|
|
20665
|
-
return (await import_isomorphic_git.statusMatrix({
|
|
20666
|
-
fs,
|
|
20667
|
-
dir
|
|
20668
|
-
})).some(([, head, workdir, stage]) => head !== 1 || workdir !== 1 || stage !== 1);
|
|
20669
|
-
} catch {
|
|
20670
|
-
return false;
|
|
20671
|
-
}
|
|
20672
|
-
}
|
|
20673
20430
|
async function cloneMirror(dir, mirror, installer) {
|
|
20674
20431
|
console.log(`[launcher] cloning ${mirror.url}#${mirror.branch} -> ${dir}`);
|
|
20675
20432
|
installer?.step("clone", `Cloning ${mirror.url}#${mirror.branch}`);
|
|
@@ -20697,41 +20454,6 @@ async function cloneMirror(dir, mirror, installer) {
|
|
|
20697
20454
|
installer?.done("clone");
|
|
20698
20455
|
}
|
|
20699
20456
|
/**
|
|
20700
|
-
* Best-effort `git fetch --depth=1` against `origin/<branch>`. Failures
|
|
20701
|
-
* are non-fatal — the resolver runs next and may still find a local
|
|
20702
|
-
* compatible commit on a previously-deepened working tree. Skips the
|
|
20703
|
-
* remote checkout entirely (the resolver decides which sha to land on).
|
|
20704
|
-
*/
|
|
20705
|
-
async function fetchTip(dir, mirror, installer) {
|
|
20706
|
-
installer?.step("fetch", `Updating from ${mirror.url}#${mirror.branch}`);
|
|
20707
|
-
try {
|
|
20708
|
-
await import_isomorphic_git.fetch({
|
|
20709
|
-
fs,
|
|
20710
|
-
http: index,
|
|
20711
|
-
dir,
|
|
20712
|
-
url: mirror.url,
|
|
20713
|
-
ref: mirror.branch,
|
|
20714
|
-
singleBranch: true,
|
|
20715
|
-
depth: 1,
|
|
20716
|
-
tags: false,
|
|
20717
|
-
onProgress: installer ? (e) => {
|
|
20718
|
-
const ratio = e.total ? e.loaded / e.total : void 0;
|
|
20719
|
-
installer.progress({
|
|
20720
|
-
phase: e.phase,
|
|
20721
|
-
loaded: e.loaded,
|
|
20722
|
-
total: e.total,
|
|
20723
|
-
ratio
|
|
20724
|
-
});
|
|
20725
|
-
} : void 0,
|
|
20726
|
-
onMessage: installer ? (msg) => installer.message(msg.replace(/\n+$/g, "")) : void 0
|
|
20727
|
-
});
|
|
20728
|
-
} catch (err) {
|
|
20729
|
-
console.warn(`[launcher] fetch failed (${err.message}); using local state`);
|
|
20730
|
-
} finally {
|
|
20731
|
-
installer?.done("fetch");
|
|
20732
|
-
}
|
|
20733
|
-
}
|
|
20734
|
-
/**
|
|
20735
20457
|
* Resolve the latest commit on origin/<branch> whose
|
|
20736
20458
|
* `package.json#zenbu.host` satisfies the running .app's `hostVersion`,
|
|
20737
20459
|
* and check it out if HEAD isn't already there. Pure delegation to
|
|
@@ -20772,20 +20494,12 @@ async function resolveAndCheckout(dir, mirror, hostVersion, installer) {
|
|
|
20772
20494
|
});
|
|
20773
20495
|
}
|
|
20774
20496
|
async function ensureAppsDir(appsDir, mirror, hostVersion, installer) {
|
|
20775
|
-
if (isExistingClone(appsDir))
|
|
20776
|
-
|
|
20777
|
-
|
|
20778
|
-
|
|
20779
|
-
return;
|
|
20780
|
-
}
|
|
20781
|
-
await fetchTip(appsDir, mirror, installer);
|
|
20782
|
-
} else {
|
|
20783
|
-
if (existsSync(appsDir)) {
|
|
20784
|
-
const entries = await fsp.readdir(appsDir).catch(() => []);
|
|
20785
|
-
if (entries.length > 0) throw new Error(`[launcher] ${appsDir} exists and isn't a git working tree (has ${entries.length} entries). Move or delete it, then relaunch.`);
|
|
20786
|
-
}
|
|
20787
|
-
await cloneMirror(appsDir, mirror, installer);
|
|
20497
|
+
if (isExistingClone(appsDir)) return;
|
|
20498
|
+
if (existsSync(appsDir)) {
|
|
20499
|
+
const entries = await fsp.readdir(appsDir).catch(() => []);
|
|
20500
|
+
if (entries.length > 0) throw new Error(`[launcher] ${appsDir} exists and isn't a git working tree (has ${entries.length} entries). Move or delete it, then relaunch.`);
|
|
20788
20501
|
}
|
|
20502
|
+
await cloneMirror(appsDir, mirror, installer);
|
|
20789
20503
|
await resolveAndCheckout(appsDir, mirror, hostVersion, installer);
|
|
20790
20504
|
}
|
|
20791
20505
|
async function ensureDepsInstalled(appsDir, pm, installer) {
|
|
@@ -13,7 +13,7 @@ async function defaultServices() {
|
|
|
13
13
|
await import("../renderer-host-Cw38dSDe.mjs").then((n) => n.i);
|
|
14
14
|
await import("../window-DgB70qeZ.mjs").then((n) => n.n);
|
|
15
15
|
await import("../runtime-DYUONc3S.mjs").then((n) => n.h);
|
|
16
|
-
await import("../updater-
|
|
16
|
+
await import("../updater-C6mWMmb5.mjs").then((n) => n.n);
|
|
17
17
|
}
|
|
18
18
|
//#endregion
|
|
19
19
|
export { defaultServices };
|
package/dist/services/index.mjs
CHANGED
|
@@ -4,5 +4,5 @@ import { a as DbService, r as ViewRegistryService, s as HttpService, t as Render
|
|
|
4
4
|
import { n as MAIN_WINDOW_ID, t as BaseWindowService } from "../base-window-4P-fVvC_.mjs";
|
|
5
5
|
import { t as RpcService } from "../rpc-Dg9zwZ33.mjs";
|
|
6
6
|
import { t as WindowService } from "../window-DgB70qeZ.mjs";
|
|
7
|
-
import { t as UpdaterService } from "../updater-
|
|
7
|
+
import { t as UpdaterService } from "../updater-C6mWMmb5.mjs";
|
|
8
8
|
export { BaseWindowService, DbService, HttpService, MAIN_WINDOW_ID, ReloaderService, RendererHostService, RpcService, ServerService, UpdaterService, ViewRegistryService, WindowService };
|
|
@@ -94,10 +94,42 @@ function electronTargetVersion(appsDir) {
|
|
|
94
94
|
return "42.0.0";
|
|
95
95
|
}
|
|
96
96
|
}
|
|
97
|
-
|
|
97
|
+
/**
|
|
98
|
+
* Build the env used to spawn `pnpm install` (and friends) on first
|
|
99
|
+
* launch. The bundled toolchain (`<resourcesPath>/toolchain/`) holds
|
|
100
|
+
* `node` and `bun` binaries; we prepend that dir to PATH so dependency
|
|
101
|
+
* install hooks with `#!/usr/bin/env node` shebangs (`@parcel/watcher`,
|
|
102
|
+
* `dugite`, etc.) resolve to the bundled node regardless of how the
|
|
103
|
+
* .app was launched.
|
|
104
|
+
*
|
|
105
|
+
* GUI launches (Finder, Raycast, Spotlight, `open <app>`) inherit a
|
|
106
|
+
* stripped PATH like `/usr/bin:/bin:/usr/sbin:/sbin`, so without this
|
|
107
|
+
* prepend the lifecycle scripts crash with `node: command not found`.
|
|
108
|
+
* We also baseline-merge the standard system bin dirs in case the
|
|
109
|
+
* inherited PATH lacks them entirely.
|
|
110
|
+
*/
|
|
111
|
+
function buildInstallEnv(appsDir, resourcesPath) {
|
|
98
112
|
const target = electronTargetVersion(appsDir);
|
|
113
|
+
const sep = process.platform === "win32" ? ";" : ":";
|
|
114
|
+
const baselinePath = process.env.PATH ?? process.env.Path ?? "";
|
|
115
|
+
const toolchainDir = resourcesPath ? path.join(resourcesPath, "toolchain") : null;
|
|
116
|
+
const systemDirs = process.platform === "win32" ? [] : [
|
|
117
|
+
"/usr/local/bin",
|
|
118
|
+
"/usr/bin",
|
|
119
|
+
"/bin",
|
|
120
|
+
"/usr/sbin",
|
|
121
|
+
"/sbin"
|
|
122
|
+
];
|
|
123
|
+
const segments = [];
|
|
124
|
+
if (toolchainDir) segments.push(toolchainDir);
|
|
125
|
+
if (baselinePath) segments.push(...baselinePath.split(sep));
|
|
126
|
+
segments.push(...systemDirs);
|
|
127
|
+
const seen = /* @__PURE__ */ new Set();
|
|
128
|
+
const PATH = segments.filter((s) => s && !seen.has(s) && seen.add(s)).join(sep);
|
|
99
129
|
return {
|
|
100
130
|
...process.env,
|
|
131
|
+
PATH,
|
|
132
|
+
Path: PATH,
|
|
101
133
|
CI: "true",
|
|
102
134
|
HOME: path.join(appsDir, ".zenbu", ".node-gyp"),
|
|
103
135
|
npm_config_runtime: "electron",
|
|
@@ -208,7 +240,7 @@ function spawnInstall(args) {
|
|
|
208
240
|
}
|
|
209
241
|
async function runInstall(opts) {
|
|
210
242
|
const { appsDir, resourcesPath, pm, reporter = null, signal } = opts;
|
|
211
|
-
const env = buildInstallEnv(appsDir);
|
|
243
|
+
const env = buildInstallEnv(appsDir, resourcesPath);
|
|
212
244
|
const entry = bundledPmEntry(pm, resourcesPath);
|
|
213
245
|
switch (pm.type) {
|
|
214
246
|
case "pnpm": {
|