@biffo/cli 0.150.0 → 0.151.1
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 +70 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1566,6 +1566,7 @@ function planMigrationCarry(options) {
|
|
|
1566
1566
|
const recognised = [];
|
|
1567
1567
|
const declinedIndex = new Map((options.declined ?? []).map((d) => [d.file, d]));
|
|
1568
1568
|
const declined = [];
|
|
1569
|
+
const divergedBodies = [];
|
|
1569
1570
|
let head = instanceHead;
|
|
1570
1571
|
for (const m of chainOrder(template)) {
|
|
1571
1572
|
const decline = declinedIndex.get(m.file);
|
|
@@ -1583,6 +1584,13 @@ function planMigrationCarry(options) {
|
|
|
1583
1584
|
if (already.how !== "filename") {
|
|
1584
1585
|
recognised.push({ file: m.file, instanceFile: already.instance.file, how: already.how });
|
|
1585
1586
|
}
|
|
1587
|
+
if (migrationBodyHash(m.content) !== migrationBodyHash(already.instance.content)) {
|
|
1588
|
+
divergedBodies.push({
|
|
1589
|
+
file: m.file,
|
|
1590
|
+
instanceFile: already.instance.file,
|
|
1591
|
+
how: already.how
|
|
1592
|
+
});
|
|
1593
|
+
}
|
|
1586
1594
|
continue;
|
|
1587
1595
|
}
|
|
1588
1596
|
let revision = m.revision;
|
|
@@ -1625,7 +1633,31 @@ function planMigrationCarry(options) {
|
|
|
1625
1633
|
);
|
|
1626
1634
|
const templateFiles = new Set(template.map((m) => m.file));
|
|
1627
1635
|
const staleDeclines = [...declinedIndex.keys()].filter((f) => !templateFiles.has(f));
|
|
1628
|
-
return {
|
|
1636
|
+
return {
|
|
1637
|
+
entries,
|
|
1638
|
+
instanceHead,
|
|
1639
|
+
skipped,
|
|
1640
|
+
recognised,
|
|
1641
|
+
declined,
|
|
1642
|
+
staleDeclines,
|
|
1643
|
+
divergedBodies
|
|
1644
|
+
};
|
|
1645
|
+
}
|
|
1646
|
+
var TEST_PATH_RE = /(^|\/)tests?\/.*\btest_[^/]*\.py$/;
|
|
1647
|
+
function findMigrationTestPairings(changes, divergedBodies) {
|
|
1648
|
+
if (divergedBodies.length === 0) return [];
|
|
1649
|
+
const pairings = [];
|
|
1650
|
+
for (const change of changes) {
|
|
1651
|
+
if (!TEST_PATH_RE.test(change.path)) continue;
|
|
1652
|
+
const content = change.content;
|
|
1653
|
+
if (content === void 0) continue;
|
|
1654
|
+
for (const d of divergedBodies) {
|
|
1655
|
+
if (content.includes(d.file)) {
|
|
1656
|
+
pairings.push({ testPath: change.path, migration: d.file, instanceFile: d.instanceFile });
|
|
1657
|
+
}
|
|
1658
|
+
}
|
|
1659
|
+
}
|
|
1660
|
+
return pairings;
|
|
1629
1661
|
}
|
|
1630
1662
|
function indexInstanceMigrations(instance) {
|
|
1631
1663
|
const index = {
|
|
@@ -2513,6 +2545,10 @@ async function runCoreUpgradeResolved(options, deps, cleanups) {
|
|
|
2513
2545
|
printBreakingChanges(breaking, options.apply === true);
|
|
2514
2546
|
printPlan(plan);
|
|
2515
2547
|
printMigrationCarry(migrations);
|
|
2548
|
+
printMigrationBodyDrift(
|
|
2549
|
+
migrations,
|
|
2550
|
+
findMigrationTestPairings(plan.changes, migrations.divergedBodies)
|
|
2551
|
+
);
|
|
2516
2552
|
printCoreVersionCleanup(coreVersionCleanup, options.apply === true);
|
|
2517
2553
|
warnStaleFirstPartyCopies(options.cwd);
|
|
2518
2554
|
console.log(
|
|
@@ -2757,6 +2793,39 @@ function printMigrationCarry(migrations) {
|
|
|
2757
2793
|
console.log(` ${chalk4.green("migration".padEnd(15))} ${e.path}${suffix}`);
|
|
2758
2794
|
}
|
|
2759
2795
|
}
|
|
2796
|
+
function printMigrationBodyDrift(migrations, pairings) {
|
|
2797
|
+
if (migrations.divergedBodies.length === 0) return;
|
|
2798
|
+
console.log();
|
|
2799
|
+
for (const d of migrations.divergedBodies) {
|
|
2800
|
+
const alias = d.instanceFile === d.file ? "" : chalk4.dim(` (this instance calls it ${d.instanceFile})`);
|
|
2801
|
+
console.log(
|
|
2802
|
+
` ${chalk4.yellow("body drift".padEnd(15))} ${d.file}${alias}
|
|
2803
|
+
` + chalk4.dim(
|
|
2804
|
+
" The template has changed this migration since you carried it.\n An applied migration cannot be re-run, so the carry left yours\n alone and this change will NOT reach you."
|
|
2805
|
+
)
|
|
2806
|
+
);
|
|
2807
|
+
}
|
|
2808
|
+
if (pairings.length === 0) {
|
|
2809
|
+
console.log(
|
|
2810
|
+
chalk4.dim(
|
|
2811
|
+
"\n No arriving test asserts the new body, so this upgrade should still go green.\n It stays a convergence gap: fresh environments get the new body, you keep the old."
|
|
2812
|
+
)
|
|
2813
|
+
);
|
|
2814
|
+
return;
|
|
2815
|
+
}
|
|
2816
|
+
console.log(
|
|
2817
|
+
`
|
|
2818
|
+
${chalk4.red.bold("This upgrade will not go green.")} ${pairings.length} arriving test(s) assert a migration body you will not receive:`
|
|
2819
|
+
);
|
|
2820
|
+
for (const p of pairings) {
|
|
2821
|
+
console.log(` ${chalk4.red(p.testPath)} ${chalk4.dim(`\u2192 asserts ${p.migration}`)}`);
|
|
2822
|
+
}
|
|
2823
|
+
console.log(
|
|
2824
|
+
chalk4.dim(
|
|
2825
|
+
"\n Resolve before merging, by one of:\n - port the migration body change into your copy by hand, keeping its\n `# biffo:carried-from:` marker \u2014 safe only if re-stating the DDL is a\n no-op against your already-migrated database;\n - drop the arriving test from this PR and raise it upstream, if the\n property it asserts cannot hold here;\n - ask upstream to ship the change as a follow-on migration instead, which\n is the only option that actually converges an applied chain.\n"
|
|
2826
|
+
)
|
|
2827
|
+
);
|
|
2828
|
+
}
|
|
2760
2829
|
function printCoreVersionCleanup(cleanup, applying) {
|
|
2761
2830
|
if (cleanup === null) return;
|
|
2762
2831
|
if (cleanup.action === "delete") {
|