watskeburt 1.0.1 → 2.0.1

Sign up to get free protection for your applications and to get access to all the features.
package/README.md CHANGED
@@ -7,8 +7,6 @@ Get changed files & their statuses since any git _revision_
7
7
  A micro-lib to retrieve an array of file names that were changed since a
8
8
  revision. Also sports a cli for use outside of JavaScript c.s.
9
9
 
10
- - :warning: Interface is stable, but can can change until 1.0.0 is published :warning:
11
-
12
10
  ## why?
13
11
 
14
12
  I needed something simple and robust to support some upcoming features in
@@ -103,6 +101,8 @@ Options:
103
101
 
104
102
  ## 🇳🇱 what does 'watskeburt' mean?
105
103
 
104
+ Wazzup.
105
+
106
106
  _watskeburt_ is a fast pronunciation of the Dutch "wat is er gebeurd?"
107
107
  (_what has happened?_) or "wat er is gebeurd" (_what has happened_). It's
108
108
  also the title of a song by the Dutch band "De Jeugd van Tegenwoordig"
package/dist/cli.js CHANGED
@@ -1,3 +1,73 @@
1
- #!/usr/bin/env node
2
- import { cli } from "./execute-cli.js";
3
- await cli();
1
+ import { EOL } from "node:os";
2
+ import { parseArgs } from "node:util";
3
+ import { list } from "./main.js";
4
+ import { VERSION } from "./version.js";
5
+ const HELP_MESSAGE = `Usage: watskeburt [options] [old-revision] [new-revision]
6
+
7
+ lists files & their statuses since [old-revision] or between [old-revision] and [new-revision].
8
+
9
+ -> When you don't pass a revision at all old-revision defaults to the current one.
10
+
11
+ Options:
12
+ -T, --outputType <type> what format to emit (choices: "json", "regex", default: "regex")
13
+ --trackedOnly only take tracked files into account (default: false)
14
+ -V, --version output the version number
15
+ -h, --help display help for command${EOL}`;
16
+ export async function cli(
17
+ pArguments = process.argv.slice(2),
18
+ pOutStream = process.stdout,
19
+ pErrorStream = process.stderr,
20
+ pErrorExitCode = 1,
21
+ ) {
22
+ try {
23
+ const lArguments = getArguments(pArguments);
24
+ if (lArguments.values.help) {
25
+ pOutStream.write(HELP_MESSAGE);
26
+ return;
27
+ }
28
+ if (lArguments.values.version) {
29
+ pOutStream.write(`${VERSION}${EOL}`);
30
+ return;
31
+ }
32
+ if (!outputTypeIsValid(lArguments.values.outputType)) {
33
+ pErrorStream.write(
34
+ `error: option '-T, --outputType <type>' argument '${lArguments.values.outputType}' is invalid. Allowed choices are json, regex.${EOL}`,
35
+ );
36
+ process.exitCode = pErrorExitCode;
37
+ return;
38
+ }
39
+ const lResult = await list(
40
+ lArguments.positionals[0],
41
+ lArguments.positionals[1],
42
+ lArguments.values,
43
+ );
44
+ pOutStream.write(`${lResult}${EOL}`);
45
+ } catch (pError) {
46
+ pErrorStream.write(`${EOL}ERROR: ${pError.message}${EOL}${EOL}`);
47
+ process.exitCode = pErrorExitCode;
48
+ }
49
+ }
50
+ function getArguments(pArguments) {
51
+ return parseArgs({
52
+ args: pArguments,
53
+ options: {
54
+ outputType: {
55
+ type: "string",
56
+ short: "T",
57
+ default: "regex",
58
+ },
59
+ trackedOnly: {
60
+ type: "boolean",
61
+ default: false,
62
+ },
63
+ help: { type: "boolean", short: "h", default: false },
64
+ version: { type: "boolean", short: "V", default: false },
65
+ },
66
+ strict: true,
67
+ allowPositionals: true,
68
+ tokens: false,
69
+ });
70
+ }
71
+ function outputTypeIsValid(pOutputType) {
72
+ return ["json", "regex"].includes(pOutputType);
73
+ }
@@ -2,9 +2,11 @@ import formatToRegex from "./regex.js";
2
2
  import formatToJSON from "./json.js";
