@geonosis/release 1.1.0 → 1.2.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/README.md +4 -0
- package/dist/{chunk-2JLVQK7Y.js → chunk-BOTEFN3W.js} +62 -23
- package/dist/index.d.ts +14 -0
- package/dist/index.js +1 -1
- package/dist/release-cli.js +2 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -17,6 +17,10 @@ geonosis-release migrations --since <ref> [--dialect <name>] [--root <dir>] [--j
|
|
|
17
17
|
|
|
18
18
|
Exit **0** clean · **1** refusals · **2** the run could not be made.
|
|
19
19
|
|
|
20
|
+
## What it reads
|
|
21
|
+
|
|
22
|
+
The files added since `--since <ref>` — committed, **staged, and untracked** — under every configured `release.migrations[].dir`. A migration that exists and narrows is a refusal whatever git thinks of it: the local gate a person runs before committing is the one window in which it is still free to fix, and a gate that only speaks after the commit speaks after the cheap moment has passed. A run that finds no migration file anywhere says `NONE … nothing was read`, never `OK`.
|
|
23
|
+
|
|
20
24
|
## `migrations` — expand-only, enforced
|
|
21
25
|
|
|
22
26
|
For every file the diff ADDED under a directory `geonosis.json` names, in the dialect it names it
|
|
@@ -191,9 +191,9 @@ var arrayTable = (into, path) => {
|
|
|
191
191
|
var parseToml = (source) => {
|
|
192
192
|
const out = {};
|
|
193
193
|
let here = out;
|
|
194
|
-
const
|
|
195
|
-
for (let index = 0; index <
|
|
196
|
-
const line = (
|
|
194
|
+
const lines2 = source.split("\n");
|
|
195
|
+
for (let index = 0; index < lines2.length; index += 1) {
|
|
196
|
+
const line = (lines2[index] ?? "").split("#")[0]?.trim() ?? "";
|
|
197
197
|
if (line === "") continue;
|
|
198
198
|
if (line.startsWith("[[") && line.endsWith("]]")) {
|
|
199
199
|
here = arrayTable(out, line.slice(2, -2).trim().split("."));
|
|
@@ -208,9 +208,9 @@ var parseToml = (source) => {
|
|
|
208
208
|
let text = line.slice(at + 1);
|
|
209
209
|
while ([...text].filter((one) => one === "[").length > [...text].filter((one) => one === "]").length) {
|
|
210
210
|
index += 1;
|
|
211
|
-
if (index >=
|
|
211
|
+
if (index >= lines2.length) throw new CannotRun("an unterminated array in the TOML config");
|
|
212
212
|
text += `
|
|
213
|
-
${(
|
|
213
|
+
${(lines2[index] ?? "").split("#")[0] ?? ""}`;
|
|
214
214
|
}
|
|
215
215
|
put(here, line.slice(0, at).trim().split("."), value(text));
|
|
216
216
|
}
|
|
@@ -353,7 +353,13 @@ var git = (root, args) => {
|
|
|
353
353
|
throw new CannotRun(`git ${args.join(" ")} failed: ${(error.message ?? "").trim()}`);
|
|
354
354
|
}
|
|
355
355
|
};
|
|
356
|
-
var
|
|
356
|
+
var lines = (out) => out.split("\n").filter((line) => line !== "");
|
|
357
|
+
var addedSince = (root, since) => {
|
|
358
|
+
const committed = lines(git(root, ["diff", "--name-only", "--diff-filter=A", `${since}..HEAD`]));
|
|
359
|
+
const staged = lines(git(root, ["diff", "--name-only", "--diff-filter=A", "--cached"]));
|
|
360
|
+
const untracked = lines(git(root, ["ls-files", "--others", "--exclude-standard"]));
|
|
361
|
+
return [.../* @__PURE__ */ new Set([...committed, ...staged, ...untracked])].toSorted();
|
|
362
|
+
};
|
|
357
363
|
var gitOk = (root, args) => {
|
|
358
364
|
const run = spawnSync("git", [...args], { cwd: root, encoding: "utf8" });
|
|
359
365
|
return run.error === void 0 && run.status === 0;
|
|
@@ -604,12 +610,17 @@ var EXTENSION = {
|
|
|
604
610
|
var under = (dir, file) => file === dir || file.startsWith(dir.endsWith("/") ? dir : `${dir}/`);
|
|
605
611
|
var fromTypeScript = (path, source, entry) => {
|
|
606
612
|
try {
|
|
607
|
-
return
|
|
608
|
-
|
|
609
|
-
|
|
613
|
+
return {
|
|
614
|
+
refusals: addSqlIn(source, entry.phases ?? ["up"]).flatMap(
|
|
615
|
+
(one) => refusalsIn(path, one.sql, one.line)
|
|
616
|
+
)
|
|
617
|
+
};
|
|
610
618
|
} catch (error) {
|
|
611
619
|
if (error instanceof Unreadable) {
|
|
612
|
-
|
|
620
|
+
return {
|
|
621
|
+
refusals: [],
|
|
622
|
+
unreadable: `${path} holds ${error.message} \u2014 this reader cannot read it`
|
|
623
|
+
};
|
|
613
624
|
}
|
|
614
625
|
throw error;
|
|
615
626
|
}
|
|
@@ -636,7 +647,9 @@ var runMigrations = (input) => {
|
|
|
636
647
|
const refusals = [];
|
|
637
648
|
const markers = [];
|
|
638
649
|
const squawk = [];
|
|
650
|
+
const unreadable = [];
|
|
639
651
|
const forSquawk = [];
|
|
652
|
+
const states = /* @__PURE__ */ new Map();
|
|
640
653
|
for (const { entry, file } of matched) {
|
|
641
654
|
const source = readFileSync4(resolve5(input.root, file), "utf8");
|
|
642
655
|
const found = markersIn(source);
|
|
@@ -646,11 +659,18 @@ var runMigrations = (input) => {
|
|
|
646
659
|
});
|
|
647
660
|
markers.push(...bad);
|
|
648
661
|
const excused = found.length > 0 && bad.length === 0;
|
|
662
|
+
states.set(file, excused ? "excused" : "clean");
|
|
649
663
|
if (!excused) {
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
664
|
+
const mine = entry.dialect === "mikro-orm-ts" ? fromTypeScript(file, source, entry) : { refusals: refusalsIn(file, source) };
|
|
665
|
+
if (mine.unreadable !== void 0) {
|
|
666
|
+
unreadable.push({ path: file, why: mine.unreadable });
|
|
667
|
+
states.set(file, "unreadable");
|
|
668
|
+
continue;
|
|
669
|
+
}
|
|
670
|
+
refusals.push(...mine.refusals);
|
|
671
|
+
if (mine.refusals.length > 0) states.set(file, "refused");
|
|
653
672
|
}
|
|
673
|
+
if (bad.length > 0) states.set(file, "refused");
|
|
654
674
|
if (entry.dialect !== "sqlite")
|
|
655
675
|
forSquawk.push({ entry, file, sql: sqlFor(file, source, entry) });
|
|
656
676
|
}
|
|
@@ -670,6 +690,7 @@ var runMigrations = (input) => {
|
|
|
670
690
|
if (!found.ok) {
|
|
671
691
|
clean = false;
|
|
672
692
|
squawk.push({ findings: found.findings, path: one.file });
|
|
693
|
+
if (states.get(one.file) === "clean") states.set(one.file, "findings");
|
|
673
694
|
}
|
|
674
695
|
}
|
|
675
696
|
} finally {
|
|
@@ -677,14 +698,18 @@ var runMigrations = (input) => {
|
|
|
677
698
|
}
|
|
678
699
|
}
|
|
679
700
|
return {
|
|
701
|
+
dirs: entries.map((one) => one.dir),
|
|
702
|
+
files: matched.map(({ file }) => ({ path: file, state: states.get(file) ?? "clean" })),
|
|
680
703
|
linted: forSquawk.length,
|
|
681
704
|
markers: markers.toSorted((a, b) => a.path.localeCompare(b.path) || a.line - b.line),
|
|
682
|
-
ok: refusals.length === 0 && markers.length === 0 && clean,
|
|
683
|
-
read: matched.length,
|
|
705
|
+
ok: refusals.length === 0 && markers.length === 0 && clean && unreadable.length === 0,
|
|
706
|
+
read: matched.length - unreadable.length,
|
|
707
|
+
since: input.since,
|
|
684
708
|
refusals: refusals.toSorted(
|
|
685
709
|
(a, b) => a.path.localeCompare(b.path) || a.line - b.line || a.verb.localeCompare(b.verb)
|
|
686
710
|
),
|
|
687
|
-
squawk
|
|
711
|
+
squawk,
|
|
712
|
+
unreadable
|
|
688
713
|
};
|
|
689
714
|
};
|
|
690
715
|
var WHY = `
|
|
@@ -695,21 +720,35 @@ is safe now:
|
|
|
695
720
|
-- contract-migration: <what expanded it, and why nothing reads it any more> since:<ref>
|
|
696
721
|
`;
|
|
697
722
|
var formatMigrations = (report) => {
|
|
723
|
+
if (report.files.length === 0) {
|
|
724
|
+
return `NONE migrations: no migration file was added since ${report.since} \u2014 committed, staged or untracked \u2014 under ${report.dirs.join(", ")}; nothing was read
|
|
725
|
+
`;
|
|
726
|
+
}
|
|
698
727
|
if (report.ok) {
|
|
699
728
|
return `OK migrations: expand-only (${String(report.read)} read, ${String(report.linted)} linted by squawk)
|
|
700
729
|
`;
|
|
701
730
|
}
|
|
702
731
|
const said = report.markers.map((one) => ` ${one.path}: ${one.why} (line ${String(one.line)})
|
|
703
732
|
`);
|
|
704
|
-
const
|
|
733
|
+
const lines2 = report.refusals.map(
|
|
705
734
|
(one) => ` ${one.path}: ${one.verb} (line ${String(one.line)})
|
|
706
735
|
`
|
|
707
736
|
);
|
|
708
737
|
const found = report.squawk.map((one) => ` ${one.path}:
|
|
709
738
|
${one.findings}
|
|
739
|
+
`);
|
|
740
|
+
const cannot = report.unreadable.map((one) => ` ${one.why}
|
|
710
741
|
`);
|
|
711
742
|
const why = report.markers.length + report.refusals.length === 0 ? "" : WHY;
|
|
712
|
-
return `${said.join("")}${
|
|
743
|
+
return `${said.join("")}${lines2.join("")}${cannot.join("")}${why}${found.join("")}${accounting(report)}`;
|
|
744
|
+
};
|
|
745
|
+
var accounting = (report) => {
|
|
746
|
+
const total = report.files.length;
|
|
747
|
+
const by = (state) => report.files.filter((one) => one.state === state).length;
|
|
748
|
+
const rows = report.files.map((one) => ` ${one.state.padEnd(10)} ${one.path}
|
|
749
|
+
`);
|
|
750
|
+
return `${rows.join("")}migrations: ${String(report.read)} of ${String(total)} files read \u2014 ${String(by("refused"))} refused, ${String(by("findings"))} with squawk findings, ${String(by("excused"))} excused, ${String(by("clean"))} clean${report.unreadable.length === 0 ? "" : `, ${String(report.unreadable.length)} unreadable`}
|
|
751
|
+
`;
|
|
713
752
|
};
|
|
714
753
|
|
|
715
754
|
// src/plan.ts
|
|
@@ -871,7 +910,7 @@ var stubPath = () => {
|
|
|
871
910
|
return path;
|
|
872
911
|
};
|
|
873
912
|
var prove = async (cwd, stub = stubPath()) => {
|
|
874
|
-
const
|
|
913
|
+
const lines2 = [];
|
|
875
914
|
let ok = true;
|
|
876
915
|
for (const plant of PLANTS) {
|
|
877
916
|
const verdict = await proveOver({
|
|
@@ -881,10 +920,10 @@ var prove = async (cwd, stub = stubPath()) => {
|
|
|
881
920
|
timeoutMs: 3e4
|
|
882
921
|
});
|
|
883
922
|
if (verdict.ok) ok = false;
|
|
884
|
-
|
|
923
|
+
lines2.push(` ${verdict.ok ? "MISSED" : "PROVEN"} ${plant.says}`);
|
|
885
924
|
if (plant.name !== "promoted" && verdict.steps.includes("promote")) {
|
|
886
925
|
ok = false;
|
|
887
|
-
|
|
926
|
+
lines2.push(" MISSED a refused smoke was followed by a promote request");
|
|
888
927
|
}
|
|
889
928
|
}
|
|
890
929
|
const honest = await proveOver({
|
|
@@ -894,10 +933,10 @@ var prove = async (cwd, stub = stubPath()) => {
|
|
|
894
933
|
timeoutMs: 3e4
|
|
895
934
|
});
|
|
896
935
|
if (!honest.ok) ok = false;
|
|
897
|
-
|
|
936
|
+
lines2.push(
|
|
898
937
|
` ${honest.ok ? "PROVEN" : "MISSED"} a smoke that answered the version it overrode to is not refused`
|
|
899
938
|
);
|
|
900
|
-
return { lines, ok };
|
|
939
|
+
return { lines: lines2, ok };
|
|
901
940
|
};
|
|
902
941
|
var formatProve = (outcome) => `${outcome.lines.join("\n")}
|
|
903
942
|
|
package/dist/index.d.ts
CHANGED
|
@@ -37,16 +37,30 @@ type MarkerRefusal = {
|
|
|
37
37
|
path: string;
|
|
38
38
|
why: string;
|
|
39
39
|
};
|
|
40
|
+
type FileState = 'clean' | 'excused' | 'findings' | 'refused' | 'unreadable';
|
|
40
41
|
type MigrationsReport = {
|
|
42
|
+
/** The configured directories the run looked under. */
|
|
43
|
+
dirs: string[];
|
|
44
|
+
/** Every file the diff added under a configured dir, by name and state — a clean file included. */
|
|
45
|
+
files: {
|
|
46
|
+
path: string;
|
|
47
|
+
state: FileState;
|
|
48
|
+
}[];
|
|
41
49
|
linted: number;
|
|
42
50
|
markers: MarkerRefusal[];
|
|
43
51
|
ok: boolean;
|
|
44
52
|
read: number;
|
|
45
53
|
refusals: Refusal[];
|
|
54
|
+
since: string;
|
|
46
55
|
squawk: {
|
|
47
56
|
findings: string;
|
|
48
57
|
path: string;
|
|
49
58
|
}[];
|
|
59
|
+
/** Files this reader could not read: named, never a stop for the others. */
|
|
60
|
+
unreadable: {
|
|
61
|
+
path: string;
|
|
62
|
+
why: string;
|
|
63
|
+
}[];
|
|
50
64
|
};
|
|
51
65
|
|
|
52
66
|
declare const parseReleaseConfig: (raw: unknown) => ReleaseConfig;
|
package/dist/index.js
CHANGED
package/dist/release-cli.js
CHANGED
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
runDeployed,
|
|
11
11
|
runMigrations,
|
|
12
12
|
runPlan
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-BOTEFN3W.js";
|
|
14
14
|
|
|
15
15
|
// src/release-cli.ts
|
|
16
16
|
import { resolve } from "path";
|
|
@@ -93,6 +93,7 @@ var migrations = (parsed, cwd) => {
|
|
|
93
93
|
parsed.json ? `${JSON.stringify(report, void 0, 2)}
|
|
94
94
|
` : formatMigrations(report)
|
|
95
95
|
);
|
|
96
|
+
if (report.unreadable.length > 0) return 2;
|
|
96
97
|
return report.ok ? 0 : 1;
|
|
97
98
|
};
|
|
98
99
|
var plan = (parsed, cwd) => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@geonosis/release",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"types": "./dist/index.d.ts",
|
|
5
5
|
"description": "The release contract with its proofs: an expand-only migration gate over three dialects, a smoke that must name the version that answered it, and declared ≠ deployed.",
|
|
6
6
|
"keywords": [
|