@penvhq/cli 0.9.2 → 0.9.4
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 +323 -137
- package/dist/bin.cjs.map +1 -1
- package/dist/index.cjs +317 -132
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +38 -11
- package/dist/index.d.ts +38 -11
- package/dist/index.js +313 -119
- package/dist/index.js.map +1 -1
- package/package.json +7 -7
package/dist/index.cjs
CHANGED
|
@@ -114,7 +114,7 @@ var startChild = (invocation) => {
|
|
|
114
114
|
const ended = new Promise((resolve9, reject) => {
|
|
115
115
|
child.on("error", (cause) => {
|
|
116
116
|
release();
|
|
117
|
-
reject(cannotStart(executable, cause));
|
|
117
|
+
reject(cannotStart(executable, cause, invocation.purpose));
|
|
118
118
|
});
|
|
119
119
|
child.on("exit", (code, signal) => {
|
|
120
120
|
release();
|
|
@@ -135,8 +135,15 @@ function noCommand() {
|
|
|
135
135
|
"Put the command after `--`, e.g. `penv run -- pnpm dev`."
|
|
136
136
|
);
|
|
137
137
|
}
|
|
138
|
-
function cannotStart(executable, cause) {
|
|
138
|
+
function cannotStart(executable, cause, purpose) {
|
|
139
139
|
const detail = cause instanceof Error ? cause.message : String(cause);
|
|
140
|
+
if (purpose !== void 0) {
|
|
141
|
+
return new import_core.PenvError(
|
|
142
|
+
"PENV_COMMAND_NOT_STARTED",
|
|
143
|
+
`penv could not start \`${executable}\` to ${purpose}: ${detail}`,
|
|
144
|
+
`Check that \`${executable}\` runs on its own \u2014 penv starts it the way your shell does, so it has to be on PATH. Nothing was changed.`
|
|
145
|
+
);
|
|
146
|
+
}
|
|
140
147
|
return new import_core.PenvError(
|
|
141
148
|
"RUN_COMMAND_NOT_STARTED",
|
|
142
149
|
`\`${executable}\` could not be started: ${detail}`,
|
|
@@ -165,12 +172,15 @@ function cmdCommandLine(resolved, args) {
|
|
|
165
172
|
" "
|
|
166
173
|
);
|
|
167
174
|
}
|
|
168
|
-
function extensions(env) {
|
|
175
|
+
function extensions(env, platform) {
|
|
176
|
+
if (platform !== "win32") {
|
|
177
|
+
return [""];
|
|
178
|
+
}
|
|
169
179
|
const declared = env.PATHEXT ?? ".COM;.EXE;.BAT;.CMD";
|
|
170
|
-
return [
|
|
180
|
+
return [...declared.split(";").filter((extension) => extension.length > 0), ""];
|
|
171
181
|
}
|
|
172
|
-
function findExecutable(executable, env) {
|
|
173
|
-
const candidates = extensions(env);
|
|
182
|
+
function findExecutable(executable, env, platform = process.platform) {
|
|
183
|
+
const candidates = extensions(env, platform);
|
|
174
184
|
const isFile = (path2) => (0, import_node_fs.existsSync)(path2) && (0, import_node_fs.statSync)(path2).isFile();
|
|
175
185
|
if (executable.includes("/") || executable.includes("\\") || (0, import_node_path.isAbsolute)(executable)) {
|
|
176
186
|
return candidates.map((extension) => executable + extension).find(isFile);
|
|
@@ -197,6 +207,7 @@ function escapeArgument(argument, doubleEscape) {
|
|
|
197
207
|
// src/install.ts
|
|
198
208
|
var import_meta = {};
|
|
199
209
|
var RUNTIME_PACKAGE = "@penvhq/penv";
|
|
210
|
+
var SCHEMA_PACKAGE = "zod";
|
|
200
211
|
var LOCKFILES = [
|
|
201
212
|
["pnpm", "pnpm-lock.yaml"],
|
|
202
213
|
["yarn", "yarn.lock"],
|
|
@@ -211,13 +222,9 @@ var ADD = {
|
|
|
211
222
|
bun: ["bun", "add", "--exact"]
|
|
212
223
|
};
|
|
213
224
|
function engineVersion() {
|
|
214
|
-
const
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
if (typeof version === "string" && version.length > 0) {
|
|
218
|
-
return version;
|
|
219
|
-
}
|
|
220
|
-
} catch {
|
|
225
|
+
const version = ownManifest()?.version;
|
|
226
|
+
if (typeof version === "string" && version.length > 0) {
|
|
227
|
+
return version;
|
|
221
228
|
}
|
|
222
229
|
throw new import_core2.PenvError(
|
|
223
230
|
"ENGINE_VERSION_UNREADABLE",
|
|
@@ -225,6 +232,29 @@ function engineVersion() {
|
|
|
225
232
|
`Reinstall penv, then run \`penv init\` again.`
|
|
226
233
|
);
|
|
227
234
|
}
|
|
235
|
+
function schemaPackageVersion() {
|
|
236
|
+
const peers = ownManifest()?.peerDependencies;
|
|
237
|
+
const declared = peers !== null && typeof peers === "object" && !Array.isArray(peers) ? peers[SCHEMA_PACKAGE] : void 0;
|
|
238
|
+
const floor = typeof declared === "string" ? declared.replace(/^[\^~>=\s]+/, "").trim() : "";
|
|
239
|
+
if (floor.length > 0) {
|
|
240
|
+
return floor;
|
|
241
|
+
}
|
|
242
|
+
throw new import_core2.PenvError(
|
|
243
|
+
"ENGINE_PEER_UNREADABLE",
|
|
244
|
+
`penv could not read its own \`${SCHEMA_PACKAGE}\` peer range, so it cannot say which ${SCHEMA_PACKAGE} this project needs`,
|
|
245
|
+
`Reinstall penv, then run \`penv init\` again.`
|
|
246
|
+
);
|
|
247
|
+
}
|
|
248
|
+
function ownManifest() {
|
|
249
|
+
try {
|
|
250
|
+
const parsed = JSON.parse(
|
|
251
|
+
(0, import_node_fs2.readFileSync)(new URL("../package.json", import_meta.url), "utf8")
|
|
252
|
+
);
|
|
253
|
+
return parsed !== null && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : void 0;
|
|
254
|
+
} catch {
|
|
255
|
+
return void 0;
|
|
256
|
+
}
|
|
257
|
+
}
|
|
228
258
|
function detectPackageManager(root) {
|
|
229
259
|
for (const [manager, lockfile] of LOCKFILES) {
|
|
230
260
|
if ((0, import_node_fs2.existsSync)((0, import_node_path2.join)(root, lockfile))) {
|
|
@@ -253,12 +283,12 @@ function manifestOf(root) {
|
|
|
253
283
|
return void 0;
|
|
254
284
|
}
|
|
255
285
|
}
|
|
256
|
-
function declaredVersion(root) {
|
|
286
|
+
function declaredVersion(root, name) {
|
|
257
287
|
const manifest = manifestOf(root);
|
|
258
288
|
for (const field of ["dependencies", "devDependencies"]) {
|
|
259
289
|
const block = manifest?.[field];
|
|
260
290
|
if (block !== null && typeof block === "object" && !Array.isArray(block)) {
|
|
261
|
-
const version = block[
|
|
291
|
+
const version = block[name];
|
|
262
292
|
if (typeof version === "string") {
|
|
263
293
|
return version;
|
|
264
294
|
}
|
|
@@ -271,27 +301,61 @@ function planInstall(root, version = engineVersion()) {
|
|
|
271
301
|
const lockfile = LOCKFILES.find(
|
|
272
302
|
([name, file]) => name === manager && (0, import_node_fs2.existsSync)((0, import_node_path2.join)(root, file))
|
|
273
303
|
)?.[1];
|
|
274
|
-
const
|
|
304
|
+
const runtimeDeclared = declaredVersion(root, RUNTIME_PACKAGE);
|
|
305
|
+
const zodDeclared = declaredVersion(root, SCHEMA_PACKAGE);
|
|
306
|
+
const packages = [
|
|
307
|
+
{
|
|
308
|
+
name: RUNTIME_PACKAGE,
|
|
309
|
+
version,
|
|
310
|
+
...runtimeDeclared === void 0 ? {} : { declared: runtimeDeclared },
|
|
311
|
+
satisfied: runtimeDeclared === version
|
|
312
|
+
},
|
|
313
|
+
{
|
|
314
|
+
name: SCHEMA_PACKAGE,
|
|
315
|
+
version: schemaPackageVersion(),
|
|
316
|
+
...zodDeclared === void 0 ? {} : { declared: zodDeclared },
|
|
317
|
+
// Any declared zod counts: which zod a project uses is the project's
|
|
318
|
+
// decision, and penv is here to make sure there is one, not to move it.
|
|
319
|
+
satisfied: zodDeclared !== void 0
|
|
320
|
+
}
|
|
321
|
+
];
|
|
322
|
+
const pending = packages.filter((entry) => !entry.satisfied);
|
|
323
|
+
const specs = (pending.length === 0 ? packages : pending).map(
|
|
324
|
+
(entry) => `${entry.name}@${entry.version}`
|
|
325
|
+
);
|
|
275
326
|
return {
|
|
276
327
|
root,
|
|
277
328
|
manager,
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
command: [...ADD[manager], `${RUNTIME_PACKAGE}@${version}`],
|
|
329
|
+
packages,
|
|
330
|
+
command: [...ADD[manager], ...specs],
|
|
281
331
|
...lockfile === void 0 ? {} : { lockfile },
|
|
282
|
-
|
|
283
|
-
satisfied: declared === version
|
|
332
|
+
satisfied: pending.length === 0
|
|
284
333
|
};
|
|
285
334
|
}
|
|
335
|
+
function describe(entry) {
|
|
336
|
+
return `${entry.name} ${entry.version}`;
|
|
337
|
+
}
|
|
286
338
|
function renderInstallPlan(plan2) {
|
|
287
339
|
if (plan2.satisfied) {
|
|
288
|
-
return [
|
|
340
|
+
return [
|
|
341
|
+
`package.json already has ${plan2.packages.map(describe).join(" and ")} \u2014 nothing to install.`
|
|
342
|
+
];
|
|
289
343
|
}
|
|
290
|
-
const
|
|
344
|
+
const pending = plan2.packages.filter((entry) => !entry.satisfied);
|
|
345
|
+
const added = pending.filter((entry) => entry.declared === void 0);
|
|
346
|
+
const replaced = pending.filter((entry) => entry.declared !== void 0);
|
|
291
347
|
return [
|
|
292
348
|
"package.json",
|
|
293
|
-
...
|
|
294
|
-
|
|
349
|
+
...added.length === 0 ? [] : [
|
|
350
|
+
' + "dependencies": {',
|
|
351
|
+
...added.map((entry) => ` + "${entry.name}": "${entry.version}"`),
|
|
352
|
+
" + }"
|
|
353
|
+
],
|
|
354
|
+
...replaced.flatMap((entry) => [
|
|
355
|
+
` - "${entry.name}": "${entry.declared}"`,
|
|
356
|
+
` + "${entry.name}": "${entry.version}"`
|
|
357
|
+
]),
|
|
358
|
+
...plan2.lockfile === void 0 ? [] : [plan2.lockfile, ...pending.map((entry) => ` + ${entry.name}@${entry.version}`)],
|
|
295
359
|
"",
|
|
296
360
|
`Run with: ${plan2.command.join(" ")}`
|
|
297
361
|
];
|
|
@@ -300,7 +364,8 @@ var installWithPackageManager = async (plan2) => {
|
|
|
300
364
|
const child = startChild({
|
|
301
365
|
command: plan2.command,
|
|
302
366
|
env: process.env,
|
|
303
|
-
cwd: plan2.root
|
|
367
|
+
cwd: plan2.root,
|
|
368
|
+
purpose: `install ${plan2.packages.map(describe).join(" and ")}`
|
|
304
369
|
});
|
|
305
370
|
const ended = await child.ended;
|
|
306
371
|
if (ended.exitCode !== 0 || ended.signal !== null) {
|
|
@@ -2139,20 +2204,20 @@ function readCutover(root) {
|
|
|
2139
2204
|
if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
2140
2205
|
throw unreadable("it is not an object");
|
|
2141
2206
|
}
|
|
2142
|
-
const
|
|
2143
|
-
if (
|
|
2207
|
+
const record2 = parsed;
|
|
2208
|
+
if (record2.format !== CUTOVER_FORMAT) {
|
|
2144
2209
|
throw unreadable(
|
|
2145
|
-
`it is format ${JSON.stringify(
|
|
2210
|
+
`it is format ${JSON.stringify(record2.format)}, and penv reads format ${CUTOVER_FORMAT}`
|
|
2146
2211
|
);
|
|
2147
2212
|
}
|
|
2148
|
-
const files =
|
|
2213
|
+
const files = record2.files;
|
|
2149
2214
|
if (!Array.isArray(files) || files.some((name) => typeof name !== "string")) {
|
|
2150
2215
|
throw unreadable("it lists no filenames");
|
|
2151
2216
|
}
|
|
2152
|
-
const environments = Array.isArray(
|
|
2217
|
+
const environments = Array.isArray(record2.environments) ? record2.environments.filter((name) => typeof name === "string") : [];
|
|
2153
2218
|
return {
|
|
2154
2219
|
format: CUTOVER_FORMAT,
|
|
2155
|
-
movedAt: typeof
|
|
2220
|
+
movedAt: typeof record2.movedAt === "string" ? record2.movedAt : "",
|
|
2156
2221
|
files,
|
|
2157
2222
|
environments
|
|
2158
2223
|
};
|
|
@@ -4156,8 +4221,8 @@ var getCommand = (0, import_citty12.defineCommand)({
|
|
|
4156
4221
|
});
|
|
4157
4222
|
|
|
4158
4223
|
// src/commands/import.ts
|
|
4159
|
-
var
|
|
4160
|
-
var
|
|
4224
|
+
var import_node_fs13 = require("fs");
|
|
4225
|
+
var import_node_path14 = require("path");
|
|
4161
4226
|
var import_core26 = require("@penvhq/core");
|
|
4162
4227
|
var import_citty14 = require("citty");
|
|
4163
4228
|
|
|
@@ -4392,12 +4457,94 @@ function draftFieldsAcross(sources, environments) {
|
|
|
4392
4457
|
}
|
|
4393
4458
|
|
|
4394
4459
|
// src/commands/init.ts
|
|
4395
|
-
var
|
|
4396
|
-
var
|
|
4460
|
+
var import_node_fs12 = require("fs");
|
|
4461
|
+
var import_node_path13 = require("path");
|
|
4397
4462
|
var import_promises = require("readline/promises");
|
|
4398
4463
|
var import_core25 = require("@penvhq/core");
|
|
4399
4464
|
var import_citty13 = require("citty");
|
|
4400
4465
|
|
|
4466
|
+
// src/scaffold-undo.ts
|
|
4467
|
+
var import_node_fs11 = require("fs");
|
|
4468
|
+
var import_node_path12 = require("path");
|
|
4469
|
+
function record(path, files, dirs) {
|
|
4470
|
+
let stats;
|
|
4471
|
+
try {
|
|
4472
|
+
stats = (0, import_node_fs11.statSync)(path);
|
|
4473
|
+
} catch {
|
|
4474
|
+
return;
|
|
4475
|
+
}
|
|
4476
|
+
if (stats.isDirectory()) {
|
|
4477
|
+
dirs.add(path);
|
|
4478
|
+
for (const entry of (0, import_node_fs11.readdirSync)(path)) {
|
|
4479
|
+
record((0, import_node_path12.join)(path, entry), files, dirs);
|
|
4480
|
+
}
|
|
4481
|
+
return;
|
|
4482
|
+
}
|
|
4483
|
+
if (stats.isFile()) {
|
|
4484
|
+
files.set(path, (0, import_node_fs11.readFileSync)(path));
|
|
4485
|
+
}
|
|
4486
|
+
}
|
|
4487
|
+
function captureScaffold(root, paths) {
|
|
4488
|
+
const files = /* @__PURE__ */ new Map();
|
|
4489
|
+
const dirs = /* @__PURE__ */ new Set();
|
|
4490
|
+
for (const path of paths) {
|
|
4491
|
+
for (let dir = (0, import_node_path12.dirname)(path); dir.startsWith(root) && dir !== root; dir = (0, import_node_path12.dirname)(dir)) {
|
|
4492
|
+
if ((0, import_node_fs11.existsSync)(dir)) {
|
|
4493
|
+
dirs.add(dir);
|
|
4494
|
+
}
|
|
4495
|
+
}
|
|
4496
|
+
record(path, files, dirs);
|
|
4497
|
+
}
|
|
4498
|
+
return { root, paths: [...paths], files, dirs };
|
|
4499
|
+
}
|
|
4500
|
+
function restoreScaffold(undo) {
|
|
4501
|
+
for (const path of undo.paths) {
|
|
4502
|
+
removeAdded(path, undo);
|
|
4503
|
+
}
|
|
4504
|
+
for (const path of undo.paths) {
|
|
4505
|
+
pruneAncestors(path, undo);
|
|
4506
|
+
}
|
|
4507
|
+
for (const [file, contents] of undo.files) {
|
|
4508
|
+
(0, import_node_fs11.mkdirSync)((0, import_node_path12.dirname)(file), { recursive: true });
|
|
4509
|
+
(0, import_node_fs11.writeFileSync)(file, contents);
|
|
4510
|
+
}
|
|
4511
|
+
}
|
|
4512
|
+
function removeAdded(path, undo) {
|
|
4513
|
+
let stats;
|
|
4514
|
+
try {
|
|
4515
|
+
stats = (0, import_node_fs11.statSync)(path);
|
|
4516
|
+
} catch {
|
|
4517
|
+
return;
|
|
4518
|
+
}
|
|
4519
|
+
if (stats.isFile()) {
|
|
4520
|
+
if (!undo.files.has(path)) {
|
|
4521
|
+
(0, import_node_fs11.unlinkSync)(path);
|
|
4522
|
+
}
|
|
4523
|
+
return;
|
|
4524
|
+
}
|
|
4525
|
+
if (!stats.isDirectory()) {
|
|
4526
|
+
return;
|
|
4527
|
+
}
|
|
4528
|
+
for (const entry of (0, import_node_fs11.readdirSync)(path)) {
|
|
4529
|
+
removeAdded((0, import_node_path12.join)(path, entry), undo);
|
|
4530
|
+
}
|
|
4531
|
+
if (!undo.dirs.has(path) && (0, import_node_fs11.readdirSync)(path).length === 0) {
|
|
4532
|
+
(0, import_node_fs11.rmdirSync)(path);
|
|
4533
|
+
}
|
|
4534
|
+
}
|
|
4535
|
+
function pruneAncestors(path, undo) {
|
|
4536
|
+
for (let dir = (0, import_node_path12.dirname)(path); dir.startsWith(undo.root) && dir !== undo.root; dir = (0, import_node_path12.dirname)(dir)) {
|
|
4537
|
+
if (undo.dirs.has(dir)) {
|
|
4538
|
+
return;
|
|
4539
|
+
}
|
|
4540
|
+
try {
|
|
4541
|
+
(0, import_node_fs11.rmdirSync)(dir);
|
|
4542
|
+
} catch {
|
|
4543
|
+
return;
|
|
4544
|
+
}
|
|
4545
|
+
}
|
|
4546
|
+
}
|
|
4547
|
+
|
|
4401
4548
|
// src/seams.ts
|
|
4402
4549
|
function nextjs({ alias, srcDir }) {
|
|
4403
4550
|
return {
|
|
@@ -4553,7 +4700,7 @@ var NOT_ENVIRONMENTS2 = [...import_core25.RESERVED_TOKENS, "example", "sample",
|
|
|
4553
4700
|
function suggestEnvironments(root) {
|
|
4554
4701
|
let entries;
|
|
4555
4702
|
try {
|
|
4556
|
-
entries = (0,
|
|
4703
|
+
entries = (0, import_node_fs12.readdirSync)(root);
|
|
4557
4704
|
} catch {
|
|
4558
4705
|
return [];
|
|
4559
4706
|
}
|
|
@@ -4597,8 +4744,8 @@ function configOf(decisions) {
|
|
|
4597
4744
|
return { environments: decisions.environments, providers: {}, schemaFile: decisions.schemaFile };
|
|
4598
4745
|
}
|
|
4599
4746
|
function declaredIn(root) {
|
|
4600
|
-
const file = (0,
|
|
4601
|
-
if (!(0,
|
|
4747
|
+
const file = (0, import_node_path13.join)(root, CONFIG_FILE);
|
|
4748
|
+
if (!(0, import_node_fs12.existsSync)(file)) {
|
|
4602
4749
|
return void 0;
|
|
4603
4750
|
}
|
|
4604
4751
|
return (0, import_core25.loadConfigFrom)(file);
|
|
@@ -5040,16 +5187,16 @@ function renderTsconfig(target, alias) {
|
|
|
5040
5187
|
`;
|
|
5041
5188
|
}
|
|
5042
5189
|
function ensurePenvDir(root) {
|
|
5043
|
-
const dir = (0,
|
|
5044
|
-
if ((0,
|
|
5190
|
+
const dir = (0, import_node_path13.resolve)(root, import_core25.PENV_DIR);
|
|
5191
|
+
if ((0, import_node_fs12.existsSync)(dir)) {
|
|
5045
5192
|
return { target: "penv-dir", action: "kept", text: `Found ${import_core25.PENV_DIR}/` };
|
|
5046
5193
|
}
|
|
5047
|
-
(0,
|
|
5194
|
+
(0, import_node_fs12.mkdirSync)(dir, { recursive: true });
|
|
5048
5195
|
return { target: "penv-dir", action: "created", text: `Created ${import_core25.PENV_DIR}/` };
|
|
5049
5196
|
}
|
|
5050
5197
|
function writeSchemaShapeFile(root, fields, draft, decisions = DEFAULT_DECISIONS) {
|
|
5051
|
-
const file = (0,
|
|
5052
|
-
if ((0,
|
|
5198
|
+
const file = (0, import_node_path13.join)(root, import_core25.SCHEMA_SHAPE_FILE);
|
|
5199
|
+
if ((0, import_node_fs12.existsSync)(file)) {
|
|
5053
5200
|
return {
|
|
5054
5201
|
target: "schema",
|
|
5055
5202
|
action: "kept",
|
|
@@ -5066,7 +5213,7 @@ function writeSchemaShapeFile(root, fields, draft, decisions = DEFAULT_DECISIONS
|
|
|
5066
5213
|
note: `(the shape lives there, from before the ${import_core25.SCHEMA_SHAPE_FILE} split \u2014 penv did not add a second one. To adopt the split: move the \`z.object\` (and any \`declare module\` block) into ${import_core25.SCHEMA_SHAPE_FILE}, leaving ${oldLayout} importing \`schema\` from it and calling \`load\`.)`
|
|
5067
5214
|
};
|
|
5068
5215
|
}
|
|
5069
|
-
(0,
|
|
5216
|
+
(0, import_node_fs12.writeFileSync)(file, renderSchemaShapeModule(fields, draft), "utf8");
|
|
5070
5217
|
return {
|
|
5071
5218
|
target: "schema",
|
|
5072
5219
|
action: "created",
|
|
@@ -5075,8 +5222,8 @@ function writeSchemaShapeFile(root, fields, draft, decisions = DEFAULT_DECISIONS
|
|
|
5075
5222
|
};
|
|
5076
5223
|
}
|
|
5077
5224
|
function writeEnvFile(root, decisions = DEFAULT_DECISIONS) {
|
|
5078
|
-
const file = (0,
|
|
5079
|
-
if ((0,
|
|
5225
|
+
const file = (0, import_node_path13.join)(root, ...decisions.schemaFile.split("/"));
|
|
5226
|
+
if ((0, import_node_fs12.existsSync)(file)) {
|
|
5080
5227
|
return {
|
|
5081
5228
|
target: "env",
|
|
5082
5229
|
action: "kept",
|
|
@@ -5084,8 +5231,8 @@ function writeEnvFile(root, decisions = DEFAULT_DECISIONS) {
|
|
|
5084
5231
|
note: "(yours \u2014 penv never regenerates it)"
|
|
5085
5232
|
};
|
|
5086
5233
|
}
|
|
5087
|
-
(0,
|
|
5088
|
-
(0,
|
|
5234
|
+
(0, import_node_fs12.mkdirSync)((0, import_node_path13.dirname)(file), { recursive: true });
|
|
5235
|
+
(0, import_node_fs12.writeFileSync)(file, renderEnvModule(decisions.schemaFile, decisions.inject), "utf8");
|
|
5089
5236
|
return {
|
|
5090
5237
|
target: "env",
|
|
5091
5238
|
action: "created",
|
|
@@ -5094,19 +5241,19 @@ function writeEnvFile(root, decisions = DEFAULT_DECISIONS) {
|
|
|
5094
5241
|
};
|
|
5095
5242
|
}
|
|
5096
5243
|
function writeConfigFile(root, decisions = DEFAULT_DECISIONS) {
|
|
5097
|
-
const file = (0,
|
|
5098
|
-
if ((0,
|
|
5244
|
+
const file = (0, import_node_path13.join)(root, CONFIG_FILE);
|
|
5245
|
+
if ((0, import_node_fs12.existsSync)(file)) {
|
|
5099
5246
|
return { target: "config", action: "kept", text: `Kept ${CONFIG_FILE}` };
|
|
5100
5247
|
}
|
|
5101
|
-
(0,
|
|
5248
|
+
(0, import_node_fs12.writeFileSync)(file, renderConfigModule(decisions), "utf8");
|
|
5102
5249
|
return { target: "config", action: "created", text: `Generated ${CONFIG_FILE}` };
|
|
5103
5250
|
}
|
|
5104
5251
|
function writeTsconfigAlias(root, decisions = DEFAULT_DECISIONS) {
|
|
5105
5252
|
const alias = decisions.alias;
|
|
5106
5253
|
const imports = alias.startsWith(IMPORTS_PREFIX);
|
|
5107
|
-
const file = (0,
|
|
5254
|
+
const file = (0, import_node_path13.join)(root, imports ? PACKAGE_FILE : TSCONFIG_FILE);
|
|
5108
5255
|
const where = imports ? PACKAGE_FILE : TSCONFIG_FILE;
|
|
5109
|
-
if (!(0,
|
|
5256
|
+
if (!(0, import_node_fs12.existsSync)(file)) {
|
|
5110
5257
|
if (imports) {
|
|
5111
5258
|
return {
|
|
5112
5259
|
target: "tsconfig",
|
|
@@ -5115,14 +5262,14 @@ function writeTsconfigAlias(root, decisions = DEFAULT_DECISIONS) {
|
|
|
5115
5262
|
note: `(run \`npm init\` first, or use \`--alias @env\` to alias through ${TSCONFIG_FILE})`
|
|
5116
5263
|
};
|
|
5117
5264
|
}
|
|
5118
|
-
(0,
|
|
5265
|
+
(0, import_node_fs12.writeFileSync)(file, renderTsconfig(decisions.schemaFile, alias), "utf8");
|
|
5119
5266
|
return {
|
|
5120
5267
|
target: "tsconfig",
|
|
5121
5268
|
action: "created",
|
|
5122
5269
|
text: `Created ${TSCONFIG_FILE} with the ${alias} path alias`
|
|
5123
5270
|
};
|
|
5124
5271
|
}
|
|
5125
|
-
const source = (0,
|
|
5272
|
+
const source = (0, import_node_fs12.readFileSync)(file, "utf8");
|
|
5126
5273
|
const edit = imports ? insertImportsAlias(source, decisions.schemaFile, alias) : insertEnvAlias(source, decisions.schemaFile, alias);
|
|
5127
5274
|
if (edit.conflict !== void 0) {
|
|
5128
5275
|
return {
|
|
@@ -5139,7 +5286,7 @@ function writeTsconfigAlias(root, decisions = DEFAULT_DECISIONS) {
|
|
|
5139
5286
|
text: `Kept the ${alias} alias in ${where}`
|
|
5140
5287
|
};
|
|
5141
5288
|
}
|
|
5142
|
-
(0,
|
|
5289
|
+
(0, import_node_fs12.writeFileSync)(file, edit.source, "utf8");
|
|
5143
5290
|
return {
|
|
5144
5291
|
target: "tsconfig",
|
|
5145
5292
|
action: "updated",
|
|
@@ -5147,14 +5294,14 @@ function writeTsconfigAlias(root, decisions = DEFAULT_DECISIONS) {
|
|
|
5147
5294
|
};
|
|
5148
5295
|
}
|
|
5149
5296
|
function writeGitignore(root, decisions = DEFAULT_DECISIONS) {
|
|
5150
|
-
const file = (0,
|
|
5297
|
+
const file = (0, import_node_path13.join)(root, ...import_core25.STATE_GITIGNORE_PATH.split("/"));
|
|
5151
5298
|
const wanted = (0, import_core25.renderStateGitignore)(configOf(decisions));
|
|
5152
|
-
const existing = (0,
|
|
5299
|
+
const existing = (0, import_node_fs12.existsSync)(file) ? (0, import_node_fs12.readFileSync)(file, "utf8") : void 0;
|
|
5153
5300
|
if (existing === wanted) {
|
|
5154
5301
|
return { target: "gitignore", action: "kept", text: `Kept ${import_core25.STATE_GITIGNORE_PATH}` };
|
|
5155
5302
|
}
|
|
5156
|
-
(0,
|
|
5157
|
-
(0,
|
|
5303
|
+
(0, import_node_fs12.mkdirSync)((0, import_node_path13.dirname)(file), { recursive: true });
|
|
5304
|
+
(0, import_node_fs12.writeFileSync)(file, wanted, "utf8");
|
|
5158
5305
|
return {
|
|
5159
5306
|
target: "gitignore",
|
|
5160
5307
|
action: existing === void 0 ? "created" : "updated",
|
|
@@ -5170,12 +5317,12 @@ function outdatedRuntimeWarning(root) {
|
|
|
5170
5317
|
return `Injection needs @penvhq/penv ${INJECT_MIN_VERSION}+ \u2014 this project has ${version}, whose \`load\` ignores \`{ inject: true }\`. Upgrade, or process.env stays empty.`;
|
|
5171
5318
|
}
|
|
5172
5319
|
function installedPenvVersion(root) {
|
|
5173
|
-
const file = (0,
|
|
5174
|
-
if (!(0,
|
|
5320
|
+
const file = (0, import_node_path13.join)(root, "node_modules", "@penvhq", "penv", "package.json");
|
|
5321
|
+
if (!(0, import_node_fs12.existsSync)(file)) {
|
|
5175
5322
|
return void 0;
|
|
5176
5323
|
}
|
|
5177
5324
|
try {
|
|
5178
|
-
const version = JSON.parse((0,
|
|
5325
|
+
const version = JSON.parse((0, import_node_fs12.readFileSync)(file, "utf8")).version;
|
|
5179
5326
|
return typeof version === "string" ? version : void 0;
|
|
5180
5327
|
} catch {
|
|
5181
5328
|
return void 0;
|
|
@@ -5215,11 +5362,11 @@ function writeSeam(root, decisions = DEFAULT_DECISIONS, framework = detectFramew
|
|
|
5215
5362
|
};
|
|
5216
5363
|
}
|
|
5217
5364
|
const alsoNote = writeAlso(root, seam.also);
|
|
5218
|
-
const file = (0,
|
|
5365
|
+
const file = (0, import_node_path13.join)(root, ...seam.file.split("/"));
|
|
5219
5366
|
const baseNotes = [...seam.notes, ...alsoNote === void 0 ? [] : [alsoNote]];
|
|
5220
5367
|
const notes = baseNotes.length === 0 ? "" : `
|
|
5221
5368
|
${baseNotes.map((n) => ` ${n}`).join("\n")}`;
|
|
5222
|
-
if ((0,
|
|
5369
|
+
if ((0, import_node_fs12.existsSync)(file)) {
|
|
5223
5370
|
return {
|
|
5224
5371
|
target: "seam",
|
|
5225
5372
|
action: "info",
|
|
@@ -5227,8 +5374,8 @@ ${baseNotes.map((n) => ` ${n}`).join("\n")}`;
|
|
|
5227
5374
|
note: withWarning(`${seam.ifPresent}${notes}`, outdated)
|
|
5228
5375
|
};
|
|
5229
5376
|
}
|
|
5230
|
-
(0,
|
|
5231
|
-
(0,
|
|
5377
|
+
(0, import_node_fs12.mkdirSync)((0, import_node_path13.dirname)(file), { recursive: true });
|
|
5378
|
+
(0, import_node_fs12.writeFileSync)(file, seam.content, "utf8");
|
|
5232
5379
|
return {
|
|
5233
5380
|
target: "seam",
|
|
5234
5381
|
action: outdated === void 0 ? "created" : "info",
|
|
@@ -5240,12 +5387,12 @@ function writeAlso(root, also) {
|
|
|
5240
5387
|
if (also === void 0) {
|
|
5241
5388
|
return void 0;
|
|
5242
5389
|
}
|
|
5243
|
-
const file = (0,
|
|
5244
|
-
if ((0,
|
|
5390
|
+
const file = (0, import_node_path13.join)(root, ...also.file.split("/"));
|
|
5391
|
+
if ((0, import_node_fs12.existsSync)(file)) {
|
|
5245
5392
|
return also.ifPresent;
|
|
5246
5393
|
}
|
|
5247
|
-
(0,
|
|
5248
|
-
(0,
|
|
5394
|
+
(0, import_node_fs12.mkdirSync)((0, import_node_path13.dirname)(file), { recursive: true });
|
|
5395
|
+
(0, import_node_fs12.writeFileSync)(file, also.content, "utf8");
|
|
5249
5396
|
return `Wrote ${also.file} to register it.`;
|
|
5250
5397
|
}
|
|
5251
5398
|
function withWarning(note, warning) {
|
|
@@ -5270,6 +5417,23 @@ function scaffold(root, fields, draft, decisions = DEFAULT_DECISIONS, framework
|
|
|
5270
5417
|
const seam = writeSeam(root, decisions, framework);
|
|
5271
5418
|
return seam === void 0 ? steps : [...steps, seam];
|
|
5272
5419
|
}
|
|
5420
|
+
function scaffoldPaths(root, decisions = DEFAULT_DECISIONS, framework = detectFramework(root)?.name) {
|
|
5421
|
+
const fileAt = (relative5) => (0, import_node_path13.join)(root, ...relative5.split("/"));
|
|
5422
|
+
const seam = decisions.inject ? seamFor(framework, {
|
|
5423
|
+
alias: decisions.alias,
|
|
5424
|
+
srcDir: srcPrefix(root),
|
|
5425
|
+
schemaFile: decisions.schemaFile
|
|
5426
|
+
}) : void 0;
|
|
5427
|
+
return [
|
|
5428
|
+
fileAt(import_core25.PENV_DIR),
|
|
5429
|
+
fileAt(import_core25.SCHEMA_SHAPE_FILE),
|
|
5430
|
+
fileAt(decisions.schemaFile),
|
|
5431
|
+
fileAt(CONFIG_FILE),
|
|
5432
|
+
fileAt(TSCONFIG_FILE),
|
|
5433
|
+
fileAt(PACKAGE_FILE),
|
|
5434
|
+
...seam?.kind === "scaffold" ? [fileAt(seam.file), ...seam.also === void 0 ? [] : [fileAt(seam.also.file)]] : []
|
|
5435
|
+
];
|
|
5436
|
+
}
|
|
5273
5437
|
var DEVELOPMENT = "development";
|
|
5274
5438
|
var LOCAL_PROVIDER = "@penvhq/provider-filesystem";
|
|
5275
5439
|
function planAdoption(root) {
|
|
@@ -5332,7 +5496,7 @@ function planCutover(input) {
|
|
|
5332
5496
|
const diagnostics = [];
|
|
5333
5497
|
let variables = 0;
|
|
5334
5498
|
for (const file of selected) {
|
|
5335
|
-
const parsed = (0, import_core25.parseDotenv)((0,
|
|
5499
|
+
const parsed = (0, import_core25.parseDotenv)((0, import_node_fs12.readFileSync)((0, import_node_path13.join)(root, file.name), "utf8"));
|
|
5336
5500
|
const fileRefs = refsForEntries(parsed.entries, file.name, config);
|
|
5337
5501
|
adopted.push({ file, entries: parsed.entries, refs: fileRefs, scope: scopeOf(file) });
|
|
5338
5502
|
refs.push(...fileRefs);
|
|
@@ -5443,17 +5607,27 @@ async function applyCutover(plan2, options = {}) {
|
|
|
5443
5607
|
if (!plan2.install.satisfied) {
|
|
5444
5608
|
await (options.install ?? installWithPackageManager)(plan2.install);
|
|
5445
5609
|
}
|
|
5446
|
-
const
|
|
5447
|
-
|
|
5448
|
-
|
|
5449
|
-
|
|
5450
|
-
|
|
5451
|
-
|
|
5452
|
-
|
|
5453
|
-
|
|
5454
|
-
|
|
5455
|
-
|
|
5610
|
+
const undo = captureScaffold(plan2.root, scaffoldPaths(plan2.root, plan2.decisions, plan2.framework));
|
|
5611
|
+
let steps;
|
|
5612
|
+
try {
|
|
5613
|
+
steps = scaffold(plan2.root, plan2.fields, true, plan2.decisions, plan2.framework);
|
|
5614
|
+
const project = openProject(plan2.root);
|
|
5615
|
+
const tree = localTree(project);
|
|
5616
|
+
for (const adopted of plan2.adopted) {
|
|
5617
|
+
writeEntries(tree, adopted.entries, adopted.refs, adopted.scope);
|
|
5618
|
+
}
|
|
5619
|
+
for (const environment of plan2.adopting) {
|
|
5620
|
+
const check = await checkEnvironment(project, environment);
|
|
5621
|
+
if (check.schema === void 0) {
|
|
5622
|
+
throw draftNotLoaded(check.result);
|
|
5623
|
+
}
|
|
5624
|
+
if (!check.result.ok) {
|
|
5625
|
+
throw invalidAfterImport(check.result);
|
|
5626
|
+
}
|
|
5456
5627
|
}
|
|
5628
|
+
} catch (error) {
|
|
5629
|
+
restoreScaffold(undo);
|
|
5630
|
+
throw error;
|
|
5457
5631
|
}
|
|
5458
5632
|
const cutover = bundleDotenvFiles(
|
|
5459
5633
|
plan2.root,
|
|
@@ -5462,13 +5636,24 @@ async function applyCutover(plan2, options = {}) {
|
|
|
5462
5636
|
);
|
|
5463
5637
|
return { plan: plan2, steps, moved: cutover.files, validated: plan2.adopting };
|
|
5464
5638
|
}
|
|
5639
|
+
function issueLines(result2) {
|
|
5640
|
+
return result2.issues.map((issue) => ` ${issue.subject}: ${issue.message}`).join("\n");
|
|
5641
|
+
}
|
|
5642
|
+
var SCAFFOLD_ROLLED_BACK = "penv put the project back as it found it \u2014 your dotenv files and everything else are exactly where they were.";
|
|
5465
5643
|
function invalidAfterImport(result2) {
|
|
5466
|
-
const lines = result2.issues.map((issue) => ` ${issue.subject}: ${issue.message}`).join("\n");
|
|
5467
5644
|
return new import_core25.PenvError(
|
|
5468
5645
|
"INIT_CUTOVER_INVALID",
|
|
5469
|
-
`The imported values do not satisfy the draft schema for ${result2.environment}
|
|
5470
|
-
${
|
|
5471
|
-
`Correct
|
|
5646
|
+
`The imported values do not satisfy the draft schema for ${result2.environment}:
|
|
5647
|
+
${issueLines(result2)}`,
|
|
5648
|
+
`Correct the values above, then run \`penv init\` again. ${SCAFFOLD_ROLLED_BACK}`
|
|
5649
|
+
);
|
|
5650
|
+
}
|
|
5651
|
+
function draftNotLoaded(result2) {
|
|
5652
|
+
return new import_core25.PenvError(
|
|
5653
|
+
"INIT_DRAFT_NOT_LOADED",
|
|
5654
|
+
`penv could not load the schema it drafted for ${result2.environment}, so nothing was checked against it:
|
|
5655
|
+
${issueLines(result2)}`,
|
|
5656
|
+
`Fix the error above, then run \`penv init\` again. ${SCAFFOLD_ROLLED_BACK}`
|
|
5472
5657
|
);
|
|
5473
5658
|
}
|
|
5474
5659
|
function renderSelection(plan2, selected = plan2.preselected) {
|
|
@@ -5531,7 +5716,7 @@ function renderCutover(result2) {
|
|
|
5531
5716
|
const glyph = step.action === "conflicted" ? WARN : step.action === "info" ? "\u2192" : CHECK;
|
|
5532
5717
|
return step.note === void 0 ? { glyph, text: step.text } : { glyph, text: step.text, note: step.note };
|
|
5533
5718
|
}),
|
|
5534
|
-
...plan2.install.
|
|
5719
|
+
...plan2.install.packages.filter((entry) => !entry.satisfied).map((entry) => ({ glyph: CHECK, text: `Installed ${entry.name}`, note: entry.version })),
|
|
5535
5720
|
{
|
|
5536
5721
|
glyph: CHECK,
|
|
5537
5722
|
text: `Imported ${plan2.fields.length} parameters`,
|
|
@@ -5555,12 +5740,12 @@ function dailyCommand(root) {
|
|
|
5555
5740
|
return `penv run -- ${detectPackageManager(root)} ${devScript(root)}`;
|
|
5556
5741
|
}
|
|
5557
5742
|
function devScript(root) {
|
|
5558
|
-
const file = (0,
|
|
5559
|
-
if (!(0,
|
|
5743
|
+
const file = (0, import_node_path13.join)(root, PACKAGE_FILE);
|
|
5744
|
+
if (!(0, import_node_fs12.existsSync)(file)) {
|
|
5560
5745
|
return "dev";
|
|
5561
5746
|
}
|
|
5562
5747
|
try {
|
|
5563
|
-
const scripts = JSON.parse((0,
|
|
5748
|
+
const scripts = JSON.parse((0, import_node_fs12.readFileSync)(file, "utf8")).scripts;
|
|
5564
5749
|
if (scripts !== null && typeof scripts === "object" && !Array.isArray(scripts)) {
|
|
5565
5750
|
const named = Object.keys(scripts);
|
|
5566
5751
|
return ["dev", "start"].find((script) => named.includes(script)) ?? named[0] ?? "dev";
|
|
@@ -5570,7 +5755,7 @@ function devScript(root) {
|
|
|
5570
5755
|
return "dev";
|
|
5571
5756
|
}
|
|
5572
5757
|
function runInit(options) {
|
|
5573
|
-
const root = (0,
|
|
5758
|
+
const root = (0, import_node_path13.resolve)(options.cwd);
|
|
5574
5759
|
const decisions = options.decisions ?? planInit(root).decisions;
|
|
5575
5760
|
return { root, decisions, steps: scaffold(root, [], false, decisions, options.framework) };
|
|
5576
5761
|
}
|
|
@@ -5733,7 +5918,7 @@ var initCommand = (0, import_citty13.defineCommand)({
|
|
|
5733
5918
|
},
|
|
5734
5919
|
run({ args }) {
|
|
5735
5920
|
return guard(async () => {
|
|
5736
|
-
const root = (0,
|
|
5921
|
+
const root = (0, import_node_path13.resolve)(process.cwd());
|
|
5737
5922
|
if (args.action !== void 0) {
|
|
5738
5923
|
runUndoAction(root, String(args.action));
|
|
5739
5924
|
return;
|
|
@@ -5809,7 +5994,7 @@ function assertDeclared(segment, config) {
|
|
|
5809
5994
|
throw new import_core26.UnknownEnvironmentError(segment, config.environments);
|
|
5810
5995
|
}
|
|
5811
5996
|
function scopeFromFilename(file, config) {
|
|
5812
|
-
const name = (0,
|
|
5997
|
+
const name = (0, import_node_path14.basename)(file);
|
|
5813
5998
|
const segments = name.split(".");
|
|
5814
5999
|
const start = segments.indexOf(DOTENV_SEGMENT);
|
|
5815
6000
|
if (start === -1) {
|
|
@@ -5893,7 +6078,7 @@ function environmentNamed(file, explicit) {
|
|
|
5893
6078
|
if (explicit !== void 0 && explicit.trim().length > 0) {
|
|
5894
6079
|
return explicit.trim();
|
|
5895
6080
|
}
|
|
5896
|
-
const segments = (0,
|
|
6081
|
+
const segments = (0, import_node_path14.basename)(file).split(".");
|
|
5897
6082
|
const start = segments.indexOf(DOTENV_SEGMENT);
|
|
5898
6083
|
if (start === -1) {
|
|
5899
6084
|
return void 0;
|
|
@@ -5927,16 +6112,16 @@ function configInEffect(cwd, environment) {
|
|
|
5927
6112
|
return { config: openProject(cwd).config, decisions };
|
|
5928
6113
|
}
|
|
5929
6114
|
function importDotenv(options) {
|
|
5930
|
-
const cwd = (0,
|
|
5931
|
-
const file = (0,
|
|
5932
|
-
if (!(0,
|
|
6115
|
+
const cwd = (0, import_node_path14.resolve)(options.cwd);
|
|
6116
|
+
const file = (0, import_node_path14.isAbsolute)(options.file) ? options.file : (0, import_node_path14.resolve)(cwd, options.file);
|
|
6117
|
+
if (!(0, import_node_fs13.existsSync)(file)) {
|
|
5933
6118
|
throw new import_core26.PenvError(
|
|
5934
6119
|
"IMPORT_FILE_MISSING",
|
|
5935
6120
|
`There is no file at ${file} to import`,
|
|
5936
6121
|
"Point `penv import` at an existing dotenv file, e.g. `penv import .env`."
|
|
5937
6122
|
);
|
|
5938
6123
|
}
|
|
5939
|
-
const parsed = (0, import_core26.parseDotenv)((0,
|
|
6124
|
+
const parsed = (0, import_core26.parseDotenv)((0, import_node_fs13.readFileSync)(file, "utf8"));
|
|
5940
6125
|
const { config, decisions } = configInEffect(cwd, environmentNamed(file, options.environment));
|
|
5941
6126
|
const source = displayPath3(cwd, file);
|
|
5942
6127
|
const named = scopeFromFilename(file, config);
|
|
@@ -5952,7 +6137,7 @@ function importDotenv(options) {
|
|
|
5952
6137
|
const tree = localTree(project);
|
|
5953
6138
|
writeEntries(tree, parsed.entries, refs, scope);
|
|
5954
6139
|
const backup = `${file}${BACKUP_SUFFIX}`;
|
|
5955
|
-
(0,
|
|
6140
|
+
(0, import_node_fs13.copyFileSync)(file, backup);
|
|
5956
6141
|
return {
|
|
5957
6142
|
root: project.root,
|
|
5958
6143
|
file,
|
|
@@ -5966,7 +6151,7 @@ function importDotenv(options) {
|
|
|
5966
6151
|
};
|
|
5967
6152
|
}
|
|
5968
6153
|
function displayPath3(root, file) {
|
|
5969
|
-
const rel = (0,
|
|
6154
|
+
const rel = (0, import_node_path14.relative)(root, file);
|
|
5970
6155
|
return rel === "" || rel.startsWith("..") ? file : rel.split("\\").join("/");
|
|
5971
6156
|
}
|
|
5972
6157
|
function keptSchemaStep(step, variables) {
|
|
@@ -6287,30 +6472,30 @@ var listCommand = (0, import_citty16.defineCommand)({
|
|
|
6287
6472
|
});
|
|
6288
6473
|
|
|
6289
6474
|
// src/commands/migrate.ts
|
|
6290
|
-
var
|
|
6291
|
-
var
|
|
6475
|
+
var import_node_fs14 = require("fs");
|
|
6476
|
+
var import_node_path15 = require("path");
|
|
6292
6477
|
var import_promises2 = require("readline/promises");
|
|
6293
6478
|
var import_core30 = require("@penvhq/core");
|
|
6294
6479
|
var import_citty17 = require("citty");
|
|
6295
6480
|
var OLD_GITIGNORE = `${import_core30.PENV_DIR}/.gitignore`;
|
|
6296
6481
|
function planMigrate(cwd) {
|
|
6297
6482
|
const { config, file } = (0, import_core30.loadConfig)(cwd);
|
|
6298
|
-
const root = (0,
|
|
6483
|
+
const root = (0, import_node_path15.dirname)(file);
|
|
6299
6484
|
const entries = (0, import_core30.oldLayoutEntries)(root, config);
|
|
6300
6485
|
const tree = (0, import_core30.recordsDir)(root);
|
|
6301
6486
|
const collisions = collidingEntries(entries, tree);
|
|
6302
6487
|
if (collisions.length > 0) {
|
|
6303
6488
|
throw new import_core30.PenvError(
|
|
6304
6489
|
"HALF_MIGRATED",
|
|
6305
|
-
`${
|
|
6490
|
+
`${describe2(collisions)} in both \`${import_core30.PENV_DIR}/\` and \`${import_core30.RECORDS_PATH}/\`, and penv cannot tell which copy is current`,
|
|
6306
6491
|
`Move what is left under \`${import_core30.PENV_DIR}/\` into \`${import_core30.RECORDS_PATH}/\` yourself, keeping the copy you want, then run \`penv validate\`.`
|
|
6307
6492
|
);
|
|
6308
6493
|
}
|
|
6309
6494
|
const creates = [];
|
|
6310
|
-
if (entries.length > 0 && !(0,
|
|
6495
|
+
if (entries.length > 0 && !(0, import_node_fs14.existsSync)(tree)) {
|
|
6311
6496
|
creates.push(`${import_core30.RECORDS_PATH}/`);
|
|
6312
6497
|
}
|
|
6313
|
-
if (readIfPresent((0,
|
|
6498
|
+
if (readIfPresent((0, import_node_path15.join)(root, ...import_core30.STATE_GITIGNORE_PATH.split("/"))) !== (0, import_core30.renderStateGitignore)(config)) {
|
|
6314
6499
|
creates.push(import_core30.STATE_GITIGNORE_PATH);
|
|
6315
6500
|
}
|
|
6316
6501
|
return {
|
|
@@ -6320,23 +6505,23 @@ function planMigrate(cwd) {
|
|
|
6320
6505
|
to: `${import_core30.RECORDS_PATH}/${entry}`
|
|
6321
6506
|
})),
|
|
6322
6507
|
creates,
|
|
6323
|
-
removes: (0,
|
|
6508
|
+
removes: (0, import_node_fs14.existsSync)((0, import_node_path15.join)(root, ...OLD_GITIGNORE.split("/"))) ? [OLD_GITIGNORE] : []
|
|
6324
6509
|
};
|
|
6325
6510
|
}
|
|
6326
6511
|
function readIfPresent(file) {
|
|
6327
|
-
return (0,
|
|
6512
|
+
return (0, import_node_fs14.existsSync)(file) ? (0, import_node_fs14.readFileSync)(file, "utf8") : void 0;
|
|
6328
6513
|
}
|
|
6329
6514
|
function collidingEntries(entries, tree) {
|
|
6330
6515
|
let held;
|
|
6331
6516
|
try {
|
|
6332
|
-
held = (0,
|
|
6517
|
+
held = (0, import_node_fs14.readdirSync)(tree);
|
|
6333
6518
|
} catch {
|
|
6334
6519
|
return [];
|
|
6335
6520
|
}
|
|
6336
6521
|
const taken = new Set(held.map((name) => name.toLowerCase()));
|
|
6337
6522
|
return entries.filter((entry) => taken.has(entry.toLowerCase())).sort();
|
|
6338
6523
|
}
|
|
6339
|
-
function
|
|
6524
|
+
function describe2(names) {
|
|
6340
6525
|
return names.length === 1 ? `\`${names[0]}\` is` : `${names.map((name) => `\`${name}\``).join(", ")} are`;
|
|
6341
6526
|
}
|
|
6342
6527
|
function isNoop(plan2) {
|
|
@@ -6348,18 +6533,18 @@ function applyMigrate(plan2) {
|
|
|
6348
6533
|
}
|
|
6349
6534
|
const { config } = (0, import_core30.loadConfig)(plan2.root);
|
|
6350
6535
|
if (plan2.moves.length > 0) {
|
|
6351
|
-
(0,
|
|
6536
|
+
(0, import_node_fs14.mkdirSync)((0, import_core30.recordsDir)(plan2.root), { recursive: true });
|
|
6352
6537
|
for (const move of plan2.moves) {
|
|
6353
|
-
(0,
|
|
6538
|
+
(0, import_node_fs14.renameSync)((0, import_node_path15.join)(plan2.root, ...move.from.split("/")), (0, import_node_path15.join)(plan2.root, ...move.to.split("/")));
|
|
6354
6539
|
}
|
|
6355
6540
|
}
|
|
6356
6541
|
if (plan2.creates.includes(import_core30.STATE_GITIGNORE_PATH)) {
|
|
6357
|
-
const ignore = (0,
|
|
6358
|
-
(0,
|
|
6359
|
-
(0,
|
|
6542
|
+
const ignore = (0, import_node_path15.join)(plan2.root, ...import_core30.STATE_GITIGNORE_PATH.split("/"));
|
|
6543
|
+
(0, import_node_fs14.mkdirSync)((0, import_node_path15.dirname)(ignore), { recursive: true });
|
|
6544
|
+
(0, import_node_fs14.writeFileSync)(ignore, (0, import_core30.renderStateGitignore)(config), "utf8");
|
|
6360
6545
|
}
|
|
6361
6546
|
for (const removed of plan2.removes) {
|
|
6362
|
-
(0,
|
|
6547
|
+
(0, import_node_fs14.rmSync)((0, import_node_path15.join)(plan2.root, ...removed.split("/")), { force: true });
|
|
6363
6548
|
}
|
|
6364
6549
|
return { ...plan2, status: "migrated" };
|
|
6365
6550
|
}
|
|
@@ -6845,14 +7030,14 @@ var rotateCommand = (0, import_citty20.defineCommand)({
|
|
|
6845
7030
|
});
|
|
6846
7031
|
|
|
6847
7032
|
// src/commands/watch.ts
|
|
6848
|
-
var
|
|
6849
|
-
var
|
|
7033
|
+
var import_node_fs15 = require("fs");
|
|
7034
|
+
var import_node_path16 = require("path");
|
|
6850
7035
|
var import_core34 = require("@penvhq/core");
|
|
6851
7036
|
var import_citty21 = require("citty");
|
|
6852
7037
|
var DEBOUNCE_MS2 = 100;
|
|
6853
7038
|
function runWatch(options) {
|
|
6854
7039
|
const project = openProject(options.cwd);
|
|
6855
|
-
const configFile = (0,
|
|
7040
|
+
const configFile = (0, import_node_path16.basename)(project.configFile);
|
|
6856
7041
|
const debounceMs = options.debounceMs ?? DEBOUNCE_MS2;
|
|
6857
7042
|
const watchers = /* @__PURE__ */ new Set();
|
|
6858
7043
|
let timer;
|
|
@@ -6905,22 +7090,22 @@ function runWatch(options) {
|
|
|
6905
7090
|
watcher.close();
|
|
6906
7091
|
}
|
|
6907
7092
|
function armRecovery(target, recursive, only) {
|
|
6908
|
-
const parent = (0,
|
|
6909
|
-
const name = (0,
|
|
7093
|
+
const parent = (0, import_node_path16.dirname)(target);
|
|
7094
|
+
const name = (0, import_node_path16.basename)(target);
|
|
6910
7095
|
let recovery;
|
|
6911
7096
|
try {
|
|
6912
|
-
recovery = (0,
|
|
7097
|
+
recovery = (0, import_node_fs15.watch)(parent, { recursive: false }, (_event, filename) => {
|
|
6913
7098
|
if (closed || recovery === void 0) {
|
|
6914
7099
|
return;
|
|
6915
7100
|
}
|
|
6916
|
-
if (!(0,
|
|
7101
|
+
if (!(0, import_node_fs15.existsSync)(parent)) {
|
|
6917
7102
|
stop2(recovery);
|
|
6918
7103
|
return;
|
|
6919
7104
|
}
|
|
6920
|
-
if (filename !== null && (0,
|
|
7105
|
+
if (filename !== null && (0, import_node_path16.basename)(filename) !== name) {
|
|
6921
7106
|
return;
|
|
6922
7107
|
}
|
|
6923
|
-
if (!(0,
|
|
7108
|
+
if (!(0, import_node_fs15.existsSync)(target)) {
|
|
6924
7109
|
return;
|
|
6925
7110
|
}
|
|
6926
7111
|
stop2(recovery);
|
|
@@ -6940,11 +7125,11 @@ function runWatch(options) {
|
|
|
6940
7125
|
}
|
|
6941
7126
|
function addWatcher(target, recursive, only) {
|
|
6942
7127
|
let watcher;
|
|
6943
|
-
const listen = (useRecursive) => (0,
|
|
7128
|
+
const listen = (useRecursive) => (0, import_node_fs15.watch)(target, { recursive: useRecursive }, (_event, filename) => {
|
|
6944
7129
|
if (closed) {
|
|
6945
7130
|
return;
|
|
6946
7131
|
}
|
|
6947
|
-
if (!(0,
|
|
7132
|
+
if (!(0, import_node_fs15.existsSync)(target)) {
|
|
6948
7133
|
if (watcher !== void 0) {
|
|
6949
7134
|
stop2(watcher);
|
|
6950
7135
|
}
|
|
@@ -6952,7 +7137,7 @@ function runWatch(options) {
|
|
|
6952
7137
|
schedule();
|
|
6953
7138
|
return;
|
|
6954
7139
|
}
|
|
6955
|
-
if (only !== void 0 && (filename === null || (0,
|
|
7140
|
+
if (only !== void 0 && (filename === null || (0, import_node_path16.basename)(filename) !== only)) {
|
|
6956
7141
|
return;
|
|
6957
7142
|
}
|
|
6958
7143
|
schedule();
|
|
@@ -6979,11 +7164,11 @@ function runWatch(options) {
|
|
|
6979
7164
|
watchers.add(watcher);
|
|
6980
7165
|
}
|
|
6981
7166
|
addWatcher(project.recordsDir, true);
|
|
6982
|
-
addWatcher((0,
|
|
7167
|
+
addWatcher((0, import_node_path16.dirname)(project.configFile), false, configFile);
|
|
6983
7168
|
addWatcher(project.root, false, import_core34.SCHEMA_SHAPE_FILE);
|
|
6984
7169
|
if ((0, import_core34.schemaInsideTree)(project.config) === void 0) {
|
|
6985
|
-
const schemaFile = (0,
|
|
6986
|
-
addWatcher((0,
|
|
7170
|
+
const schemaFile = (0, import_node_path16.resolve)(project.root, (0, import_core34.schemaFileOf)(project.config));
|
|
7171
|
+
addWatcher((0, import_node_path16.dirname)(schemaFile), false, (0, import_node_path16.basename)(schemaFile));
|
|
6987
7172
|
}
|
|
6988
7173
|
void validate();
|
|
6989
7174
|
return {
|