3
3
  const identity = (pX) => pX;
4
4
  const OUTPUT_TYPE_TO_FUNCTION = new Map([
5
- ["regex", formatToRegex],
6
- ["json", formatToJSON],
5
+ ["regex", formatToRegex],
6
+ ["json", formatToJSON],
7
7
  ]);
8
8
  export default function format(pChanges, pOutputType) {
9
- return (OUTPUT_TYPE_TO_FUNCTION.get(pOutputType ?? "unknown") || identity)(pChanges);
9
+ return (OUTPUT_TYPE_TO_FUNCTION.get(pOutputType ?? "unknown") || identity)(
10
+ pChanges,
11
+ );
10
12
  }
@@ -1,4 +1,4 @@
1
1
  const INDENT = 2;
2
2
  export default function formatToJSON(pChanges) {
3
- return JSON.stringify(pChanges, null, INDENT);
3
+ return JSON.stringify(pChanges, null, INDENT);
4
4
  }
@@ -1,36 +1,40 @@
1
1
  import { extname } from "node:path";
2
2
  const DEFAULT_EXTENSIONS = new Set([
3
- ".cjs",
4
- ".cjsx",
5
- ".coffee",
6
- ".csx",
7
- ".cts",
8
- ".js",
9
- ".json",
10
- ".jsx",
11
- ".litcoffee",
12
- ".ls",
13
- ".mjs",
14
- ".mts",
15
- ".svelte",
16
- ".ts",
17
- ".tsx",
18
- ".vue",
19
- ".vuex",
3
+ ".cjs",
4
+ ".cjsx",
5
+ ".coffee",
6
+ ".csx",
7
+ ".cts",
8
+ ".js",
9
+ ".json",
10
+ ".jsx",
11
+ ".litcoffee",
12
+ ".ls",
13
+ ".mjs",
14
+ ".mts",
15
+ ".svelte",
16
+ ".ts",
17
+ ".tsx",
18
+ ".vue",
19
+ ".vuex",
20
20
  ]);
21
21
  const DEFAULT_CHANGE_TYPES = new Set([
22
- "modified",
23
- "added",
24
- "renamed",
25
- "copied",
26
- "untracked",
22
+ "modified",
23
+ "added",
24
+ "renamed",
25
+ "copied",
26
+ "untracked",
27
27
  ]);
