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 +2 -2
- package/dist/cli.js +73 -3
- package/dist/formatters/format.js +5 -3
- package/dist/formatters/json.js +1 -1
- package/dist/formatters/regex.js +34 -30
- package/dist/git-primitives.js +76 -55
- package/dist/main.js +16 -12
- package/dist/map-change-type.js +12 -12
- package/dist/parse-diff-lines.js +20 -18
- package/dist/parse-status-lines.js +27 -23
- package/dist/run-cli.js +3 -0
- package/dist/version.js +1 -1
- package/package.json +19 -18
- package/dist/execute-cli.js +0 -63
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
|
-
|
2
|
-
import {
|
3
|
-
|
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
|
-
|
6
|
-
|
5
|
+
["regex", formatToRegex],
|
6
|
+
["json", formatToJSON],
|
7
7
|
]);
|
8
8
|
export default function format(pChanges, pOutputType) {
|
9
|
-
|
9
|
+
return (OUTPUT_TYPE_TO_FUNCTION.get(pOutputType ?? "unknown") || identity)(
|
10
|
+
pChanges,
|
11
|
+
);
|
10
12
|
}
|
package/dist/formatters/json.js
CHANGED
package/dist/formatters/regex.js
CHANGED
@@ -1,36 +1,40 @@
|
|
1
1
|
import { extname } from "node:path";
|
2
2
|
const DEFAULT_EXTENSIONS = new Set([
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
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
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
22
|
+
"modified",
|
23
|
+
"added",
|
24
|
+
"renamed",
|
25
|
+
"copied",
|
26
|
+
"untracked",
|
27
27
|
]);
|
28
|
-
export default function formatToRegex(
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
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
|
}
|
package/dist/git-primitives.js
CHANGED
@@ -1,67 +1,88 @@
|
|
1
1
|
import { spawn } from "node:child_process";
|
2
2
|
export async function getStatusShort(pSpawnFunction = spawn) {
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
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(
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
?
|
19
|
-
|
20
|
-
|
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
|
-
|
24
|
-
|
25
|
-
|
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
|
-
|
29
|
-
|
30
|
-
|
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
|
-
|
33
|
-
|
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
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
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
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
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
|
-
|
23
|
+
return primitives.getSHA();
|
20
24
|
}
|
package/dist/map-change-type.js
CHANGED
@@ -1,16 +1,16 @@
|
|
1
1
|
const CHANGE_CHAR_2_CHANGE_TYPE = new Map([
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
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
|
-
|
15
|
+
return CHANGE_CHAR_2_CHANGE_TYPE.get(pChar) ?? "unknown";
|
16
16
|
}
|
package/dist/parse-diff-lines.js
CHANGED
@@ -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 =
|
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
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
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
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
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
|
-
|
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 =
|
3
|
+
const DIFF_SHORT_STATUS_LINE_PATTERN =
|
4
|
+
/^(?<stagedChangeType>[ ACDMRTUXB?!])(?<unStagedChangeType>[ ACDMRTUXB?!])[ \t]+(?<name>[^ \t]+)(( -> )(?<newName>[^ \t]+))?$/;
|
4
5
|
export function parseStatusLines(pString) {
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
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
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
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
|
-
|
32
|
+
}
|
33
|
+
return lReturnValue;
|
30
34
|
}
|
package/dist/run-cli.js
ADDED
package/dist/version.js
CHANGED
@@ -1 +1 @@
|
|
1
|
-
export const VERSION = "
|
1
|
+
export const VERSION = "2.0.1";
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "watskeburt",
|
3
|
-
"version": "
|
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.
|
46
|
-
"@typescript-eslint/eslint-plugin": "6.
|
45
|
+
"@types/node": "20.8.7",
|
46
|
+
"@typescript-eslint/eslint-plugin": "6.9.0",
|
47
47
|
"c8": "8.0.1",
|
48
|
-
"dependency-cruiser": "
|
49
|
-
"eslint": "8.
|
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.
|
55
|
-
"eslint-plugin-mocha": "10.
|
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.
|
61
|
-
"
|
62
|
-
"typescript": "5.
|
63
|
-
"upem": "
|
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": "^
|
66
|
+
"node": "^18||>=20"
|
67
67
|
},
|
68
68
|
"scripts": {
|
69
|
-
"build": "npm-run-all --sequential build:clean build:version build:dist",
|
70
|
-
"build:version": "
|
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": "
|
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",
|
package/dist/execute-cli.js
DELETED
@@ -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
|
-
}
|