redlinegate 0.0.2 → 0.0.3

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.
Files changed (63) hide show
  1. package/README.md +2 -2
  2. package/dist/bin/redline.js +247 -42
  3. package/dist/bin/redline.js.map +1 -1
  4. package/dist/commands/init.js +274 -26
  5. package/dist/commands/init.js.map +1 -1
  6. package/dist/commands/remove.js +40 -0
  7. package/dist/commands/remove.js.map +1 -1
  8. package/dist/commands/status.js +94 -0
  9. package/dist/commands/status.js.map +1 -0
  10. package/dist/config/redline-json.js +18 -1
  11. package/dist/config/redline-json.js.map +1 -1
  12. package/dist/core/git.js +50 -3
  13. package/dist/core/git.js.map +1 -1
  14. package/dist/core/version.js +6 -0
  15. package/dist/core/version.js.map +1 -1
  16. package/dist/detect/setup.js +200 -0
  17. package/dist/detect/setup.js.map +1 -0
  18. package/dist/detect/stack.js +56 -17
  19. package/dist/detect/stack.js.map +1 -1
  20. package/dist/metrics/options.js +0 -9
  21. package/dist/metrics/options.js.map +1 -1
  22. package/dist/platforms/azure/install.js +1 -5
  23. package/dist/platforms/azure/install.js.map +1 -1
  24. package/dist/platforms/azure/verify.js +4 -2
  25. package/dist/platforms/azure/verify.js.map +1 -1
  26. package/dist/platforms/github/install.js +110 -22
  27. package/dist/platforms/github/install.js.map +1 -1
  28. package/dist/platforms/github/vendor.js +81 -0
  29. package/dist/platforms/github/vendor.js.map +1 -0
  30. package/dist/platforms/github/verify.js +17 -2
  31. package/dist/platforms/github/verify.js.map +1 -1
  32. package/dist/platforms/types.js +4 -0
  33. package/dist/platforms/types.js.map +1 -1
  34. package/dist/render/standards.js +8 -1
  35. package/dist/render/standards.js.map +1 -1
  36. package/dist/render/vendors.js +9 -52
  37. package/dist/render/vendors.js.map +1 -1
  38. package/dist/rules/catalogue.js +127 -0
  39. package/dist/rules/catalogue.js.map +1 -0
  40. package/dist/ui/facts.js +30 -1
  41. package/dist/ui/facts.js.map +1 -1
  42. package/dist/ui/prompt.js +137 -8
  43. package/dist/ui/prompt.js.map +1 -1
  44. package/dist/ui/report.js +214 -0
  45. package/dist/ui/report.js.map +1 -0
  46. package/dist/ui/tty.js +358 -25
  47. package/dist/ui/tty.js.map +1 -1
  48. package/dist/ui/wizard.js +133 -19
  49. package/dist/ui/wizard.js.map +1 -1
  50. package/dist/verify/remote.js +33 -0
  51. package/dist/verify/remote.js.map +1 -1
  52. package/package.json +4 -1
  53. package/scripts/fetch-stars.mjs +92 -0
  54. package/scripts/lib/rules.d.mts +18 -0
  55. package/scripts/publish-local.mjs +183 -0
  56. package/standards/manifest.json +79 -8
  57. package/standards/stacks/angular.md +57 -0
  58. package/standards/stacks/dom.md +61 -0
  59. package/standards/stacks/svelte.md +45 -0
  60. package/standards/stacks/vue.md +54 -0
  61. package/templates/redline.yml +4 -0
  62. package/workflows/redline-gate.yml +28 -4
  63. package/scripts/measure-context.mjs +0 -101