28
- export default function formatToRegex(pChanges, pExtensions = DEFAULT_EXTENSIONS, pChangeTypes = DEFAULT_CHANGE_TYPES) {
29
- const lChanges = pChanges
30
- .filter((pChange) => pChangeTypes.has(pChange.changeType))
31
- .map(({ name }) => name)
32
- .filter((pName) => pExtensions.has(extname(pName)))
33
- .map((pName) => pName.replace(/\\/g, "\\\\").replace(/\./g, "\\."))
34
- .join("|");
35
- return `^(${lChanges})$`;
28
+ export default function formatToRegex(
29
+ pChanges,
30
+ pExtensions = DEFAULT_EXTENSIONS,
31
+ pChangeTypes = DEFAULT_CHANGE_TYPES,
32
+ ) {
33
+ const lChanges = pChanges
34
+ .filter((pChange) => pChangeTypes.has(pChange.changeType))
35
+ .map(({ name }) => name)
36
+ .filter((pName) => pExtensions.has(extname(pName)))
37
+ .map((pName) => pName.replace(/\\/g, "\\\\").replace(/\./g, "\\."))
38
+ .join("|");
39
+ return `^(${lChanges})$`;
36
40
  }
@@ -1,67 +1,88 @@
1
1
  import { spawn } from "node:child_process";
2
2
  export async function getStatusShort(pSpawnFunction = spawn) {
3
- const lErrorMap = new Map([
4
- [129, `'${process.cwd()}' does not seem to be a git repository`],
5
- ]);
6
- const lResult = await getGitResult(["status", "--porcelain"], lErrorMap, pSpawnFunction);
7
- return lResult;
3
+ const lErrorMap = new Map([
4
+ [129, `'${process.cwd()}' does not seem to be a git repository`],
5
+ ]);
6
+ const lResult = await getGitResult(
7
+ ["status", "--porcelain"],
8
+ lErrorMap,
9
+ pSpawnFunction,
10
+ );
11
+ return lResult;
8
12
  }
9
- export async function getDiffLines(pOldRevision, pNewRevision, pSpawnFunction = spawn) {
10
- const lErrorMap = new Map([
11
- [
12
- 128,
13
- `revision '${pOldRevision}' ${pNewRevision ? `(or '${pNewRevision}') ` : ""}unknown`,
14
- ],
15
- [129, `'${process.cwd()}' does not seem to be a git repository`],
16
- ]);
17
- const lResult = await getGitResult(pNewRevision
18
- ? ["diff", pOldRevision, pNewRevision, "--name-status"]
19
- : ["diff", pOldRevision, "--name-status"], lErrorMap, pSpawnFunction);
20
- return lResult;
13
+ export async function getDiffLines(
14
+ pOldRevision,
15
+ pNewRevision,
16
+ pSpawnFunction = spawn,
17
+ ) {
18
+ const lErrorMap = new Map([
19
+ [
20
+ 128,
21
+ `revision '${pOldRevision}' ${
22
+ pNewRevision ? `(or '${pNewRevision}') ` : ""
23
+ }unknown`,
24
+ ],
25
+ [129, `'${process.cwd()}' does not seem to be a git repository`],
26
+ ]);
27
+ const lResult = await getGitResult(
28
+ pNewRevision
29
+ ? ["diff", pOldRevision, pNewRevision, "--name-status"]
30
+ : ["diff", pOldRevision, "--name-status"],
31
+ lErrorMap,
32
+ pSpawnFunction,
33
+ );
34
+ return lResult;
21
35
  }
22
36
  export async function getSHA(pSpawnFunction = spawn) {
23
- const lSha1Length = 40;
24
- const lResult = await getGitResult(["rev-parse", "HEAD"], new Map(), pSpawnFunction);
25
- return lResult.slice(0, lSha1Length);
37
+ const lSha1Length = 40;
38
+ const lResult = await getGitResult(
39
+ ["rev-parse", "HEAD"],
40
+ new Map(),
41
+ pSpawnFunction,
42
+ );
43
+ return lResult.slice(0, lSha1Length);
26
44
  }
27
45
  function getGitResult(pArguments, pErrorMap, pSpawnFunction) {
28
- const lGit = pSpawnFunction("git", pArguments, {
29
- cwd: process.cwd(),
30
- env: process.env,
46
+ const lGit = pSpawnFunction("git", pArguments, {
47
+ cwd: process.cwd(),
48
+ env: process.env,
49
+ });
50
+ let lStdOutData = "";
51
+ let lStdErrorData = "";
52
+ return new Promise((pResolve, pReject) => {
53
+ lGit.stdout?.on("data", (pData) => {
54
+ lStdOutData = lStdOutData.concat(pData);
31
55
  });
32
- let lStdOutData = "";
33
- let lStdErrorData = "";
34
- return new Promise((pResolve, pReject) => {
35
- lGit.stdout?.on("data", (pData) => {
36
- lStdOutData = lStdOutData.concat(pData);
37
- });
38
- lGit.stderr?.on("data", (pData) => {
39
- lStdErrorData = lStdErrorData.concat(pData);
40
- });
41
- lGit.on("close", (pCode) => {
42
- if (pCode === 0) {
43
- pResolve(stringifyOutStream(lStdOutData));
44
- }
45
- else {
46
- pReject(new Error(pErrorMap.get(pCode ?? 0) ||
47
- `internal git error: ${pCode} (${stringifyOutStream(lStdErrorData)})`));
48
- }
49
- });
50
- lGit.on("error", (pError) => {
51
- if (pError?.code === "ENOENT") {
52
- pReject(new Error("git executable not found"));
53
- }
54
- else {
55
- pReject(new Error(`internal spawn error: ${pError}`));
56
- }
57
- });
56
+ lGit.stderr?.on("data", (pData) => {
57
+ lStdErrorData = lStdErrorData.concat(pData);
58
58
  });
59
+ lGit.on("close", (pCode) => {
60
+ if (pCode === 0) {
61
+ pResolve(stringifyOutStream(lStdOutData));
62
+ } else {
63
+ pReject(
64
+ new Error(
65
+ pErrorMap.get(pCode ?? 0) ||
66
+ `internal git error: ${pCode} (${stringifyOutStream(
67
+ lStdErrorData,
68
+ )})`,
69
+ ),
70
+ );
71
+ }
72
+ });
73
+ lGit.on("error", (pError) => {
74
+ if (pError?.code === "ENOENT") {
75
+ pReject(new Error("git executable not found"));
76
+ } else {
77
+ pReject(new Error(`internal spawn error: ${pError}`));
78
+ }
79
+ });
80
+ });
59
81
  }
60
82
  function stringifyOutStream(pBufferOrString) {
61
- if (pBufferOrString instanceof Buffer) {
62
- return pBufferOrString.toString("utf8");
63
- }
64
- else {
65
- return pBufferOrString;
66
- }
83
+ if (pBufferOrString instanceof Buffer) {
84
+ return pBufferOrString.toString("utf8");
85
+ } else {
86
+ return pBufferOrString;
87
+ }
67
88
  }
package/dist/main.js CHANGED
@@ -3,18 +3,22 @@ import { parseStatusLines } from "./parse-status-lines.js";
3
3
  import * as primitives from "./git-primitives.js";
4
4
  import format from "./formatters/format.js";
5
5
  export async function list(pOldRevision, pNewRevision, pOptions) {
6
- const lOldRevision = pOldRevision || (await primitives.getSHA());
7
- const lOptions = pOptions || {};
8
- const [lDiffLines, lStatusLines] = await Promise.all([
9
- primitives.getDiffLines(lOldRevision, pNewRevision),
10
- !lOptions.trackedOnly ? primitives.getStatusShort() : "",
11
- ]);
12
- let lChanges = parseDiffLines(lDiffLines);
13
- if (!lOptions.trackedOnly) {
14
- lChanges = lChanges.concat(parseStatusLines(lStatusLines).filter(({ changeType }) => changeType === "untracked"));
15
- }
16
- return format(lChanges, lOptions.outputType);
6
+ const lOldRevision = pOldRevision || (await primitives.getSHA());
7
+ const lOptions = pOptions || {};
8
+ const [lDiffLines, lStatusLines] = await Promise.all([
9
+ primitives.getDiffLines(lOldRevision, pNewRevision),
10
+ !lOptions.trackedOnly ? primitives.getStatusShort() : "",
11
+ ]);
12
+ let lChanges = parseDiffLines(lDiffLines);
13
+ if (!lOptions.trackedOnly) {
14
+ lChanges = lChanges.concat(
15
+ parseStatusLines(lStatusLines).filter(
16
+ ({ changeType }) => changeType === "untracked",
17
+ ),
18
+ );
19
+ }
20
+ return format(lChanges, lOptions.outputType);
17
21
  }
18
22
  export function getSHA() {
19
- return primitives.getSHA();
23
+ return primitives.getSHA();
20
24
  }
@@ -1,16 +1,16 @@
1
1
  const CHANGE_CHAR_2_CHANGE_TYPE = new Map([
2
- ["A", "added"],
3
- ["C", "copied"],
4
- ["D", "deleted"],
5
- ["M", "modified"],
6
- ["R", "renamed"],
7
- ["T", "type changed"],
8
- ["U", "unmerged"],
9
- ["B", "pairing broken"],
10
- [" ", "unmodified"],
11
- ["?", "untracked"],
12
- ["!", "ignored"],
2
+ ["A", "added"],
3
+ ["C", "copied"],
4
+ ["D", "deleted"],
5
+ ["M", "modified"],
6
+ ["R", "renamed"],
7
+ ["T", "type changed"],
8
+ ["U", "unmerged"],
9
+ ["B", "pairing broken"],
10
+ [" ", "unmodified"],
11
+ ["?", "untracked"],
12
+ ["!", "ignored"],
13
13
  ]);
14
14
  export function changeChar2ChangeType(pChar) {
15
- return CHANGE_CHAR_2_CHANGE_TYPE.get(pChar) ?? "unknown";
15
+ return CHANGE_CHAR_2_CHANGE_TYPE.get(pChar) ?? "unknown";
16
16
  }
@@ -1,25 +1,27 @@
1
1
  import { EOL } from "node:os";
2
2
  import { changeChar2ChangeType } from "./map-change-type.js";
3
- const DIFF_NAME_STATUS_LINE_PATTERN = /^(?<changeType>[ACDMRTUXB])(?<similarity>[0-9]{3})?[ \t]+(?<name>[^ \t]+)[ \t]*(?<newName>[^ \t]+)?$/;
3
+ const DIFF_NAME_STATUS_LINE_PATTERN =
4
+ /^(?<changeType>[ACDMRTUXB])(?<similarity>[0-9]{3})?[ \t]+(?<name>[^ \t]+)[ \t]*(?<newName>[^ \t]+)?$/;
4
5
  export function parseDiffLines(pString) {
5
- return pString
6
- .split(EOL)
7
- .filter(Boolean)
8
- .map(parseDiffLine)
9
- .filter(({ name, changeType }) => Boolean(name) && Boolean(changeType));
6
+ return pString
7
+ .split(EOL)
8
+ .filter(Boolean)
9
+ .map(parseDiffLine)
10
+ .filter(({ name, changeType }) => Boolean(name) && Boolean(changeType));
10
11
  }
11
12
  export function parseDiffLine(pString) {
12
- const lMatchResult = pString.match(DIFF_NAME_STATUS_LINE_PATTERN);
13
- const lReturnValue = {};
14
- if (lMatchResult?.groups) {
15
- lReturnValue.changeType = changeChar2ChangeType(lMatchResult.groups.changeType);
16
- if (lMatchResult.groups.newName) {
17
- lReturnValue.name = lMatchResult.groups.newName;
18
- lReturnValue.oldName = lMatchResult.groups.name;
19
- }
20
- else {
21
- lReturnValue.name = lMatchResult.groups.name;
22
- }
13
+ const lMatchResult = pString.match(DIFF_NAME_STATUS_LINE_PATTERN);
14
+ const lReturnValue = {};
15
+ if (lMatchResult?.groups) {
16
+ lReturnValue.changeType = changeChar2ChangeType(
17
+ lMatchResult.groups.changeType,
18
+ );
19
+ if (lMatchResult.groups.newName) {
20
+ lReturnValue.name = lMatchResult.groups.newName;
21
+ lReturnValue.oldName = lMatchResult.groups.name;
22
+ } else {
23
+ lReturnValue.name = lMatchResult.groups.name;
23
24
  }
24
- return lReturnValue;
25
+ }
26
+ return lReturnValue;
25
27
  }
@@ -1,30 +1,34 @@
1
1
  import { EOL } from "node:os";
2
2
  import { changeChar2ChangeType } from "./map-change-type.js";
3
- const DIFF_SHORT_STATUS_LINE_PATTERN = /^(?<stagedChangeType>[ ACDMRTUXB?!])(?<unStagedChangeType>[ ACDMRTUXB?!])[ \t]+(?<name>[^ \t]+)(( -> )(?<newName>[^ \t]+))?$/;
3
+ const DIFF_SHORT_STATUS_LINE_PATTERN =
4
+ /^(?<stagedChangeType>[ ACDMRTUXB?!])(?<unStagedChangeType>[ ACDMRTUXB?!])[ \t]+(?<name>[^ \t]+)(( -> )(?<newName>[^ \t]+))?$/;
4
5
  export function parseStatusLines(pString) {
5
- return pString
6
- .split(EOL)
7
- .filter(Boolean)
8
- .map(parseStatusLine)
9
- .filter(({ name, changeType }) => Boolean(name) && Boolean(changeType));
6
+ return pString
7
+ .split(EOL)
8
+ .filter(Boolean)
9
+ .map(parseStatusLine)
10
+ .filter(({ name, changeType }) => Boolean(name) && Boolean(changeType));
10
11
  }
11
12
  export function parseStatusLine(pString) {
12
- const lMatchResult = pString.match(DIFF_SHORT_STATUS_LINE_PATTERN);
13
- const lReturnValue = {};
14
- if (lMatchResult?.groups) {
15
- const lStagedChangeType = changeChar2ChangeType(lMatchResult.groups.stagedChangeType);
16
- const lUnStagedChangeType = changeChar2ChangeType(lMatchResult.groups.unStagedChangeType);
17
- lReturnValue.changeType =
18
- lStagedChangeType === "unmodified"
19
- ? lUnStagedChangeType
20
- : lStagedChangeType;
21
- if (lMatchResult.groups.newName) {
22
- lReturnValue.name = lMatchResult.groups.newName;
23
- lReturnValue.oldName = lMatchResult.groups.name;
24
- }
25
- else {
26
- lReturnValue.name = lMatchResult.groups.name;
27
- }
13
+ const lMatchResult = pString.match(DIFF_SHORT_STATUS_LINE_PATTERN);
14
+ const lReturnValue = {};
15
+ if (lMatchResult?.groups) {
16
+ const lStagedChangeType = changeChar2ChangeType(
17
+ lMatchResult.groups.stagedChangeType,
18
+ );
19
+ const lUnStagedChangeType = changeChar2ChangeType(
20
+ lMatchResult.groups.unStagedChangeType,
21
+ );
22
+ lReturnValue.changeType =
23
+ lStagedChangeType === "unmodified"
24
+ ? lUnStagedChangeType
25
+ : lStagedChangeType;
26
+ if (lMatchResult.groups.newName) {
27
+ lReturnValue.name = lMatchResult.groups.newName;
28
+ lReturnValue.oldName = lMatchResult.groups.name;
29
+ } else {
30
+ lReturnValue.name = lMatchResult.groups.name;
28
31
  }
29
- return lReturnValue;
32
+ }
33
+ return lReturnValue;
30
34
  }
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ import { cli } from "./cli.js";
3
+ await cli();
package/dist/version.js CHANGED
@@ -1 +1 @@
1
- export const VERSION = "1.0.1";
1
+ export const VERSION = "2.0.1";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "watskeburt",
3
- "version": "1.0.1",
3
+ "version": "2.0.1",
4
4
  "description": "List files changed since a git revision",
5
5
  "keywords": [
6
6
  "git",
@@ -19,7 +19,7 @@
19
19
  "url": "https://sverweij.github.io"
20
20
  },
21
21
  "license": "MIT",
22
- "bin": "dist/cli.js",
22
+ "bin": "dist/run-cli.js",
23
23
  "main": "dist/main.js",
24
24
  "module": "dist/main.js",
25
25
  "type": "module",
@@ -42,44 +42,45 @@
42
42
  "README.md"
43
43
  ],
44
44
  "devDependencies": {
45
- "@types/node": "20.5.1",
46
- "@typescript-eslint/eslint-plugin": "6.4.1",
45
+ "@types/node": "20.8.7",
46
+ "@typescript-eslint/eslint-plugin": "6.9.0",
47
47
  "c8": "8.0.1",
48
- "dependency-cruiser": "13.1.4",
49
- "eslint": "8.47.0",
48
+ "dependency-cruiser": "15.0.0",
49
+ "eslint": "8.52.0",
50
50
  "eslint-config-moving-meadow": "4.0.2",
51
51
  "eslint-config-prettier": "9.0.0",
52
52
  "eslint-plugin-budapestian": "5.0.1",
53
53
  "eslint-plugin-eslint-comments": "3.2.0",
54
- "eslint-plugin-import": "2.28.1",
55
- "eslint-plugin-mocha": "10.1.0",
54
+ "eslint-plugin-import": "2.29.0",
55
+ "eslint-plugin-mocha": "10.2.0",
56
56
  "eslint-plugin-node": "11.1.0",
57
57
  "eslint-plugin-security": "1.7.1",
58
58
  "eslint-plugin-unicorn": "48.0.1",
59
59
  "npm-run-all": "4.1.5",
60
- "prettier": "3.0.2",
61
- "ts-node": "10.9.1",
62
- "typescript": "5.1.6",
63
- "upem": "8.0.0"
60
+ "prettier": "3.0.3",
61
+ "tsx": "3.14.0",
62
+ "typescript": "5.2.2",
63
+ "upem": "9.0.2"
64
64
  },
65
65
  "engines": {
66
- "node": "^16.14||>=18"
66
+ "node": "^18||>=20"
67
67
  },
68
68
  "scripts": {
69
- "build": "npm-run-all --sequential build:clean build:version build:dist",
70
- "build:version": "node --no-warnings --loader ts-node/esm tools/get-version.ts > src/version.ts",
69
+ "build": "npm-run-all --sequential build:clean build:version build:dist build:format",
70
+ "build:version": "tsx tools/get-version.ts > src/version.ts",
71
71
  "build:clean": "rm -rf dist/*",
72
72
  "build:dist": "tsc",
73
+ "build:format": "prettier --log-level warn --write dist/",
73
74
  "check": "npm-run-all --parallel --aggregate-output lint depcruise test:cover",
74
75
  "clean": "rm -rf dist",
75
- "test": "node --no-warnings --loader 'ts-node/esm' --test-reporter ./tools/dot-with-summary.reporter.js --test src/*.spec.ts src/**/*.spec.ts",
76
+ "test": "tsx --test-reporter ./tools/dot-with-summary.reporter.js --test src/*.spec.ts src/**/*.spec.ts",
76
77
  "test:cover": "c8 npm test",
77
78
  "depcruise": "depcruise dist src types",
78
79
  "depcruise:graph": "depcruise src types --include-only '^(dist|src|types)' --output-type dot | dot -T svg | tee docs/dependency-graph.svg | depcruise-wrap-stream-in-html > docs/dependency-graph.html",
79
80
  "depcruise:graph:archi": "depcruise src --include-only '^(dist|src|types)' --output-type archi | dot -T svg | depcruise-wrap-stream-in-html > docs/high-level-dependency-graph.html",
80
81
  "depcruise:graph:dev": "depcruise dist src types --include-only '^(dist|src|types)' --prefix vscode://file/$(pwd)/ --output-type dot | dot -T svg | depcruise-wrap-stream-in-html | browser",
81
- "depcruise:graph:diff:dev": "depcruise dist src types --include-only '^(dist|src|types)' --highlight \"$(node dist/cli.js main -T regex)\" --prefix vscode://file/$(pwd)/ --output-type dot | dot -T svg | depcruise-wrap-stream-in-html | browser",
82
- "depcruise:graph:diff:mermaid": "depcruise dist src types --include-only '^(dist|src|types)' --output-type mermaid --output-to - --highlight \"$(node dist/cli.js $SHA -T regex)\"",
82
+ "depcruise:graph:diff:dev": "depcruise dist src types --include-only '^(dist|src|types)' --highlight \"$(node dist/run-cli.js main -T regex)\" --prefix vscode://file/$(pwd)/ --output-type dot | dot -T svg | depcruise-wrap-stream-in-html | browser",
83
+ "depcruise:graph:diff:mermaid": "depcruise dist src types --include-only '^(dist|src|types)' --output-type mermaid --output-to - --highlight \"$(node dist/run-cli.js $SHA -T regex)\"",
83
84
  "depcruise:html": "depcruise src types --progress --output-type err-html --output-to dependency-violation-report.html",
84
85
  "depcruise:text": "depcruise src types --progress --output-type text",
85
86
  "depcruise:focus": "depcruise src types --progress --output-type text --focus",
@@ -1,63 +0,0 @@
1
- import { EOL } from "node:os";
2
- import { parseArgs } from "node:util";
3
- import { list } from "./main.js";
4
- import { VERSION } from "./version.js";
5
- const HELP_MESSAGE = `Usage: watskeburt [options] [old-revision] [new-revision]
6
-
7
- lists files & their statuses since [old-revision] or between [old-revision] and [new-revision].
8
-
9
- -> When you don't pass a revision at all old-revision defaults to the current one.
10
-
11
- Options:
12
- -T, --outputType <type> what format to emit (choices: "json", "regex", default: "regex")
13
- --trackedOnly only take tracked files into account (default: false)
14
- -V, --version output the version number
15
- -h, --help display help for command${EOL}`;
16
- export async function cli(pArguments = process.argv.slice(2), pOutStream = process.stdout, pErrorStream = process.stderr, pErrorExitCode = 1) {
17
- try {
18
- const lArguments = getArguments(pArguments);
19
- if (lArguments.values.help) {
20
- pOutStream.write(HELP_MESSAGE);
21
- return;
22
- }
23
- if (lArguments.values.version) {
24
- pOutStream.write(`${VERSION}${EOL}`);
25
- return;
26
- }
27
- if (!outputTypeIsValid(lArguments.values.outputType)) {
28
- pErrorStream.write(`error: option '-T, --outputType <type>' argument '${lArguments.values.outputType}' is invalid. Allowed choices are json, regex.${EOL}`);
29
- process.exitCode = pErrorExitCode;
30
- return;
31
- }
32
- const lResult = await list(lArguments.positionals[0], lArguments.positionals[1], lArguments.values);
33
- pOutStream.write(`${lResult}${EOL}`);
34
- }
35
- catch (pError) {
36
- pErrorStream.write(`${EOL}ERROR: ${pError.message}${EOL}${EOL}`);
37
- process.exitCode = pErrorExitCode;
38
- }
39
- }
40
- function getArguments(pArguments) {
41
- return parseArgs({
42
- args: pArguments,
43
- options: {
44
- outputType: {
45
- type: "string",
46
- short: "T",
47
- default: "regex",
48
- },
49
- trackedOnly: {
50
- type: "boolean",
51
- default: false,
52
- },
53
- help: { type: "boolean", short: "h", default: false },
54
- version: { type: "boolean", short: "V", default: false },
55
- },
56
- strict: true,
57
- allowPositionals: true,
58
- tokens: false,
59
- });
60
- }
61
- function outputTypeIsValid(pOutputType) {
62
- return ["json", "regex"].includes(pOutputType);
63
- }