@aklinker1/check 1.0.5 → 1.1.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/dist/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import type { CheckOptions, Problem } from "./types";
2
2
  export type * from "./types";
3
3
  export declare function check(options?: CheckOptions): Promise<void>;
4
+ export declare function renderProblemGroup(problems: Problem[]): string;
4
5
  export declare function renderProblem(problem: Problem): string;
package/dist/index.mjs CHANGED
@@ -37,7 +37,13 @@ export async function check(options = {}) {
37
37
  return problems2;
38
38
  }
39
39
  );
40
- const problems = results.flat().sort((l, r) => {
40
+ const problems = results.flat();
41
+ console.log();
42
+ if (problems.length === 0) {
43
+ process.exit(0);
44
+ }
45
+ console.log(plural(problems.length, "Problem:", "Problems:"));
46
+ problems.sort((l, r) => {
41
47
  const nameCompare = l.file.localeCompare(r.file);
42
48
  if (nameCompare !== 0)
43
49
  return nameCompare;
@@ -46,14 +52,14 @@ export async function check(options = {}) {
46
52
  return lineCompare;
47
53
  return (l.location?.column ?? 0) - (r.location?.column ?? 0);
48
54
  });
49
- console.log();
50
- if (problems.length === 0) {
51
- process.exit(0);
52
- }
53
- console.log(plural(problems.length, "Problem:", "Problems:"));
54
- problems.forEach((problem) => {
55
- console.log(renderProblem(problem));
56
- });
55
+ const groupedProblems = problems.reduce((acc, problem) => {
56
+ const locationHash = `${problem.file}:${problem.location?.line}:${problem.location?.column}`;
57
+ const list = acc.get(locationHash) ?? [];
58
+ list.push(problem);
59
+ acc.set(locationHash, list);
60
+ return acc;
61
+ }, /* @__PURE__ */ new Map());
62
+ console.log([...groupedProblems.values()].map(renderProblemGroup).join("\n"));
57
63
  const files = Object.entries(
58
64
  problems.reduce((acc, problem) => {
59
65
  const file = "." + sep + relative(process.cwd(), problem.file);
@@ -91,12 +97,17 @@ async function findInstalledTools(root) {
91
97
  function plural(count, singular, plural2) {
92
98
  return `${count} ${count === 1 ? singular : plural2} `;
93
99
  }
94
- export function renderProblem(problem) {
95
- const icon = problem.kind === "warning" ? bold(yellow("\u26A0")) : bold(red("\u2717"));
100
+ export function renderProblemGroup(problems) {
101
+ const renderedProblems = problems.map(renderProblem);
102
+ const problem = problems[0];
96
103
  const path = relative(process.cwd(), problem.file);
97
104
  const location = problem.location ? `${path}:${problem.location.line}:${problem.location.column}` : path;
98
- const source = problem.rule ? dim(` (${problem.rule})`) : "";
99
105
  const link = dim(`\u2192 .${sep}${location}`);
100
- return `${icon} ${problem.message}${source}
106
+ return `${renderedProblems.join("\n")}
101
107
  ${link}`;
102
108
  }
109
+ export function renderProblem(problem) {
110
+ const icon = problem.kind === "warning" ? bold(yellow("\u26A0")) : bold(red("\u2717"));
111
+ const source = problem.rule ? dim(` (${problem.rule})`) : "";
112
+ return `${icon} ${problem.message}${source}`;
113
+ }
@@ -18,19 +18,19 @@ export const eslint = {
18
18
  export const parseOuptut = ({ stdout, stderr }) => {
19
19
  return `${stdout}
20
20
  ${stderr}`.split(/\r?\n/).reduce((acc, line) => {
21
- const match = /^(.*?): line ([0-9]+), col ([0-9]+), (\S+) - (.*?) \((\S*?)\)$/.exec(
21
+ const groups = /^(?<file>.*?): line (?<line>[0-9]+), col (?<column>[0-9]+), (?<kind>\S+) - (?<message>.*?) \((?<rule>\S*?)\)$/.exec(
22
22
  line
23
- );
24
- if (match) {
23
+ )?.groups;
24
+ if (groups) {
25
25
  acc.push({
26
- file: match[1],
27
- kind: match[4] === "Warning" ? "warning" : "error",
28
- message: match[5],
26
+ file: groups.file,
27
+ kind: groups.kind === "Warning" ? "warning" : "error",
28
+ message: groups.message,
29
29
  location: {
30
- line: parseInt(match[2], 10),
31
- column: parseInt(match[3], 10)
30
+ line: parseInt(groups.line, 10),
31
+ column: parseInt(groups.column, 10)
32
32
  },
33
- rule: match[6]
33
+ rule: groups.rule
34
34
  });
35
35
  }
36
36
  return acc;
@@ -11,17 +11,17 @@ export const prettier = {
11
11
  export const parseOuptut = ({ stdout, stderr }) => {
12
12
  if (stderr.trim()) {
13
13
  return stderr.split(/\r?\n/).reduce((acc, line) => {
14
- const match = /^\[(.+?)\]\s?(.+?):\s?(.*?)\s?\(([0-9]+):([0-9])\)$/.exec(
14
+ const groups = /^\[(?<kind>.+?)\]\s?(?<file>.+?):\s?(?<message>.*?)\s?\((?<line>[0-9]+):(?<column>[0-9])\)$/.exec(
15
15
  line
16
- );
17
- if (match) {
16
+ )?.groups;
17
+ if (groups) {
18
18
  acc.push({
19
- file: match[2],
20
- kind: match[1] === "error" ? "error" : "warning",
21
- message: match[3],
19
+ file: groups.file,
20
+ kind: groups.kind === "error" ? "error" : "warning",
21
+ message: groups.message,
22
22
  location: {
23
- line: parseInt(match[4], 10),
24
- column: parseInt(match[5], 10)
23
+ line: parseInt(groups.line, 10),
24
+ column: parseInt(groups.column, 10)
25
25
  }
26
26
  });
27
27
  }
@@ -13,12 +13,12 @@ export const parseOuptut = ({ stdout }) => {
13
13
  kind = "error";
14
14
  return acc;
15
15
  }
16
- const match = /^[0-9]+\.\s?(.*)$/.exec(line);
17
- if (match == null)
16
+ const groups = /^[0-9]+\.\s?(?<message>.*)$/.exec(line)?.groups;
17
+ if (groups == null)
18
18
  return acc;
19
19
  acc.push({
20
20
  kind,
21
- message: match[1],
21
+ message: groups.message,
22
22
  file: "package.json"
23
23
  });
24
24
  return acc;
@@ -8,19 +8,19 @@ export const typescript = {
8
8
  };
9
9
  export const parseOuptut = ({ stdout }) => {
10
10
  return stdout.split(/\r?\n/).reduce((acc, line) => {
11
- const match = /^(\S+?)\(([0-9]+),([0-9]+)\): \w+? (TS[0-9]+): (.*)$/.exec(
11
+ const groups = /^(?<file>\S+?)\((?<line>[0-9]+),(?<column>[0-9]+)\): \w+? (?<rule>TS[0-9]+): (?<message>.*)$/.exec(
12
12
  line
13
- );
14
- if (match) {
13
+ )?.groups;
14
+ if (groups) {
15
15
  acc.push({
16
- file: match[1],
16
+ file: groups.file,
17
17
  kind: "error",
18
- message: match[5],
18
+ message: groups.message,
19
19
  location: {
20
- line: parseInt(match[2], 10),
21
- column: parseInt(match[3], 10)
20
+ line: parseInt(groups.line, 10),
21
+ column: parseInt(groups.column, 10)
22
22
  },
23
- rule: match[4]
23
+ rule: groups.rule
24
24
  });
25
25
  }
26
26
  return acc;
package/dist/utils.mjs CHANGED
@@ -17,7 +17,7 @@ export async function isBinInstalled(bin, root) {
17
17
  }
18
18
  function exec(cmd, args, opts) {
19
19
  return new Promise((resolve2, reject) => {
20
- const child = spawn(cmd, args, opts);
20
+ const child = spawn(cmd, args, { ...opts, shell: true });
21
21
  let stderr = "";
22
22
  let stdout = "";
23
23
  child.stdout.on("data", (data) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aklinker1/check",
3
- "version": "1.0.5",
3
+ "version": "1.1.1",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/aklinker1/check"