@biffo/cli 0.69.1 → 0.69.2
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/index.js +90 -17
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -125,6 +125,31 @@ function readInstanceCoreVersion(cwd) {
|
|
|
125
125
|
}
|
|
126
126
|
return result.data.version;
|
|
127
127
|
}
|
|
128
|
+
function planCoreVersionCleanup(cwd) {
|
|
129
|
+
const path = join(cwd, CORE_VERSION_FILE);
|
|
130
|
+
if (!existsSync(path)) return null;
|
|
131
|
+
const found = readFileSync(path, "utf8").trim();
|
|
132
|
+
if (!existsSync(join(cwd, INSTANCE_CORE_FILE))) {
|
|
133
|
+
return { path, action: "keep", found, reason: "no-authority" };
|
|
134
|
+
}
|
|
135
|
+
let authority;
|
|
136
|
+
try {
|
|
137
|
+
authority = readInstanceCoreVersion(cwd);
|
|
138
|
+
} catch {
|
|
139
|
+
return { path, action: "keep", found, reason: "no-authority" };
|
|
140
|
+
}
|
|
141
|
+
if (authority !== null && coreVersionsEqual(found, authority)) {
|
|
142
|
+
return { path, action: "delete", found };
|
|
143
|
+
}
|
|
144
|
+
return { path, action: "keep", found, reason: "repurposed" };
|
|
145
|
+
}
|
|
146
|
+
function coreVersionsEqual(a, b) {
|
|
147
|
+
try {
|
|
148
|
+
return compareCoreVersions(a, b) === 0;
|
|
149
|
+
} catch {
|
|
150
|
+
return false;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
128
153
|
function serializeInstanceCoreVersion(version) {
|
|
129
154
|
parseCoreVersion(version);
|
|
130
155
|
return `${JSON.stringify({ version }, null, 2)}
|
|
@@ -407,7 +432,7 @@ async function runCoreStatus(options) {
|
|
|
407
432
|
|
|
408
433
|
// src/commands/core-upgrade.ts
|
|
409
434
|
import { execSync as execSync2 } from "child_process";
|
|
410
|
-
import { existsSync as existsSync10 } from "fs";
|
|
435
|
+
import { existsSync as existsSync10, rmSync as rmSync5 } from "fs";
|
|
411
436
|
import { join as join11, resolve as resolve3 } from "path";
|
|
412
437
|
import chalk4 from "chalk";
|
|
413
438
|
import { execa as execa3 } from "execa";
|
|
@@ -2182,6 +2207,7 @@ async function runCoreUpgradeResolved(options, deps, cleanups) {
|
|
|
2182
2207
|
console.log(` target: ${toVersion}
|
|
2183
2208
|
`);
|
|
2184
2209
|
const migrations = planMigrationCarry({ templateDir: theirsDir, instanceDir: options.cwd });
|
|
2210
|
+
const coreVersionCleanup = planCoreVersionCleanup(options.cwd);
|
|
2185
2211
|
if (plan.changes.length === 0 && migrations.entries.length === 0) {
|
|
2186
2212
|
log.success("Nothing to upgrade \u2014 the instance already matches the target for all core files.");
|
|
2187
2213
|
return;
|
|
@@ -2196,6 +2222,7 @@ async function runCoreUpgradeResolved(options, deps, cleanups) {
|
|
|
2196
2222
|
printBreakingChanges(breaking, options.apply === true);
|
|
2197
2223
|
printPlan(plan);
|
|
2198
2224
|
printMigrationCarry(migrations);
|
|
2225
|
+
printCoreVersionCleanup(coreVersionCleanup, options.apply === true);
|
|
2199
2226
|
warnStaleFirstPartyCopies(options.cwd);
|
|
2200
2227
|
console.log(
|
|
2201
2228
|
`
|
|
@@ -2210,9 +2237,19 @@ async function runCoreUpgradeResolved(options, deps, cleanups) {
|
|
|
2210
2237
|
);
|
|
2211
2238
|
return;
|
|
2212
2239
|
}
|
|
2213
|
-
await applyAndOpenPr(
|
|
2240
|
+
await applyAndOpenPr(
|
|
2241
|
+
options,
|
|
2242
|
+
deps,
|
|
2243
|
+
plan,
|
|
2244
|
+
migrations,
|
|
2245
|
+
fromVersion,
|
|
2246
|
+
toVersion,
|
|
2247
|
+
breaking,
|
|
2248
|
+
theirsDir,
|
|
2249
|
+
coreVersionCleanup
|
|
2250
|
+
);
|
|
2214
2251
|
}
|
|
2215
|
-
async function applyAndOpenPr(options, deps, plan, migrations, fromVersion, toVersion, breaking, theirsDir) {
|
|
2252
|
+
async function applyAndOpenPr(options, deps, plan, migrations, fromVersion, toVersion, breaking, theirsDir, coreVersionCleanup) {
|
|
2216
2253
|
if (breaking.length > 0 && !options.acknowledgeBreaking) {
|
|
2217
2254
|
throw new Error(
|
|
2218
2255
|
`This upgrade crosses ${breaking.length} documented breaking change(s): ${breaking.map((b) => b.version).join(", ")}. They are printed above and in ${UPGRADE_GUIDE_PATH}. Read what each one requires \u2014 some destroy data or need manual work after the deploy \u2014 then re-run with --acknowledge-breaking.`
|
|
@@ -2234,10 +2271,17 @@ async function applyAndOpenPr(options, deps, plan, migrations, fromVersion, toVe
|
|
|
2234
2271
|
const applied = applyUpgradePlan(options.cwd, plan, theirsDir);
|
|
2235
2272
|
const carried = applyMigrationCarry(options.cwd, migrations);
|
|
2236
2273
|
writeInstanceCoreVersion(options.cwd, toVersion);
|
|
2274
|
+
const cleanedCoreVersion = coreVersionCleanup?.action === "delete";
|
|
2275
|
+
if (cleanedCoreVersion && existsSync10(coreVersionCleanup.path)) {
|
|
2276
|
+
rmSync5(coreVersionCleanup.path);
|
|
2277
|
+
log.info(
|
|
2278
|
+
`Deleted orphaned ${CORE_VERSION_FILE} (inherited copy recording ${coreVersionCleanup.found}, superseded by biffo.core.json) \u2014 nothing reads it as an authority (#434).`
|
|
2279
|
+
);
|
|
2280
|
+
}
|
|
2237
2281
|
log.step(
|
|
2238
2282
|
2,
|
|
2239
2283
|
4,
|
|
2240
|
-
`Applied ${applied.written.length} change(s), ${applied.deleted.length} deletion(s), ${carried.length} new migration(s)`
|
|
2284
|
+
`Applied ${applied.written.length} change(s), ${applied.deleted.length + (cleanedCoreVersion ? 1 : 0)} deletion(s), ${carried.length} new migration(s)`
|
|
2241
2285
|
);
|
|
2242
2286
|
const lockfiles = await refreshInstanceLockfiles(options.cwd, applied, deps);
|
|
2243
2287
|
await git.add(options.cwd, ["-A"]);
|
|
@@ -2257,7 +2301,16 @@ async function applyAndOpenPr(options, deps, plan, migrations, fromVersion, toVe
|
|
|
2257
2301
|
head: branch,
|
|
2258
2302
|
base,
|
|
2259
2303
|
title: `Upgrade Biffo core ${fromVersion} \u2192 ${toVersion}`,
|
|
2260
|
-
body: buildPrBody(
|
|
2304
|
+
body: buildPrBody(
|
|
2305
|
+
fromVersion,
|
|
2306
|
+
toVersion,
|
|
2307
|
+
plan,
|
|
2308
|
+
migrations,
|
|
2309
|
+
base,
|
|
2310
|
+
lockfiles,
|
|
2311
|
+
breaking,
|
|
2312
|
+
cleanedCoreVersion ? coreVersionCleanup : null
|
|
2313
|
+
)
|
|
2261
2314
|
});
|
|
2262
2315
|
if (plan.conflicts.length > 0) {
|
|
2263
2316
|
log.warn(`PR opened with ${plan.conflicts.length} conflict(s) to resolve: ${pr.url}`);
|
|
@@ -2265,7 +2318,7 @@ async function applyAndOpenPr(options, deps, plan, migrations, fromVersion, toVe
|
|
|
2265
2318
|
log.success(`Opened PR #${pr.number}: ${pr.url}`);
|
|
2266
2319
|
}
|
|
2267
2320
|
}
|
|
2268
|
-
function buildPrBody(from, to, plan, migrations, base = GLOBAL_DISPATCH_REF, lockfiles = [], breaking = []) {
|
|
2321
|
+
function buildPrBody(from, to, plan, migrations, base = GLOBAL_DISPATCH_REF, lockfiles = [], breaking = [], coreVersionCleanup = null) {
|
|
2269
2322
|
const lines = [];
|
|
2270
2323
|
if (breaking.length > 0) {
|
|
2271
2324
|
lines.push(
|
|
@@ -2304,6 +2357,14 @@ function buildPrBody(from, to, plan, migrations, base = GLOBAL_DISPATCH_REF, loc
|
|
|
2304
2357
|
"Review the DDL before merging: merging this PR runs these migrations against the database on the next deploy."
|
|
2305
2358
|
);
|
|
2306
2359
|
}
|
|
2360
|
+
if (coreVersionCleanup && coreVersionCleanup.action === "delete") {
|
|
2361
|
+
lines.push(
|
|
2362
|
+
"",
|
|
2363
|
+
"## Cleanup \u2014 removed orphaned `core.version`",
|
|
2364
|
+
"",
|
|
2365
|
+
`This instance still carried a \`${CORE_VERSION_FILE}\` file (recording \`${coreVersionCleanup.found}\`), inherited through GitHub template generation before the template retired it (#423). It matched the version \`biffo.core.json\` records, so it was the un-repurposed inherited copy, and nothing reads it as an authority \u2014 \`biffo.core.json\` wins every lookup. This upgrade **deleted it** (#434). The fallback readers in \`deploy.ts\` and \`core-upgrade.ts\` still read \`${CORE_VERSION_FILE}\` when it is present elsewhere; only this orphaned instance copy was removed.`
|
|
2366
|
+
);
|
|
2367
|
+
}
|
|
2307
2368
|
const globalWorkflowChanges = plan.changes.filter(
|
|
2308
2369
|
(c) => GLOBAL_DISPATCH_WORKFLOW_PATHS.includes(c.path)
|
|
2309
2370
|
);
|
|
@@ -2374,6 +2435,18 @@ function printMigrationCarry(migrations) {
|
|
|
2374
2435
|
console.log(` ${chalk4.green("migration".padEnd(15))} ${e.path}${suffix}`);
|
|
2375
2436
|
}
|
|
2376
2437
|
}
|
|
2438
|
+
function printCoreVersionCleanup(cleanup, applying) {
|
|
2439
|
+
if (cleanup === null) return;
|
|
2440
|
+
if (cleanup.action === "delete") {
|
|
2441
|
+
const verb = applying ? "delete" : "will delete";
|
|
2442
|
+
console.log(
|
|
2443
|
+
` ${chalk4.red("cleanup".padEnd(15))} ${CORE_VERSION_FILE} ` + chalk4.dim(`(orphaned inherited copy recording ${cleanup.found}) \u2014 ${verb}`)
|
|
2444
|
+
);
|
|
2445
|
+
return;
|
|
2446
|
+
}
|
|
2447
|
+
const why = cleanup.reason === "repurposed" ? `does not match biffo.core.json \u2014 looks repurposed, keeping ${CORE_VERSION_FILE}` : `biffo.core.json absent or unparseable \u2014 no authority to check, keeping ${CORE_VERSION_FILE}`;
|
|
2448
|
+
console.log(` ${chalk4.dim("cleanup".padEnd(15))} ${chalk4.dim(`${cleanup.found}: ${why}`)}`);
|
|
2449
|
+
}
|
|
2377
2450
|
function printPlan(plan) {
|
|
2378
2451
|
const ordered = [...plan.conflicts, ...plan.changes.filter((c) => !c.conflicted)];
|
|
2379
2452
|
for (const e of ordered) {
|
|
@@ -2921,7 +2994,7 @@ import {
|
|
|
2921
2994
|
mkdirSync as mkdirSync4,
|
|
2922
2995
|
readdirSync as readdirSync4,
|
|
2923
2996
|
readFileSync as readFileSync7,
|
|
2924
|
-
rmSync as
|
|
2997
|
+
rmSync as rmSync6,
|
|
2925
2998
|
statSync as statSync2,
|
|
2926
2999
|
writeFileSync as writeFileSync5
|
|
2927
3000
|
} from "fs";
|
|
@@ -2989,7 +3062,7 @@ function markStepComplete(session, step) {
|
|
|
2989
3062
|
}
|
|
2990
3063
|
function deleteSession(projectName) {
|
|
2991
3064
|
const path = sessionPath(projectName);
|
|
2992
|
-
if (existsSync11(path))
|
|
3065
|
+
if (existsSync11(path)) rmSync6(path);
|
|
2993
3066
|
}
|
|
2994
3067
|
function projectsDir() {
|
|
2995
3068
|
return process.env["BIFFO_PROJECTS_DIR"] ?? join12(homedir(), ".biffo", "projects");
|
|
@@ -3011,7 +3084,7 @@ function loadProjectConfig(name) {
|
|
|
3011
3084
|
}
|
|
3012
3085
|
function deleteProjectConfig(name) {
|
|
3013
3086
|
const path = join12(projectsDir(), `${name}.json`);
|
|
3014
|
-
if (existsSync11(path))
|
|
3087
|
+
if (existsSync11(path)) rmSync6(path);
|
|
3015
3088
|
}
|
|
3016
3089
|
function listProjectConfigs() {
|
|
3017
3090
|
const dir = projectsDir();
|
|
@@ -4665,7 +4738,7 @@ import {
|
|
|
4665
4738
|
mkdirSync as mkdirSync6,
|
|
4666
4739
|
readdirSync as readdirSync8,
|
|
4667
4740
|
readFileSync as readFileSync12,
|
|
4668
|
-
rmSync as
|
|
4741
|
+
rmSync as rmSync7,
|
|
4669
4742
|
statSync as statSync5,
|
|
4670
4743
|
writeFileSync as writeFileSync6
|
|
4671
4744
|
} from "fs";
|
|
@@ -4710,7 +4783,7 @@ function markSiblingStepComplete(session, step) {
|
|
|
4710
4783
|
}
|
|
4711
4784
|
function deleteSiblingSession(projectName) {
|
|
4712
4785
|
const path = sessionPath2(projectName);
|
|
4713
|
-
if (existsSync18(path))
|
|
4786
|
+
if (existsSync18(path)) rmSync7(path);
|
|
4714
4787
|
}
|
|
4715
4788
|
|
|
4716
4789
|
// src/commands/sibling-create.ts
|
|
@@ -6717,7 +6790,7 @@ async function runPluginSyncMigrations(name, options, deps) {
|
|
|
6717
6790
|
}
|
|
6718
6791
|
|
|
6719
6792
|
// src/commands/plugin-uninstall.ts
|
|
6720
|
-
import { existsSync as existsSync26, readFileSync as readFileSync19, rmSync as
|
|
6793
|
+
import { existsSync as existsSync26, readFileSync as readFileSync19, rmSync as rmSync8 } from "fs";
|
|
6721
6794
|
import { join as join27, resolve as resolve15 } from "path";
|
|
6722
6795
|
import chalk18 from "chalk";
|
|
6723
6796
|
import { Command as Command18 } from "commander";
|
|
@@ -6789,10 +6862,10 @@ async function runPluginUninstall(name, options, deps) {
|
|
|
6789
6862
|
`${options.cwd} is not a git repository \u2014 biffo plugin uninstall must be run from a Biffo project checkout.`
|
|
6790
6863
|
);
|
|
6791
6864
|
}
|
|
6792
|
-
|
|
6865
|
+
rmSync8(targetDir, { recursive: true, force: true });
|
|
6793
6866
|
log.success(`Removed services/${name}/`);
|
|
6794
6867
|
if (existsSync26(modulesDir)) {
|
|
6795
|
-
|
|
6868
|
+
rmSync8(modulesDir, { recursive: true, force: true });
|
|
6796
6869
|
log.success(`Removed modules/plugins/${name}/`);
|
|
6797
6870
|
const wiring = syncPluginTerraform(options.cwd);
|
|
6798
6871
|
stagePaths.push(...wiring.changedPaths);
|
|
@@ -6864,7 +6937,7 @@ function printDryRun5(name, version, stagePaths, keepData) {
|
|
|
6864
6937
|
}
|
|
6865
6938
|
|
|
6866
6939
|
// src/commands/plugin-upgrade.ts
|
|
6867
|
-
import { cpSync as cpSync4, existsSync as existsSync27, mkdirSync as mkdirSync10, readFileSync as readFileSync20, rmSync as
|
|
6940
|
+
import { cpSync as cpSync4, existsSync as existsSync27, mkdirSync as mkdirSync10, readFileSync as readFileSync20, rmSync as rmSync9 } from "fs";
|
|
6868
6941
|
import { join as join28, relative as relative5, resolve as resolve16 } from "path";
|
|
6869
6942
|
import chalk19 from "chalk";
|
|
6870
6943
|
import { Command as Command19 } from "commander";
|
|
@@ -6939,13 +7012,13 @@ async function runPluginUpgrade(target, options, deps) {
|
|
|
6939
7012
|
log.success(
|
|
6940
7013
|
`Manifest valid \u2014 ${manifest.tables.length} table(s), ${manifest.api_routes.length} route(s)`
|
|
6941
7014
|
);
|
|
6942
|
-
|
|
7015
|
+
rmSync9(targetDir, { recursive: true, force: true });
|
|
6943
7016
|
mkdirSync10(targetDir, { recursive: true });
|
|
6944
7017
|
cpSync4(tmpDir, targetDir, { recursive: true });
|
|
6945
7018
|
log.success(`Upgraded plugin source at services/${entry.name}/`);
|
|
6946
7019
|
const stagePaths = [`services/${entry.name}`];
|
|
6947
7020
|
if (existsSync27(modulesDir)) {
|
|
6948
|
-
|
|
7021
|
+
rmSync9(modulesDir, { recursive: true, force: true });
|
|
6949
7022
|
}
|
|
6950
7023
|
const tfSourceDir = join28(targetDir, "terraform");
|
|
6951
7024
|
if (existsSync27(tfSourceDir)) {
|