(committed: string, regenerated: string)
| 76 | /** The lines each side has and the other does not — enough to name the route |
| 77 | * that drifted, without pulling in a diff library for a CI guard. */ |
| 78 | const lineDiff = (committed: string, regenerated: string): string => { |
| 79 | const committedLines = new Set(committed.split("\n")); |
| 80 | const regeneratedLines = new Set(regenerated.split("\n")); |
| 81 | const missing = [...regeneratedLines].filter((line) => !committedLines.has(line)); |
| 82 | const extra = [...committedLines].filter((line) => !regeneratedLines.has(line)); |
| 83 | const show = (label: string, lines: readonly string[]) => |
| 84 | lines.length === 0 |
| 85 | ? [] |
| 86 | : [` ${label}:`, ...lines.slice(0, 20).map((line) => ` ${line}`)]; |
| 87 | return [ |
| 88 | ...show("in the regenerated tree but NOT committed (missing routes)", missing), |
| 89 | ...show("committed but NOT regenerated (stale routes)", extra), |
| 90 | ].join("\n"); |
| 91 | }; |
| 92 | |
| 93 | type Failure = { readonly tree: string; readonly detail: string }; |
| 94 | const failures: Failure[] = []; |
no test coverage detected