reslop 0.2.7 → 0.3.1
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 +30 -1
- package/README.md +16 -14
- package/bin/reslop.js +8 -5
- package/lib/agents/agents.js +573 -0
- package/lib/agents/allow.js +71 -0
- package/lib/agents/allow.json +17 -0
- package/lib/agents/models.js +467 -0
- package/lib/api.js +15 -12
- package/lib/cli.js +43 -68
- package/lib/{files.js → common/files.js} +48 -55
- package/lib/{find.js → common/find.js} +1 -1
- package/lib/common/format.js +101 -0
- package/lib/{utilities.js → common/process.js} +7 -95
- package/lib/common/tasks.json +27 -0
- package/lib/common/utilities.js +112 -0
- package/lib/dashboard/git.js +9 -16
- package/lib/dashboard/model.js +90 -49
- package/lib/dashboard/npm.js +17 -13
- package/lib/dashboard/tree.js +27 -30
- package/lib/{session → dashboard}/watch.js +36 -31
- package/lib/{workspace.js → dashboard/workspace.js} +23 -38
- package/lib/{deps.js → deps/deps.js} +31 -45
- package/lib/{deps-diff.js → deps/diff.js} +35 -25
- package/lib/{manifest.js → deps/manifest.js} +47 -30
- package/lib/diff/align.js +1 -2
- package/lib/diff/diff.js +2 -2
- package/lib/diff/display.js +29 -5
- package/lib/diff/inline.js +10 -14
- package/lib/diff/items.js +6 -4
- package/lib/diff/patch.js +39 -3
- package/lib/diff/unit.js +45 -16
- package/lib/{git-branches.js → git/branches.js} +53 -48
- package/lib/{git-deps.js → git/deps.js} +151 -95
- package/lib/git/git.js +71 -0
- package/lib/git/worktree.js +504 -0
- package/lib/highlight/bash.js +1 -2
- package/lib/highlight/csv.js +1 -2
- package/lib/highlight/dot.js +1 -2
- package/lib/{highlight.js → highlight/highlight.js} +42 -11
- package/lib/highlight/html.js +20 -18
- package/lib/highlight/json.js +1 -2
- package/lib/highlight/log.js +1 -2
- package/lib/highlight/txt.js +1 -2
- package/lib/{session → input}/actions.js +114 -48
- package/lib/{editor.js → input/editor.js} +16 -8
- package/lib/{keys.js → input/keys.js} +24 -45
- package/lib/input/line-edit.js +78 -0
- package/lib/input/menu-pick.js +70 -0
- package/lib/render/agents.js +642 -0
- package/lib/render/branches.js +4 -5
- package/lib/render/commits.js +54 -64
- package/lib/render/{dash-activity.js → dashboard/activity.js} +25 -40
- package/lib/render/{dash-blocks.js → dashboard/blocks.js} +131 -137
- package/lib/render/{dashboard.js → dashboard/dashboard.js} +25 -22
- package/lib/render/diff.js +166 -45
- package/lib/render/field.js +131 -0
- package/lib/render/files.js +9 -14
- package/lib/render/footer.js +385 -0
- package/lib/render/frame.js +123 -25
- package/lib/render/header.js +176 -0
- package/lib/render/log.js +320 -0
- package/lib/render/menu.js +60 -0
- package/lib/render/notes.js +16 -11
- package/lib/render/npm.js +322 -196
- package/lib/render/packages.js +9 -13
- package/lib/render/primitives.js +101 -15
- package/lib/render/render.js +7 -11
- package/lib/render/repos.js +13 -25
- package/lib/render/status.js +370 -0
- package/lib/render/status.json +85 -0
- package/lib/render/{dash-table.js → table.js} +13 -60
- package/lib/render/tiles.js +109 -48
- package/lib/render/unit.js +32 -13
- package/lib/{report-model.js → report/model.js} +4 -6
- package/lib/{report-parse.js → report/parse.js} +9 -14
- package/lib/{report-render.js → report/render.js} +48 -19
- package/lib/{report-run.js → report/run.js} +42 -30
- package/lib/{report-test.js → report/test.js} +56 -55
- package/lib/{report-tools.js → report/tools.js} +24 -33
- package/lib/review/agent-instructions.md +14 -0
- package/lib/review/format.js +420 -0
- package/lib/{review-merge.js → review/merge.js} +9 -8
- package/lib/review/review.js +190 -0
- package/lib/review/store.js +281 -0
- package/lib/review/templates.js +83 -0
- package/lib/runs/commands.js +14 -0
- package/lib/runs/logs.js +299 -0
- package/lib/runs/output.js +174 -0
- package/lib/runs/process.js +113 -0
- package/lib/{runs.js → runs/runs.js} +84 -36
- package/lib/runs/scripts.js +150 -0
- package/lib/session/agents/agents.js +976 -0
- package/lib/session/agents/job.js +320 -0
- package/lib/session/agents/jobs.js +355 -0
- package/lib/session/agents/options.js +153 -0
- package/lib/session/agents/plans.js +83 -0
- package/lib/session/branches.js +33 -40
- package/lib/session/change-actions.js +34 -100
- package/lib/session/commit.js +91 -52
- package/lib/session/compose.js +189 -147
- package/lib/session/dashboard.js +23 -22
- package/lib/session/dispatch.js +86 -21
- package/lib/session/files-pane.js +47 -26
- package/lib/session/find.js +16 -29
- package/lib/session/import.js +93 -0
- package/lib/session/items.js +8 -17
- package/lib/session/lifecycle.js +78 -72
- package/lib/session/load.js +2 -4
- package/lib/session/navigation.js +6 -3
- package/lib/session/npm/history.js +250 -0
- package/lib/session/npm/npm.js +836 -0
- package/lib/session/{packages.js → npm/packages.js} +21 -14
- package/lib/session/ops.js +125 -34
- package/lib/session/pointer.js +202 -10
- package/lib/session/prefs.js +112 -0
- package/lib/session/reads.js +109 -0
- package/lib/session/review.js +28 -10
- package/lib/session/run-panel.js +40 -0
- package/lib/{session.js → session/session.js} +158 -63
- package/lib/session/tasks.js +321 -66
- package/lib/session/templates.js +1 -1
- package/lib/session/terminal.js +94 -12
- package/lib/session/unit.js +35 -30
- package/lib/session/update.js +194 -6
- package/lib/session/view.js +65 -65
- package/lib/session/workspace.js +39 -78
- package/lib/{capabilities.js → source/capabilities.js} +3 -12
- package/lib/{github.js → source/github.js} +102 -32
- package/lib/{gitlab.js → source/gitlab.js} +87 -10
- package/lib/{remote.js → source/remote.js} +144 -40
- package/lib/source/review-threads.graphql +20 -0
- package/lib/source/source.js +74 -0
- package/lib/term/ansi.js +396 -0
- package/lib/{clipboard.js → term/clipboard.js} +3 -6
- package/lib/{select.js → term/select.js} +4 -3
- package/lib/term/themes/dark.json +122 -0
- package/lib/term/themes/light.json +122 -0
- package/lib/term/wide.txt +21 -0
- package/lib/{wrap.js → term/wrap.js} +4 -4
- package/package.json +2 -2
- package/lib/ansi.js +0 -545
- package/lib/detect.js +0 -34
- package/lib/diff/edit.js +0 -33
- package/lib/git-worktree.js +0 -455
- package/lib/git.js +0 -79
- package/lib/npm-commands.js +0 -522
- package/lib/render/chrome.js +0 -806
- package/lib/render/present.js +0 -19
- package/lib/render/report.js +0 -43
- package/lib/render/search.js +0 -25
- package/lib/review.js +0 -745
- package/lib/session/accessors.js +0 -26
- package/lib/session/edit-click.js +0 -57
- package/lib/session/npm.js +0 -452
- package/lib/session/progress.js +0 -41
- package/lib/source.js +0 -36
- package/lib/update.js +0 -192
- /package/lib/{git-reword-todo.js → git/reword-todo.js} +0 -0
|
@@ -1,18 +1,14 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const
|
|
4
|
-
const {
|
|
3
|
+
const { unquote } = require('../common/utilities.js');
|
|
4
|
+
const { formatTable } = require('../runs/output.js');
|
|
5
5
|
|
|
6
|
-
const NOTICE_HEAD =
|
|
7
|
-
'reslop: reduced output; passing results are omitted ' +
|
|
8
|
-
'and similar problems are grouped';
|
|
6
|
+
const NOTICE_HEAD = 'Reduced output;';
|
|
9
7
|
|
|
10
8
|
const notice = (rawFile) => {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
const hint = `Agent: if this report hides a needed detail, read ${target}.`;
|
|
15
|
-
return `${NOTICE_HEAD}\n${hint}`;
|
|
9
|
+
let target = 'under `.log/`';
|
|
10
|
+
if (rawFile) target = `\`.log/${rawFile}\``;
|
|
11
|
+
return `${NOTICE_HEAD} the raw log if needed ${target}.`;
|
|
16
12
|
};
|
|
17
13
|
|
|
18
14
|
const addRow = (rows, key, value) => {
|
|
@@ -38,12 +34,12 @@ const sameValue = (line, value) => {
|
|
|
38
34
|
return text === value || unquote(text) === value;
|
|
39
35
|
};
|
|
40
36
|
|
|
41
|
-
const startsDiff = (line, item) =>
|
|
42
|
-
isComparison(line) ||
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
sameValue(line, item.
|
|
46
|
-
|
|
37
|
+
const startsDiff = (line, item) => {
|
|
38
|
+
if (isComparison(line) || isDiffHeader(line)) return true;
|
|
39
|
+
if (isMarkedDiff(line)) return true;
|
|
40
|
+
if (sameValue(line, item.expected)) return true;
|
|
41
|
+
return sameValue(line, item.actual);
|
|
42
|
+
};
|
|
47
43
|
|
|
48
44
|
const displayMessage = (item) => {
|
|
49
45
|
const values = item.expected !== '' || item.actual !== '';
|
|
@@ -135,13 +131,46 @@ const loggedText = (text, rawFile) => {
|
|
|
135
131
|
return `${head}\n\n${body}`;
|
|
136
132
|
};
|
|
137
133
|
|
|
134
|
+
const reportProblem = (item) => {
|
|
135
|
+
const title = item.name || item.message || item.code || 'problem';
|
|
136
|
+
const mark = item.severity === 'warning' ? '△' : '✖';
|
|
137
|
+
const count = item.count > 1 ? ` × ${item.count}` : '';
|
|
138
|
+
const lines = ['', `${mark} ${title.split('\n')[0]}${count}`, ''];
|
|
139
|
+
lines.push(...formatTable(problemRows(item)));
|
|
140
|
+
const message = displayMessage(item);
|
|
141
|
+
if (message) lines.push('', ...quoteLines(message));
|
|
142
|
+
if (item.trace) {
|
|
143
|
+
lines.push('', 'Stack');
|
|
144
|
+
for (const row of item.trace.split(/\r?\n/)) {
|
|
145
|
+
const frame = row.trim().replace(/^at\s+/, '');
|
|
146
|
+
if (frame) lines.push(` at ${frame}`);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
if (item.related.length) {
|
|
150
|
+
lines.push('', 'Related failures');
|
|
151
|
+
for (const row of item.related) lines.push(` ↳ ${row}`);
|
|
152
|
+
}
|
|
153
|
+
return lines;
|
|
154
|
+
};
|
|
155
|
+
|
|
156
|
+
const renderReport = (doc) => {
|
|
157
|
+
const lines = [];
|
|
158
|
+
for (const item of doc.reports) {
|
|
159
|
+
if (lines.length) lines.push('');
|
|
160
|
+
const mark = item.ok ? '✔' : '✖';
|
|
161
|
+
lines.push(`${mark} ${item.tool} · exit ${doc.exit}`, '');
|
|
162
|
+
lines.push(...formatTable(summaryRows(item.summary)));
|
|
163
|
+
for (const entry of item.problems) lines.push(...reportProblem(entry));
|
|
164
|
+
}
|
|
165
|
+
if (doc.stderr) lines.push('', 'Stderr', doc.stderr);
|
|
166
|
+
return `${lines.join('\n')}\n`;
|
|
167
|
+
};
|
|
168
|
+
|
|
138
169
|
module.exports = {
|
|
139
170
|
NOTICE_HEAD,
|
|
140
171
|
notice,
|
|
141
|
-
summaryRows,
|
|
142
|
-
problemRows,
|
|
143
172
|
displayMessage,
|
|
144
|
-
quoteLines,
|
|
145
173
|
loggedText,
|
|
146
174
|
renderDocument,
|
|
175
|
+
renderReport,
|
|
147
176
|
};
|
|
@@ -1,19 +1,18 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
const path = require('node:path');
|
|
4
|
-
const
|
|
5
|
-
const { spawn } = childProcess;
|
|
4
|
+
const { spawn } = require('node:child_process');
|
|
6
5
|
|
|
7
|
-
const
|
|
8
|
-
const {
|
|
9
|
-
const
|
|
10
|
-
const {
|
|
11
|
-
const
|
|
12
|
-
const {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
6
|
+
const { spawnBase } = require('../common/process.js');
|
|
7
|
+
const { withNewline } = require('../common/utilities.js');
|
|
8
|
+
const { nextLogFile, saveLogs } = require('../runs/logs.js');
|
|
9
|
+
const { toolHint, buildDocument } = require('./parse.js');
|
|
10
|
+
const { renderDocument } = require('./render.js');
|
|
11
|
+
const {
|
|
12
|
+
RunRecorder,
|
|
13
|
+
commandLabel,
|
|
14
|
+
summarizeDocument,
|
|
15
|
+
} = require('../runs/runs.js');
|
|
17
16
|
|
|
18
17
|
const OUTPUTS = ['md', 'raw'];
|
|
19
18
|
const PIPE = ['ignore', 'pipe', 'pipe'];
|
|
@@ -73,8 +72,16 @@ const collect = (child, onOut, onErr) =>
|
|
|
73
72
|
child.on('close', (status) => finish(status ?? 1));
|
|
74
73
|
});
|
|
75
74
|
|
|
76
|
-
const beginRun = (cwd, command) =>
|
|
77
|
-
|
|
75
|
+
const beginRun = (cwd, command) => {
|
|
76
|
+
let slot = null;
|
|
77
|
+
try {
|
|
78
|
+
slot = nextLogFile(cwd, path.basename(command.program));
|
|
79
|
+
} catch {
|
|
80
|
+
// ignore errors
|
|
81
|
+
}
|
|
82
|
+
const label = commandLabel(command.program, command.args);
|
|
83
|
+
return new RunRecorder(cwd, label, { slot });
|
|
84
|
+
};
|
|
78
85
|
|
|
79
86
|
const documentOf = (command, result, cwd) => {
|
|
80
87
|
const hint = toolHint(command.program, command.args);
|
|
@@ -84,7 +91,7 @@ const documentOf = (command, result, cwd) => {
|
|
|
84
91
|
|
|
85
92
|
const rawStreams = (stdout, stderr) => {
|
|
86
93
|
if (!stderr.trim()) return stdout;
|
|
87
|
-
const lead = stdout
|
|
94
|
+
const lead = withNewline(stdout);
|
|
88
95
|
return `${lead}# stderr\n${stderr}`;
|
|
89
96
|
};
|
|
90
97
|
|
|
@@ -99,44 +106,49 @@ const runInherit = async (command, cwd, env) => {
|
|
|
99
106
|
|
|
100
107
|
const runRaw = async (proc, command, cwd, env) => {
|
|
101
108
|
const recorder = beginRun(cwd, command);
|
|
102
|
-
let child;
|
|
103
|
-
try {
|
|
104
|
-
child = spawnCommand(command, { cwd, env, stdio: PIPE });
|
|
105
|
-
} catch {
|
|
106
|
-
recorder.finish(1);
|
|
107
|
-
return 1;
|
|
108
|
-
}
|
|
109
109
|
const onOut = (chunk) => {
|
|
110
110
|
proc.stdout.write(chunk);
|
|
111
111
|
recorder.feed(chunk);
|
|
112
112
|
};
|
|
113
113
|
const onErr = (chunk) => proc.stderr.write(chunk);
|
|
114
|
+
const childEnv = { ...env, RESLOP_CAPTURE: '1' };
|
|
115
|
+
let child = null;
|
|
116
|
+
try {
|
|
117
|
+
child = spawnCommand(command, { cwd, env: childEnv, stdio: PIPE });
|
|
118
|
+
} catch {
|
|
119
|
+
recorder.finish(1);
|
|
120
|
+
}
|
|
121
|
+
if (!child) return 1;
|
|
114
122
|
const result = await collect(child, onOut, onErr);
|
|
115
123
|
const doc = documentOf(command, result, cwd);
|
|
124
|
+
const slot = recorder.slot;
|
|
116
125
|
recorder.finish(result.status, summarizeDocument(doc));
|
|
126
|
+
if (!slot) return result.status;
|
|
127
|
+
const text = renderDocument(doc, slot.rawName);
|
|
128
|
+
const raw = rawStreams(result.stdout, result.stderr);
|
|
129
|
+
try {
|
|
130
|
+
await saveLogs(slot, text, raw);
|
|
131
|
+
} catch {
|
|
132
|
+
// the record remains even if the log files cannot be written
|
|
133
|
+
}
|
|
117
134
|
return result.status;
|
|
118
135
|
};
|
|
119
136
|
|
|
120
137
|
const runReport = async (proc, command, cwd, env) => {
|
|
121
138
|
const recorder = beginRun(cwd, command);
|
|
122
139
|
const fail = (error) => proc.stderr.write(`reslop: ${error.message}\n`);
|
|
123
|
-
let child;
|
|
140
|
+
let child = null;
|
|
124
141
|
try {
|
|
125
142
|
const childEnv = { ...env, RESLOP_CAPTURE: '1' };
|
|
126
143
|
child = spawnCommand(command, { cwd, env: childEnv, stdio: PIPE });
|
|
127
144
|
} catch (error) {
|
|
128
145
|
fail(error);
|
|
129
146
|
recorder.finish(1);
|
|
130
|
-
return 1;
|
|
131
147
|
}
|
|
148
|
+
if (!child) return 1;
|
|
132
149
|
const result = await collect(child, (chunk) => recorder.feed(chunk));
|
|
133
150
|
const doc = documentOf(command, result, cwd);
|
|
134
|
-
|
|
135
|
-
try {
|
|
136
|
-
slot = nextLogFile(cwd, path.basename(command.program));
|
|
137
|
-
} catch (error) {
|
|
138
|
-
fail(error);
|
|
139
|
-
}
|
|
151
|
+
const slot = recorder.slot;
|
|
140
152
|
const text = renderDocument(doc, slot ? slot.rawName : '');
|
|
141
153
|
recorder.finish(result.status, summarizeDocument(doc));
|
|
142
154
|
proc.stdout.write(text);
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const
|
|
4
|
-
const
|
|
5
|
-
const { isPassingTest } =
|
|
6
|
-
const
|
|
7
|
-
const { unquote } = utilities;
|
|
3
|
+
const { jsonParse } = require('metautil');
|
|
4
|
+
const model = require('./model.js');
|
|
5
|
+
const { isPassingTest } = require('../runs/output.js');
|
|
6
|
+
const { unquote } = require('../common/utilities.js');
|
|
8
7
|
|
|
9
8
|
const { summary, problem, report, userTrace, errorKey } = model;
|
|
10
9
|
|
|
@@ -75,57 +74,62 @@ const extraFrom = (fields) => {
|
|
|
75
74
|
return extra;
|
|
76
75
|
};
|
|
77
76
|
|
|
77
|
+
const either = (...values) => values.find(Boolean) ?? values.at(-1);
|
|
78
|
+
|
|
79
|
+
const defined = (...values) =>
|
|
80
|
+
values.find((value) => value !== null && value !== undefined);
|
|
81
|
+
|
|
82
|
+
const errorParts = (map, parsed) => {
|
|
83
|
+
const raw = either(
|
|
84
|
+
map.get('error'),
|
|
85
|
+
map.get('message'),
|
|
86
|
+
parsed.get('message'),
|
|
87
|
+
);
|
|
88
|
+
const text = show(raw);
|
|
89
|
+
const header = ERROR_HEAD.exec(text);
|
|
90
|
+
const [lead, name, tag] = header ?? [];
|
|
91
|
+
return {
|
|
92
|
+
message: header ? text.slice(lead.length).trim() : text,
|
|
93
|
+
type: show(either(map.get('name'), name, parsed.get('name'))),
|
|
94
|
+
code: show(either(map.get('code'), tag, parsed.get('code'))),
|
|
95
|
+
};
|
|
96
|
+
};
|
|
97
|
+
|
|
78
98
|
const problemFromFields = (name, fields, root, fallback = '') => {
|
|
79
99
|
const map = new Map(fields);
|
|
80
100
|
const stack = show(map.get('stack'));
|
|
81
101
|
const parsed = new Map(exceptionFields(stack.split(/\r?\n/)));
|
|
82
|
-
const
|
|
83
|
-
|
|
84
|
-
);
|
|
85
|
-
const
|
|
86
|
-
const
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
name,
|
|
91
|
-
message,
|
|
92
|
-
duration,
|
|
93
|
-
code: show(map.get('code') || (header && header[2]) || parsed.get('code')),
|
|
94
|
-
operator: show(map.get('operator')),
|
|
95
|
-
expected: show(
|
|
96
|
-
map.get('expected') ?? map.get('wanted') ?? map.get('expect'),
|
|
97
|
-
),
|
|
98
|
-
actual: show(map.get('actual') ?? map.get('found') ?? map.get('got')),
|
|
99
|
-
extra: extraFrom(fields),
|
|
100
|
-
};
|
|
101
|
-
const type = show(
|
|
102
|
-
map.get('name') || (header && header[1]) || parsed.get('name'),
|
|
102
|
+
const { message, type, code } = errorParts(map, parsed);
|
|
103
|
+
const location = show(either(map.get('at'), map.get('location')));
|
|
104
|
+
const duration = show(either(map.get('duration_ms'), map.get('duration')));
|
|
105
|
+
const operator = show(map.get('operator'));
|
|
106
|
+
const wanted = defined(
|
|
107
|
+
map.get('expected'),
|
|
108
|
+
map.get('wanted'),
|
|
109
|
+
map.get('expect'),
|
|
103
110
|
);
|
|
104
|
-
|
|
105
|
-
const
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
details.actual;
|
|
113
|
-
if (!known) details.message = fallback;
|
|
111
|
+
const got = defined(map.get('actual'), map.get('found'), map.get('got'));
|
|
112
|
+
const expected = show(wanted);
|
|
113
|
+
const actual = show(got);
|
|
114
|
+
const extra = extraFrom(fields);
|
|
115
|
+
if (type) extra.unshift(['type', type]);
|
|
116
|
+
const details = { name, message, duration, code, operator, expected, actual };
|
|
117
|
+
const facts = [message, stack, location, operator, code, expected, actual];
|
|
118
|
+
if (!facts.some(Boolean)) details.message = fallback;
|
|
114
119
|
const source = show(map.get('at')) || stack || location;
|
|
115
|
-
const key = errorKey({ ...details, type }, source, root);
|
|
120
|
+
const key = errorKey({ ...details, extra, type }, source, root);
|
|
116
121
|
const trace = userTrace(parsed.get('stack') || stack || location, root);
|
|
117
|
-
return problem({ ...details, key, trace });
|
|
122
|
+
return problem({ ...details, extra, key, trace });
|
|
118
123
|
};
|
|
119
124
|
|
|
120
125
|
const quoted = (value) => value.startsWith('"') || value.startsWith('\x27');
|
|
121
126
|
|
|
122
127
|
const scalarText = (value) => {
|
|
123
128
|
if (value.startsWith('"')) {
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
}
|
|
129
|
+
const text = value.replace(/\r?\n/g, '\\n');
|
|
130
|
+
const parsed = jsonParse(text);
|
|
131
|
+
if (typeof parsed === 'string') return parsed;
|
|
132
|
+
return unquote(value);
|
|
129
133
|
}
|
|
130
134
|
return unquote(value);
|
|
131
135
|
};
|
|
@@ -354,11 +358,9 @@ const parseNodeJsonl = (text, root) => {
|
|
|
354
358
|
const events = [];
|
|
355
359
|
for (const line of lines) {
|
|
356
360
|
if (line[0] !== '{') return null;
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
return null;
|
|
361
|
-
}
|
|
361
|
+
const event = jsonParse(line);
|
|
362
|
+
if (event === null) return null;
|
|
363
|
+
events.push(event);
|
|
362
364
|
}
|
|
363
365
|
return parseNodeEvents(events, root);
|
|
364
366
|
};
|
|
@@ -536,13 +538,12 @@ const takeSpecFrame = (lines, index, current) => {
|
|
|
536
538
|
return block.next - index;
|
|
537
539
|
};
|
|
538
540
|
|
|
539
|
-
const hasDetail = (item) =>
|
|
540
|
-
item.message ||
|
|
541
|
-
item.
|
|
542
|
-
item.
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
item.actual;
|
|
541
|
+
const hasDetail = (item) => {
|
|
542
|
+
const message = item.message || item.trace;
|
|
543
|
+
const code = item.code || item.operator;
|
|
544
|
+
const values = item.expected || item.actual;
|
|
545
|
+
return message || code || values;
|
|
546
|
+
};
|
|
546
547
|
|
|
547
548
|
const dropPreviews = (problems) => {
|
|
548
549
|
const named = new Set();
|
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const
|
|
4
|
-
const {
|
|
5
|
-
const
|
|
6
|
-
|
|
7
|
-
const { summary, problem, report, userTrace } = model;
|
|
3
|
+
const { parseAuditReport, parseOutdatedReport } = require('../deps/deps.js');
|
|
4
|
+
const { summary, problem, report, userTrace } = require('./model.js');
|
|
5
|
+
const { trimText } = require('../common/utilities.js');
|
|
8
6
|
|
|
9
7
|
const PRETTIER_SUMMARY = [
|
|
10
8
|
'Code style issues',
|
|
@@ -41,33 +39,28 @@ const parseEslintJson = (data, root) => {
|
|
|
41
39
|
item.column || 0,
|
|
42
40
|
root,
|
|
43
41
|
);
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
trace,
|
|
50
|
-
}),
|
|
51
|
-
);
|
|
42
|
+
const severity = item.severity === 1 ? 'warning' : 'error';
|
|
43
|
+
const message = item.message || '';
|
|
44
|
+
const code = item.ruleId || '';
|
|
45
|
+
const issue = { severity, message, code, trace };
|
|
46
|
+
problems.push(problem(issue));
|
|
52
47
|
}
|
|
53
48
|
}
|
|
54
49
|
return eslintReport(problems);
|
|
55
50
|
};
|
|
56
51
|
|
|
57
|
-
const eslintLine = (
|
|
58
|
-
const match = /^\s*(\d+):(\d+)\s+(error|warning)\s+(.*)$/.exec(
|
|
52
|
+
const eslintLine = (text) => {
|
|
53
|
+
const match = /^\s*(\d+):(\d+)\s+(error|warning)\s+(.*)$/.exec(text);
|
|
59
54
|
if (!match) return null;
|
|
60
55
|
const rest = match[4];
|
|
61
56
|
const ruleAt = rest.lastIndexOf(' ');
|
|
62
|
-
const
|
|
57
|
+
const raw = ruleAt < 0 ? rest : rest.slice(0, ruleAt);
|
|
63
58
|
const code = ruleAt < 0 ? '' : rest.slice(ruleAt + 2).trim();
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
code,
|
|
70
|
-
};
|
|
59
|
+
const line = match[1];
|
|
60
|
+
const column = match[2];
|
|
61
|
+
const severity = match[3];
|
|
62
|
+
const message = raw.trim();
|
|
63
|
+
return { line, column, severity, message, code };
|
|
71
64
|
};
|
|
72
65
|
|
|
73
66
|
const isPathLine = (line) => {
|
|
@@ -141,14 +134,12 @@ const auditExtra = (item) => {
|
|
|
141
134
|
const parseAudit = (text) => {
|
|
142
135
|
const problems = [];
|
|
143
136
|
for (const item of parseAuditReport(text).values()) {
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
}),
|
|
151
|
-
);
|
|
137
|
+
const severity = item.severity || 'error';
|
|
138
|
+
const { name } = item;
|
|
139
|
+
const message = item.title || '';
|
|
140
|
+
const extra = auditExtra(item);
|
|
141
|
+
const issue = { severity, name, message, extra };
|
|
142
|
+
problems.push(problem(issue));
|
|
152
143
|
}
|
|
153
144
|
return problems.length ? errorReport('audit', problems) : null;
|
|
154
145
|
};
|
|
@@ -183,7 +174,7 @@ const parseOutdated = (text) => {
|
|
|
183
174
|
};
|
|
184
175
|
|
|
185
176
|
const pushLs = (problems, text) => {
|
|
186
|
-
const message =
|
|
177
|
+
const message = trimText(text);
|
|
187
178
|
if (message) problems.push(problem({ message }));
|
|
188
179
|
};
|
|
189
180
|
|
|
@@ -226,7 +217,7 @@ const parseToolJson = (data, root) => {
|
|
|
226
217
|
};
|
|
227
218
|
|
|
228
219
|
const parseAuditText = (text) => {
|
|
229
|
-
if (
|
|
220
|
+
if (trimText(text).startsWith('{')) return null;
|
|
230
221
|
const lines = `${text ?? ''}`.split(/\r?\n/);
|
|
231
222
|
const problems = [];
|
|
232
223
|
for (let index = 0; index < lines.length; index++) {
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
Work through unchecked items.
|
|
2
|
+
|
|
3
|
+
- Run reviews with status `editing` or `partial`
|
|
4
|
+
- Do not start or change reviews with status `done`
|
|
5
|
+
- After finishing an item, mark it `[x]`
|
|
6
|
+
- Mark `[x]` only after the code changes are done and tests pass
|
|
7
|
+
- For `code` items, replace the added lines at the given location
|
|
8
|
+
- Set `status` to `partial` if any items remain, or `done` if all are `[x]`
|
|
9
|
+
- Do not redo items already marked `[x]`
|
|
10
|
+
- Run the full check with `npm t`
|
|
11
|
+
- Run specific test files with `reslop t -- node --test <files>`
|
|
12
|
+
- An item prefixed with `F<number>:` gets its own commit in this repo
|
|
13
|
+
- Leave items without that prefix unstaged, do not commit or stage them
|
|
14
|
+
- Do not add `Authored-by` or `Co-authored-by` unless the issue asks for it
|