@intentius/sql-yodeler 0.0.0-stage → 0.1.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/LICENSE +202 -0
- package/README.md +110 -2
- package/dist/bin.d.ts +2 -0
- package/dist/bin.js +14 -0
- package/dist/bin.js.map +1 -0
- package/dist/chant/apply.d.ts +51 -0
- package/dist/chant/apply.js +104 -0
- package/dist/chant/apply.js.map +1 -0
- package/dist/chant/build.d.ts +34 -0
- package/dist/chant/build.js +48 -0
- package/dist/chant/build.js.map +1 -0
- package/dist/chant/drift.d.ts +44 -0
- package/dist/chant/drift.js +91 -0
- package/dist/chant/drift.js.map +1 -0
- package/dist/chant/plan.d.ts +45 -0
- package/dist/chant/plan.js +61 -0
- package/dist/chant/plan.js.map +1 -0
- package/dist/chant/process.d.ts +41 -0
- package/dist/chant/process.js +87 -0
- package/dist/chant/process.js.map +1 -0
- package/dist/cli.d.ts +4 -0
- package/dist/cli.js +59 -0
- package/dist/cli.js.map +1 -0
- package/dist/command.d.ts +17 -0
- package/dist/command.js +13 -0
- package/dist/command.js.map +1 -0
- package/dist/commands/apply.d.ts +3 -0
- package/dist/commands/apply.js +306 -0
- package/dist/commands/apply.js.map +1 -0
- package/dist/commands/drift.d.ts +3 -0
- package/dist/commands/drift.js +38 -0
- package/dist/commands/drift.js.map +1 -0
- package/dist/commands/index.d.ts +3 -0
- package/dist/commands/index.js +22 -0
- package/dist/commands/index.js.map +1 -0
- package/dist/commands/init.d.ts +3 -0
- package/dist/commands/init.js +135 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/lint.d.ts +3 -0
- package/dist/commands/lint.js +193 -0
- package/dist/commands/lint.js.map +1 -0
- package/dist/commands/new.d.ts +3 -0
- package/dist/commands/new.js +168 -0
- package/dist/commands/new.js.map +1 -0
- package/dist/commands/plan.d.ts +3 -0
- package/dist/commands/plan.js +171 -0
- package/dist/commands/plan.js.map +1 -0
- package/dist/commands/rebase.d.ts +3 -0
- package/dist/commands/rebase.js +167 -0
- package/dist/commands/rebase.js.map +1 -0
- package/dist/commands/repair.d.ts +3 -0
- package/dist/commands/repair.js +117 -0
- package/dist/commands/repair.js.map +1 -0
- package/dist/commands/status.d.ts +7 -0
- package/dist/commands/status.js +54 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/config/define.d.ts +50 -0
- package/dist/config/define.js +20 -0
- package/dist/config/define.js.map +1 -0
- package/dist/config/index.d.ts +11 -0
- package/dist/config/index.js +12 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config/load.d.ts +17 -0
- package/dist/config/load.js +102 -0
- package/dist/config/load.js.map +1 -0
- package/dist/config/settings.d.ts +40 -0
- package/dist/config/settings.js +88 -0
- package/dist/config/settings.js.map +1 -0
- package/dist/env-args.d.ts +18 -0
- package/dist/env-args.js +62 -0
- package/dist/env-args.js.map +1 -0
- package/dist/history/client.d.ts +17 -0
- package/dist/history/client.js +19 -0
- package/dist/history/client.js.map +1 -0
- package/dist/history/ddl.d.ts +58 -0
- package/dist/history/ddl.js +100 -0
- package/dist/history/ddl.js.map +1 -0
- package/dist/history/index.d.ts +25 -0
- package/dist/history/index.js +26 -0
- package/dist/history/index.js.map +1 -0
- package/dist/history/lock.d.ts +100 -0
- package/dist/history/lock.js +224 -0
- package/dist/history/lock.js.map +1 -0
- package/dist/history/postgres/ddl.d.ts +22 -0
- package/dist/history/postgres/ddl.js +47 -0
- package/dist/history/postgres/ddl.js.map +1 -0
- package/dist/history/postgres/index.d.ts +12 -0
- package/dist/history/postgres/index.js +13 -0
- package/dist/history/postgres/index.js.map +1 -0
- package/dist/history/postgres/lock.d.ts +48 -0
- package/dist/history/postgres/lock.js +95 -0
- package/dist/history/postgres/lock.js.map +1 -0
- package/dist/history/postgres/store.d.ts +39 -0
- package/dist/history/postgres/store.js +68 -0
- package/dist/history/postgres/store.js.map +1 -0
- package/dist/history/rows.d.ts +96 -0
- package/dist/history/rows.js +73 -0
- package/dist/history/rows.js.map +1 -0
- package/dist/history/store.d.ts +72 -0
- package/dist/history/store.js +134 -0
- package/dist/history/store.js.map +1 -0
- package/dist/history/topology.d.ts +41 -0
- package/dist/history/topology.js +54 -0
- package/dist/history/topology.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +10 -0
- package/dist/index.js.map +1 -0
- package/dist/init/adopt.d.ts +70 -0
- package/dist/init/adopt.js +138 -0
- package/dist/init/adopt.js.map +1 -0
- package/dist/init/baseline.d.ts +61 -0
- package/dist/init/baseline.js +88 -0
- package/dist/init/baseline.js.map +1 -0
- package/dist/init/files.d.ts +23 -0
- package/dist/init/files.js +77 -0
- package/dist/init/files.js.map +1 -0
- package/dist/init/index.d.ts +16 -0
- package/dist/init/index.js +17 -0
- package/dist/init/index.js.map +1 -0
- package/dist/init/live.d.ts +28 -0
- package/dist/init/live.js +45 -0
- package/dist/init/live.js.map +1 -0
- package/dist/lint/check.d.ts +81 -0
- package/dist/lint/check.js +208 -0
- package/dist/lint/check.js.map +1 -0
- package/dist/lint/config.d.ts +21 -0
- package/dist/lint/config.js +43 -0
- package/dist/lint/config.js.map +1 -0
- package/dist/lint/index.d.ts +31 -0
- package/dist/lint/index.js +43 -0
- package/dist/lint/index.js.map +1 -0
- package/dist/lint/project-rules.d.ts +19 -0
- package/dist/lint/project-rules.js +32 -0
- package/dist/lint/project-rules.js.map +1 -0
- package/dist/lint/report.d.ts +7 -0
- package/dist/lint/report.js +48 -0
- package/dist/lint/report.js.map +1 -0
- package/dist/lint/rules.d.ts +53 -0
- package/dist/lint/rules.js +42 -0
- package/dist/lint/rules.js.map +1 -0
- package/dist/lint/silences.d.ts +49 -0
- package/dist/lint/silences.js +91 -0
- package/dist/lint/silences.js.map +1 -0
- package/dist/lint/statements.d.ts +38 -0
- package/dist/lint/statements.js +120 -0
- package/dist/lint/statements.js.map +1 -0
- package/dist/migrations/checksum.d.ts +56 -0
- package/dist/migrations/checksum.js +72 -0
- package/dist/migrations/checksum.js.map +1 -0
- package/dist/migrations/create.d.ts +73 -0
- package/dist/migrations/create.js +119 -0
- package/dist/migrations/create.js.map +1 -0
- package/dist/migrations/directory.d.ts +119 -0
- package/dist/migrations/directory.js +225 -0
- package/dist/migrations/directory.js.map +1 -0
- package/dist/migrations/document.d.ts +83 -0
- package/dist/migrations/document.js +82 -0
- package/dist/migrations/document.js.map +1 -0
- package/dist/migrations/index.d.ts +20 -0
- package/dist/migrations/index.js +21 -0
- package/dist/migrations/index.js.map +1 -0
- package/dist/pr/comment.d.ts +32 -0
- package/dist/pr/comment.js +99 -0
- package/dist/pr/comment.js.map +1 -0
- package/dist/pr/forge.d.ts +50 -0
- package/dist/pr/forge.js +105 -0
- package/dist/pr/forge.js.map +1 -0
- package/dist/pr/model.d.ts +91 -0
- package/dist/pr/model.js +113 -0
- package/dist/pr/model.js.map +1 -0
- package/dist/pr/render.d.ts +27 -0
- package/dist/pr/render.js +246 -0
- package/dist/pr/render.js.map +1 -0
- package/dist/project.d.ts +62 -0
- package/dist/project.js +92 -0
- package/dist/project.js.map +1 -0
- package/dist/rebase/index.d.ts +121 -0
- package/dist/rebase/index.js +390 -0
- package/dist/rebase/index.js.map +1 -0
- package/dist/rebase/repair.d.ts +41 -0
- package/dist/rebase/repair.js +68 -0
- package/dist/rebase/repair.js.map +1 -0
- package/dist/replay/clickhouse.d.ts +33 -0
- package/dist/replay/clickhouse.js +106 -0
- package/dist/replay/clickhouse.js.map +1 -0
- package/dist/replay/index.d.ts +36 -0
- package/dist/replay/index.js +54 -0
- package/dist/replay/index.js.map +1 -0
- package/dist/replay/postgres.d.ts +31 -0
- package/dist/replay/postgres.js +140 -0
- package/dist/replay/postgres.js.map +1 -0
- package/dist/replay/replay.d.ts +114 -0
- package/dist/replay/replay.js +98 -0
- package/dist/replay/replay.js.map +1 -0
- package/dist/replay/report.d.ts +18 -0
- package/dist/replay/report.js +72 -0
- package/dist/replay/report.js.map +1 -0
- package/dist/steps/backfill.d.ts +128 -0
- package/dist/steps/backfill.js +307 -0
- package/dist/steps/backfill.js.map +1 -0
- package/dist/steps/index.d.ts +52 -0
- package/dist/steps/index.js +52 -0
- package/dist/steps/index.js.map +1 -0
- package/dist/steps/kinds.d.ts +101 -0
- package/dist/steps/kinds.js +143 -0
- package/dist/steps/kinds.js.map +1 -0
- package/dist/steps/postgres-migration.d.ts +95 -0
- package/dist/steps/postgres-migration.js +149 -0
- package/dist/steps/postgres-migration.js.map +1 -0
- package/dist/steps/rebuild.d.ts +97 -0
- package/dist/steps/rebuild.js +162 -0
- package/dist/steps/rebuild.js.map +1 -0
- package/dist/steps/run.d.ts +45 -0
- package/dist/steps/run.js +72 -0
- package/dist/steps/run.js.map +1 -0
- package/dist/topology/render.d.ts +17 -0
- package/dist/topology/render.js +17 -0
- package/dist/topology/render.js.map +1 -0
- package/dist/version.d.ts +2 -0
- package/dist/version.js +11 -0
- package/dist/version.js.map +1 -0
- package/dist/versioned/approval.d.ts +35 -0
- package/dist/versioned/approval.js +53 -0
- package/dist/versioned/approval.js.map +1 -0
- package/dist/versioned/clickhouse.d.ts +24 -0
- package/dist/versioned/clickhouse.js +34 -0
- package/dist/versioned/clickhouse.js.map +1 -0
- package/dist/versioned/digest.d.ts +77 -0
- package/dist/versioned/digest.js +69 -0
- package/dist/versioned/digest.js.map +1 -0
- package/dist/versioned/driver.d.ts +41 -0
- package/dist/versioned/driver.js +13 -0
- package/dist/versioned/driver.js.map +1 -0
- package/dist/versioned/engine.d.ts +152 -0
- package/dist/versioned/engine.js +277 -0
- package/dist/versioned/engine.js.map +1 -0
- package/dist/versioned/explain.d.ts +123 -0
- package/dist/versioned/explain.js +289 -0
- package/dist/versioned/explain.js.map +1 -0
- package/dist/versioned/index.d.ts +37 -0
- package/dist/versioned/index.js +54 -0
- package/dist/versioned/index.js.map +1 -0
- package/dist/versioned/op.d.ts +62 -0
- package/dist/versioned/op.js +153 -0
- package/dist/versioned/op.js.map +1 -0
- package/dist/versioned/postgres/catalog.d.ts +33 -0
- package/dist/versioned/postgres/catalog.js +34 -0
- package/dist/versioned/postgres/catalog.js.map +1 -0
- package/dist/versioned/postgres/driver.d.ts +69 -0
- package/dist/versioned/postgres/driver.js +113 -0
- package/dist/versioned/postgres/driver.js.map +1 -0
- package/dist/versioned/postgres/executor.d.ts +104 -0
- package/dist/versioned/postgres/executor.js +172 -0
- package/dist/versioned/postgres/executor.js.map +1 -0
- package/dist/versioned/postgres/index.d.ts +11 -0
- package/dist/versioned/postgres/index.js +12 -0
- package/dist/versioned/postgres/index.js.map +1 -0
- package/dist/versioned/report.d.ts +22 -0
- package/dist/versioned/report.js +81 -0
- package/dist/versioned/report.js.map +1 -0
- package/dist/versioned/state.d.ts +108 -0
- package/dist/versioned/state.js +153 -0
- package/dist/versioned/state.js.map +1 -0
- package/package.json +51 -4
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The versioned plan as text (`yodel plan <env>`), as the pull request
|
|
3
|
+
* comment's markdown (`--format markdown`, `--comment`) and as JSON.
|
|
4
|
+
*
|
|
5
|
+
* The comment starts with a hidden marker, `<!-- yodel:plan env=<env> -->`,
|
|
6
|
+
* by which `--comment` finds the comment it posted before and updates it,
|
|
7
|
+
* and ends with the digest's subject, hidden, so the next comment can say
|
|
8
|
+
* what moved. Neither holds a secret: migration ids, checksums, a hash of
|
|
9
|
+
* the live catalog. Server addresses and tokens are never rendered.
|
|
10
|
+
*/
|
|
11
|
+
import { askedAgainLine, describeMove, encodeSubject } from "../versioned/explain.js";
|
|
12
|
+
import { asBackfill } from "../steps/kinds.js";
|
|
13
|
+
/** The marker that identifies one environment's plan comment. */
|
|
14
|
+
export const commentMarker = (env) => `<!-- yodel:plan env=${env} -->`;
|
|
15
|
+
const SUBJECT = /<!-- yodel:subject ([A-Za-z0-9_-]+) -->/;
|
|
16
|
+
/** The subject a comment body carries, encoded. */
|
|
17
|
+
export const subjectIn = (body) => SUBJECT.exec(body)?.[1];
|
|
18
|
+
/** GitHub refuses a comment over 65536 characters; GitLab and Forgejo allow more. */
|
|
19
|
+
export const COMMENT_LIMIT = 65_000;
|
|
20
|
+
/** Values a statement may quote that do not belong in a comment, though the file is in the repo. */
|
|
21
|
+
export function redact(sql) {
|
|
22
|
+
return sql.replace(/\b(PASSWORD|SECRET|SECRET_ACCESS_KEY|ACCESS_KEY_ID|TOKEN)(\s*=?\s*)'(?:[^'\\]|\\.)*'/gi, "$1$2'[redacted]'");
|
|
23
|
+
}
|
|
24
|
+
const changes = (cs) => cs.map((c) => `${c.rule} ${c.class}${c.destructive ? " (destructive)" : ""} ${c.field}`).join(", ");
|
|
25
|
+
const stepRule = (s) => s.kind === "statement"
|
|
26
|
+
? { rule: s.rule, cls: `${s.class}${s.destructive ? ", destructive" : ""}` }
|
|
27
|
+
: { rule: [...new Set(s.changes.map((c) => c.rule))].join(", "), cls: [...new Set(s.changes.map((c) => `${c.class}${c.destructive ? ", destructive" : ""}`))].join("; ") };
|
|
28
|
+
const stepKind = (s) => (s.kind === "statement" ? "statement" : s.kind === "op" ? `Op ${s.op}` : "manual");
|
|
29
|
+
function pendingMarks(p) {
|
|
30
|
+
const marks = [];
|
|
31
|
+
if (p.outOfOrder)
|
|
32
|
+
marks.push("out of order");
|
|
33
|
+
if (p.resumeAt !== undefined)
|
|
34
|
+
marks.push(`ran part way; resumes at step ${String(p.resumeAt)}`);
|
|
35
|
+
return marks;
|
|
36
|
+
}
|
|
37
|
+
function approvalLines(a, digest, md) {
|
|
38
|
+
const code = (s) => (md ? `\`${s}\`` : s);
|
|
39
|
+
if (!a)
|
|
40
|
+
return [];
|
|
41
|
+
if (a.kind === "no-op")
|
|
42
|
+
return [md ? `No migrations Op: ${a.message.split("\n")[0] ?? ""}` : a.message];
|
|
43
|
+
const out = [];
|
|
44
|
+
if (a.latest) {
|
|
45
|
+
const l = a.latest;
|
|
46
|
+
if (l.holds)
|
|
47
|
+
out.push(`Approved by ${l.by} at ${l.at}: the apply after merge runs this plan.`);
|
|
48
|
+
else if (digest && l.sameDigest)
|
|
49
|
+
out.push(`The newest approval of ${code(a.gate)}, by ${l.by} at ${l.at}, ${askedAgainLine(l, code)}.`);
|
|
50
|
+
else if (digest && l.digest) {
|
|
51
|
+
out.push(`The newest approval of ${code(a.gate)}, by ${l.by} at ${l.at}, is for ${code(l.digest)}, not this plan; it does not hold.`);
|
|
52
|
+
if (l.moved)
|
|
53
|
+
out.push(`What moved${l.moved.confirmed ? "" : " (as far as yodel can tell)"}: ${describeMove(l.moved)}.`);
|
|
54
|
+
}
|
|
55
|
+
else if (!digest)
|
|
56
|
+
out.push(`The newest approval of ${code(a.gate)} is by ${l.by} at ${l.at}${l.digest ? ` for ${code(l.digest)}` : ""}.`);
|
|
57
|
+
}
|
|
58
|
+
else if (digest)
|
|
59
|
+
out.push(`Not approved yet. Approving binds exactly this digest; if anything it covers changes before the apply runs, the gate asks again and nothing is applied.`);
|
|
60
|
+
if (a.ledgerNote)
|
|
61
|
+
out.push(a.ledgerNote);
|
|
62
|
+
return out;
|
|
63
|
+
}
|
|
64
|
+
/** `yodel plan <env>` for a project with migrations. */
|
|
65
|
+
export function renderPlanText(plan) {
|
|
66
|
+
const lines = [`Plan for ${plan.environment} (${plan.dialect}${plan.history ? `, history ${plan.history}` : ""}): ${String(plan.appliedCount)} applied, ${String(plan.pending.length)} pending`];
|
|
67
|
+
for (const n of plan.notes)
|
|
68
|
+
lines.push("", n);
|
|
69
|
+
for (const p of plan.pending) {
|
|
70
|
+
const marks = pendingMarks(p);
|
|
71
|
+
lines.push("", `${p.id}${marks.length > 0 ? ` (${marks.join("; ")})` : ""}`);
|
|
72
|
+
for (const { index, step, done, refused: why } of p.steps) {
|
|
73
|
+
const { rule, cls } = stepRule(step);
|
|
74
|
+
lines.push(` ${String(index)} ${stepKind(step)} ${rule} ${cls} ${step.name}${done ? " (done in an earlier run)" : ""}`);
|
|
75
|
+
if (step.kind === "statement")
|
|
76
|
+
lines.push(...redact(step.sql).split("\n").map((l) => ` ${l}`));
|
|
77
|
+
else
|
|
78
|
+
lines.push(...step.detail.split("\n").map((l) => ` ${l}`));
|
|
79
|
+
if (step.kind !== "statement")
|
|
80
|
+
lines.push(` ${why ? `yodel apply refuses it: ${why}` : "yodel apply runs it as this step"}`);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
if (plan.pending.length === 0 && !plan.refusal)
|
|
84
|
+
lines.push("", "Nothing pending: every migration is applied.");
|
|
85
|
+
if (plan.problems.length > 0)
|
|
86
|
+
lines.push("", `Integrity problems (${String(plan.problems.length)}):`, ...plan.problems.map((p) => ` ${p}`));
|
|
87
|
+
if (plan.refusal)
|
|
88
|
+
lines.push("", `yodel apply would refuse (exit ${String(plan.refusal.exitCode)}): ${plan.refusal.message}`);
|
|
89
|
+
if (plan.sinceLast)
|
|
90
|
+
lines.push("", `Since the last comment's plan (${plan.sinceLast.approved}): ${describeMove(plan.sinceLast)}`);
|
|
91
|
+
if (plan.digest) {
|
|
92
|
+
lines.push("", `Plan digest: ${plan.digest}`);
|
|
93
|
+
if (plan.approval?.kind === "op" && plan.approval.command)
|
|
94
|
+
lines.push(`Approve it with:`, ` ${plan.approval.command}`);
|
|
95
|
+
}
|
|
96
|
+
const a = approvalLines(plan.approval, plan.digest, false);
|
|
97
|
+
if (a.length > 0)
|
|
98
|
+
lines.push("", ...a);
|
|
99
|
+
return `${lines.join("\n")}\n`;
|
|
100
|
+
}
|
|
101
|
+
const cell = (s) => s.replace(/\|/g, "\\|").replace(/\s*\n\s*/g, " ");
|
|
102
|
+
const fence = (text, lang) => {
|
|
103
|
+
const ticks = "`".repeat(Math.max(3, ...[...text.matchAll(/`+/g)].map((m) => m[0].length + 1)));
|
|
104
|
+
return `${ticks}${lang}\n${text}\n${ticks}`;
|
|
105
|
+
};
|
|
106
|
+
function pendingMarkdown(p, withSql) {
|
|
107
|
+
const marks = pendingMarks(p);
|
|
108
|
+
const out = [`#### \`${p.id}\`${marks.length > 0 ? ` (${marks.join("; ")})` : ""}`, "", "| # | Step | Rule | Class | Object |", "|---|---|---|---|---|"];
|
|
109
|
+
for (const { index, step, done } of p.steps) {
|
|
110
|
+
const { rule, cls } = stepRule(step);
|
|
111
|
+
out.push(`| ${String(index)} | ${step.kind === "statement" ? "statement" : `**${cell(stepKind(step))}**`}${done ? " (done)" : ""} | ${cell(rule)} | ${cell(cls)} | \`${cell(step.name)}\` |`);
|
|
112
|
+
}
|
|
113
|
+
const statements = p.steps.filter((s) => s.step.kind === "statement");
|
|
114
|
+
if (withSql && statements.length > 0) {
|
|
115
|
+
const sql = statements.map(({ index, step }) => (step.kind === "statement" ? `-- ${String(index)}: ${step.rule} ${step.class}, ${step.name}\n${redact(step.sql)};` : "")).join("\n\n");
|
|
116
|
+
out.push("", `<details><summary>Statements (${String(statements.length)})</summary>`, "", fence(sql, "sql"), "", "</details>");
|
|
117
|
+
}
|
|
118
|
+
const nonStatements = p.steps.filter((s) => s.step.kind !== "statement");
|
|
119
|
+
const runs = nonStatements.filter((s) => s.refused === undefined && s.step.kind === "op");
|
|
120
|
+
const refused = nonStatements.filter((s) => !runs.includes(s));
|
|
121
|
+
if (runs.length > 0) {
|
|
122
|
+
out.push("", "Op steps:");
|
|
123
|
+
for (const s of runs)
|
|
124
|
+
out.push(...opStepMarkdown(s, " yodel apply runs it as this step."));
|
|
125
|
+
}
|
|
126
|
+
if (refused.length > 0) {
|
|
127
|
+
out.push("", "Refused changes:");
|
|
128
|
+
for (const s of refused) {
|
|
129
|
+
const { index, step, refused: why } = s;
|
|
130
|
+
if (step.kind === "op")
|
|
131
|
+
out.push(...opStepMarkdown(s, why ? ` **yodel apply refuses it:** ${cell(why)}` : ""));
|
|
132
|
+
else if (step.kind === "manual") {
|
|
133
|
+
out.push(`- step ${String(index)}, \`${step.name}\`: manual, no Op makes it (${cell(changes(step.changes))}).${why ? " yodel apply refuses it." : ""}`);
|
|
134
|
+
out.push("", indent(fence(step.detail, "text")));
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
return out;
|
|
139
|
+
}
|
|
140
|
+
/** An Op step: what makes it (the changes, or a backfill's module), then its detail and declaration (a backfill's module as written). */
|
|
141
|
+
function opStepMarkdown({ index, step, source }, runs) {
|
|
142
|
+
if (step.kind !== "op")
|
|
143
|
+
return [];
|
|
144
|
+
const made = step.changes.length > 0 ? changes(step.changes) : (source?.file ?? asBackfill(step)?.options.file ?? "");
|
|
145
|
+
const what = made ? ` (${cell(made)})` : "";
|
|
146
|
+
const declaration = source ? fence(redact(source.text).replace(/\n+$/, ""), "ts") : fence(step.declaration, "ts");
|
|
147
|
+
return [
|
|
148
|
+
`- step ${String(index)}, \`${step.name}\`: made by Op \`${step.op}\`${what}.${runs}`,
|
|
149
|
+
"",
|
|
150
|
+
` <details><summary>${source ? `${cell(step.op)}: ${cell(source.file)}` : `${cell(step.op)} for ${cell(step.object)}`}</summary>`,
|
|
151
|
+
"",
|
|
152
|
+
indent(fence(step.detail, "text")),
|
|
153
|
+
"",
|
|
154
|
+
indent(declaration),
|
|
155
|
+
"",
|
|
156
|
+
" </details>",
|
|
157
|
+
];
|
|
158
|
+
}
|
|
159
|
+
const indent = (s) => s.split("\n").map((l) => (l ? ` ${l}` : l)).join("\n");
|
|
160
|
+
/** The pull request comment body. */
|
|
161
|
+
export function renderPlanMarkdown(plan, options = {}) {
|
|
162
|
+
const withSql = options.sql !== false;
|
|
163
|
+
const out = [
|
|
164
|
+
commentMarker(plan.environment),
|
|
165
|
+
`### yodel plan: \`${plan.environment}\``,
|
|
166
|
+
"",
|
|
167
|
+
`${plan.dialect === "clickhouse" ? "ClickHouse" : "Postgres"}${plan.history ? `, history \`${plan.history}\`` : ""}: ${String(plan.appliedCount)} applied, **${String(plan.pending.length)} pending**.`,
|
|
168
|
+
];
|
|
169
|
+
for (const n of plan.notes)
|
|
170
|
+
out.push("", `> ${n}`);
|
|
171
|
+
if (plan.pending.length > 0) {
|
|
172
|
+
for (const p of plan.pending)
|
|
173
|
+
out.push("", ...pendingMarkdown(p, withSql));
|
|
174
|
+
}
|
|
175
|
+
else if (!plan.refusal)
|
|
176
|
+
out.push("", "Nothing pending: every migration is applied.");
|
|
177
|
+
if (plan.problems.length > 0)
|
|
178
|
+
out.push("", `#### Integrity problems (${String(plan.problems.length)})`, "", ...plan.problems.map((p) => `- ${cell(p)}`));
|
|
179
|
+
if (plan.refusal)
|
|
180
|
+
out.push("", `**\`yodel apply\` would refuse (exit ${String(plan.refusal.exitCode)})**, and applies nothing:`, "", fence(plan.refusal.message, "text"));
|
|
181
|
+
if (plan.sinceLast)
|
|
182
|
+
out.push("", `Since the previous version of this comment (\`${plan.sinceLast.approved}\`): ${describeMove(plan.sinceLast)}.`);
|
|
183
|
+
if (plan.digest) {
|
|
184
|
+
out.push("", "#### Approval", "", `Plan digest the apply gate binds: \`${plan.digest}\``);
|
|
185
|
+
if (plan.approval?.kind === "op" && plan.approval.command)
|
|
186
|
+
out.push("", "Approve it with:", "", fence(plan.approval.command, "sh"));
|
|
187
|
+
}
|
|
188
|
+
const a = approvalLines(plan.approval, plan.digest, true);
|
|
189
|
+
if (a.length > 0)
|
|
190
|
+
out.push("", ...a);
|
|
191
|
+
if (plan.approval?.kind === "no-op" && plan.digest) {
|
|
192
|
+
out.push("", "<details><summary>Declare one</summary>", "", fence(plan.approval.message.split("\n\n").slice(1).join("\n\n"), "ts"), "", "</details>");
|
|
193
|
+
}
|
|
194
|
+
if (!withSql)
|
|
195
|
+
out.push("", "_The statements are left out: the comment would be too long. `yodel plan` prints them._");
|
|
196
|
+
if (plan.subject)
|
|
197
|
+
out.push("", `<!-- yodel:subject ${encodeSubject(plan.subject)} -->`);
|
|
198
|
+
const body = `${out.join("\n")}\n`;
|
|
199
|
+
if (withSql && body.length > COMMENT_LIMIT)
|
|
200
|
+
return renderPlanMarkdown(plan, { sql: false });
|
|
201
|
+
return body;
|
|
202
|
+
}
|
|
203
|
+
/** `yodel plan <env> --json` for a project with migrations. */
|
|
204
|
+
export function planJsonVersioned(plan) {
|
|
205
|
+
const a = plan.approval;
|
|
206
|
+
return {
|
|
207
|
+
environment: plan.environment,
|
|
208
|
+
dialect: plan.dialect,
|
|
209
|
+
mode: "versioned",
|
|
210
|
+
...(plan.history ? { history: plan.history } : {}),
|
|
211
|
+
applied: plan.appliedCount,
|
|
212
|
+
pending: plan.pending.map((p) => ({
|
|
213
|
+
id: p.id,
|
|
214
|
+
outOfOrder: p.outOfOrder,
|
|
215
|
+
...(p.resumeAt !== undefined ? { resumeAt: p.resumeAt } : {}),
|
|
216
|
+
steps: p.steps.map(({ index, step, done, refused }) => ({
|
|
217
|
+
index,
|
|
218
|
+
kind: step.kind,
|
|
219
|
+
object: step.object,
|
|
220
|
+
name: step.name,
|
|
221
|
+
...stepRuleJson(step),
|
|
222
|
+
...(step.kind === "statement" ? { sql: redact(step.sql) } : { detail: step.detail }),
|
|
223
|
+
...(step.kind === "op" ? { op: step.op } : {}),
|
|
224
|
+
...(step.kind !== "statement" ? { applyRuns: refused === undefined, ...(refused ? { refused } : {}) } : {}),
|
|
225
|
+
done,
|
|
226
|
+
})),
|
|
227
|
+
})),
|
|
228
|
+
problems: plan.problems,
|
|
229
|
+
...(plan.refusal ? { refusal: plan.refusal } : {}),
|
|
230
|
+
...(plan.digest ? { planDigest: plan.digest } : {}),
|
|
231
|
+
...(a?.kind === "op"
|
|
232
|
+
? {
|
|
233
|
+
op: a.op,
|
|
234
|
+
gate: a.gate,
|
|
235
|
+
...(a.command ? { approve: a.command } : {}),
|
|
236
|
+
...(a.latest ? { approval: { ...a.latest, moved: a.latest.moved ? { confirmed: a.latest.moved.confirmed, changes: a.latest.moved.changes } : undefined } } : {}),
|
|
237
|
+
}
|
|
238
|
+
: a
|
|
239
|
+
? { opMissing: a.message.split("\n")[0] }
|
|
240
|
+
: {}),
|
|
241
|
+
...(plan.sinceLast ? { sinceLast: { digest: plan.sinceLast.approved, confirmed: plan.sinceLast.confirmed, changes: plan.sinceLast.changes } } : {}),
|
|
242
|
+
notes: plan.notes,
|
|
243
|
+
};
|
|
244
|
+
}
|
|
245
|
+
const stepRuleJson = (s) => s.kind === "statement" ? { rule: s.rule, class: s.class, ...(s.destructive ? { destructive: true } : {}) } : { changes: s.changes.map((c) => ({ rule: c.rule, class: c.class, field: c.field, ...(c.destructive ? { destructive: true } : {}) })) };
|
|
246
|
+
//# sourceMappingURL=render.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render.js","sourceRoot":"","sources":["../../src/pr/render.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A SQL Yodeler project: the directory that holds `chant.config.ts`, its
|
|
3
|
+
* dialect, and the server each environment names in `sql.profiles.<env>`.
|
|
4
|
+
*
|
|
5
|
+
* Every verb starts here: `loadProject()` finds and evaluates the config,
|
|
6
|
+
* `resolveEnvironment()` picks one profile. Calling chant is in `./chant/`.
|
|
7
|
+
*/
|
|
8
|
+
import type { SqlConfig, SqlProfile } from "@intentius/chant-lexicon-sql/config";
|
|
9
|
+
import type { SqlDialect } from "@intentius/chant-lexicon-sql/dialects";
|
|
10
|
+
import type { YodelConfig } from "./config/define.js";
|
|
11
|
+
export type { SqlDialect, SqlProfile };
|
|
12
|
+
/** An error a verb reports as one line on stderr, with the exit code it ends with. */
|
|
13
|
+
export declare class YodelError extends Error {
|
|
14
|
+
readonly exitCode: number;
|
|
15
|
+
constructor(message: string, exitCode?: number);
|
|
16
|
+
}
|
|
17
|
+
/** The parts of a loaded `chant.config.ts` yodel reads. */
|
|
18
|
+
export interface ProjectConfig {
|
|
19
|
+
lexicons?: string[];
|
|
20
|
+
sourceDir?: string;
|
|
21
|
+
sql?: SqlConfig;
|
|
22
|
+
[key: string]: unknown;
|
|
23
|
+
}
|
|
24
|
+
export interface Project {
|
|
25
|
+
/** The absolute directory holding `chant.config.ts`. */
|
|
26
|
+
dir: string;
|
|
27
|
+
configPath: string;
|
|
28
|
+
/** The config as chant loaded and validated it. */
|
|
29
|
+
config: ProjectConfig;
|
|
30
|
+
/** `sql.dialect`, `clickhouse` when the config names none (chant's default). */
|
|
31
|
+
dialect: SqlDialect;
|
|
32
|
+
/** Where the declared schema lives, relative to `dir`: `sourceDir`, else `src` when it exists, else `.`. */
|
|
33
|
+
sourceDir: string;
|
|
34
|
+
/** `yodel.config.ts`, checked, when the project has one (`./config/`). */
|
|
35
|
+
yodel?: {
|
|
36
|
+
path: string;
|
|
37
|
+
config: YodelConfig;
|
|
38
|
+
} | undefined;
|
|
39
|
+
}
|
|
40
|
+
export interface Environment {
|
|
41
|
+
name: string;
|
|
42
|
+
/** `sql.profiles.<name>`. */
|
|
43
|
+
profile: SqlProfile;
|
|
44
|
+
}
|
|
45
|
+
/** The nearest directory at or above `start` that holds `chant.config.ts`. */
|
|
46
|
+
export declare function findProjectDir(start: string): string | undefined;
|
|
47
|
+
/**
|
|
48
|
+
* The dialect a config declares. A list is refused: yodel manages one
|
|
49
|
+
* database per project, and one chant build holds one dialect.
|
|
50
|
+
*/
|
|
51
|
+
export declare function projectDialect(config: ProjectConfig, configPath: string): SqlDialect;
|
|
52
|
+
/** Builds a {@link Project} from a config already loaded. Pure, for tests and callers that load the config themselves. */
|
|
53
|
+
export declare function projectFromConfig(dir: string, configPath: string, config: ProjectConfig, yodel?: Project["yodel"]): Project;
|
|
54
|
+
/**
|
|
55
|
+
* Finds the project at or above `start` (default: the working directory) and
|
|
56
|
+
* loads its `chant.config.ts` through chant's own loader, so it is validated
|
|
57
|
+
* the same way `chant build` validates it, and its `yodel.config.ts` when
|
|
58
|
+
* there is one.
|
|
59
|
+
*/
|
|
60
|
+
export declare function loadProject(start?: string): Promise<Project>;
|
|
61
|
+
/** `sql.profiles.<name>`, or an error naming the environments the project declares. */
|
|
62
|
+
export declare function resolveEnvironment(project: Project, name: string): Environment;
|
package/dist/project.js
ADDED
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A SQL Yodeler project: the directory that holds `chant.config.ts`, its
|
|
3
|
+
* dialect, and the server each environment names in `sql.profiles.<env>`.
|
|
4
|
+
*
|
|
5
|
+
* Every verb starts here: `loadProject()` finds and evaluates the config,
|
|
6
|
+
* `resolveEnvironment()` picks one profile. Calling chant is in `./chant/`.
|
|
7
|
+
*/
|
|
8
|
+
import { existsSync } from "node:fs";
|
|
9
|
+
import { dirname, join, resolve } from "node:path";
|
|
10
|
+
/** An error a verb reports as one line on stderr, with the exit code it ends with. */
|
|
11
|
+
export class YodelError extends Error {
|
|
12
|
+
exitCode;
|
|
13
|
+
constructor(message, exitCode = 1) {
|
|
14
|
+
super(message);
|
|
15
|
+
this.exitCode = exitCode;
|
|
16
|
+
this.name = "YodelError";
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
/** The nearest directory at or above `start` that holds `chant.config.ts`. */
|
|
20
|
+
export function findProjectDir(start) {
|
|
21
|
+
let dir = resolve(start);
|
|
22
|
+
for (;;) {
|
|
23
|
+
if (existsSync(join(dir, "chant.config.ts")))
|
|
24
|
+
return dir;
|
|
25
|
+
const parent = dirname(dir);
|
|
26
|
+
if (parent === dir)
|
|
27
|
+
return undefined;
|
|
28
|
+
dir = parent;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* The dialect a config declares. A list is refused: yodel manages one
|
|
33
|
+
* database per project, and one chant build holds one dialect.
|
|
34
|
+
*/
|
|
35
|
+
export function projectDialect(config, configPath) {
|
|
36
|
+
const dialect = config.sql?.dialect;
|
|
37
|
+
if (dialect === undefined)
|
|
38
|
+
return "clickhouse";
|
|
39
|
+
if (Array.isArray(dialect)) {
|
|
40
|
+
if (dialect.length === 1 && dialect[0])
|
|
41
|
+
return dialect[0];
|
|
42
|
+
throw new YodelError(`${configPath}: sql.dialect lists ${dialect.join(", ")}; a yodel project is one database, so name one dialect`);
|
|
43
|
+
}
|
|
44
|
+
return dialect;
|
|
45
|
+
}
|
|
46
|
+
/** Builds a {@link Project} from a config already loaded. Pure, for tests and callers that load the config themselves. */
|
|
47
|
+
export function projectFromConfig(dir, configPath, config, yodel) {
|
|
48
|
+
if (!(config.lexicons ?? []).includes("sql")) {
|
|
49
|
+
throw new YodelError(`${configPath}: lexicons does not include "sql"; add lexicons: ["sql"] and import "@intentius/chant-lexicon-sql"`);
|
|
50
|
+
}
|
|
51
|
+
const sourceDir = config.sourceDir ?? (existsSync(join(dir, "src")) ? "src" : ".");
|
|
52
|
+
return { dir, configPath, config, dialect: projectDialect(config, configPath), sourceDir, ...(yodel ? { yodel } : {}) };
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Finds the project at or above `start` (default: the working directory) and
|
|
56
|
+
* loads its `chant.config.ts` through chant's own loader, so it is validated
|
|
57
|
+
* the same way `chant build` validates it, and its `yodel.config.ts` when
|
|
58
|
+
* there is one.
|
|
59
|
+
*/
|
|
60
|
+
export async function loadProject(start = process.cwd()) {
|
|
61
|
+
const dir = findProjectDir(start);
|
|
62
|
+
if (!dir)
|
|
63
|
+
throw new YodelError(`no chant.config.ts in ${resolve(start)} or any directory above it`);
|
|
64
|
+
const { loadChantConfig } = await import("@intentius/chant/config");
|
|
65
|
+
let loaded;
|
|
66
|
+
try {
|
|
67
|
+
loaded = await loadChantConfig(dir);
|
|
68
|
+
}
|
|
69
|
+
catch (e) {
|
|
70
|
+
throw new YodelError(e instanceof Error ? e.message : String(e));
|
|
71
|
+
}
|
|
72
|
+
const config = loaded.config;
|
|
73
|
+
const { loadYodelConfig } = await import("./config/load.js");
|
|
74
|
+
const yodel = await loadYodelConfig(dir, Object.keys(config.sql?.profiles ?? {}));
|
|
75
|
+
return projectFromConfig(dir, loaded.configPath ?? join(dir, "chant.config.ts"), config, yodel);
|
|
76
|
+
}
|
|
77
|
+
/** `sql.profiles.<name>`, or an error naming the environments the project declares. */
|
|
78
|
+
export function resolveEnvironment(project, name) {
|
|
79
|
+
const profiles = project.config.sql?.profiles ?? {};
|
|
80
|
+
const profile = profiles[name];
|
|
81
|
+
if (!profile) {
|
|
82
|
+
const declared = Object.keys(profiles);
|
|
83
|
+
throw new YodelError(`no environment "${name}": ${project.configPath} declares no sql.profiles.${name}` +
|
|
84
|
+
(declared.length > 0 ? ` (declared: ${declared.join(", ")})` : " (it declares no sql.profiles)"));
|
|
85
|
+
}
|
|
86
|
+
const postgres = /^postgres(ql)?:\/\//.test(profile.url);
|
|
87
|
+
if (postgres !== (project.dialect === "postgres")) {
|
|
88
|
+
throw new YodelError(`sql.profiles.${name}.url is a ${postgres ? "Postgres" : "ClickHouse"} server, but the project's dialect is ${project.dialect}`);
|
|
89
|
+
}
|
|
90
|
+
return { name, profile };
|
|
91
|
+
}
|
|
92
|
+
//# sourceMappingURL=project.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project.js","sourceRoot":"","sources":["../src/project.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `yodel rebase` (#15): move a migration onto another parent, so two
|
|
3
|
+
* branches that each added one can both merge.
|
|
4
|
+
*
|
|
5
|
+
* Two pull requests that each ran `yodel new` from the same newest
|
|
6
|
+
* migration give it two children: a fork, which `readMigrations` refuses.
|
|
7
|
+
* Rebasing moves one of them (the newer, unless named) and every migration
|
|
8
|
+
* that follows it onto the end of the other branch, and rewrites each one's
|
|
9
|
+
* `migration.json` and `migration.sql`:
|
|
10
|
+
*
|
|
11
|
+
* - its change is its recorded schema minus its old parent's recorded
|
|
12
|
+
* schema, object by object (keyed by export name, as chant's diff keys
|
|
13
|
+
* them);
|
|
14
|
+
* - its new recorded schema is the new parent's recorded schema with that
|
|
15
|
+
* change applied: a three-way merge, base the old parent, ours the
|
|
16
|
+
* migration, theirs the new parent. For the usual case, two branches that
|
|
17
|
+
* change different objects, that is the schema the declared build has
|
|
18
|
+
* once both are merged;
|
|
19
|
+
* - its statements are diffed again, from the new parent's recorded schema
|
|
20
|
+
* to the new recorded schema, and its checksum recomputed; a backfill
|
|
21
|
+
* step (#12) is kept at the end, and its module (one of the migration's
|
|
22
|
+
* own files, unchanged) counts in the new checksum;
|
|
23
|
+
* - each `-- yodel:allow <rule> <reason>` line (#14) is carried over to the
|
|
24
|
+
* same step in the new file: the step `migration.json` records exactly as
|
|
25
|
+
* before, found in order. When the step a line silenced is gone from the
|
|
26
|
+
* rebased migration, or is not the same step any more, the rebase refuses
|
|
27
|
+
* and names the line: a reason given for one statement is not moved onto
|
|
28
|
+
* another.
|
|
29
|
+
*
|
|
30
|
+
* When both sides change the same object (by export name, or by the name it
|
|
31
|
+
* has on the server) and do not make the same change, the rebase refuses
|
|
32
|
+
* and names the object: no merge of two changes to one table is safe to
|
|
33
|
+
* guess. The author resolves it by hand: delete the migration and run
|
|
34
|
+
* `yodel new` again on top of the other branch.
|
|
35
|
+
*
|
|
36
|
+
* Ids are kept. The order is the chain of parent ids, never the ids'
|
|
37
|
+
* timestamps, so a rebased migration whose timestamp is older than its new
|
|
38
|
+
* parent's is in order; renaming it would change nothing about when it
|
|
39
|
+
* runs and would break whatever already names it (a review, a branch,
|
|
40
|
+
* another migration's parent).
|
|
41
|
+
*
|
|
42
|
+
* Pure apart from {@link writeRebase}: migrations in, the rewritten ones
|
|
43
|
+
* out.
|
|
44
|
+
*/
|
|
45
|
+
import { type SchemaStatements } from "@intentius/chant-lexicon-sql/migration-statements";
|
|
46
|
+
import { YodelError } from "../project.js";
|
|
47
|
+
import type { BuildOutput } from "../chant/build.js";
|
|
48
|
+
import { type Migration, type MigrationDocument, type MigrationFiles } from "../migrations/index.js";
|
|
49
|
+
import { type Silence } from "../lint/index.js";
|
|
50
|
+
/** Exit code: the rebase is refused (a conflict, hand edits, a silence it cannot carry over, or a migration a history records). Nothing was written. */
|
|
51
|
+
export declare const REBASE_REFUSED = 4;
|
|
52
|
+
export interface RebaseOptions {
|
|
53
|
+
/** The migration to move. Default: the newer child of the directory's one fork. */
|
|
54
|
+
id?: string | undefined;
|
|
55
|
+
/** Its new parent. Default: the end of the other branch of its fork. */
|
|
56
|
+
onto?: string | undefined;
|
|
57
|
+
}
|
|
58
|
+
/** One migration as the rebase rewrites it. */
|
|
59
|
+
export interface RebasedMigration {
|
|
60
|
+
id: string;
|
|
61
|
+
dir: string;
|
|
62
|
+
oldParent: string | null;
|
|
63
|
+
parent: string;
|
|
64
|
+
oldChecksum: string;
|
|
65
|
+
checksum: string;
|
|
66
|
+
document: MigrationDocument;
|
|
67
|
+
files: MigrationFiles;
|
|
68
|
+
statements: SchemaStatements;
|
|
69
|
+
/** Its `-- yodel:allow` lines, carried over: each with its step and line in the rewritten files. */
|
|
70
|
+
silences: Silence[];
|
|
71
|
+
/** Its files differed from what yodel writes for it (an edit by hand, or a checksum that no longer matches): the rewrite drops that edit. */
|
|
72
|
+
handEdited: boolean;
|
|
73
|
+
}
|
|
74
|
+
export interface RebasePlan {
|
|
75
|
+
/** The migration moved; the ones after it in {@link rewritten} follow it, and move with it. */
|
|
76
|
+
moved: string;
|
|
77
|
+
from: string | null;
|
|
78
|
+
onto: string;
|
|
79
|
+
/** In chain order, the moved migration first. */
|
|
80
|
+
rewritten: RebasedMigration[];
|
|
81
|
+
}
|
|
82
|
+
/** Nothing to rebase: the directory has no fork and no migration was named. */
|
|
83
|
+
export interface NothingToRebase {
|
|
84
|
+
moved: undefined;
|
|
85
|
+
}
|
|
86
|
+
/** Two sides change one object differently. */
|
|
87
|
+
export declare class RebaseConflict extends YodelError {
|
|
88
|
+
readonly migration: string;
|
|
89
|
+
readonly objects: string[];
|
|
90
|
+
constructor(migration: string, objects: string[], message: string);
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* The three-way merge of one migration's change onto a new base: `base1`
|
|
94
|
+
* with every object `ours` changed from `base0` changed the same way.
|
|
95
|
+
* Throws a {@link RebaseConflict} when `base1` (theirs) changed one of
|
|
96
|
+
* those objects too, differently.
|
|
97
|
+
*/
|
|
98
|
+
export declare function mergeChange(base0: BuildOutput, ours: BuildOutput, base1: BuildOutput, label: {
|
|
99
|
+
migration: string;
|
|
100
|
+
theirs: string;
|
|
101
|
+
}): BuildOutput;
|
|
102
|
+
/** A migration document's steps as chant's `SchemaStatements`, to render them again. */
|
|
103
|
+
export declare function statementsOf(doc: MigrationDocument): SchemaStatements;
|
|
104
|
+
/**
|
|
105
|
+
* Whether a migration's files are what yodel writes for its document: its
|
|
106
|
+
* SQL rendered from its steps, and its checksum matching. Its well-formed
|
|
107
|
+
* `-- yodel:allow` lines do not count as an edit: a rebase carries them
|
|
108
|
+
* over.
|
|
109
|
+
*/
|
|
110
|
+
export declare function asWritten(m: Migration): boolean;
|
|
111
|
+
/**
|
|
112
|
+
* What a rebase would write. `migrations` is every migration in the
|
|
113
|
+
* directory (`scanMigrations(dir).migrations`: a fork is what this is for,
|
|
114
|
+
* so `readMigrations` would refuse it). Throws a YodelError when the
|
|
115
|
+
* migration or its new parent cannot be chosen, and a
|
|
116
|
+
* {@link RebaseConflict} when one rewritten migration's change meets a
|
|
117
|
+
* different change to the same object.
|
|
118
|
+
*/
|
|
119
|
+
export declare function planRebase(migrations: readonly Migration[], options?: RebaseOptions): RebasePlan | NothingToRebase;
|
|
120
|
+
/** Writes each rewritten migration over its files, each file through a temporary one renamed into place. */
|
|
121
|
+
export declare function writeRebase(plan: RebasePlan): void;
|