@penvhq/launcher 0.10.0 → 0.12.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 +298 -56
- package/dist/bin.cjs.map +1 -1
- package/dist/bin.js +1 -1
- package/dist/{chunk-BNUZ52VN.js → chunk-A5LJQPYS.js} +319 -62
- package/dist/chunk-A5LJQPYS.js.map +1 -0
- package/dist/index.cjs +318 -58
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +128 -18
- package/dist/index.d.ts +128 -18
- package/dist/index.js +21 -3
- package/package.json +9 -3
- package/dist/chunk-BNUZ52VN.js.map +0 -1
package/dist/bin.js
CHANGED
|
@@ -170,6 +170,8 @@ import {
|
|
|
170
170
|
PenvError
|
|
171
171
|
} from "@penvhq/core";
|
|
172
172
|
var INSTALL_COMMAND = "penv install";
|
|
173
|
+
var UPGRADE_COMMAND = "penv upgrade";
|
|
174
|
+
var YES_FLAG = "--yes";
|
|
173
175
|
var MIN_PACKAGE_AGE_DAYS = 7;
|
|
174
176
|
var TRUST_YOUNG_FLAG = "--trust-young";
|
|
175
177
|
function addCommand(name, version, extra) {
|
|
@@ -275,7 +277,7 @@ var AddFlagError = class extends PenvError {
|
|
|
275
277
|
super(
|
|
276
278
|
"PENV_ADD_FLAG",
|
|
277
279
|
`\`penv add\` does not understand \`${flag}\``,
|
|
278
|
-
`Run \`penv add <package>\` with \`${TRUST_YOUNG_FLAG}\`, \`--registry <url>\`, or \`${
|
|
280
|
+
`Run \`penv add <package>\` with \`${TRUST_YOUNG_FLAG}\`, \`--registry <url>\`, \`${LOCAL_FLAG}\`, or \`${YES_FLAG}\` \u2014 those are the four it takes.`
|
|
279
281
|
);
|
|
280
282
|
}
|
|
281
283
|
};
|
|
@@ -352,11 +354,11 @@ var OfficialRegistryError = class extends PenvError {
|
|
|
352
354
|
};
|
|
353
355
|
var RegistryUnreadableError = class extends PenvError {
|
|
354
356
|
name = "RegistryUnreadableError";
|
|
355
|
-
constructor(name, url, detail) {
|
|
357
|
+
constructor(name, url, detail, retry = addCommand(name)) {
|
|
356
358
|
super(
|
|
357
359
|
"PENV_REGISTRY_UNREADABLE",
|
|
358
360
|
`Reading ${name} from ${url} failed: ${detail}`,
|
|
359
|
-
`Run \`${
|
|
361
|
+
`Run \`${retry}\` again when the registry is reachable.`
|
|
360
362
|
);
|
|
361
363
|
}
|
|
362
364
|
};
|
|
@@ -372,11 +374,11 @@ var PackageUnknownError = class extends PenvError {
|
|
|
372
374
|
};
|
|
373
375
|
var VersionUnknownError = class extends PenvError {
|
|
374
376
|
name = "VersionUnknownError";
|
|
375
|
-
constructor(name, version, url) {
|
|
377
|
+
constructor(name, version, url, retry = addCommand(name)) {
|
|
376
378
|
super(
|
|
377
379
|
"PENV_VERSION_UNKNOWN",
|
|
378
380
|
`${url} publishes no ${version} of ${name}`,
|
|
379
|
-
`Run \`${
|
|
381
|
+
`Run \`${retry}\` to take the version \`latest\` points at.`
|
|
380
382
|
);
|
|
381
383
|
}
|
|
382
384
|
};
|
|
@@ -421,13 +423,13 @@ var AddNoDownloadError = class extends PenvError {
|
|
|
421
423
|
);
|
|
422
424
|
}
|
|
423
425
|
};
|
|
424
|
-
var
|
|
425
|
-
name = "
|
|
426
|
-
constructor(name) {
|
|
426
|
+
var AddTrustUnattendedError = class extends PenvError {
|
|
427
|
+
name = "AddTrustUnattendedError";
|
|
428
|
+
constructor(name, ceremony) {
|
|
427
429
|
super(
|
|
428
|
-
"
|
|
429
|
-
`Adding ${name}
|
|
430
|
-
`Run \`${addCommand(name)}\` from a terminal
|
|
430
|
+
"PENV_ADD_TRUST_UNATTENDED",
|
|
431
|
+
`Adding ${name} records ${ceremony}, and this run has nobody to write it`,
|
|
432
|
+
`Run \`${addCommand(name)}\` from a terminal, without \`${YES_FLAG}\` \u2014 the trust block is a line only a person can write. In CI, run \`${INSTALL_COMMAND}\`: it installs the versions the committed manifest already pins.`
|
|
431
433
|
);
|
|
432
434
|
}
|
|
433
435
|
};
|
|
@@ -501,6 +503,66 @@ var EnginePinMismatchError = class extends PenvError {
|
|
|
501
503
|
);
|
|
502
504
|
}
|
|
503
505
|
};
|
|
506
|
+
var UpgradeSubjectError = class extends PenvError {
|
|
507
|
+
name = "UpgradeSubjectError";
|
|
508
|
+
constructor() {
|
|
509
|
+
super(
|
|
510
|
+
"PENV_UPGRADE_SUBJECT",
|
|
511
|
+
"`penv upgrade` takes one version, or none",
|
|
512
|
+
`Run \`${UPGRADE_COMMAND}\` to move to whatever \`latest\` points at, or \`${UPGRADE_COMMAND} 0.9.6\` to move to an exact release.`
|
|
513
|
+
);
|
|
514
|
+
}
|
|
515
|
+
};
|
|
516
|
+
var UpgradeFlagError = class extends PenvError {
|
|
517
|
+
name = "UpgradeFlagError";
|
|
518
|
+
constructor(flag) {
|
|
519
|
+
super(
|
|
520
|
+
"PENV_UPGRADE_FLAG",
|
|
521
|
+
`\`${UPGRADE_COMMAND}\` does not understand \`${flag}\``,
|
|
522
|
+
`Run \`${UPGRADE_COMMAND} [version]\` with \`${YES_FLAG}\` \u2014 that is the one flag it takes.`
|
|
523
|
+
);
|
|
524
|
+
}
|
|
525
|
+
};
|
|
526
|
+
var UpgradeNoDownloadError = class extends PenvError {
|
|
527
|
+
name = "UpgradeNoDownloadError";
|
|
528
|
+
constructor() {
|
|
529
|
+
super(
|
|
530
|
+
"PENV_UPGRADE_NO_DOWNLOAD",
|
|
531
|
+
`Upgrading means reading the registry for the version and integrity to pin, and \`--no-download\` says this run does not`,
|
|
532
|
+
`Run \`${UPGRADE_COMMAND}\` without \`--no-download\`. Nothing was fetched or written.`
|
|
533
|
+
);
|
|
534
|
+
}
|
|
535
|
+
};
|
|
536
|
+
var UpgradeUnattendedError = class extends PenvError {
|
|
537
|
+
name = "UpgradeUnattendedError";
|
|
538
|
+
constructor() {
|
|
539
|
+
super(
|
|
540
|
+
"PENV_UPGRADE_UNATTENDED",
|
|
541
|
+
`Upgrading rewrites ${MANIFEST_PATH} and package.json, and this run has nobody to decide that`,
|
|
542
|
+
`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.`
|
|
543
|
+
);
|
|
544
|
+
}
|
|
545
|
+
};
|
|
546
|
+
var UpgradeDeclinedError = class extends PenvError {
|
|
547
|
+
name = "UpgradeDeclinedError";
|
|
548
|
+
constructor(version) {
|
|
549
|
+
super(
|
|
550
|
+
"PENV_UPGRADE_DECLINED",
|
|
551
|
+
`${ENGINE_PACKAGE} ${version} was not installed, so ${MANIFEST_PATH} and package.json are unchanged`,
|
|
552
|
+
`Run \`${UPGRADE_COMMAND} ${version}\` again when you want both of them to move.`
|
|
553
|
+
);
|
|
554
|
+
}
|
|
555
|
+
};
|
|
556
|
+
var UpgradeInstallFailedError = class extends PenvError {
|
|
557
|
+
name = "UpgradeInstallFailedError";
|
|
558
|
+
constructor(manager, version) {
|
|
559
|
+
super(
|
|
560
|
+
"PENV_UPGRADE_INSTALL_FAILED",
|
|
561
|
+
`${manager} did not finish moving this project to ${ENGINE_PACKAGE} ${version}, so ${MANIFEST_PATH} still pins the engine it pinned before`,
|
|
562
|
+
`Read what ${manager} printed above \u2014 it names what it refused. Fix that and run \`${UPGRADE_COMMAND} ${version}\` again; the pin and the dependency move together or not at all.`
|
|
563
|
+
);
|
|
564
|
+
}
|
|
565
|
+
};
|
|
504
566
|
var EngineEntryError = class extends PenvError {
|
|
505
567
|
name = "EngineEntryError";
|
|
506
568
|
constructor(name, version, dir) {
|
|
@@ -811,7 +873,8 @@ async function fetchRelease(query) {
|
|
|
811
873
|
throw new RegistryUnreadableError(
|
|
812
874
|
query.name,
|
|
813
875
|
url,
|
|
814
|
-
cause instanceof Error ? cause.message : String(cause)
|
|
876
|
+
cause instanceof Error ? cause.message : String(cause),
|
|
877
|
+
query.retry
|
|
815
878
|
);
|
|
816
879
|
}
|
|
817
880
|
let parsed;
|
|
@@ -821,7 +884,8 @@ async function fetchRelease(query) {
|
|
|
821
884
|
throw new RegistryUnreadableError(
|
|
822
885
|
query.name,
|
|
823
886
|
url,
|
|
824
|
-
cause instanceof Error ? cause.message : String(cause)
|
|
887
|
+
cause instanceof Error ? cause.message : String(cause),
|
|
888
|
+
query.retry
|
|
825
889
|
);
|
|
826
890
|
}
|
|
827
891
|
const packument = record(parsed);
|
|
@@ -837,7 +901,7 @@ async function fetchRelease(query) {
|
|
|
837
901
|
const version = record(at(versions, asked)) === void 0 ? text3(at(tags, asked)) ?? asked : asked;
|
|
838
902
|
const release = record(at(versions, version));
|
|
839
903
|
if (release === void 0) {
|
|
840
|
-
throw new VersionUnknownError(query.name, asked, url);
|
|
904
|
+
throw new VersionUnknownError(query.name, asked, url, query.retry);
|
|
841
905
|
}
|
|
842
906
|
const dist = record(at(release, "dist"));
|
|
843
907
|
const integrity = text3(at(dist, "integrity"));
|
|
@@ -939,12 +1003,17 @@ function parseRequest(argv) {
|
|
|
939
1003
|
let registry;
|
|
940
1004
|
let trustYoung = false;
|
|
941
1005
|
let local = false;
|
|
1006
|
+
let yes = false;
|
|
942
1007
|
for (let index = 0; index < argv.length; index += 1) {
|
|
943
1008
|
const token = argv[index] ?? "";
|
|
944
1009
|
if (token === LOCAL_FLAG) {
|
|
945
1010
|
local = true;
|
|
946
1011
|
continue;
|
|
947
1012
|
}
|
|
1013
|
+
if (token === YES_FLAG) {
|
|
1014
|
+
yes = true;
|
|
1015
|
+
continue;
|
|
1016
|
+
}
|
|
948
1017
|
if (token === TRUST_YOUNG_FLAG) {
|
|
949
1018
|
trustYoung = true;
|
|
950
1019
|
continue;
|
|
@@ -984,7 +1053,10 @@ function parseRequest(argv) {
|
|
|
984
1053
|
throw new AddLocalFlagError(`\`${TRUST_YOUNG_FLAG}\``);
|
|
985
1054
|
}
|
|
986
1055
|
}
|
|
987
|
-
return { name, version, registry, trustYoung, local };
|
|
1056
|
+
return { name, version, registry, trustYoung, local, yes };
|
|
1057
|
+
}
|
|
1058
|
+
function ceremonyFor(tier) {
|
|
1059
|
+
return tier === "official" ? void 0 : "who publishes it and why you trust it";
|
|
988
1060
|
}
|
|
989
1061
|
function tierOf(request) {
|
|
990
1062
|
if (request.name.startsWith(OFFICIAL_SCOPE2)) {
|
|
@@ -1063,7 +1135,29 @@ function recordExtension(manifestFile, name, entry) {
|
|
|
1063
1135
|
};
|
|
1064
1136
|
return serializeManifest(next);
|
|
1065
1137
|
}
|
|
1066
|
-
|
|
1138
|
+
var NONE = /* @__PURE__ */ new Set(["", "none", "no", "n"]);
|
|
1139
|
+
var ALL = /* @__PURE__ */ new Set(["all", "a", "yes", "y"]);
|
|
1140
|
+
function chooseEnvironments(answer, offered) {
|
|
1141
|
+
const normalized = answer.trim().toLowerCase();
|
|
1142
|
+
if (NONE.has(normalized)) {
|
|
1143
|
+
return { chosen: [], unknown: [] };
|
|
1144
|
+
}
|
|
1145
|
+
if (ALL.has(normalized)) {
|
|
1146
|
+
return { chosen: offered, unknown: [] };
|
|
1147
|
+
}
|
|
1148
|
+
const chosen = [];
|
|
1149
|
+
const unknown = [];
|
|
1150
|
+
for (const token of normalized.split(/[\s,]+/).filter((part) => part !== "")) {
|
|
1151
|
+
const match = offered.find((environment) => environment.toLowerCase() === token);
|
|
1152
|
+
if (match === void 0) {
|
|
1153
|
+
unknown.push(token);
|
|
1154
|
+
} else {
|
|
1155
|
+
chosen.push(match);
|
|
1156
|
+
}
|
|
1157
|
+
}
|
|
1158
|
+
return { chosen, unknown };
|
|
1159
|
+
}
|
|
1160
|
+
async function offerConfigEdit(options, name, ask) {
|
|
1067
1161
|
const { io, root } = options;
|
|
1068
1162
|
const configFile = findConfigFile(root);
|
|
1069
1163
|
const line = `Add \`type: ${JSON.stringify(name)}\` to an environment in penv.config.ts.`;
|
|
@@ -1078,31 +1172,35 @@ async function offerConfigEdit(options, name) {
|
|
|
1078
1172
|
io.out(line);
|
|
1079
1173
|
return;
|
|
1080
1174
|
}
|
|
1081
|
-
|
|
1175
|
+
const offered = entries.filter((entry) => entry.type !== name).map((entry) => entry.environment);
|
|
1176
|
+
if (offered.length === 0) {
|
|
1082
1177
|
return;
|
|
1083
1178
|
}
|
|
1084
|
-
if (!
|
|
1179
|
+
if (!ask) {
|
|
1085
1180
|
io.out(line);
|
|
1086
1181
|
return;
|
|
1087
1182
|
}
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1183
|
+
const { chosen, unknown } = chooseEnvironments(
|
|
1184
|
+
await io.ask(`Point which of ${offered.join(", ")} at ${name} in ${shown}? all / none / names`),
|
|
1185
|
+
offered
|
|
1186
|
+
);
|
|
1187
|
+
if (unknown.length > 0) {
|
|
1188
|
+
io.out(`${shown} declares no ${unknown.join(", ")}, so nothing was repointed.`);
|
|
1189
|
+
io.out(line);
|
|
1190
|
+
return;
|
|
1191
|
+
}
|
|
1192
|
+
for (const environment of chosen) {
|
|
1193
|
+
const next = setProviderType(current, environment, name);
|
|
1096
1194
|
if (next === void 0) {
|
|
1097
|
-
io.out(`Add \`type: ${JSON.stringify(name)}\` to \`${
|
|
1195
|
+
io.out(`Add \`type: ${JSON.stringify(name)}\` to \`${environment}\` in ${shown}.`);
|
|
1098
1196
|
continue;
|
|
1099
1197
|
}
|
|
1100
1198
|
current = next;
|
|
1101
1199
|
writeFileSync3(configFile, current);
|
|
1102
|
-
io.out(`\u2713 ${shown} points \`${
|
|
1200
|
+
io.out(`\u2713 ${shown} points \`${environment}\` at ${name}`);
|
|
1103
1201
|
}
|
|
1104
1202
|
}
|
|
1105
|
-
async function offerOnboarding(io, name, onboard) {
|
|
1203
|
+
async function offerOnboarding(io, name, onboard, ask) {
|
|
1106
1204
|
if (onboard === void 0) {
|
|
1107
1205
|
return void 0;
|
|
1108
1206
|
}
|
|
@@ -1111,7 +1209,7 @@ async function offerOnboarding(io, name, onboard) {
|
|
|
1111
1209
|
return void 0;
|
|
1112
1210
|
}
|
|
1113
1211
|
const command = `penv ${args.join(" ")}`;
|
|
1114
|
-
if (
|
|
1212
|
+
if (ask && await io.confirm(`Run \`${command}\` now?`)) {
|
|
1115
1213
|
return args;
|
|
1116
1214
|
}
|
|
1117
1215
|
io.out(`Run \`${command}\` to finish setting ${name} up.`);
|
|
@@ -1192,8 +1290,9 @@ async function addLocal(options, request) {
|
|
|
1192
1290
|
io.out(`\u2713 ${request.name} resolves from this project and imports \u2014 nothing is pinned`);
|
|
1193
1291
|
io.out(`\u2713 ${LOCAL_EXTENSIONS_PATH2} records it`);
|
|
1194
1292
|
io.out(`\u2713 ${declaration} declares its config type`);
|
|
1195
|
-
|
|
1196
|
-
|
|
1293
|
+
const ask = io.interactive && !request.yes;
|
|
1294
|
+
await offerConfigEdit(options, request.name, ask);
|
|
1295
|
+
return { onboard: await offerOnboarding(io, request.name, installed.onboard, ask) };
|
|
1197
1296
|
}
|
|
1198
1297
|
async function add(options) {
|
|
1199
1298
|
const { io, fetcher, home, root, manifestFile } = options;
|
|
@@ -1203,11 +1302,13 @@ async function add(options) {
|
|
|
1203
1302
|
}
|
|
1204
1303
|
const tier = tierOf(request);
|
|
1205
1304
|
const now = (options.now ?? (() => /* @__PURE__ */ new Date()))();
|
|
1305
|
+
const ask = io.interactive && !request.yes;
|
|
1206
1306
|
if (options.noDownload === true) {
|
|
1207
1307
|
throw new AddNoDownloadError(request.name);
|
|
1208
1308
|
}
|
|
1209
|
-
|
|
1210
|
-
|
|
1309
|
+
const ceremony = ceremonyFor(tier);
|
|
1310
|
+
if (ceremony !== void 0 && (options.ci === true || !ask)) {
|
|
1311
|
+
throw new AddTrustUnattendedError(request.name, ceremony);
|
|
1211
1312
|
}
|
|
1212
1313
|
const release = await fetchRelease({
|
|
1213
1314
|
name: request.name,
|
|
@@ -1249,8 +1350,8 @@ async function add(options) {
|
|
|
1249
1350
|
io.out(`\u2713 ${release.name} ${release.version} installed \u2014 ${provenance}`);
|
|
1250
1351
|
io.out(`\u2713 ${MANIFEST_PATH2} pins it`);
|
|
1251
1352
|
io.out(`\u2713 ${declaration} declares its config type`);
|
|
1252
|
-
await offerConfigEdit(options, release.name);
|
|
1253
|
-
return { onboard: await offerOnboarding(io, release.name, installed.onboard) };
|
|
1353
|
+
await offerConfigEdit(options, release.name, ask);
|
|
1354
|
+
return { onboard: await offerOnboarding(io, release.name, installed.onboard, ask) };
|
|
1254
1355
|
}
|
|
1255
1356
|
|
|
1256
1357
|
// src/delegate.ts
|
|
@@ -1299,12 +1400,12 @@ function nodeSpawner() {
|
|
|
1299
1400
|
// src/engine.ts
|
|
1300
1401
|
import { existsSync as existsSync2, readFileSync as readFileSync5 } from "fs";
|
|
1301
1402
|
import { createRequire as createRequire2 } from "module";
|
|
1302
|
-
import { dirname as dirname4, join as
|
|
1403
|
+
import { dirname as dirname4, join as join4, resolve as resolve3, sep as sep3 } from "path";
|
|
1303
1404
|
import { ENGINE_PACKAGE as ENGINE_PACKAGE2, PenvError as PenvError2 } from "@penvhq/core";
|
|
1304
1405
|
var ENGINE_BIN = "penv-engine";
|
|
1305
1406
|
function readPackageManifest(dir) {
|
|
1306
1407
|
try {
|
|
1307
|
-
return JSON.parse(readFileSync5(
|
|
1408
|
+
return JSON.parse(readFileSync5(join4(dir, "package.json"), "utf8"));
|
|
1308
1409
|
} catch {
|
|
1309
1410
|
return void 0;
|
|
1310
1411
|
}
|
|
@@ -1369,8 +1470,8 @@ var DEV_PIN_INTEGRITY = "sha512-development-build-not-a-published-release";
|
|
|
1369
1470
|
var DEV_PIN_VERSION = "0.0.0-dev";
|
|
1370
1471
|
var BUNDLED_ENGINE_PIN = {
|
|
1371
1472
|
package: ENGINE_PACKAGE3,
|
|
1372
|
-
version: "0.
|
|
1373
|
-
integrity: "sha512-
|
|
1473
|
+
version: "0.12.0",
|
|
1474
|
+
integrity: "sha512-9HUylEIbFq0BGTOW54Vxhkzv8AvuB7H3bImTFP5J+dfglkR7udP2KUsr8b0I2mf45YMTQO5xsYpI5+nhLERGtA=="
|
|
1374
1475
|
};
|
|
1375
1476
|
function assertReleasePin(pin) {
|
|
1376
1477
|
if (pin.integrity === DEV_PIN_INTEGRITY || pin.version === DEV_PIN_VERSION) {
|
|
@@ -1387,7 +1488,7 @@ function releaseEnginePin(pin, ranVersion) {
|
|
|
1387
1488
|
|
|
1388
1489
|
// src/project.ts
|
|
1389
1490
|
import { existsSync as existsSync3 } from "fs";
|
|
1390
|
-
import { dirname as dirname5, join as
|
|
1491
|
+
import { dirname as dirname5, join as join5, resolve as resolve4 } from "path";
|
|
1391
1492
|
import { MANIFEST_PATH as MANIFEST_PATH3, stateDir } from "@penvhq/core";
|
|
1392
1493
|
var MANIFEST_SEGMENTS = MANIFEST_PATH3.split("/");
|
|
1393
1494
|
function findUp(cwd, matches) {
|
|
@@ -1404,42 +1505,152 @@ function findUp(cwd, matches) {
|
|
|
1404
1505
|
}
|
|
1405
1506
|
}
|
|
1406
1507
|
function findProject(cwd) {
|
|
1407
|
-
const root = findUp(cwd, (dir) => existsSync3(
|
|
1408
|
-
return root === void 0 ? void 0 : { root, manifestFile:
|
|
1508
|
+
const root = findUp(cwd, (dir) => existsSync3(join5(dir, ...MANIFEST_SEGMENTS)));
|
|
1509
|
+
return root === void 0 ? void 0 : { root, manifestFile: join5(root, ...MANIFEST_SEGMENTS) };
|
|
1409
1510
|
}
|
|
1410
1511
|
function findAdoptedRoot(cwd) {
|
|
1411
1512
|
return findUp(cwd, (dir) => existsSync3(stateDir(dir)));
|
|
1412
1513
|
}
|
|
1413
1514
|
|
|
1515
|
+
// src/upgrade.ts
|
|
1516
|
+
import { writeFileSync as writeFileSync4 } from "fs";
|
|
1517
|
+
import {
|
|
1518
|
+
installWithPackageManager,
|
|
1519
|
+
planInstall,
|
|
1520
|
+
RUNTIME_PACKAGE,
|
|
1521
|
+
renderInstallPlan
|
|
1522
|
+
} from "@penvhq/cli/install";
|
|
1523
|
+
import { ENGINE_PACKAGE as ENGINE_PACKAGE4, MANIFEST_PATH as MANIFEST_PATH4, serializeManifest as serializeManifest2 } from "@penvhq/core";
|
|
1524
|
+
function parseRequest2(argv) {
|
|
1525
|
+
let version;
|
|
1526
|
+
let yes = false;
|
|
1527
|
+
for (const token of argv) {
|
|
1528
|
+
if (token === YES_FLAG) {
|
|
1529
|
+
yes = true;
|
|
1530
|
+
continue;
|
|
1531
|
+
}
|
|
1532
|
+
if (token.startsWith("-")) {
|
|
1533
|
+
throw new UpgradeFlagError(token);
|
|
1534
|
+
}
|
|
1535
|
+
if (version !== void 0 || token === "") {
|
|
1536
|
+
throw new UpgradeSubjectError();
|
|
1537
|
+
}
|
|
1538
|
+
version = token;
|
|
1539
|
+
}
|
|
1540
|
+
return { version, yes };
|
|
1541
|
+
}
|
|
1542
|
+
function renderPinChange(engine, release) {
|
|
1543
|
+
return [
|
|
1544
|
+
MANIFEST_PATH4,
|
|
1545
|
+
` - "integrity": "${engine.integrity}"`,
|
|
1546
|
+
` - "version": "${engine.version}"`,
|
|
1547
|
+
` + "integrity": "${release.integrity}"`,
|
|
1548
|
+
` + "version": "${release.version}"`
|
|
1549
|
+
];
|
|
1550
|
+
}
|
|
1551
|
+
function pinnedElsewhere(manifest, version) {
|
|
1552
|
+
return Object.entries(manifest.extensions).filter(([, entry]) => entry.version !== version).map(([name]) => name);
|
|
1553
|
+
}
|
|
1554
|
+
async function consent(options, release, plan, yes) {
|
|
1555
|
+
const { io, manifest } = options;
|
|
1556
|
+
io.out(`${ENGINE_PACKAGE4} ${manifest.engine.version} \u2192 ${release.version}`);
|
|
1557
|
+
io.out("");
|
|
1558
|
+
for (const line of renderPinChange(manifest.engine, release)) {
|
|
1559
|
+
io.out(line);
|
|
1560
|
+
}
|
|
1561
|
+
for (const line of renderInstallPlan(plan)) {
|
|
1562
|
+
io.out(line);
|
|
1563
|
+
}
|
|
1564
|
+
if (yes) {
|
|
1565
|
+
return;
|
|
1566
|
+
}
|
|
1567
|
+
if (!await io.confirm(`Move this project to ${release.version}?`)) {
|
|
1568
|
+
throw new UpgradeDeclinedError(release.version);
|
|
1569
|
+
}
|
|
1570
|
+
}
|
|
1571
|
+
async function upgrade(options) {
|
|
1572
|
+
const { io, fetcher, home, root, manifest, manifestFile } = options;
|
|
1573
|
+
const request = parseRequest2(options.argv);
|
|
1574
|
+
if (options.noDownload === true) {
|
|
1575
|
+
throw new UpgradeNoDownloadError();
|
|
1576
|
+
}
|
|
1577
|
+
if ((options.ci === true || !io.interactive) && !(request.yes && request.version !== void 0)) {
|
|
1578
|
+
throw new UpgradeUnattendedError();
|
|
1579
|
+
}
|
|
1580
|
+
const release = await fetchRelease({
|
|
1581
|
+
name: ENGINE_PACKAGE4,
|
|
1582
|
+
...request.version === void 0 ? {} : { version: request.version },
|
|
1583
|
+
retry: UPGRADE_COMMAND,
|
|
1584
|
+
fetcher
|
|
1585
|
+
});
|
|
1586
|
+
const plan = planInstall(root, release.version);
|
|
1587
|
+
if (manifest.engine.version === release.version && plan.satisfied) {
|
|
1588
|
+
io.out(`\u2713 Already on ${ENGINE_PACKAGE4} ${release.version} \u2014 nothing to move`);
|
|
1589
|
+
return;
|
|
1590
|
+
}
|
|
1591
|
+
const manifestText = serializeManifest2({
|
|
1592
|
+
...manifest,
|
|
1593
|
+
engine: { package: ENGINE_PACKAGE4, version: release.version, integrity: release.integrity }
|
|
1594
|
+
});
|
|
1595
|
+
await consent(options, release, plan, request.yes);
|
|
1596
|
+
await installPin({
|
|
1597
|
+
home,
|
|
1598
|
+
kind: "engines",
|
|
1599
|
+
pin: { name: ENGINE_PACKAGE4, version: release.version, integrity: release.integrity },
|
|
1600
|
+
fetcher
|
|
1601
|
+
});
|
|
1602
|
+
io.out(`\u2713 ${ENGINE_PACKAGE4} ${release.version} installed`);
|
|
1603
|
+
if (!plan.satisfied) {
|
|
1604
|
+
try {
|
|
1605
|
+
await (options.install ?? installWithPackageManager)(plan);
|
|
1606
|
+
} catch {
|
|
1607
|
+
throw new UpgradeInstallFailedError(plan.manager, release.version);
|
|
1608
|
+
}
|
|
1609
|
+
for (const step of plan.steps.filter((entry) => !entry.satisfied)) {
|
|
1610
|
+
io.out(`\u2713 ${step.manifest} depends on ${RUNTIME_PACKAGE} ${release.version}`);
|
|
1611
|
+
}
|
|
1612
|
+
}
|
|
1613
|
+
writeFileSync4(manifestFile, manifestText);
|
|
1614
|
+
io.out(`\u2713 ${MANIFEST_PATH4} pins ${ENGINE_PACKAGE4} ${release.version}`);
|
|
1615
|
+
const kept = pinnedElsewhere(manifest, release.version);
|
|
1616
|
+
if (kept.length > 0) {
|
|
1617
|
+
const subject = kept.length === 1 ? "keeps its own pin" : "keep their own pins";
|
|
1618
|
+
io.out(`\u2192 ${kept.join(", ")} ${subject} \u2014 \`penv add <package>@<version>\` moves one.`);
|
|
1619
|
+
}
|
|
1620
|
+
}
|
|
1621
|
+
|
|
1414
1622
|
// src/launcher.ts
|
|
1415
|
-
import { existsSync as existsSync4, readFileSync as readFileSync6, writeFileSync as
|
|
1416
|
-
import { join as
|
|
1623
|
+
import { existsSync as existsSync4, readFileSync as readFileSync6, writeFileSync as writeFileSync5 } from "fs";
|
|
1624
|
+
import { join as join6 } from "path";
|
|
1417
1625
|
import {
|
|
1418
1626
|
MANIFEST_FORMAT,
|
|
1419
|
-
MANIFEST_PATH as
|
|
1627
|
+
MANIFEST_PATH as MANIFEST_PATH6,
|
|
1420
1628
|
PENV_HOME_VAR,
|
|
1421
1629
|
PenvError as PenvError3,
|
|
1630
|
+
packageEntry as packageEntry2,
|
|
1422
1631
|
parseManifest as parseManifest2,
|
|
1423
1632
|
penvHome,
|
|
1424
|
-
serializeManifest as
|
|
1633
|
+
serializeManifest as serializeManifest3,
|
|
1425
1634
|
UnsupportedManifestFormatError
|
|
1426
1635
|
} from "@penvhq/core";
|
|
1427
1636
|
|
|
1428
1637
|
// src/help.ts
|
|
1429
|
-
import {
|
|
1638
|
+
import { RUNTIME_PACKAGE as RUNTIME_PACKAGE2 } from "@penvhq/cli/install";
|
|
1639
|
+
import { ENGINE_PACKAGE as ENGINE_PACKAGE5, EXTENSIONS_PATH as EXTENSIONS_PATH3, MANIFEST_PATH as MANIFEST_PATH5, OFFICIAL_SCOPE as OFFICIAL_SCOPE3 } from "@penvhq/core";
|
|
1430
1640
|
function printLauncherCommands(io) {
|
|
1431
1641
|
io.out("");
|
|
1432
1642
|
io.out("LAUNCHER COMMANDS (penv itself, whatever engine a project pins)");
|
|
1433
1643
|
io.out("");
|
|
1434
|
-
io.out(` install Installs everything ${
|
|
1644
|
+
io.out(` install Installs everything ${MANIFEST_PATH5} pins`);
|
|
1435
1645
|
io.out(" add <package> Pins a provider extension, and commits the decision");
|
|
1436
1646
|
io.out(` add ${LOCAL_FLAG} <package> Adds the one this repository builds \u2014 nothing is pinned`);
|
|
1647
|
+
io.out(` upgrade [version] Moves the engine pin and ${RUNTIME_PACKAGE2} together`);
|
|
1437
1648
|
io.out("");
|
|
1438
1649
|
}
|
|
1439
1650
|
function printInstallHelp(io) {
|
|
1440
1651
|
io.out(`${INSTALL_COMMAND}`);
|
|
1441
1652
|
io.out("");
|
|
1442
|
-
io.out(`Downloads, verifies and installs every version ${
|
|
1653
|
+
io.out(`Downloads, verifies and installs every version ${MANIFEST_PATH5} pins \u2014 the engine and`);
|
|
1443
1654
|
io.out("every extension \u2014 into $PENV_HOME. The one penv command CI and production run that");
|
|
1444
1655
|
io.out("may reach the registry.");
|
|
1445
1656
|
}
|
|
@@ -1451,15 +1662,32 @@ function printAddHelp(io) {
|
|
|
1451
1662
|
io.out(
|
|
1452
1663
|
` ${TRUST_YOUNG_FLAG} Add a release published less than ${MIN_PACKAGE_AGE_DAYS} days ago`
|
|
1453
1664
|
);
|
|
1665
|
+
io.out(` ${YES_FLAG} Ask nothing \u2014 the config and onboarding offers print instead`);
|
|
1454
1666
|
io.out("");
|
|
1455
|
-
io.out(`Pins the release in ${
|
|
1667
|
+
io.out(`Pins the release in ${MANIFEST_PATH5} and writes its type declaration to`);
|
|
1456
1668
|
io.out(`${EXTENSIONS_PATH3}/. Both are committed, so \`${INSTALL_COMMAND}\` gives every machine`);
|
|
1457
1669
|
io.out(`the bytes you reviewed. \`${LOCAL_FLAG}\` pins nothing and touches no manifest.`);
|
|
1670
|
+
io.out("");
|
|
1671
|
+
io.out(`An \`${OFFICIAL_SCOPE3}*\` package asks nothing, so it adds unattended. Anything else`);
|
|
1672
|
+
io.out("records who publishes it and why you trust it, which needs a person at a terminal \u2014");
|
|
1673
|
+
io.out(`\`${YES_FLAG}\` cannot write that line for you.`);
|
|
1674
|
+
}
|
|
1675
|
+
function printUpgradeHelp(io) {
|
|
1676
|
+
io.out("penv upgrade [version]");
|
|
1677
|
+
io.out("");
|
|
1678
|
+
io.out(` ${YES_FLAG} Skip the question \u2014 unattended runs need it and a version`);
|
|
1679
|
+
io.out("");
|
|
1680
|
+
io.out(`Moves the ${ENGINE_PACKAGE5} pin in ${MANIFEST_PATH5} and this project's`);
|
|
1681
|
+
io.out(`${RUNTIME_PACKAGE2} dependency to the same exact version. No version takes whatever`);
|
|
1682
|
+
io.out("`latest` points at; the integrity is the one the registry states, never one penv");
|
|
1683
|
+
io.out("computed. Both files are shown before either moves, and they move together or not");
|
|
1684
|
+
io.out("at all. Extensions keep their own pins.");
|
|
1458
1685
|
}
|
|
1459
1686
|
|
|
1460
1687
|
// src/launcher.ts
|
|
1461
1688
|
var INSTALL = "install";
|
|
1462
1689
|
var ADD = "add";
|
|
1690
|
+
var UPGRADE = "upgrade";
|
|
1463
1691
|
var VERSION_FLAGS = /* @__PURE__ */ new Set(["--version", "-v"]);
|
|
1464
1692
|
var HELP_FLAGS = /* @__PURE__ */ new Set(["--help", "-h"]);
|
|
1465
1693
|
var NO_DOWNLOAD = "--no-download";
|
|
@@ -1555,6 +1783,10 @@ async function launch(options) {
|
|
|
1555
1783
|
printAddHelp(io);
|
|
1556
1784
|
return 0;
|
|
1557
1785
|
}
|
|
1786
|
+
if (first === UPGRADE) {
|
|
1787
|
+
printUpgradeHelp(io);
|
|
1788
|
+
return 0;
|
|
1789
|
+
}
|
|
1558
1790
|
}
|
|
1559
1791
|
const project = findProject(cwd);
|
|
1560
1792
|
if (project === void 0) {
|
|
@@ -1582,6 +1814,20 @@ async function launch(options) {
|
|
|
1582
1814
|
io.out(`penv ${manifest.engine.version}`);
|
|
1583
1815
|
return 0;
|
|
1584
1816
|
}
|
|
1817
|
+
if (first === UPGRADE) {
|
|
1818
|
+
await upgrade({
|
|
1819
|
+
argv: forwarded.slice(1),
|
|
1820
|
+
root: project.root,
|
|
1821
|
+
manifestFile: project.manifestFile,
|
|
1822
|
+
manifest,
|
|
1823
|
+
home,
|
|
1824
|
+
io,
|
|
1825
|
+
fetcher: options.fetcher,
|
|
1826
|
+
noDownload,
|
|
1827
|
+
ci: isCi(env)
|
|
1828
|
+
});
|
|
1829
|
+
return 0;
|
|
1830
|
+
}
|
|
1585
1831
|
const enginePin = enginePinOf(manifest);
|
|
1586
1832
|
const engineDir = await ensure(options, "engines", enginePin, home, noDownload);
|
|
1587
1833
|
for (const pin of extensionPinsOf(manifest)) {
|
|
@@ -1600,16 +1846,16 @@ async function adopt(options, forwarded, home, cwd, noDownload) {
|
|
|
1600
1846
|
if (root === void 0) {
|
|
1601
1847
|
return 0;
|
|
1602
1848
|
}
|
|
1603
|
-
const manifestFile =
|
|
1849
|
+
const manifestFile = join6(root, ...MANIFEST_PATH6.split("/"));
|
|
1604
1850
|
if (existsSync4(manifestFile)) {
|
|
1605
1851
|
return 0;
|
|
1606
1852
|
}
|
|
1607
1853
|
const pin = releaseEnginePin(options.bundledPin, engine.version);
|
|
1608
|
-
|
|
1854
|
+
writeFileSync5(
|
|
1609
1855
|
manifestFile,
|
|
1610
|
-
|
|
1856
|
+
serializeManifest3({ format: MANIFEST_FORMAT, engine: pin, extensions: {} })
|
|
1611
1857
|
);
|
|
1612
|
-
options.io.out(`\u2713 ${
|
|
1858
|
+
options.io.out(`\u2713 ${MANIFEST_PATH6} pins ${pin.package} ${pin.version}`);
|
|
1613
1859
|
await ensureAdoptedEngine(
|
|
1614
1860
|
options,
|
|
1615
1861
|
{ name: pin.package, version: pin.version, integrity: pin.integrity },
|
|
@@ -1656,12 +1902,14 @@ async function install(options, pins, home, broken) {
|
|
|
1656
1902
|
if (state === "corrupt") {
|
|
1657
1903
|
throw new PackageCorruptError(pin.name, pin.version, dir);
|
|
1658
1904
|
}
|
|
1659
|
-
if (state === "
|
|
1660
|
-
|
|
1661
|
-
|
|
1905
|
+
if (state === "absent") {
|
|
1906
|
+
await installPin({ home, kind, pin, fetcher: options.fetcher });
|
|
1907
|
+
}
|
|
1908
|
+
if (kind === "extensions") {
|
|
1909
|
+
await assertLoadable(pin.name, packageEntry2(dir), false);
|
|
1662
1910
|
}
|
|
1663
|
-
|
|
1664
|
-
options.io.out(`\u2713 ${pin.name} ${pin.version}
|
|
1911
|
+
const verb = state === "absent" ? "installed" : "already installed";
|
|
1912
|
+
options.io.out(`\u2713 ${pin.name} ${pin.version} ${verb}`);
|
|
1665
1913
|
}
|
|
1666
1914
|
if (broken.length > 0) {
|
|
1667
1915
|
report(new ManifestEntriesUnreadableError(broken), options.io);
|
|
@@ -1709,6 +1957,8 @@ export {
|
|
|
1709
1957
|
readProviderEntries,
|
|
1710
1958
|
setProviderType,
|
|
1711
1959
|
INSTALL_COMMAND,
|
|
1960
|
+
UPGRADE_COMMAND,
|
|
1961
|
+
YES_FLAG,
|
|
1712
1962
|
MIN_PACKAGE_AGE_DAYS,
|
|
1713
1963
|
TRUST_YOUNG_FLAG,
|
|
1714
1964
|
NoProjectError,
|
|
@@ -1735,7 +1985,7 @@ export {
|
|
|
1735
1985
|
ReleaseIncompleteError,
|
|
1736
1986
|
PackageTooYoungError,
|
|
1737
1987
|
AddNoDownloadError,
|
|
1738
|
-
|
|
1988
|
+
AddTrustUnattendedError,
|
|
1739
1989
|
TrustDeclinedError,
|
|
1740
1990
|
TrustPublisherMissingError,
|
|
1741
1991
|
TrustReasonMissingError,
|
|
@@ -1743,6 +1993,12 @@ export {
|
|
|
1743
1993
|
DeclarationNotSelfContainedError,
|
|
1744
1994
|
EnginePinUnreleasedError,
|
|
1745
1995
|
EnginePinMismatchError,
|
|
1996
|
+
UpgradeSubjectError,
|
|
1997
|
+
UpgradeFlagError,
|
|
1998
|
+
UpgradeNoDownloadError,
|
|
1999
|
+
UpgradeUnattendedError,
|
|
2000
|
+
UpgradeDeclinedError,
|
|
2001
|
+
UpgradeInstallFailedError,
|
|
1746
2002
|
EngineEntryError,
|
|
1747
2003
|
readExtensionPackage,
|
|
1748
2004
|
renderDeclaration,
|
|
@@ -1773,6 +2029,7 @@ export {
|
|
|
1773
2029
|
releaseEnginePin,
|
|
1774
2030
|
findProject,
|
|
1775
2031
|
findAdoptedRoot,
|
|
2032
|
+
upgrade,
|
|
1776
2033
|
runLauncher
|
|
1777
2034
|
};
|
|
1778
|
-
//# sourceMappingURL=chunk-
|
|
2035
|
+
//# sourceMappingURL=chunk-A5LJQPYS.js.map
|