@@ -0,0 +1,214 @@
1
+ const INDENT = ' ';
2
+ const BULLET = ' ';
3
+ // The status word column. `unsupported` is the longest at eleven, and a column
4
+ // sized to it keeps every detail starting at the same cell — which is the
5
+ // property that makes the block scannable rather than merely aligned.
6
+ const STATUS_WIDTH = 11;
7
+ const MIN_TEXT = 24;
8
+ /**
9
+ * Break `text` into lines that fit `width`, never mid-word where it can be
10
+ * helped.
11
+ *
12
+ * A word longer than the whole width is emitted on its own over-long line
13
+ * rather than chopped: it is a URL or a path, and half of either is worse than
14
+ * a line that runs on. Nothing here redraws, so an over-long line costs a soft
15
+ * wrap in the terminal and nothing else.
16
+ */
17
+ export function wrap(text, width) {
18
+ if (width <= 0)
19
+ return [text];
20
+ const lines = [];
21
+ let line = '';
22
+ for (const word of text.split(/\s+/).filter((w) => w !== '')) {
23
+ if (line === '') {
24
+ line = word;
25
+ continue;
26
+ }
27
+ if (line.length + 1 + word.length <= width) {
28
+ line = `${line} ${word}`;
29
+ continue;
30
+ }
31
+ lines.push(line);
32
+ line = word;
33
+ }
34
+ if (line !== '')
35
+ lines.push(line);
36
+ return lines.length === 0 ? [''] : lines;
37
+ }
38
+ // Escape sequences have width on the wire and none on the terminal. Every
39
+ // column here is measured after they are stripped, because a marker painted
40
+ // green is eleven bytes and one cell, and an indent computed from the eleven
41
+ // puts the continuation line a third of the way across the screen.
42
+ const ANSI = /\x1b\[[0-9;]*m/g;
43
+ export const visibleWidth = (text) => text.replace(ANSI, '').length;
44
+ // A block of text set under a marker, with every line after the first indented
45
+ // to sit under the text rather than under the marker. Used by every section
46
+ // here, because the alternative — letting the terminal soft-wrap — puts the
47
+ // continuation hard against the left edge and breaks the column the section
48
+ // exists to create.
49
+ function hanging(marker, text, indent, width) {
50
+ const markWidth = visibleWidth(marker);
51
+ const room = Math.max(MIN_TEXT, width - indent.length - markWidth);
52
+ const [first, ...rest] = wrap(text, room);
53
+ const pad = ' '.repeat(markWidth);
54
+ return [`${indent}${marker}${first ?? ''}`, ...rest.map((line) => `${indent}${pad}${line}`)];
55
+ }
56
+ function heading(title, count, theme) {
57
+ const { palette: c } = theme;
58
+ const tail = count === '' ? '' : ` ${c.dim(count)}`;
59
+ return ['', `${INDENT}${c.bold(title)}${tail}`];
60
+ }
61
+ // Which marker a capability's status earns, and what colour it is in.
62
+ //
63
+ // `already` is green with `applied`: the operator asked for a state, and the
64
+ // repository is in it. Whether this run or an earlier one put it there is a
65
+ // fact about Redline's history, not about the repository, and colouring it
66
+ // differently made a settled re-run look half-broken.
67
+ //
68
+ // `unsupported` and `unknown` are deliberately NOT red. Neither is a failure
69
+ // anybody can act on — one is a feature this repository does not have, the
70
+ // other is a read that gave no answer — and painting them like a denial is how
71
+ // a fully-onboarded repository came out of this report looking alarming.
72
+ function mark(status, theme) {
73
+ const { palette: c, glyphs: g } = theme;
74
+ switch (status) {
75
+ case 'applied':
76
+ case 'already':
77
+ return c.green(g.ok);
78
+ case 'denied':
79
+ return c.red(g.fail);
80
+ default:
81
+ return c.dim(g.skip);
82
+ }
83
+ }
84
+ function statusWord(status, theme) {
85
+ const { palette: c } = theme;
86
+ const padded = status.padEnd(STATUS_WIDTH);
87
+ if (status === 'applied' || status === 'already')
88
+ return c.green(padded);
89
+ if (status === 'denied')
90
+ return c.red(padded);
91
+ return c.dim(padded);
92
+ }
93
+ /**
94
+ * The whole report, as lines. Never ends in a blank line.
95
+ *
96
+ * Sections are emitted only when they have something in them: a run with no
97
+ * notes must not print an empty "Notes" heading, because a heading over nothing
98
+ * reads as a section that failed to render.
99
+ */
100
+ export function renderReport(summary, theme) {
101
+ const { palette: c, glyphs: g, width } = theme;
102
+ const out = [];
103
+ // A plan and a record of work read differently and must say so: "17 written"
104
+ // on a dry run is a claim about files that are not there.
105
+ const dry = summary.dryRun === true;
106
+ const title = [
107
+ summary.profile === undefined ? null : `profile ${c.cyan(summary.profile)}`,
108
+ summary.migratedFrom == null ? null : c.dim(`migrated from ${summary.migratedFrom}`),
109
+ dry ? c.yellow('dry run') : null,
110
+ ].filter((part) => part !== null);
111
+ if (title.length > 0)
112
+ out.push(`${INDENT}${title.join(c.dim(' · '))}`);
113
+ if (summary.optedOut !== undefined && summary.optedOut.length > 0) {
114
+ out.push(`${INDENT}${c.dim(`opted out: ${summary.optedOut.join(', ')}`)}`);
115
+ }
116
+ // Notes first, and never folded into a section. Each one is the reason a
117
+ // later line says what it says — why a gate job is missing, why a context was
118
+ // dropped — and a reader who meets the consequence before the reason goes
119
+ // looking for a bug.
120
+ for (const note of summary.notes ?? []) {
121
+ const [first, ...rest] = hanging(`${g.warn} `, note, INDENT, width);
122
+ out.push(`${INDENT}${c.yellow(g.warn)} ${c.dim((first ?? '').slice(INDENT.length + 2))}`);
123
+ for (const line of rest)
124
+ out.push(c.dim(line));
125
+ }
126
+ const removals = new Set(summary.removals ?? []);
127
+ const files = summary.files ?? [];
128
+ if (files.length > 0) {
129
+ const written = files.filter((f) => !removals.has(f)).length;
130
+ const removed = files.length - written;
131
+ const count = [
132
+ written > 0 ? `${written} ${dry ? 'to write' : 'written'}` : null,
133
+ removed > 0 ? `${removed} ${dry ? 'to remove' : 'removed'}` : null,
134
+ ]
135
+ .filter((part) => part !== null)
136
+ .join(', ');
137
+ out.push(...heading('Files', count, theme));
138
+ for (const file of files) {
139
+ const gone = removals.has(file);
140
+ const glyph = gone ? c.yellow(g.remove) : c.green(g.write);
141
+ out.push(`${BULLET}${glyph} ${gone ? c.dim(file) : file}`);
142
+ }
143
+ }
144
+ // A dry run has no outcomes — it made no host call — so it prints the plan it
145
+ // would have applied instead. Silence there read as "Redline changes nothing
146
+ // on the host", which is the opposite of true.
147
+ const hostPlan = summary.hostPlan ?? [];
148
+ if (dry && hostPlan.length > 0) {
149
+ out.push(...heading('Repository settings', `${hostPlan.length} to apply`, theme));
150
+ for (const step of hostPlan) {
151
+ out.push(...hanging(`${c.dim(g.arrow)} `, step, BULLET, width));
152
+ }
153
+ }
154
+ const outcomes = summary.outcomes ?? [];
155
+ if (outcomes.length > 0) {
156
+ const tally = (...states) => outcomes.filter((o) => states.includes(o.status)).length;
157
+ // Three separate numbers, not a fraction. `2/7` counted `unsupported`
158
+ // against the repository — and a capability this repository cannot have is
159
+ // not a capability it is missing.
160
+ const count = [
161
+ `${tally('applied', 'already')} in place`,
162
+ tally('denied') > 0 ? `${tally('denied')} refused` : null,
163
+ tally('unsupported', 'unknown') > 0 ? `${tally('unsupported', 'unknown')} unavailable` : null,
164
+ ]
165
+ .filter((part) => part !== null)
166
+ .join(' · ');
167
+ out.push(...heading('Repository settings', count, theme));
168
+ const nameWidth = Math.max(...outcomes.map((o) => o.capability.length));
169
+ for (const outcome of outcomes) {
170
+ const marker = `${mark(outcome.status, theme)} ${statusWord(outcome.status, theme)} `;
171
+ // Measured on the raw text: a painted string carries escape bytes that
172
+ // have width on the wire and none on the terminal, and a column padded
173
+ // from them is a column that does not line up.
174
+ const rawMarker = `${g.ok} ${''.padEnd(STATUS_WIDTH)} `;
175
+ const name = outcome.capability.padEnd(nameWidth);
176
+ const prefix = `${BULLET}${rawMarker}${name} `;
177
+ const room = Math.max(MIN_TEXT, width - prefix.length);
178
+ const [first, ...rest] = wrap(outcome.detail, room);
179
+ out.push(`${BULLET}${marker}${c.bold(name)} ${c.dim(first ?? '')}`);
180
+ for (const line of rest)
181
+ out.push(c.dim(`${' '.repeat(prefix.length)}${line}`));
182
+ }
183
+ }
184
+ if (summary.pullRequestUrl != null && summary.pullRequestUrl !== '') {
185
+ out.push(...heading('Pull request', '', theme));
186
+ out.push(`${BULLET}${c.cyan(summary.pullRequestUrl)}`);
187
+ }
188
+ // The whole point of the redesign. Everything above is a record of what
189
+ // happened; this is the only part that asks the operator for anything, so it
190
+ // goes last, numbered, and carries the command to run rather than the state
191
+ // to regret.
192
+ const left = outcomes.filter((o) => o.status === 'denied');
193
+ if (left.length > 0) {
194
+ out.push(...heading("What's left", `${left.length} for an administrator`, theme));
195
+ left.forEach((outcome, index) => {
196
+ const step = `${index + 1}.`;
197
+ const indent = `${BULLET}${' '.repeat(step.length + 1)}`;
198
+ // Measured off the raw first line, not off `indent`: the capability name
199
+ // and the dash sit on it too, and wrapping to the continuation's width
200
+ // would overshoot the terminal by exactly their length.
201
+ const room = Math.max(MIN_TEXT, width - indent.length - outcome.capability.length - 3);
202
+ const [first, ...rest] = wrap(outcome.detail, room);
203
+ out.push(`${BULLET}${c.red(step)} ${c.bold(outcome.capability)} ${c.dim('—')} ${first ?? ''}`);
204
+ for (const line of rest)
205
+ out.push(`${indent}${line}`);
206
+ const fix = outcome.hint;
207
+ if (fix !== undefined && fix !== '') {
208
+ out.push(...hanging(`${g.arrow} `, fix, indent, width).map((line) => c.dim(line)));
209
+ }
210
+ });
211
+ }
212
+ return out;
213
+ }
214
+ //# sourceMappingURL=report.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"report.js","sourceRoot":"","sources":["../../cli/ui/report.ts"],"names":[],"mappings":"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"}