@penvhq/launcher 0.9.5 → 0.11.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.
- package/dist/bin.cjs +325 -54
- package/dist/bin.cjs.map +1 -1
- package/dist/bin.js +1 -1
- package/dist/{chunk-4YZYBC5T.js → chunk-USYQEKPW.js} +349 -59
- package/dist/chunk-USYQEKPW.js.map +1 -0
- package/dist/index.cjs +349 -62
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +147 -49
- package/dist/index.d.ts +147 -49
- package/dist/index.js +23 -7
- package/package.json +3 -3
- package/dist/chunk-4YZYBC5T.js.map +0 -1
package/dist/bin.cjs
CHANGED
|
@@ -53,12 +53,17 @@ var import_core2 = require("@penvhq/core");
|
|
|
53
53
|
// src/errors.ts
|
|
54
54
|
var import_core = require("@penvhq/core");
|
|
55
55
|
var INSTALL_COMMAND = "penv install";
|
|
56
|
+
var UPGRADE_COMMAND = "penv upgrade";
|
|
57
|
+
var YES_FLAG = "--yes";
|
|
56
58
|
var MIN_PACKAGE_AGE_DAYS = 7;
|
|
57
59
|
var TRUST_YOUNG_FLAG = "--trust-young";
|
|
58
60
|
function addCommand(name, version, extra) {
|
|
59
61
|
const spec = version === void 0 ? name : `${name}@${version}`;
|
|
60
62
|
return `penv add ${spec}${extra === void 0 ? "" : ` ${extra}`}`;
|
|
61
63
|
}
|
|
64
|
+
function addCommandFor(name, local) {
|
|
65
|
+
return local ? `penv add ${LOCAL_FLAG} ${name}` : addCommand(name);
|
|
66
|
+
}
|
|
62
67
|
var NoProjectError = class extends import_core.PenvError {
|
|
63
68
|
name = "NoProjectError";
|
|
64
69
|
constructor(cwd) {
|
|
@@ -170,6 +175,26 @@ var AddLocalFlagError = class extends import_core.PenvError {
|
|
|
170
175
|
);
|
|
171
176
|
}
|
|
172
177
|
};
|
|
178
|
+
var ExtensionNotImportableError = class extends import_core.PenvError {
|
|
179
|
+
name = "ExtensionNotImportableError";
|
|
180
|
+
constructor(name, entry, local) {
|
|
181
|
+
super(
|
|
182
|
+
"PENV_EXTENSION_NOT_IMPORTABLE",
|
|
183
|
+
entry === void 0 ? `${name} declares no entry point penv can import` : `${name} resolves to ${entry}, which penv cannot import`,
|
|
184
|
+
`penv imports a provider with no transform, so its entry has to be built JavaScript. Point the package's \`exports\` at its build output \u2014 \`dist/index.js\` \u2014 then run \`${addCommandFor(name, local)}\` again.`
|
|
185
|
+
);
|
|
186
|
+
}
|
|
187
|
+
};
|
|
188
|
+
var ExtensionUnloadableError = class extends import_core.PenvError {
|
|
189
|
+
name = "ExtensionUnloadableError";
|
|
190
|
+
constructor(name, entry, detail, local) {
|
|
191
|
+
super(
|
|
192
|
+
"PENV_EXTENSION_UNLOADABLE",
|
|
193
|
+
`${name} threw while penv imported ${entry}: ${detail}`,
|
|
194
|
+
`Build the package and install its dependencies, then run \`${addCommandFor(name, local)}\` again. penv adds a provider it has loaded once, or none.`
|
|
195
|
+
);
|
|
196
|
+
}
|
|
197
|
+
};
|
|
173
198
|
var LocalExtensionUnresolvedError = class extends import_core.PenvError {
|
|
174
199
|
name = "LocalExtensionUnresolvedError";
|
|
175
200
|
constructor(name, root) {
|
|
@@ -212,11 +237,11 @@ var OfficialRegistryError = class extends import_core.PenvError {
|
|
|
212
237
|
};
|
|
213
238
|
var RegistryUnreadableError = class extends import_core.PenvError {
|
|
214
239
|
name = "RegistryUnreadableError";
|
|
215
|
-
constructor(name, url, detail) {
|
|
240
|
+
constructor(name, url, detail, retry = addCommand(name)) {
|
|
216
241
|
super(
|
|
217
242
|
"PENV_REGISTRY_UNREADABLE",
|
|
218
243
|
`Reading ${name} from ${url} failed: ${detail}`,
|
|
219
|
-
`Run \`${
|
|
244
|
+
`Run \`${retry}\` again when the registry is reachable.`
|
|
220
245
|
);
|
|
221
246
|
}
|
|
222
247
|
};
|
|
@@ -232,11 +257,11 @@ var PackageUnknownError = class extends import_core.PenvError {
|
|
|
232
257
|
};
|
|
233
258
|
var VersionUnknownError = class extends import_core.PenvError {
|
|
234
259
|
name = "VersionUnknownError";
|
|
235
|
-
constructor(name, version, url) {
|
|
260
|
+
constructor(name, version, url, retry = addCommand(name)) {
|
|
236
261
|
super(
|
|
237
262
|
"PENV_VERSION_UNKNOWN",
|
|
238
263
|
`${url} publishes no ${version} of ${name}`,
|
|
239
|
-
`Run \`${
|
|
264
|
+
`Run \`${retry}\` to take the version \`latest\` points at.`
|
|
240
265
|
);
|
|
241
266
|
}
|
|
242
267
|
};
|
|
@@ -361,6 +386,66 @@ var EnginePinMismatchError = class extends import_core.PenvError {
|
|
|
361
386
|
);
|
|
362
387
|
}
|
|
363
388
|
};
|
|
389
|
+
var UpgradeSubjectError = class extends import_core.PenvError {
|
|
390
|
+
name = "UpgradeSubjectError";
|
|
391
|
+
constructor() {
|
|
392
|
+
super(
|
|
393
|
+
"PENV_UPGRADE_SUBJECT",
|
|
394
|
+
"`penv upgrade` takes one version, or none",
|
|
395
|
+
`Run \`${UPGRADE_COMMAND}\` to move to whatever \`latest\` points at, or \`${UPGRADE_COMMAND} 0.9.6\` to move to an exact release.`
|
|
396
|
+
);
|
|
397
|
+
}
|
|
398
|
+
};
|
|
399
|
+
var UpgradeFlagError = class extends import_core.PenvError {
|
|
400
|
+
name = "UpgradeFlagError";
|
|
401
|
+
constructor(flag) {
|
|
402
|
+
super(
|
|
403
|
+
"PENV_UPGRADE_FLAG",
|
|
404
|
+
`\`${UPGRADE_COMMAND}\` does not understand \`${flag}\``,
|
|
405
|
+
`Run \`${UPGRADE_COMMAND} [version]\` with \`${YES_FLAG}\` \u2014 that is the one flag it takes.`
|
|
406
|
+
);
|
|
407
|
+
}
|
|
408
|
+
};
|
|
409
|
+
var UpgradeNoDownloadError = class extends import_core.PenvError {
|
|
410
|
+
name = "UpgradeNoDownloadError";
|
|
411
|
+
constructor() {
|
|
412
|
+
super(
|
|
413
|
+
"PENV_UPGRADE_NO_DOWNLOAD",
|
|
414
|
+
`Upgrading means reading the registry for the version and integrity to pin, and \`--no-download\` says this run does not`,
|
|
415
|
+
`Run \`${UPGRADE_COMMAND}\` without \`--no-download\`. Nothing was fetched or written.`
|
|
416
|
+
);
|
|
417
|
+
}
|
|
418
|
+
};
|
|
419
|
+
var UpgradeUnattendedError = class extends import_core.PenvError {
|
|
420
|
+
name = "UpgradeUnattendedError";
|
|
421
|
+
constructor() {
|
|
422
|
+
super(
|
|
423
|
+
"PENV_UPGRADE_UNATTENDED",
|
|
424
|
+
`Upgrading rewrites ${import_core.MANIFEST_PATH} and package.json, and this run has nobody to decide that`,
|
|
425
|
+
`Run \`${UPGRADE_COMMAND} <version> ${YES_FLAG}\` \u2014 unattended, penv moves the pin only to a version you named. In CI, run \`${INSTALL_COMMAND}\`: it installs what the committed manifest already pins.`
|
|
426
|
+
);
|
|
427
|
+
}
|
|
428
|
+
};
|
|
429
|
+
var UpgradeDeclinedError = class extends import_core.PenvError {
|
|
430
|
+
name = "UpgradeDeclinedError";
|
|
431
|
+
constructor(version) {
|
|
432
|
+
super(
|
|
433
|
+
"PENV_UPGRADE_DECLINED",
|
|
434
|
+
`${import_core.ENGINE_PACKAGE} ${version} was not installed, so ${import_core.MANIFEST_PATH} and package.json are unchanged`,
|
|
435
|
+
`Run \`${UPGRADE_COMMAND} ${version}\` again when you want both of them to move.`
|
|
436
|
+
);
|
|
437
|
+
}
|
|
438
|
+
};
|
|
439
|
+
var UpgradeInstallFailedError = class extends import_core.PenvError {
|
|
440
|
+
name = "UpgradeInstallFailedError";
|
|
441
|
+
constructor(command) {
|
|
442
|
+
super(
|
|
443
|
+
"PENV_UPGRADE_INSTALL_FAILED",
|
|
444
|
+
`${command} did not finish, so ${import_core.MANIFEST_PATH} still pins the engine it pinned before`,
|
|
445
|
+
`Run \`${command}\` yourself, then run \`${UPGRADE_COMMAND}\` again \u2014 the pin and the dependency move together or not at all.`
|
|
446
|
+
);
|
|
447
|
+
}
|
|
448
|
+
};
|
|
364
449
|
var EngineEntryError = class extends import_core.PenvError {
|
|
365
450
|
name = "EngineEntryError";
|
|
366
451
|
constructor(name, version, dir) {
|
|
@@ -437,14 +522,15 @@ function httpFetcher() {
|
|
|
437
522
|
}
|
|
438
523
|
|
|
439
524
|
// src/launcher.ts
|
|
440
|
-
var
|
|
525
|
+
var import_node_fs8 = require("fs");
|
|
441
526
|
var import_node_path7 = require("path");
|
|
442
|
-
var
|
|
527
|
+
var import_core11 = require("@penvhq/core");
|
|
443
528
|
|
|
444
529
|
// src/add.ts
|
|
445
530
|
var import_node_fs5 = require("fs");
|
|
446
531
|
var import_node_module2 = require("module");
|
|
447
532
|
var import_node_path5 = require("path");
|
|
533
|
+
var import_node_url = require("url");
|
|
448
534
|
var import_core6 = require("@penvhq/core");
|
|
449
535
|
|
|
450
536
|
// src/config-edit.ts
|
|
@@ -714,35 +800,14 @@ function writeDeclaration(options) {
|
|
|
714
800
|
// src/store.ts
|
|
715
801
|
var import_node_fs4 = require("fs");
|
|
716
802
|
var import_node_path4 = require("path");
|
|
803
|
+
var import_core4 = require("@penvhq/core");
|
|
717
804
|
|
|
718
805
|
// src/home.ts
|
|
719
806
|
var import_node_fs3 = require("fs");
|
|
720
|
-
var import_node_os2 = require("os");
|
|
721
807
|
var import_node_path3 = require("path");
|
|
722
|
-
var import_core4 = require("@penvhq/core");
|
|
723
|
-
var PENV_HOME_VAR = "PENV_HOME";
|
|
724
808
|
var HOME_META_FILE = "meta.json";
|
|
725
809
|
var INTEGRITY_FILE = ".penv-integrity";
|
|
726
810
|
var NPM_UPDATE_COMMAND = "npm install -g @penvhq/launcher";
|
|
727
|
-
function penvHome(env) {
|
|
728
|
-
const declared = env[PENV_HOME_VAR];
|
|
729
|
-
if (declared !== void 0 && declared.trim() !== "") {
|
|
730
|
-
return (0, import_node_path3.resolve)(declared);
|
|
731
|
-
}
|
|
732
|
-
return (0, import_node_path3.join)((0, import_node_os2.homedir)(), ".penv");
|
|
733
|
-
}
|
|
734
|
-
function packageDir(home, kind, name, version) {
|
|
735
|
-
const bucket = (0, import_node_path3.resolve)(home, kind);
|
|
736
|
-
const dir = (0, import_node_path3.resolve)(bucket, ...name.split("/"), version);
|
|
737
|
-
if (!dir.startsWith(bucket + import_node_path3.sep)) {
|
|
738
|
-
throw new import_core4.PenvError(
|
|
739
|
-
"PENV_HOME_ESCAPE",
|
|
740
|
-
`\`${name}\` at \`${version}\` resolves to ${dir}, which is outside ${bucket}`,
|
|
741
|
-
"Name the package exactly as npm does, e.g. `@penvhq/provider-vault`."
|
|
742
|
-
);
|
|
743
|
-
}
|
|
744
|
-
return dir;
|
|
745
|
-
}
|
|
746
811
|
function launcherUpdateCommand(home) {
|
|
747
812
|
let meta;
|
|
748
813
|
try {
|
|
@@ -844,7 +909,7 @@ function tarballUrl(pin) {
|
|
|
844
909
|
return `${registry}/${pin.name}/-/${basename}-${pin.version}.tgz`;
|
|
845
910
|
}
|
|
846
911
|
function inspectInstall(home, kind, pin) {
|
|
847
|
-
const dir = packageDir(home, kind, pin.name, pin.version);
|
|
912
|
+
const dir = (0, import_core4.packageDir)(home, kind, pin.name, pin.version);
|
|
848
913
|
if (!(0, import_node_fs4.existsSync)(dir)) {
|
|
849
914
|
return { dir, state: "absent" };
|
|
850
915
|
}
|
|
@@ -858,7 +923,7 @@ function inspectInstall(home, kind, pin) {
|
|
|
858
923
|
}
|
|
859
924
|
async function installPin(options) {
|
|
860
925
|
const { home, kind, pin, fetcher } = options;
|
|
861
|
-
const dir = packageDir(home, kind, pin.name, pin.version);
|
|
926
|
+
const dir = (0, import_core4.packageDir)(home, kind, pin.name, pin.version);
|
|
862
927
|
const url = tarballUrl(pin);
|
|
863
928
|
let bytes;
|
|
864
929
|
try {
|
|
@@ -923,7 +988,8 @@ async function fetchRelease(query) {
|
|
|
923
988
|
throw new RegistryUnreadableError(
|
|
924
989
|
query.name,
|
|
925
990
|
url,
|
|
926
|
-
cause instanceof Error ? cause.message : String(cause)
|
|
991
|
+
cause instanceof Error ? cause.message : String(cause),
|
|
992
|
+
query.retry
|
|
927
993
|
);
|
|
928
994
|
}
|
|
929
995
|
let parsed;
|
|
@@ -933,7 +999,8 @@ async function fetchRelease(query) {
|
|
|
933
999
|
throw new RegistryUnreadableError(
|
|
934
1000
|
query.name,
|
|
935
1001
|
url,
|
|
936
|
-
cause instanceof Error ? cause.message : String(cause)
|
|
1002
|
+
cause instanceof Error ? cause.message : String(cause),
|
|
1003
|
+
query.retry
|
|
937
1004
|
);
|
|
938
1005
|
}
|
|
939
1006
|
const packument = record(parsed);
|
|
@@ -949,7 +1016,7 @@ async function fetchRelease(query) {
|
|
|
949
1016
|
const version = record(at(versions, asked)) === void 0 ? text3(at(tags, asked)) ?? asked : asked;
|
|
950
1017
|
const release = record(at(versions, version));
|
|
951
1018
|
if (release === void 0) {
|
|
952
|
-
throw new VersionUnknownError(query.name, asked, url);
|
|
1019
|
+
throw new VersionUnknownError(query.name, asked, url, query.retry);
|
|
953
1020
|
}
|
|
954
1021
|
const dist = record(at(release, "dist"));
|
|
955
1022
|
const integrity = text3(at(dist, "integrity"));
|
|
@@ -1231,6 +1298,26 @@ function resolvePackageDir(name, root) {
|
|
|
1231
1298
|
return void 0;
|
|
1232
1299
|
}
|
|
1233
1300
|
}
|
|
1301
|
+
function resolveProjectEntry(name, root) {
|
|
1302
|
+
let file;
|
|
1303
|
+
try {
|
|
1304
|
+
file = (0, import_node_module2.createRequire)((0, import_node_path5.resolve)(root, "noop.js")).resolve(name);
|
|
1305
|
+
} catch {
|
|
1306
|
+
return void 0;
|
|
1307
|
+
}
|
|
1308
|
+
return { file, importable: (0, import_core6.isImportableEntry)(file) };
|
|
1309
|
+
}
|
|
1310
|
+
async function assertLoadable(name, entry, local) {
|
|
1311
|
+
if (entry === void 0 || !entry.importable) {
|
|
1312
|
+
throw new ExtensionNotImportableError(name, entry?.file, local);
|
|
1313
|
+
}
|
|
1314
|
+
try {
|
|
1315
|
+
await import((0, import_node_url.pathToFileURL)(entry.file).href);
|
|
1316
|
+
} catch (cause) {
|
|
1317
|
+
const detail = cause instanceof Error ? cause.message : String(cause);
|
|
1318
|
+
throw new ExtensionUnloadableError(name, entry.file, detail, local);
|
|
1319
|
+
}
|
|
1320
|
+
}
|
|
1234
1321
|
function recordLocalExtension(root, name) {
|
|
1235
1322
|
const file = (0, import_core6.localExtensionsFile)(root);
|
|
1236
1323
|
let current;
|
|
@@ -1251,6 +1338,7 @@ async function addLocal(options, request) {
|
|
|
1251
1338
|
if (dir === void 0) {
|
|
1252
1339
|
throw new LocalExtensionUnresolvedError(request.name, root);
|
|
1253
1340
|
}
|
|
1341
|
+
await assertLoadable(request.name, resolveProjectEntry(request.name, root), true);
|
|
1254
1342
|
const installed = readExtensionPackage(dir);
|
|
1255
1343
|
const declaration = writeDeclaration({
|
|
1256
1344
|
root,
|
|
@@ -1262,7 +1350,7 @@ async function addLocal(options, request) {
|
|
|
1262
1350
|
types: installed.types
|
|
1263
1351
|
});
|
|
1264
1352
|
recordLocalExtension(root, request.name);
|
|
1265
|
-
io2.out(`\u2713 ${request.name} resolves from this project \u2014 nothing is pinned`);
|
|
1353
|
+
io2.out(`\u2713 ${request.name} resolves from this project and imports \u2014 nothing is pinned`);
|
|
1266
1354
|
io2.out(`\u2713 ${import_core6.LOCAL_EXTENSIONS_PATH} records it`);
|
|
1267
1355
|
io2.out(`\u2713 ${declaration} declares its config type`);
|
|
1268
1356
|
await offerConfigEdit(options, request.name);
|
|
@@ -1307,6 +1395,7 @@ async function add(options) {
|
|
|
1307
1395
|
},
|
|
1308
1396
|
fetcher
|
|
1309
1397
|
});
|
|
1398
|
+
await assertLoadable(release.name, (0, import_core6.packageEntry)(dir), false);
|
|
1310
1399
|
const installed = readExtensionPackage(dir);
|
|
1311
1400
|
const declaration = writeDeclaration({
|
|
1312
1401
|
root,
|
|
@@ -1325,14 +1414,59 @@ async function add(options) {
|
|
|
1325
1414
|
return { onboard: await offerOnboarding(io2, release.name, installed.onboard) };
|
|
1326
1415
|
}
|
|
1327
1416
|
|
|
1328
|
-
// src/
|
|
1417
|
+
// src/help.ts
|
|
1418
|
+
var import_install = require("@penvhq/cli/install");
|
|
1329
1419
|
var import_core7 = require("@penvhq/core");
|
|
1420
|
+
function printLauncherCommands(io2) {
|
|
1421
|
+
io2.out("");
|
|
1422
|
+
io2.out("LAUNCHER COMMANDS (penv itself, whatever engine a project pins)");
|
|
1423
|
+
io2.out("");
|
|
1424
|
+
io2.out(` install Installs everything ${import_core7.MANIFEST_PATH} pins`);
|
|
1425
|
+
io2.out(" add <package> Pins a provider extension, and commits the decision");
|
|
1426
|
+
io2.out(` add ${LOCAL_FLAG} <package> Adds the one this repository builds \u2014 nothing is pinned`);
|
|
1427
|
+
io2.out(` upgrade [version] Moves the engine pin and ${import_install.RUNTIME_PACKAGE} together`);
|
|
1428
|
+
io2.out("");
|
|
1429
|
+
}
|
|
1430
|
+
function printInstallHelp(io2) {
|
|
1431
|
+
io2.out(`${INSTALL_COMMAND}`);
|
|
1432
|
+
io2.out("");
|
|
1433
|
+
io2.out(`Downloads, verifies and installs every version ${import_core7.MANIFEST_PATH} pins \u2014 the engine and`);
|
|
1434
|
+
io2.out("every extension \u2014 into $PENV_HOME. The one penv command CI and production run that");
|
|
1435
|
+
io2.out("may reach the registry.");
|
|
1436
|
+
}
|
|
1437
|
+
function printAddHelp(io2) {
|
|
1438
|
+
io2.out("penv add <package>[@<version>]");
|
|
1439
|
+
io2.out("");
|
|
1440
|
+
io2.out(` ${LOCAL_FLAG} Add the package this repository builds, resolved from it`);
|
|
1441
|
+
io2.out(" --registry <url> Take the release from a private registry instead of npmjs");
|
|
1442
|
+
io2.out(
|
|
1443
|
+
` ${TRUST_YOUNG_FLAG} Add a release published less than ${MIN_PACKAGE_AGE_DAYS} days ago`
|
|
1444
|
+
);
|
|
1445
|
+
io2.out("");
|
|
1446
|
+
io2.out(`Pins the release in ${import_core7.MANIFEST_PATH} and writes its type declaration to`);
|
|
1447
|
+
io2.out(`${import_core7.EXTENSIONS_PATH}/. Both are committed, so \`${INSTALL_COMMAND}\` gives every machine`);
|
|
1448
|
+
io2.out(`the bytes you reviewed. \`${LOCAL_FLAG}\` pins nothing and touches no manifest.`);
|
|
1449
|
+
}
|
|
1450
|
+
function printUpgradeHelp(io2) {
|
|
1451
|
+
io2.out("penv upgrade [version]");
|
|
1452
|
+
io2.out("");
|
|
1453
|
+
io2.out(` ${YES_FLAG} Skip the question \u2014 unattended runs need it and a version`);
|
|
1454
|
+
io2.out("");
|
|
1455
|
+
io2.out(`Moves the ${import_core7.ENGINE_PACKAGE} pin in ${import_core7.MANIFEST_PATH} and this project's`);
|
|
1456
|
+
io2.out(`${import_install.RUNTIME_PACKAGE} dependency to the same exact version. No version takes whatever`);
|
|
1457
|
+
io2.out("`latest` points at; the integrity is the one the registry states, never one penv");
|
|
1458
|
+
io2.out("computed. Both files are shown before either moves, and they move together or not");
|
|
1459
|
+
io2.out("at all. Extensions keep their own pins.");
|
|
1460
|
+
}
|
|
1461
|
+
|
|
1462
|
+
// src/pins.ts
|
|
1463
|
+
var import_core8 = require("@penvhq/core");
|
|
1330
1464
|
var DEV_PIN_INTEGRITY = "sha512-development-build-not-a-published-release";
|
|
1331
1465
|
var DEV_PIN_VERSION = "0.0.0-dev";
|
|
1332
1466
|
var BUNDLED_ENGINE_PIN = {
|
|
1333
|
-
package:
|
|
1334
|
-
version: "0.
|
|
1335
|
-
integrity: "sha512-
|
|
1467
|
+
package: import_core8.ENGINE_PACKAGE,
|
|
1468
|
+
version: "0.11.0",
|
|
1469
|
+
integrity: "sha512-Y+WKyuPsX4U8/1j0e+VMUhj0LaGrp67YEoDAWyyinrgA+c8IM4H1blqje/YK4LsQwzQDQQDF9bhWIhfmDAWoxA=="
|
|
1336
1470
|
};
|
|
1337
1471
|
function assertReleasePin(pin) {
|
|
1338
1472
|
if (pin.integrity === DEV_PIN_INTEGRITY || pin.version === DEV_PIN_VERSION) {
|
|
@@ -1350,8 +1484,8 @@ function releaseEnginePin(pin, ranVersion) {
|
|
|
1350
1484
|
// src/project.ts
|
|
1351
1485
|
var import_node_fs6 = require("fs");
|
|
1352
1486
|
var import_node_path6 = require("path");
|
|
1353
|
-
var
|
|
1354
|
-
var MANIFEST_SEGMENTS =
|
|
1487
|
+
var import_core9 = require("@penvhq/core");
|
|
1488
|
+
var MANIFEST_SEGMENTS = import_core9.MANIFEST_PATH.split("/");
|
|
1355
1489
|
function findUp(cwd, matches) {
|
|
1356
1490
|
let dir = (0, import_node_path6.resolve)(cwd);
|
|
1357
1491
|
for (; ; ) {
|
|
@@ -1370,12 +1504,113 @@ function findProject(cwd) {
|
|
|
1370
1504
|
return root === void 0 ? void 0 : { root, manifestFile: (0, import_node_path6.join)(root, ...MANIFEST_SEGMENTS) };
|
|
1371
1505
|
}
|
|
1372
1506
|
function findAdoptedRoot(cwd) {
|
|
1373
|
-
return findUp(cwd, (dir) => (0, import_node_fs6.existsSync)((0,
|
|
1507
|
+
return findUp(cwd, (dir) => (0, import_node_fs6.existsSync)((0, import_core9.stateDir)(dir)));
|
|
1508
|
+
}
|
|
1509
|
+
|
|
1510
|
+
// src/upgrade.ts
|
|
1511
|
+
var import_node_fs7 = require("fs");
|
|
1512
|
+
var import_install2 = require("@penvhq/cli/install");
|
|
1513
|
+
var import_core10 = require("@penvhq/core");
|
|
1514
|
+
function parseRequest2(argv) {
|
|
1515
|
+
let version;
|
|
1516
|
+
let yes = false;
|
|
1517
|
+
for (const token of argv) {
|
|
1518
|
+
if (token === YES_FLAG) {
|
|
1519
|
+
yes = true;
|
|
1520
|
+
continue;
|
|
1521
|
+
}
|
|
1522
|
+
if (token.startsWith("-")) {
|
|
1523
|
+
throw new UpgradeFlagError(token);
|
|
1524
|
+
}
|
|
1525
|
+
if (version !== void 0 || token === "") {
|
|
1526
|
+
throw new UpgradeSubjectError();
|
|
1527
|
+
}
|
|
1528
|
+
version = token;
|
|
1529
|
+
}
|
|
1530
|
+
return { version, yes };
|
|
1531
|
+
}
|
|
1532
|
+
function renderPinChange(engine, release) {
|
|
1533
|
+
return [
|
|
1534
|
+
import_core10.MANIFEST_PATH,
|
|
1535
|
+
` - "integrity": "${engine.integrity}"`,
|
|
1536
|
+
` - "version": "${engine.version}"`,
|
|
1537
|
+
` + "integrity": "${release.integrity}"`,
|
|
1538
|
+
` + "version": "${release.version}"`
|
|
1539
|
+
];
|
|
1540
|
+
}
|
|
1541
|
+
function pinnedElsewhere(manifest, version) {
|
|
1542
|
+
return Object.entries(manifest.extensions).filter(([, entry]) => entry.version !== version).map(([name]) => name);
|
|
1543
|
+
}
|
|
1544
|
+
async function consent(options, release, plan, yes) {
|
|
1545
|
+
const { io: io2, manifest } = options;
|
|
1546
|
+
io2.out(`${import_core10.ENGINE_PACKAGE} ${manifest.engine.version} \u2192 ${release.version}`);
|
|
1547
|
+
io2.out("");
|
|
1548
|
+
for (const line of renderPinChange(manifest.engine, release)) {
|
|
1549
|
+
io2.out(line);
|
|
1550
|
+
}
|
|
1551
|
+
for (const line of (0, import_install2.renderInstallPlan)(plan)) {
|
|
1552
|
+
io2.out(line);
|
|
1553
|
+
}
|
|
1554
|
+
if (yes) {
|
|
1555
|
+
return;
|
|
1556
|
+
}
|
|
1557
|
+
if (!await io2.confirm(`Move this project to ${release.version}?`)) {
|
|
1558
|
+
throw new UpgradeDeclinedError(release.version);
|
|
1559
|
+
}
|
|
1560
|
+
}
|
|
1561
|
+
async function upgrade(options) {
|
|
1562
|
+
const { io: io2, fetcher, home, root, manifest, manifestFile } = options;
|
|
1563
|
+
const request = parseRequest2(options.argv);
|
|
1564
|
+
if (options.noDownload === true) {
|
|
1565
|
+
throw new UpgradeNoDownloadError();
|
|
1566
|
+
}
|
|
1567
|
+
if ((options.ci === true || !io2.interactive) && !(request.yes && request.version !== void 0)) {
|
|
1568
|
+
throw new UpgradeUnattendedError();
|
|
1569
|
+
}
|
|
1570
|
+
const release = await fetchRelease({
|
|
1571
|
+
name: import_core10.ENGINE_PACKAGE,
|
|
1572
|
+
...request.version === void 0 ? {} : { version: request.version },
|
|
1573
|
+
retry: UPGRADE_COMMAND,
|
|
1574
|
+
fetcher
|
|
1575
|
+
});
|
|
1576
|
+
const plan = (0, import_install2.planInstall)(root, release.version);
|
|
1577
|
+
if (manifest.engine.version === release.version && plan.satisfied) {
|
|
1578
|
+
io2.out(`\u2713 Already on ${import_core10.ENGINE_PACKAGE} ${release.version} \u2014 nothing to move`);
|
|
1579
|
+
return;
|
|
1580
|
+
}
|
|
1581
|
+
const manifestText = (0, import_core10.serializeManifest)({
|
|
1582
|
+
...manifest,
|
|
1583
|
+
engine: { package: import_core10.ENGINE_PACKAGE, version: release.version, integrity: release.integrity }
|
|
1584
|
+
});
|
|
1585
|
+
await consent(options, release, plan, request.yes);
|
|
1586
|
+
await installPin({
|
|
1587
|
+
home,
|
|
1588
|
+
kind: "engines",
|
|
1589
|
+
pin: { name: import_core10.ENGINE_PACKAGE, version: release.version, integrity: release.integrity },
|
|
1590
|
+
fetcher
|
|
1591
|
+
});
|
|
1592
|
+
io2.out(`\u2713 ${import_core10.ENGINE_PACKAGE} ${release.version} installed`);
|
|
1593
|
+
if (!plan.satisfied) {
|
|
1594
|
+
try {
|
|
1595
|
+
await (options.install ?? import_install2.installWithPackageManager)(plan);
|
|
1596
|
+
} catch {
|
|
1597
|
+
throw new UpgradeInstallFailedError(plan.command.join(" "));
|
|
1598
|
+
}
|
|
1599
|
+
io2.out(`\u2713 package.json depends on ${import_install2.RUNTIME_PACKAGE} ${release.version}`);
|
|
1600
|
+
}
|
|
1601
|
+
(0, import_node_fs7.writeFileSync)(manifestFile, manifestText);
|
|
1602
|
+
io2.out(`\u2713 ${import_core10.MANIFEST_PATH} pins ${import_core10.ENGINE_PACKAGE} ${release.version}`);
|
|
1603
|
+
const kept = pinnedElsewhere(manifest, release.version);
|
|
1604
|
+
if (kept.length > 0) {
|
|
1605
|
+
const subject = kept.length === 1 ? "keeps its own pin" : "keep their own pins";
|
|
1606
|
+
io2.out(`\u2192 ${kept.join(", ")} ${subject} \u2014 \`penv add <package>@<version>\` moves one.`);
|
|
1607
|
+
}
|
|
1374
1608
|
}
|
|
1375
1609
|
|
|
1376
1610
|
// src/launcher.ts
|
|
1377
1611
|
var INSTALL = "install";
|
|
1378
1612
|
var ADD = "add";
|
|
1613
|
+
var UPGRADE = "upgrade";
|
|
1379
1614
|
var VERSION_FLAGS = /* @__PURE__ */ new Set(["--version", "-v"]);
|
|
1380
1615
|
var HELP_FLAGS = /* @__PURE__ */ new Set(["--help", "-h"]);
|
|
1381
1616
|
var NO_DOWNLOAD = "--no-download";
|
|
@@ -1419,27 +1654,27 @@ function pinsOf(manifest) {
|
|
|
1419
1654
|
];
|
|
1420
1655
|
}
|
|
1421
1656
|
function reportable(error, home, argv) {
|
|
1422
|
-
return error instanceof
|
|
1657
|
+
return error instanceof import_core11.UnsupportedManifestFormatError ? error.withLauncherUpdate({
|
|
1423
1658
|
updateCommand: launcherUpdateCommand(home),
|
|
1424
1659
|
invokedCommand: invokedCommand(argv)
|
|
1425
1660
|
}) : error;
|
|
1426
1661
|
}
|
|
1427
1662
|
function readManifest(manifestFile, home, argv) {
|
|
1428
1663
|
try {
|
|
1429
|
-
return (0,
|
|
1664
|
+
return (0, import_core11.parseManifest)((0, import_node_fs8.readFileSync)(manifestFile, "utf8"));
|
|
1430
1665
|
} catch (error) {
|
|
1431
1666
|
throw reportable(error, home, argv);
|
|
1432
1667
|
}
|
|
1433
1668
|
}
|
|
1434
1669
|
function readManifestToRepair(manifestFile, home, argv) {
|
|
1435
1670
|
try {
|
|
1436
|
-
return readManifestForRepair((0,
|
|
1671
|
+
return readManifestForRepair((0, import_node_fs8.readFileSync)(manifestFile, "utf8"));
|
|
1437
1672
|
} catch (error) {
|
|
1438
1673
|
throw reportable(error, home, argv);
|
|
1439
1674
|
}
|
|
1440
1675
|
}
|
|
1441
1676
|
function report(error, io2) {
|
|
1442
|
-
if (error instanceof
|
|
1677
|
+
if (error instanceof import_core11.PenvError && error.remedy !== void 0) {
|
|
1443
1678
|
const suffix = `
|
|
1444
1679
|
${error.remedy}`;
|
|
1445
1680
|
const message = error.message.endsWith(suffix) ? error.message.slice(0, -suffix.length) : error.message;
|
|
@@ -1461,7 +1696,21 @@ async function launch(options) {
|
|
|
1461
1696
|
const { argv, cwd, env, io: io2 } = options;
|
|
1462
1697
|
const { noDownload, forwarded } = splitLauncherFlags(argv);
|
|
1463
1698
|
const first = forwarded[0];
|
|
1464
|
-
const home = penvHome(env);
|
|
1699
|
+
const home = (0, import_core11.penvHome)(env);
|
|
1700
|
+
if (first !== void 0 && forwarded.slice(1).some((token) => HELP_FLAGS.has(token))) {
|
|
1701
|
+
if (first === INSTALL) {
|
|
1702
|
+
printInstallHelp(io2);
|
|
1703
|
+
return 0;
|
|
1704
|
+
}
|
|
1705
|
+
if (first === ADD) {
|
|
1706
|
+
printAddHelp(io2);
|
|
1707
|
+
return 0;
|
|
1708
|
+
}
|
|
1709
|
+
if (first === UPGRADE) {
|
|
1710
|
+
printUpgradeHelp(io2);
|
|
1711
|
+
return 0;
|
|
1712
|
+
}
|
|
1713
|
+
}
|
|
1465
1714
|
const project = findProject(cwd);
|
|
1466
1715
|
if (project === void 0) {
|
|
1467
1716
|
if (first !== void 0 && VERSION_FLAGS.has(first)) {
|
|
@@ -1488,6 +1737,20 @@ async function launch(options) {
|
|
|
1488
1737
|
io2.out(`penv ${manifest.engine.version}`);
|
|
1489
1738
|
return 0;
|
|
1490
1739
|
}
|
|
1740
|
+
if (first === UPGRADE) {
|
|
1741
|
+
await upgrade({
|
|
1742
|
+
argv: forwarded.slice(1),
|
|
1743
|
+
root: project.root,
|
|
1744
|
+
manifestFile: project.manifestFile,
|
|
1745
|
+
manifest,
|
|
1746
|
+
home,
|
|
1747
|
+
io: io2,
|
|
1748
|
+
fetcher: options.fetcher,
|
|
1749
|
+
noDownload,
|
|
1750
|
+
ci: isCi(env)
|
|
1751
|
+
});
|
|
1752
|
+
return 0;
|
|
1753
|
+
}
|
|
1491
1754
|
const enginePin = enginePinOf(manifest);
|
|
1492
1755
|
const engineDir = await ensure(options, "engines", enginePin, home, noDownload);
|
|
1493
1756
|
for (const pin of extensionPinsOf(manifest)) {
|
|
@@ -1506,16 +1769,16 @@ async function adopt(options, forwarded, home, cwd, noDownload) {
|
|
|
1506
1769
|
if (root === void 0) {
|
|
1507
1770
|
return 0;
|
|
1508
1771
|
}
|
|
1509
|
-
const manifestFile = (0, import_node_path7.join)(root, ...
|
|
1510
|
-
if ((0,
|
|
1772
|
+
const manifestFile = (0, import_node_path7.join)(root, ...import_core11.MANIFEST_PATH.split("/"));
|
|
1773
|
+
if ((0, import_node_fs8.existsSync)(manifestFile)) {
|
|
1511
1774
|
return 0;
|
|
1512
1775
|
}
|
|
1513
1776
|
const pin = releaseEnginePin(options.bundledPin, engine.version);
|
|
1514
|
-
(0,
|
|
1777
|
+
(0, import_node_fs8.writeFileSync)(
|
|
1515
1778
|
manifestFile,
|
|
1516
|
-
(0,
|
|
1779
|
+
(0, import_core11.serializeManifest)({ format: import_core11.MANIFEST_FORMAT, engine: pin, extensions: {} })
|
|
1517
1780
|
);
|
|
1518
|
-
options.io.out(`\u2713 ${
|
|
1781
|
+
options.io.out(`\u2713 ${import_core11.MANIFEST_PATH} pins ${pin.package} ${pin.version}`);
|
|
1519
1782
|
await ensureAdoptedEngine(
|
|
1520
1783
|
options,
|
|
1521
1784
|
{ name: pin.package, version: pin.version, integrity: pin.integrity },
|
|
@@ -1594,13 +1857,21 @@ async function addExtension(options, project, home, argv, noDownload) {
|
|
|
1594
1857
|
const engine = engineAt(dir, enginePin.name, enginePin.version);
|
|
1595
1858
|
return delegate(options, engine, onboard, home, options.cwd);
|
|
1596
1859
|
}
|
|
1597
|
-
function
|
|
1598
|
-
|
|
1860
|
+
function isRootHelp(forwarded) {
|
|
1861
|
+
const first = forwarded[0];
|
|
1862
|
+
return first === void 0 || HELP_FLAGS.has(first);
|
|
1863
|
+
}
|
|
1864
|
+
async function delegate(options, engine, forwarded, home, cwd) {
|
|
1865
|
+
const code = await options.spawn({
|
|
1599
1866
|
command: process.execPath,
|
|
1600
1867
|
args: [engine.entry, ...forwarded],
|
|
1601
1868
|
cwd,
|
|
1602
|
-
env: { ...options.env, [PENV_HOME_VAR]: home }
|
|
1869
|
+
env: { ...options.env, [import_core11.PENV_HOME_VAR]: home }
|
|
1603
1870
|
});
|
|
1871
|
+
if (code === 0 && isRootHelp(forwarded)) {
|
|
1872
|
+
printLauncherCommands(options.io);
|
|
1873
|
+
}
|
|
1874
|
+
return code;
|
|
1604
1875
|
}
|
|
1605
1876
|
|
|
1606
1877
|
// src/bin.ts
|