reslop 0.2.4 → 0.2.6

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 (109) hide show
  1. package/CHANGELOG.md +25 -1
  2. package/LICENSE +1 -1
  3. package/README.md +12 -13
  4. package/bin/reslop.js +3 -8
  5. package/lib/ansi.js +32 -19
  6. package/lib/capabilities.js +8 -12
  7. package/lib/cli.js +40 -74
  8. package/lib/clipboard.js +48 -18
  9. package/lib/dashboard/git.js +128 -0
  10. package/lib/dashboard/model.js +332 -0
  11. package/lib/dashboard/npm.js +193 -0
  12. package/lib/dashboard/tree.js +278 -0
  13. package/lib/deps-diff.js +196 -404
  14. package/lib/deps.js +240 -399
  15. package/lib/detect.js +8 -18
  16. package/lib/diff/align.js +41 -113
  17. package/lib/diff/diff.js +12 -43
  18. package/lib/diff/display.js +25 -36
  19. package/lib/diff/edit.js +6 -20
  20. package/lib/diff/inline.js +138 -141
  21. package/lib/diff/items.js +33 -47
  22. package/lib/diff/parse.js +28 -56
  23. package/lib/diff/patch.js +12 -33
  24. package/lib/diff/unit.js +90 -206
  25. package/lib/editor.js +98 -55
  26. package/lib/files.js +86 -103
  27. package/lib/git-branches.js +254 -416
  28. package/lib/git-deps.js +182 -344
  29. package/lib/git-reword-todo.js +5 -13
  30. package/lib/git-worktree.js +141 -212
  31. package/lib/git.js +21 -49
  32. package/lib/github.js +67 -181
  33. package/lib/gitlab.js +40 -90
  34. package/lib/highlight/bash.js +55 -177
  35. package/lib/highlight/core.js +157 -132
  36. package/lib/highlight/css.js +25 -58
  37. package/lib/highlight/csv.js +19 -37
  38. package/lib/highlight/dart.js +72 -213
  39. package/lib/highlight/dot.js +16 -26
  40. package/lib/highlight/html.js +42 -63
  41. package/lib/highlight/js.js +177 -506
  42. package/lib/highlight/json.js +17 -37
  43. package/lib/highlight/log.js +22 -35
  44. package/lib/highlight/txt.js +9 -22
  45. package/lib/highlight.js +17 -46
  46. package/lib/keys.js +62 -85
  47. package/lib/manifest.js +67 -130
  48. package/lib/npm-commands.js +119 -189
  49. package/lib/remote.js +141 -197
  50. package/lib/render/branches.js +66 -73
  51. package/lib/render/chrome.js +264 -323
  52. package/lib/render/commits.js +187 -500
  53. package/lib/render/dash-activity.js +212 -0
  54. package/lib/render/dash-blocks.js +245 -0
  55. package/lib/render/dash-table.js +290 -0
  56. package/lib/render/dashboard.js +62 -0
  57. package/lib/render/diff.js +123 -228
  58. package/lib/render/files.js +45 -99
  59. package/lib/render/frame.js +129 -183
  60. package/lib/render/notes.js +144 -160
  61. package/lib/render/npm.js +234 -112
  62. package/lib/render/present.js +4 -11
  63. package/lib/render/primitives.js +131 -170
  64. package/lib/render/render.js +5 -14
  65. package/lib/render/report.js +43 -0
  66. package/lib/render/tiles.js +260 -0
  67. package/lib/render/unit.js +15 -28
  68. package/lib/report-model.js +110 -33
  69. package/lib/report-parse.js +56 -38
  70. package/lib/report-render.js +102 -59
  71. package/lib/report-run.js +87 -78
  72. package/lib/report-test.js +256 -141
  73. package/lib/report-tools.js +96 -161
  74. package/lib/review-merge.js +114 -152
  75. package/lib/review.js +115 -189
  76. package/lib/runs.js +225 -0
  77. package/lib/select.js +89 -75
  78. package/lib/session/accessors.js +14 -21
  79. package/lib/session/actions.js +82 -63
  80. package/lib/session/branches.js +193 -247
  81. package/lib/session/change-actions.js +171 -214
  82. package/lib/session/commit.js +280 -342
  83. package/lib/session/compose.js +559 -674
  84. package/lib/session/dashboard.js +385 -0
  85. package/lib/session/dispatch.js +164 -157
  86. package/lib/session/edit-click.js +57 -0
  87. package/lib/session/files-pane.js +85 -53
  88. package/lib/session/items.js +73 -104
  89. package/lib/session/lifecycle.js +403 -541
  90. package/lib/session/load.js +48 -68
  91. package/lib/session/navigation.js +96 -87
  92. package/lib/session/npm.js +409 -345
  93. package/lib/session/ops.js +196 -63
  94. package/lib/session/pointer.js +23 -15
  95. package/lib/session/progress.js +33 -21
  96. package/lib/session/review.js +33 -54
  97. package/lib/session/tasks.js +333 -0
  98. package/lib/session/templates.js +51 -59
  99. package/lib/session/terminal.js +85 -136
  100. package/lib/session/unit.js +3 -4
  101. package/lib/session/update.js +76 -97
  102. package/lib/session/view.js +52 -83
  103. package/lib/session/watch.js +208 -204
  104. package/lib/session.js +112 -237
  105. package/lib/update.js +45 -116
  106. package/lib/utilities.js +67 -89
  107. package/lib/wrap.js +33 -44
  108. package/package.json +1 -1
  109. package/lib/session/todos.js +0 -293
