reslop 0.2.3 → 0.2.4
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/CHANGELOG.md +14 -1
- package/README.md +8 -3
- package/bin/reslop.js +4 -2
- package/lib/api.js +2 -1
- package/lib/cli.js +19 -10
- package/lib/clipboard.js +6 -3
- package/lib/deps-diff.js +61 -115
- package/lib/deps.js +24 -61
- package/lib/detect.js +4 -2
- package/lib/diff/align.js +2 -1
- package/lib/diff/diff.js +6 -3
- package/lib/diff/display.js +2 -1
- package/lib/diff/inline.js +2 -1
- package/lib/diff/patch.js +2 -1
- package/lib/diff/unit.js +4 -2
- package/lib/editor.js +22 -4
- package/lib/files.js +38 -12
- package/lib/git-branches.js +107 -154
- package/lib/git-deps.js +20 -60
- package/lib/git-worktree.js +508 -0
- package/lib/git.js +23 -580
- package/lib/github.js +2 -1
- package/lib/gitlab.js +2 -1
- package/lib/highlight/bash.js +2 -1
- package/lib/highlight/css.js +2 -1
- package/lib/highlight/csv.js +2 -1
- package/lib/highlight/dot.js +2 -1
- package/lib/highlight/html.js +2 -1
- package/lib/highlight/json.js +2 -1
- package/lib/highlight/log.js +2 -1
- package/lib/highlight/txt.js +2 -1
- package/lib/highlight.js +2 -1
- package/lib/keys.js +2 -2
- package/lib/manifest.js +4 -2
- package/lib/npm-commands.js +83 -4
- package/lib/remote.js +20 -13
- package/lib/render/branches.js +6 -15
- package/lib/render/chrome.js +27 -7
- package/lib/render/commits.js +158 -46
- package/lib/render/diff.js +130 -47
- package/lib/render/files.js +4 -12
- package/lib/render/frame.js +3 -9
- package/lib/render/notes.js +4 -11
- package/lib/render/npm.js +1 -13
- package/lib/render/present.js +2 -1
- package/lib/render/primitives.js +28 -15
- package/lib/render/render.js +2 -1
- package/lib/render/unit.js +14 -11
- package/lib/report-model.js +6 -4
- package/lib/report-parse.js +8 -13
- package/lib/report-render.js +38 -21
- package/lib/report-run.js +12 -10
- package/lib/report-test.js +5 -4
- package/lib/report-tools.js +44 -18
- package/lib/review-merge.js +2 -1
- package/lib/review.js +6 -2
- package/lib/session/actions.js +49 -65
- package/lib/session/branches.js +13 -49
- package/lib/session/change-actions.js +2 -1
- package/lib/session/commit.js +34 -49
- package/lib/session/compose.js +37 -11
- package/lib/session/dispatch.js +17 -25
- package/lib/session/files-pane.js +6 -27
- package/lib/session/items.js +6 -3
- package/lib/session/lifecycle.js +8 -4
- package/lib/session/load.js +4 -2
- package/lib/session/navigation.js +1 -0
- package/lib/session/npm.js +54 -1
- package/lib/session/ops.js +15 -1
- package/lib/session/pointer.js +22 -3
- package/lib/session/review.js +2 -1
- package/lib/session/terminal.js +4 -2
- package/lib/session/update.js +2 -1
- package/lib/session/view.js +29 -3
- package/lib/session.js +37 -23
- package/lib/source.js +6 -3
- package/lib/update.js +5 -9
- package/lib/utilities.js +4 -2
- package/lib/wrap.js +3 -1
- package/package.json +1 -1
package/lib/render/notes.js
CHANGED
|
@@ -7,7 +7,7 @@ const primitives = require('./primitives.js');
|
|
|
7
7
|
|
|
8
8
|
const { REPO_TODOS_LABEL } = files;
|
|
9
9
|
const { wrapMultiline, cursorInWrap } = wrap;
|
|
10
|
-
const { THEME,
|
|
10
|
+
const { THEME, truncateVisible } = ansi;
|
|
11
11
|
const { paintBar, paintCheckBar, windowRows } = primitives;
|
|
12
12
|
const { LIST_PANES, CHECK_LEAD, paneResult } = primitives;
|
|
13
13
|
|
|
@@ -73,6 +73,7 @@ const paintTodoList = (texts, focus, width, color, edit) => {
|
|
|
73
73
|
fgRgb,
|
|
74
74
|
bgRgb,
|
|
75
75
|
color,
|
|
76
|
+
true,
|
|
76
77
|
);
|
|
77
78
|
rows.push(painted);
|
|
78
79
|
owners.push(i);
|
|
@@ -168,16 +169,8 @@ const paintNotePanel = (view, width, color, cap) => {
|
|
|
168
169
|
return paintIdleNote(view, width, color);
|
|
169
170
|
};
|
|
170
171
|
|
|
171
|
-
const paintTodoCaption = (width, color) =>
|
|
172
|
-
|
|
173
|
-
const clipped = truncateVisible(text, width);
|
|
174
|
-
const pad = Math.max(0, width - visibleWidth(clipped));
|
|
175
|
-
const filled = clipped + ' '.repeat(pad);
|
|
176
|
-
if (!color) return filled;
|
|
177
|
-
const fgRgb = THEME.buttonHotFg;
|
|
178
|
-
const bgRgb = THEME.ctxBg;
|
|
179
|
-
return `${BOLD}${seq(fgRgb, bgRgb)}${EL}${filled}${RESET}`;
|
|
180
|
-
};
|
|
172
|
+
const paintTodoCaption = (width, color) =>
|
|
173
|
+
paintBar(` ${REPO_TODOS_LABEL}`, width, THEME.mutedFg, THEME.ctxBg, color);
|
|
181
174
|
|
|
182
175
|
const paintBodyTodo = (view, width, color) => {
|
|
183
176
|
const texts = view.todos ?? [];
|
package/lib/render/npm.js
CHANGED
|
@@ -78,7 +78,7 @@ const paintNpmList = (view, width, color, bodyH, headerLines) => {
|
|
|
78
78
|
const at = view.npmEditName ? 'replace' : 'end';
|
|
79
79
|
extra = { row: painted.row, cursor: painted.cursor, at, index: cursor };
|
|
80
80
|
}
|
|
81
|
-
|
|
81
|
+
return paintCursorList(
|
|
82
82
|
commands,
|
|
83
83
|
cursor,
|
|
84
84
|
width,
|
|
@@ -89,14 +89,6 @@ const paintNpmList = (view, width, color, bodyH, headerLines) => {
|
|
|
89
89
|
extra,
|
|
90
90
|
view.listScroll,
|
|
91
91
|
);
|
|
92
|
-
return paneResult({
|
|
93
|
-
body: painted.body,
|
|
94
|
-
fileHits: painted.fileHits,
|
|
95
|
-
todoOwners: [],
|
|
96
|
-
cursor: painted.cursor,
|
|
97
|
-
splitBody: false,
|
|
98
|
-
listScroll: painted.offset,
|
|
99
|
-
});
|
|
100
92
|
};
|
|
101
93
|
|
|
102
94
|
const logStart = (view, count, rows) => {
|
|
@@ -213,10 +205,6 @@ const paintNpmLog = (view, width, color, bodyH) => {
|
|
|
213
205
|
for (let i = 0; i < padY - top; i++) body.push(blank);
|
|
214
206
|
return paneResult({
|
|
215
207
|
body,
|
|
216
|
-
fileHits: [],
|
|
217
|
-
todoOwners: [],
|
|
218
|
-
cursor: null,
|
|
219
|
-
splitBody: false,
|
|
220
208
|
});
|
|
221
209
|
};
|
|
222
210
|
|
package/lib/render/present.js
CHANGED
package/lib/render/primitives.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
const ansi = require('../ansi.js');
|
|
4
|
+
const actions = require('../session/actions.js');
|
|
5
|
+
const { LIST_PANES } = actions;
|
|
4
6
|
|
|
5
7
|
const { THEME, paint, visibleWidth, truncateVisible, seq, EL, RESET } = ansi;
|
|
6
8
|
|
|
@@ -8,7 +10,6 @@ const GUTTER_W = 2;
|
|
|
8
10
|
const FILE_MARK = '▶';
|
|
9
11
|
const FILE_LIST_PAD = 1;
|
|
10
12
|
const CHECK_DONE = 'xX';
|
|
11
|
-
const LIST_PANES = ['files', 'branches', 'commits', 'npm'];
|
|
12
13
|
const CHECK_TOKEN = /\[([ xX])\]/;
|
|
13
14
|
const CHECK_LEAD = /^\[[ xX]\] /;
|
|
14
15
|
|
|
@@ -34,14 +35,21 @@ const splitCheck = (text) => {
|
|
|
34
35
|
return { before, mark, token, after };
|
|
35
36
|
};
|
|
36
37
|
|
|
37
|
-
const paintCheckBar = (text, width, fgRgb, bgRgb, color) => {
|
|
38
|
+
const paintCheckBar = (text, width, fgRgb, bgRgb, color, plain = false) => {
|
|
38
39
|
const clipped = truncateVisible(text, width);
|
|
39
40
|
const parts = color ? splitCheck(clipped) : null;
|
|
40
41
|
if (!parts) return paintBar(text, width, fgRgb, bgRgb, color);
|
|
41
42
|
const pad = Math.max(0, width - visibleWidth(clipped));
|
|
42
43
|
const done = CHECK_DONE.includes(parts.mark);
|
|
43
|
-
|
|
44
|
-
|
|
44
|
+
let chipFg = THEME.checkFg;
|
|
45
|
+
let chipBg = THEME.checkBg;
|
|
46
|
+
if (plain) {
|
|
47
|
+
chipFg = fgRgb;
|
|
48
|
+
chipBg = bgRgb;
|
|
49
|
+
} else if (done) {
|
|
50
|
+
chipFg = THEME.checkDoneFg;
|
|
51
|
+
chipBg = THEME.checkDoneBg;
|
|
52
|
+
}
|
|
45
53
|
const after = `${parts.after}${' '.repeat(pad)}`;
|
|
46
54
|
let out = `${seq(fgRgb, bgRgb)}${EL}`;
|
|
47
55
|
if (parts.before) out += paint(parts.before, fgRgb, bgRgb, color);
|
|
@@ -111,6 +119,16 @@ const extraIdx = (extraRow, cursor, count) => {
|
|
|
111
119
|
return count;
|
|
112
120
|
};
|
|
113
121
|
|
|
122
|
+
const paneResult = (fields = {}) => ({
|
|
123
|
+
body: fields.body ?? [],
|
|
124
|
+
fileHits: fields.fileHits ?? [],
|
|
125
|
+
todoOwners: fields.todoOwners ?? [],
|
|
126
|
+
todoChecks: fields.todoChecks ?? [],
|
|
127
|
+
cursor: fields.cursor ?? null,
|
|
128
|
+
splitBody: fields.splitBody === true,
|
|
129
|
+
listScroll: fields.listScroll ?? 0,
|
|
130
|
+
});
|
|
131
|
+
|
|
114
132
|
const paintCursorList = (
|
|
115
133
|
items,
|
|
116
134
|
cursor,
|
|
@@ -153,7 +171,12 @@ const paintCursorList = (
|
|
|
153
171
|
fileHits.push({ y, cursor: itemIdx });
|
|
154
172
|
}
|
|
155
173
|
if (pad) body.push(blank);
|
|
156
|
-
return {
|
|
174
|
+
return paneResult({
|
|
175
|
+
body,
|
|
176
|
+
fileHits,
|
|
177
|
+
cursor: textCursor,
|
|
178
|
+
listScroll: start,
|
|
179
|
+
});
|
|
157
180
|
};
|
|
158
181
|
|
|
159
182
|
const branchLabel = (name) => `${name ?? ''}`.trim();
|
|
@@ -183,16 +206,6 @@ const paintListEdit = (compose, width, color, edgeW = 0) => {
|
|
|
183
206
|
return { row, cursor: { x: prefixW + col + 1 } };
|
|
184
207
|
};
|
|
185
208
|
|
|
186
|
-
const paneResult = (fields) => ({
|
|
187
|
-
body: fields.body,
|
|
188
|
-
fileHits: fields.fileHits,
|
|
189
|
-
todoOwners: fields.todoOwners,
|
|
190
|
-
todoChecks: fields.todoChecks ?? [],
|
|
191
|
-
cursor: fields.cursor ?? null,
|
|
192
|
-
splitBody: fields.splitBody === true,
|
|
193
|
-
listScroll: fields.listScroll ?? 0,
|
|
194
|
-
});
|
|
195
|
-
|
|
196
209
|
const measureColumns = (entries, rowFields, align) => {
|
|
197
210
|
const keys = Object.keys(align);
|
|
198
211
|
const widths = Object.fromEntries(keys.map((key) => [key, 0]));
|
package/lib/render/render.js
CHANGED
|
@@ -4,7 +4,8 @@ const chrome = require('./chrome.js');
|
|
|
4
4
|
const notes = require('./notes.js');
|
|
5
5
|
const diff = require('./diff.js');
|
|
6
6
|
const present = require('./present.js');
|
|
7
|
-
const
|
|
7
|
+
const frame = require('./frame.js');
|
|
8
|
+
const { renderFrame } = frame;
|
|
8
9
|
|
|
9
10
|
const { QUIT_PROMPT, PUSH_PROMPT } = chrome;
|
|
10
11
|
const { updatePrompt, dropPrompt } = chrome;
|
package/lib/render/unit.js
CHANGED
|
@@ -1,23 +1,29 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const
|
|
3
|
+
const detect = require('../detect.js');
|
|
4
|
+
const { detectLang } = detect;
|
|
4
5
|
const primitives = require('./primitives.js');
|
|
5
6
|
const diff = require('./diff.js');
|
|
6
7
|
|
|
7
8
|
const { paneResult } = primitives;
|
|
8
|
-
const { paintDiffLine, codeCursorInRows } = diff;
|
|
9
|
-
const
|
|
9
|
+
const { paintDiffLine, codeCursorInRows, expandSoftRows } = diff;
|
|
10
|
+
const diffLib = require('../diff/diff.js');
|
|
11
|
+
const { sameHunk } = diffLib;
|
|
10
12
|
|
|
11
13
|
const paintBodyUnit = (view, width, color) => {
|
|
12
14
|
const lines = view.unitLines ?? [];
|
|
13
15
|
const item = view.item;
|
|
14
16
|
const lang = detectLang(view.reviewPath ?? '');
|
|
15
17
|
const overlay = view.codeOverlay;
|
|
16
|
-
const editing =
|
|
17
|
-
|
|
18
|
+
const editing =
|
|
19
|
+
view.mode === 'compose' && overlay && typeof overlay.cursor === 'number';
|
|
20
|
+
const picked = editing ? overlay.scrollCol : 0;
|
|
21
|
+
const scrollCol = picked ?? 0;
|
|
22
|
+
const source = editing ? lines : expandSoftRows(lines, width, false, true);
|
|
23
|
+
const { length } = source;
|
|
18
24
|
const body = new Array(length);
|
|
19
25
|
for (let i = 0; i < length; i++) {
|
|
20
|
-
const line =
|
|
26
|
+
const line = source[i];
|
|
21
27
|
const isBlock = item && sameHunk(line.item, item);
|
|
22
28
|
const row = { ...line };
|
|
23
29
|
if (editing) {
|
|
@@ -25,16 +31,13 @@ const paintBodyUnit = (view, width, color) => {
|
|
|
25
31
|
} else if ((row.type === 'add' || row.type === 'del') && !isBlock) {
|
|
26
32
|
row.mark = ' ';
|
|
27
33
|
}
|
|
28
|
-
body[i] = paintDiffLine(row, width, color, row.origin, lang);
|
|
34
|
+
body[i] = paintDiffLine(row, width, color, row.origin, lang, scrollCol);
|
|
29
35
|
}
|
|
30
36
|
const edit = overlay ? overlay.cursor : null;
|
|
31
|
-
const cursor = codeCursorInRows(
|
|
37
|
+
const cursor = codeCursorInRows(source, false, width, edit, scrollCol);
|
|
32
38
|
return paneResult({
|
|
33
39
|
body,
|
|
34
|
-
fileHits: [],
|
|
35
|
-
todoOwners: [],
|
|
36
40
|
cursor,
|
|
37
|
-
splitBody: false,
|
|
38
41
|
});
|
|
39
42
|
};
|
|
40
43
|
|
package/lib/report-model.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const
|
|
3
|
+
const ansi = require('./ansi.js');
|
|
4
|
+
const { stripAnsi } = ansi;
|
|
4
5
|
const commands = require('./npm-commands.js');
|
|
5
6
|
|
|
6
7
|
const { withoutNodeFrame, indentStack, relativize } = commands;
|
|
@@ -108,9 +109,10 @@ const shortTail = (text) => {
|
|
|
108
109
|
const envelope = (reports, exit, stderr) => {
|
|
109
110
|
const status = exit === null || exit === undefined ? 1 : exit;
|
|
110
111
|
const ok = status === 0;
|
|
111
|
-
const items =
|
|
112
|
-
for (
|
|
113
|
-
|
|
112
|
+
const items = new Array(reports.length);
|
|
113
|
+
for (let i = 0; i < reports.length; i++) {
|
|
114
|
+
const item = reports[i];
|
|
115
|
+
items[i] = report(item.tool, { ...item, ok });
|
|
114
116
|
}
|
|
115
117
|
return { ok, exit: status, reports: items, stderr: stderr || '' };
|
|
116
118
|
};
|
package/lib/report-parse.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const
|
|
3
|
+
const ansi = require('./ansi.js');
|
|
4
|
+
const { stripAnsi } = ansi;
|
|
4
5
|
const model = require('./report-model.js');
|
|
5
6
|
const testParse = require('./report-test.js');
|
|
6
7
|
const toolParse = require('./report-tools.js');
|
|
@@ -10,15 +11,7 @@ const { reduceStderr, shortTail, envelope } = model;
|
|
|
10
11
|
const { parseTap, parseNodeJsonl, parseTestJson, parseSpec } = testParse;
|
|
11
12
|
const { parseToolJson, parseToolText } = toolParse;
|
|
12
13
|
|
|
13
|
-
const KNOWN =
|
|
14
|
-
'test',
|
|
15
|
-
'tsc',
|
|
16
|
-
'eslint',
|
|
17
|
-
'prettier',
|
|
18
|
-
'audit',
|
|
19
|
-
'outdated',
|
|
20
|
-
'ls',
|
|
21
|
-
]);
|
|
14
|
+
const KNOWN = ['test', 'tsc', 'eslint', 'prettier', 'audit', 'outdated', 'ls'];
|
|
22
15
|
|
|
23
16
|
const toolHint = (program, args) => {
|
|
24
17
|
const name = `${program ?? ''}`.split(/[/\\]/).pop();
|
|
@@ -75,15 +68,17 @@ const parseReports = (text, root) => {
|
|
|
75
68
|
|
|
76
69
|
const withHint = (reports, text, exit, hint) => {
|
|
77
70
|
if (reports.length || !`${text ?? ''}`.trim() || exit === 0) return reports;
|
|
78
|
-
const tool = KNOWN.
|
|
71
|
+
const tool = KNOWN.includes(hint) ? hint : 'test';
|
|
79
72
|
return [report(tool, { problems: [problem({ message: shortTail(text) })] })];
|
|
80
73
|
};
|
|
81
74
|
|
|
82
75
|
const buildDocument = (stdout, stderr, root, exit, hint) => {
|
|
83
76
|
const text = stripAnsi(stdout);
|
|
84
77
|
const reports = withHint(parseReports(text, root), text, exit, hint);
|
|
85
|
-
const grouped =
|
|
86
|
-
for (
|
|
78
|
+
const grouped = new Array(reports.length);
|
|
79
|
+
for (let i = 0; i < reports.length; i++) {
|
|
80
|
+
grouped[i] = groupReport(reports[i]);
|
|
81
|
+
}
|
|
87
82
|
return envelope(grouped, exit, reduceStderr(stderr, root));
|
|
88
83
|
};
|
|
89
84
|
|
package/lib/report-render.js
CHANGED
|
@@ -10,34 +10,51 @@ const NOTICE = [
|
|
|
10
10
|
'rerun the same command with RESLOP_OUTPUT=raw.',
|
|
11
11
|
].join('\n');
|
|
12
12
|
|
|
13
|
-
const
|
|
14
|
-
|
|
15
|
-
|
|
13
|
+
const SUMMARY_ROWS = 6;
|
|
14
|
+
const PROBLEM_FIELDS = 7;
|
|
15
|
+
|
|
16
|
+
const writeRow = (rows, index, key, value) => {
|
|
17
|
+
if (value === null || value === undefined || value === '') return index;
|
|
18
|
+
rows[index] = [key, `${value}`];
|
|
19
|
+
return index + 1;
|
|
16
20
|
};
|
|
17
21
|
|
|
18
22
|
const summaryRows = (stats) => {
|
|
19
|
-
const rows =
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
23
|
+
const rows = new Array(SUMMARY_ROWS);
|
|
24
|
+
let index = 0;
|
|
25
|
+
index = writeRow(rows, index, 'passed', stats.passed);
|
|
26
|
+
index = writeRow(rows, index, 'failed', stats.failed);
|
|
27
|
+
index = writeRow(rows, index, 'skipped', stats.skipped);
|
|
28
|
+
index = writeRow(rows, index, 'errors', stats.errors);
|
|
29
|
+
index = writeRow(rows, index, 'warnings', stats.warnings);
|
|
30
|
+
index = writeRow(rows, index, 'duration', stats.duration);
|
|
31
|
+
rows.length = index;
|
|
26
32
|
return rows;
|
|
27
33
|
};
|
|
28
34
|
|
|
29
35
|
const problemRows = (item) => {
|
|
30
|
-
const
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
36
|
+
const extra = item.extra;
|
|
37
|
+
let size = PROBLEM_FIELDS + extra.length;
|
|
38
|
+
if (item.count > 1) size += 1;
|
|
39
|
+
if (item.omitted > 0) size += 1;
|
|
40
|
+
const rows = new Array(size);
|
|
41
|
+
let index = 0;
|
|
42
|
+
index = writeRow(rows, index, 'severity', item.severity);
|
|
43
|
+
index = writeRow(rows, index, 'duration', item.duration);
|
|
44
|
+
index = writeRow(rows, index, 'code', item.code);
|
|
45
|
+
index = writeRow(rows, index, 'operator', item.operator);
|
|
46
|
+
index = writeRow(rows, index, 'expected', item.expected);
|
|
47
|
+
index = writeRow(rows, index, 'actual', item.actual);
|
|
48
|
+
index = writeRow(rows, index, 'message', item.message);
|
|
49
|
+
for (let i = 0; i < extra.length; i++) {
|
|
50
|
+
const pair = extra[i];
|
|
51
|
+
index = writeRow(rows, index, pair[0], pair[1]);
|
|
52
|
+
}
|
|
53
|
+
if (item.count > 1) index = writeRow(rows, index, 'count', item.count);
|
|
54
|
+
if (item.omitted > 0) {
|
|
55
|
+
index = writeRow(rows, index, 'omitted', item.omitted);
|
|
56
|
+
}
|
|
57
|
+
rows.length = index;
|
|
41
58
|
return rows;
|
|
42
59
|
};
|
|
43
60
|
|
package/lib/report-run.js
CHANGED
|
@@ -1,12 +1,17 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
const path = require('node:path');
|
|
4
|
-
const
|
|
4
|
+
const childProcess = require('node:child_process');
|
|
5
|
+
const { spawn } = childProcess;
|
|
5
6
|
|
|
6
|
-
const
|
|
7
|
-
const {
|
|
8
|
-
const
|
|
9
|
-
const {
|
|
7
|
+
const utilities = require('./utilities.js');
|
|
8
|
+
const { spawnBase } = utilities;
|
|
9
|
+
const npmCommands = require('./npm-commands.js');
|
|
10
|
+
const { writeLog } = npmCommands;
|
|
11
|
+
const reportParse = require('./report-parse.js');
|
|
12
|
+
const { toolHint, buildDocument } = reportParse;
|
|
13
|
+
const reportRender = require('./report-render.js');
|
|
14
|
+
const { renderDocument } = reportRender;
|
|
10
15
|
|
|
11
16
|
const OUTPUTS = new Set(['md', 'raw']);
|
|
12
17
|
|
|
@@ -31,11 +36,8 @@ const winCommand = (program, args) => {
|
|
|
31
36
|
};
|
|
32
37
|
|
|
33
38
|
const spawnCommand = (program, args, options) => {
|
|
34
|
-
const
|
|
35
|
-
|
|
36
|
-
env: options.env,
|
|
37
|
-
stdio: options.stdio,
|
|
38
|
-
};
|
|
39
|
+
const { cwd, env, stdio } = options;
|
|
40
|
+
const base = { cwd, env, stdio };
|
|
39
41
|
if (process.platform !== 'win32') {
|
|
40
42
|
return spawn(program, args, spawnBase(base));
|
|
41
43
|
}
|
package/lib/report-test.js
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
const model = require('./report-model.js');
|
|
4
|
-
const
|
|
4
|
+
const npmCommands = require('./npm-commands.js');
|
|
5
|
+
const { isPassingTest } = npmCommands;
|
|
5
6
|
|
|
6
7
|
const { summary, problem, report, userTrace } = model;
|
|
7
8
|
|
|
8
|
-
const KNOWN =
|
|
9
|
+
const KNOWN = [
|
|
9
10
|
'message',
|
|
10
11
|
'error',
|
|
11
12
|
'code',
|
|
@@ -19,7 +20,7 @@ const KNOWN = new Set([
|
|
|
19
20
|
'location',
|
|
20
21
|
'severity',
|
|
21
22
|
'type',
|
|
22
|
-
]
|
|
23
|
+
];
|
|
23
24
|
|
|
24
25
|
const show = (value) => {
|
|
25
26
|
if (value === null || value === undefined) return '';
|
|
@@ -33,7 +34,7 @@ const show = (value) => {
|
|
|
33
34
|
const extraFrom = (fields) => {
|
|
34
35
|
const extra = [];
|
|
35
36
|
for (const field of fields) {
|
|
36
|
-
if (KNOWN.
|
|
37
|
+
if (KNOWN.includes(field[0])) continue;
|
|
37
38
|
const value = show(field[1]);
|
|
38
39
|
if (!value) continue;
|
|
39
40
|
const shown = value.length > 500 ? `${value.slice(0, 500)}…` : value;
|
package/lib/report-tools.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const
|
|
3
|
+
const deps = require('./deps.js');
|
|
4
|
+
const { parseAuditReport, parseOutdatedReport } = deps;
|
|
4
5
|
const model = require('./report-model.js');
|
|
5
6
|
|
|
6
7
|
const { summary, problem, report, userTrace } = model;
|
|
@@ -160,21 +161,30 @@ const parsePrettier = (text, root) => {
|
|
|
160
161
|
return report('prettier', { summary: stats, problems });
|
|
161
162
|
};
|
|
162
163
|
|
|
164
|
+
const auditExtra = (item) => {
|
|
165
|
+
const size = (item.range ? 1 : 0) + (item.fix ? 1 : 0);
|
|
166
|
+
const extra = new Array(size);
|
|
167
|
+
let index = 0;
|
|
168
|
+
if (item.range) {
|
|
169
|
+
extra[index] = ['range', item.range];
|
|
170
|
+
index += 1;
|
|
171
|
+
}
|
|
172
|
+
if (item.fix) extra[index] = ['fix', item.fix];
|
|
173
|
+
return extra;
|
|
174
|
+
};
|
|
175
|
+
|
|
163
176
|
const auditProblems = (text) => {
|
|
164
177
|
const audit = parseAuditReport(text);
|
|
165
|
-
const problems =
|
|
178
|
+
const problems = new Array(audit.size);
|
|
179
|
+
let index = 0;
|
|
166
180
|
for (const item of audit.values()) {
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
message: item.title || '',
|
|
175
|
-
extra,
|
|
176
|
-
}),
|
|
177
|
-
);
|
|
181
|
+
problems[index] = problem({
|
|
182
|
+
severity: item.severity || 'error',
|
|
183
|
+
name: item.name,
|
|
184
|
+
message: item.title || '',
|
|
185
|
+
extra: auditExtra(item),
|
|
186
|
+
});
|
|
187
|
+
index += 1;
|
|
178
188
|
}
|
|
179
189
|
return problems;
|
|
180
190
|
};
|
|
@@ -285,16 +295,32 @@ const parseAuditText = (text) => {
|
|
|
285
295
|
return report('audit', { summary: stats, problems });
|
|
286
296
|
};
|
|
287
297
|
|
|
298
|
+
const TOOL_SLOTS = 4;
|
|
299
|
+
|
|
288
300
|
const parseToolText = (text, root) => {
|
|
289
|
-
const reports =
|
|
301
|
+
const reports = new Array(TOOL_SLOTS);
|
|
302
|
+
let index = 0;
|
|
290
303
|
const eslint = parseEslintStylish(text, root);
|
|
291
|
-
if (eslint)
|
|
304
|
+
if (eslint) {
|
|
305
|
+
reports[index] = eslint;
|
|
306
|
+
index += 1;
|
|
307
|
+
}
|
|
292
308
|
const tsc = parseTsc(text, root);
|
|
293
|
-
if (tsc)
|
|
309
|
+
if (tsc) {
|
|
310
|
+
reports[index] = tsc;
|
|
311
|
+
index += 1;
|
|
312
|
+
}
|
|
294
313
|
const prettier = parsePrettier(text, root);
|
|
295
|
-
if (prettier)
|
|
314
|
+
if (prettier) {
|
|
315
|
+
reports[index] = prettier;
|
|
316
|
+
index += 1;
|
|
317
|
+
}
|
|
296
318
|
const audit = parseAuditText(text);
|
|
297
|
-
if (audit)
|
|
319
|
+
if (audit) {
|
|
320
|
+
reports[index] = audit;
|
|
321
|
+
index += 1;
|
|
322
|
+
}
|
|
323
|
+
reports.length = index;
|
|
298
324
|
return reports;
|
|
299
325
|
};
|
|
300
326
|
|
package/lib/review-merge.js
CHANGED
package/lib/review.js
CHANGED
|
@@ -3,8 +3,10 @@
|
|
|
3
3
|
const fs = require('node:fs');
|
|
4
4
|
const path = require('node:path');
|
|
5
5
|
|
|
6
|
-
const
|
|
7
|
-
const {
|
|
6
|
+
const files = require('./files.js');
|
|
7
|
+
const { TODO_FILE, REVIEW_DIR } = files;
|
|
8
|
+
const reviewMerge = require('./review-merge.js');
|
|
9
|
+
const { captureBaseline, mergeReview } = reviewMerge;
|
|
8
10
|
|
|
9
11
|
const createStore = (reviewPath, templates = []) => ({
|
|
10
12
|
reviewPath,
|
|
@@ -240,6 +242,8 @@ const AGENT_INSTRUCTIONS = [
|
|
|
240
242
|
'- If not `editing`, set `status` to `partial` if some remain, ' +
|
|
241
243
|
'or `done` if all are `[x]`',
|
|
242
244
|
'- Do not redo items already marked `[x]`',
|
|
245
|
+
'- Run the full check with `npm t`',
|
|
246
|
+
'- Run specific test files with `reslop t -- node --test <files>`',
|
|
243
247
|
].join('\n');
|
|
244
248
|
|
|
245
249
|
const toInt = (text) => parseInt(text, 10);
|