@@ -6,41 +6,52 @@ const model = require('./report-model.js');
6
6
 
7
7
  const { summary, problem, report, userTrace } = model;
8
8
 
9
+ const PRETTIER_SUMMARY = [
10
+ 'Code style issues',
11
+ 'All matched files use Prettier',
12
+ ];
13
+
9
14
  const place = (file, line, column, root) =>
10
15
  userTrace(`${file}:${line}:${column}`, root);
11
16
 
17
+ const errorReport = (tool, problems) => {
18
+ const stats = summary();
19
+ stats.errors = problems.length;
20
+ return report(tool, { summary: stats, problems });
21
+ };
22
+
23
+ const eslintReport = (problems) => {
24
+ const stats = summary();
25
+ const isWarning = (item) => item.severity === 'warning';
26
+ stats.warnings = problems.filter(isWarning).length;
27
+ stats.errors = problems.length - stats.warnings;
28
+ return report('eslint', { summary: stats, problems });
29
+ };
30
+
12
31
  const parseEslintJson = (data, root) => {
13
32
  const rows = Array.isArray(data) ? data : data && data.results;
14
33
  if (!Array.isArray(rows) || !rows.length) return null;
15
34
  if (!rows[0] || !Array.isArray(rows[0].messages)) return null;
16
- const stats = summary();
17
- let errors = 0;
18
- let warnings = 0;
19
35
  const problems = [];
20
36
  for (const file of rows) {
21
- const messages = file.messages || [];
22
- for (const item of messages) {
23
- const severity = item.severity === 1 ? 'warning' : 'error';
24
- if (severity === 'warning') warnings += 1;
25
- else errors += 1;
37
+ for (const item of file.messages || []) {
38
+ const trace = place(
39
+ file.filePath || '',
40
+ item.line || 0,
41
+ item.column || 0,
42
+ root,
43
+ );
26
44
  problems.push(
27
45
  problem({
28
- severity,
46
+ severity: item.severity === 1 ? 'warning' : 'error',
29
47
  message: item.message || '',
30
48
  code: item.ruleId || '',
31
- trace: place(
32
- file.filePath || '',
33
- item.line || 0,
34
- item.column || 0,
35
- root,
36
- ),
49
+ trace,
37
50
  }),
38
51
  );
39
52
  }
40
53
  }
41
- stats.errors = errors;
42
- stats.warnings = warnings;
43
- return report('eslint', { summary: stats, problems });
54
+ return eslintReport(problems);
44
55
  };
45
56
 
46
57
  const eslintLine = (line) => {
@@ -67,69 +78,35 @@ const isPathLine = (line) => {
67
78
  };
68
79
 
69
80
  const parseEslintStylish = (text, root) => {
70
- const lines = `${text ?? ''}`.split(/\r?\n/);
71
81
  const problems = [];
72
82
  let file = '';
73
- let errors = 0;
74
- let warnings = 0;
75
83
  let seen = false;
76
- for (const line of lines) {
84
+ for (const line of `${text ?? ''}`.split(/\r?\n/)) {
77
85
  const item = eslintLine(line);
78
86
  if (item) {
79
87
  seen = true;
80
- if (item.severity === 'warning') warnings += 1;
81
- else errors += 1;
82
- problems.push(
83
- problem({
84
- severity: item.severity,
85
- message: item.message,
86
- code: item.code,
87
- trace: place(file, item.line, item.column, root),
88
- }),
89
- );
88
+ const { severity, message, code } = item;
89
+ const trace = place(file, item.line, item.column, root);
90
+ problems.push(problem({ severity, message, code, trace }));
90
91
  continue;
91
92
  }
92
93
  if (/✖\s+\d+\s+problems?\b/.test(line)) seen = true;
93
94
  if (isPathLine(line)) file = line.trim();
94
95
  }
95
- if (!seen) return null;
96
- const stats = summary();
97
- stats.errors = errors;
98
- stats.warnings = warnings;
99
- return report('eslint', { summary: stats, problems });
96
+ return seen ? eslintReport(problems) : null;
100
97
  };
101
98
 
102
- const tscLine = (line) => {
103
- const match = /^(.*)\((\d+),(\d+)\):\s+error\s+(TS\d+):\s+(.*)$/.exec(
104
- line.trim(),
105
- );
106
- if (!match) return null;
107
- return {
108
- file: match[1],
109
- line: match[2],
110
- column: match[3],
111
- code: match[4],
112
- message: match[5],
113
- };
114
- };
99
+ const TSC_LINE = /^(.*)\((\d+),(\d+)\):\s+error\s+(TS\d+):\s+(.*)$/;
115
100
 
116
101
  const parseTsc = (text, root) => {
117
102
  const problems = [];
118
103
  for (const line of `${text ?? ''}`.split(/\r?\n/)) {
119
- const item = tscLine(line);
120
- if (!item) continue;
121
- problems.push(
122
- problem({
123
- message: item.message,
124
- code: item.code,
125
- trace: place(item.file, item.line, item.column, root),
126
- }),
127
- );
104
+ const match = TSC_LINE.exec(line.trim());
105
+ if (!match) continue;
106
+ const trace = place(match[1], match[2], match[3], root);
107
+ problems.push(problem({ message: match[5], code: match[4], trace }));
128
108
  }
129
- if (!problems.length) return null;
130
- const stats = summary();
131
- stats.errors = problems.length;
132
- return report('tsc', { summary: stats, problems });
109
+ return problems.length ? errorReport('tsc', problems) : null;
133
110
  };
134
111
 
135
112
  const prettierFile = (line) => {
@@ -138,76 +115,53 @@ const prettierFile = (line) => {
138
115
  return '';
139
116
  };
140
117
 
118
+ const isPrettierSummary = (line) =>
119
+ PRETTIER_SUMMARY.some((text) => line.includes(text));
120
+
141
121
  const parsePrettier = (text, root) => {
142
- const lines = `${text ?? ''}`.split(/\r?\n/);
143
122
  const problems = [];
144
123
  let seen = false;
145
- for (const line of lines) {
146
- if (line.includes('Code style issues')) seen = true;
147
- if (line.includes('All matched files use Prettier')) seen = true;
124
+ for (const line of `${text ?? ''}`.split(/\r?\n/)) {
125
+ if (isPrettierSummary(line)) seen = true;
148
126
  const file = prettierFile(line);
149
127
  if (!file) continue;
150
128
  seen = true;
151
- problems.push(
152
- problem({
153
- message: 'format',
154
- trace: userTrace(file, root),
155
- }),
156
- );
129
+ problems.push(problem({ message: 'format', trace: userTrace(file, root) }));
157
130
  }
158
- if (!seen) return null;
159
- const stats = summary();
160
- stats.errors = problems.length;
161
- return report('prettier', { summary: stats, problems });
131
+ return seen ? errorReport('prettier', problems) : null;
162
132
  };
163
133
 
164
134
  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];
135
+ const extra = [];
136
+ if (item.range) extra.push(['range', item.range]);
137
+ if (item.fix) extra.push(['fix', item.fix]);
173
138
  return extra;
174
139
  };
175
140
 
176
- const auditProblems = (text) => {
177
- const audit = parseAuditReport(text);
178
- const problems = new Array(audit.size);
179
- let index = 0;
180
- for (const item of audit.values()) {
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;
188
- }
189
- return problems;
190
- };
191
-
192
141
  const parseAudit = (text) => {
193
- const problems = auditProblems(text);
194
- if (!problems.length) return null;
195
- const stats = summary();
196
- stats.errors = problems.length;
197
- return report('audit', { summary: stats, problems });
142
+ const problems = [];
143
+ for (const item of parseAuditReport(text).values()) {
144
+ problems.push(
145
+ problem({
146
+ severity: item.severity || 'error',
147
+ name: item.name,
148
+ message: item.title || '',
149
+ extra: auditExtra(item),
150
+ }),
151
+ );
152
+ }
153
+ return problems.length ? errorReport('audit', problems) : null;
198
154
  };
199
155
 
200
156
  const behind = (item) => {
201
157
  if (!item.current) return true;
202
158
  if (item.wanted && item.wanted !== item.current) return true;
203
- if (item.latest && item.latest !== item.current) return true;
204
- return false;
159
+ return !!item.latest && item.latest !== item.current;
205
160
  };
206
161
 
207
162
  const parseOutdated = (text) => {
208
- const outdated = parseOutdatedReport(text);
209
163
  const problems = [];
210
- for (const [name, item] of outdated) {
164
+ for (const [name, item] of parseOutdatedReport(text)) {
211
165
  if (!behind(item)) continue;
212
166
  problems.push(
213
167
  problem({
@@ -230,8 +184,7 @@ const parseOutdated = (text) => {
230
184
 
231
185
  const pushLs = (problems, text) => {
232
186
  const message = `${text ?? ''}`.trim();
233
- if (!message) return;
234
- problems.push(problem({ message }));
187
+ if (message) problems.push(problem({ message }));
235
188
  };
236
189
 
237
190
  const walkLs = (node, problems) => {
@@ -251,13 +204,12 @@ const walkLs = (node, problems) => {
251
204
 
252
205
  const parseLs = (data) => {
253
206
  if (!data || typeof data !== 'object' || Array.isArray(data)) return null;
254
- if (!data.dependencies && !Array.isArray(data.problems)) return null;
207
+ const listed = Array.isArray(data.problems);
208
+ if (!data.dependencies && !listed) return null;
255
209
  const problems = [];
256
210
  walkLs(data, problems);
257
- if (!problems.length && !Array.isArray(data.problems)) return null;
258
- const stats = summary();
259
- stats.errors = problems.length;
260
- return report('ls', { summary: stats, problems });
211
+ if (!problems.length && !listed) return null;
212
+ return errorReport('ls', problems);
261
213
  };
262
214
 
263
215
  const parseToolJson = (data, root) => {
@@ -281,57 +233,40 @@ const parseAuditText = (text) => {
281
233
  const match = /^Severity:\s+(\w+)\s*$/.exec(lines[index].trim());
282
234
  if (!match) continue;
283
235
  const name = (lines[index - 1] || '').trim();
284
- problems.push(
285
- problem({
286
- severity: match[1].toLowerCase(),
287
- name,
288
- message: name,
289
- }),
290
- );
236
+ const severity = match[1].toLowerCase();
237
+ problems.push(problem({ severity, name, message: name }));
291
238
  }
292
- if (!problems.length) return null;
293
- const stats = summary();
294
- stats.errors = problems.length;
295
- return report('audit', { summary: stats, problems });
239
+ return problems.length ? errorReport('audit', problems) : null;
296
240
  };
297
241
 
298
- const TOOL_SLOTS = 4;
299
-
300
242
  const parseToolText = (text, root) => {
301
- const reports = new Array(TOOL_SLOTS);
302
- let index = 0;
303
- const eslint = parseEslintStylish(text, root);
304
- if (eslint) {
305
- reports[index] = eslint;
306
- index += 1;
307
- }
308
- const tsc = parseTsc(text, root);
309
- if (tsc) {
310
- reports[index] = tsc;
311
- index += 1;
312
- }
313
- const prettier = parsePrettier(text, root);
314
- if (prettier) {
315
- reports[index] = prettier;
316
- index += 1;
317
- }
318
- const audit = parseAuditText(text);
319
- if (audit) {
320
- reports[index] = audit;
321
- index += 1;
322
- }
323
- reports.length = index;
324
- return reports;
243
+ const reports = [
244
+ parseEslintStylish(text, root),
245
+ parseTsc(text, root),
246
+ parsePrettier(text, root),
247
+ parseAuditText(text),
248
+ ];
249
+ return reports.filter(Boolean);
250
+ };
251
+
252
+ const isPrettierLine = (line) => {
253
+ const text = line.trim();
254
+ if (!text) return false;
255
+ if (prettierFile(text) || isPrettierSummary(text)) return true;
256
+ return text.startsWith('Checking formatting');
257
+ };
258
+
259
+ const stderrRest = (text, reports) => {
260
+ if (!reports.some((item) => item.tool === 'prettier')) return text;
261
+ const lines = `${text ?? ''}`.split(/\r?\n/);
262
+ return lines
263
+ .filter((line) => !isPrettierLine(line))
264
+ .join('\n')
265
+ .trim();
325
266
  };
326
267
 
327
268
  module.exports = {
328
- parseEslintJson,
329
- parseEslintStylish,
330
- parseTsc,
331
- parsePrettier,
332
- parseAudit,
333
- parseOutdated,
334
- parseLs,
335
269
  parseToolJson,
336
270
  parseToolText,
271
+ stderrRest,
337
272
  };