watskeburt 2.0.5 → 4.0.0
Sign up to get free protection for your applications and to get access to all the features.
- package/README.md +30 -36
- package/dist/cli.js +6 -6
- package/dist/format/format.js +9 -0
- package/dist/{formatters → format}/json.js +1 -1
- package/dist/{formatters → format}/regex.js +2 -2
- package/dist/main.js +8 -5
- package/dist/parse-diff-lines.js +4 -4
- package/dist/parse-status-lines.js +4 -2
- package/dist/version.js +1 -1
- package/package.json +1 -1
- package/types/watskeburt.d.ts +29 -48
- package/dist/formatters/format.js +0 -12
package/README.md
CHANGED
@@ -2,21 +2,6 @@
|
|
2
2
|
|
3
3
|
Get changed files & their statuses since any git _revision_
|
4
4
|
|
5
|
-
## what's this do?
|
6
|
-
|
7
|
-
A micro-lib to retrieve an array of file names that were changed since a
|
8
|
-
revision. Also sports a cli for use outside of JavaScript c.s.
|
9
|
-
|
10
|
-
## why?
|
11
|
-
|
12
|
-
I needed something simple and robust to support some upcoming features in
|
13
|
-
[dependency-cruiser](https://github.com/sverweij/dependency-cruiser) and to
|
14
|
-
run standalone to use _in combination_ with dependency-cruiser.
|
15
|
-
|
16
|
-
There are a few specialized packages like this on npm, but it seems they've
|
17
|
-
fallen out of maintenance. More generic packages are still maintained,
|
18
|
-
but for just this simple usage they're a bit overkill.
|
19
|
-
|
20
5
|
## :construction_worker: usage
|
21
6
|
|
22
7
|
### :scroll: API
|
@@ -30,20 +15,23 @@ console.log(await getSHA());
|
|
30
15
|
// list all files that differ between 'main' and the current revision (including
|
31
16
|
// files not staged for commit and files not under revision control)
|
32
17
|
/** @type {import('watskeburt').IChange[]} */
|
33
|
-
const lChangedFiles = await list("main");
|
18
|
+
const lChangedFiles = await list({ oldRevision: "main" });
|
34
19
|
|
35
20
|
// list all files that differ between 'v0.6.1' and 'v0.7.1' (by definition
|
36
21
|
// won't include files staged for commit and/ or not under revision control)
|
37
22
|
/** @type {import('watskeburt').IChange[]} */
|
38
|
-
const lChangedFiles = await list(
|
23
|
+
const lChangedFiles = await list({
|
24
|
+
oldRevision: "v0.6.1",
|
25
|
+
newRevision: "v0.7.1",
|
26
|
+
});
|
39
27
|
|
40
|
-
//
|
41
|
-
// (
|
42
|
-
// a revision and the working tree):
|
28
|
+
// list all files that differ between 'main' and the current revision
|
29
|
+
// (excluding files not staged for commit)
|
43
30
|
/** @type {import('watskeburt').IChange[]|string} */
|
44
|
-
const lChangedFiles = await list(
|
31
|
+
const lChangedFiles = await list({
|
32
|
+
oldRevision: "main",
|
45
33
|
trackedOnly: false, // when set to true leaves out files not under revision control
|
46
|
-
outputType: "
|
34
|
+
outputType: "json", // options: "object", "json" and "regex"
|
47
35
|
});
|
48
36
|
```
|
49
37
|
|
@@ -53,24 +41,23 @@ The array of changes this returns looks like this:
|
|
53
41
|
[
|
54
42
|
{
|
55
43
|
name: "doc/cli.md",
|
56
|
-
|
44
|
+
type: "modified",
|
57
45
|
},
|
58
46
|
{
|
59
47
|
name: "test/thing.spec.mjs",
|
60
|
-
|
48
|
+
type: "renamed",
|
61
49
|
oldName: "test/old-thing.spec.mjs",
|
62
50
|
},
|
63
51
|
{
|
64
52
|
name: "src/not-tracked-yet.mjs",
|
65
|
-
|
53
|
+
type: "untracked",
|
66
54
|
},
|
67
55
|
];
|
68
56
|
```
|
69
57
|
|
70
58
|
### :shell: cli
|
71
59
|
|
72
|
-
|
73
|
-
node >=18.11).
|
60
|
+
Works with node >=18.11
|
74
61
|
|
75
62
|
```shell
|
76
63
|
# list all JavaScript-ish files changed since main in a regular expression
|
@@ -78,19 +65,18 @@ $ npx watskeburt main
|
|
78
65
|
^(src/cli[.]mjs|src/formatters/regex[.]mjs|src/version[.]mjs)$
|
79
66
|
```
|
80
67
|
|
81
|
-
|
82
|
-
source files in the JavaScript ecosystem (.js, .mjs, .ts, .tsx ...)
|
83
|
-
be used in e.g.
|
68
|
+
This emits a regex that contains all changed files that could be
|
69
|
+
source files in the JavaScript ecosystem (.js, .mjs, .ts, .tsx ...). It can
|
70
|
+
be used in e.g. dependency-cruiser's `--focus` and `--reaches` filters.
|
84
71
|
|
85
|
-
The JSON output (
|
86
|
-
also contains other extensions.
|
72
|
+
The JSON output (= the array above, serialized) also contains other extensions.
|
87
73
|
|
88
74
|
```
|
89
75
|
Usage: watskeburt [options] [old-revision] [new-revision]
|
90
76
|
|
91
77
|
lists files & their statuses since [old-revision] or between [old-revision] and [new-revision].
|
92
78
|
|
93
|
-
-> When you don't pass a revision
|
79
|
+
-> When you don't pass a revision old-revision defaults to the current one.
|
94
80
|
|
95
81
|
Options:
|
96
82
|
-T, --outputType <type> what format to emit (choices: "json", "regex", default: "regex")
|
@@ -99,11 +85,19 @@ Options:
|
|
99
85
|
-h, --help display help for command
|
100
86
|
```
|
101
87
|
|
88
|
+
## why?
|
89
|
+
|
90
|
+
I needed something robust to support caching in
|
91
|
+
[dependency-cruiser](https://github.com/sverweij/dependency-cruiser) and to
|
92
|
+
run standalone to use _in combination_ with dependency-cruiser.
|
93
|
+
|
94
|
+
A few specialized packages like this existed, but they had fallen out of
|
95
|
+
maintenance. More generic packages still were maintained, but for my use
|
96
|
+
case they were overkill.
|
97
|
+
|
102
98
|
## 🇳🇱 what does 'watskeburt' mean?
|
103
99
|
|
104
100
|
Wazzup.
|
105
101
|
|
106
102
|
_watskeburt_ is a fast pronunciation of the Dutch "wat is er gebeurd?"
|
107
|
-
(_what has happened?_) or "wat er is gebeurd" (_what has happened_).
|
108
|
-
also the title of a song by the Dutch band "De Jeugd van Tegenwoordig"
|
109
|
-
(_Youth these days_).
|
103
|
+
(_what has happened?_) or "wat er is gebeurd" (_what has happened_).
|
package/dist/cli.js
CHANGED
@@ -6,7 +6,7 @@ const HELP_MESSAGE = `Usage: watskeburt [options] [old-revision] [new-revision]
|
|
6
6
|
|
7
7
|
lists files & their statuses since [old-revision] or between [old-revision] and [new-revision].
|
8
8
|
|
9
|
-
-> When you don't pass a revision
|
9
|
+
-> When you don't pass a revision old-revision defaults to the current one.
|
10
10
|
|
11
11
|
Options:
|
12
12
|
-T, --outputType <type> what format to emit (choices: "json", "regex", default: "regex")
|
@@ -36,11 +36,11 @@ export async function cli(
|
|
36
36
|
process.exitCode = pErrorExitCode;
|
37
37
|
return;
|
38
38
|
}
|
39
|
-
const lResult = await list(
|
40
|
-
lArguments.
|
41
|
-
lArguments.positionals[
|
42
|
-
lArguments.
|
43
|
-
);
|
39
|
+
const lResult = await list({
|
40
|
+
...lArguments.values,
|
41
|
+
oldRevision: lArguments.positionals[0],
|
42
|
+
newRevision: lArguments.positionals[1],
|
43
|
+
});
|
44
44
|
pOutStream.write(`${lResult}${EOL}`);
|
45
45
|
} catch (pError) {
|
46
46
|
pErrorStream.write(`${EOL}ERROR: ${pError.message}${EOL}${EOL}`);
|
@@ -0,0 +1,9 @@
|
|
1
|
+
import formatAsRegex from "./regex.js";
|
2
|
+
import formatAsJSON from "./json.js";
|
3
|
+
const OUTPUT_TYPE_TO_FUNCTION = new Map([
|
4
|
+
["regex", formatAsRegex],
|
5
|
+
["json", formatAsJSON],
|
6
|
+
]);
|
7
|
+
export function format(pChanges, pOutputType) {
|
8
|
+
return OUTPUT_TYPE_TO_FUNCTION.get(pOutputType)(pChanges);
|
9
|
+
}
|
@@ -25,7 +25,7 @@ const DEFAULT_CHANGE_TYPES = new Set([
|
|
25
25
|
"copied",
|
26
26
|
"untracked",
|
27
27
|
]);
|
28
|
-
export default function
|
28
|
+
export default function formatAsRegex(
|
29
29
|
pChanges,
|
30
30
|
pExtensions = DEFAULT_EXTENSIONS,
|
31
31
|
pChangeTypes = DEFAULT_CHANGE_TYPES,
|
@@ -33,7 +33,7 @@ export default function formatToRegex(
|
|
33
33
|
const lChanges = pChanges
|
34
34
|
.filter(
|
35
35
|
(pChange) =>
|
36
|
-
pChangeTypes.has(pChange.
|
36
|
+
pChangeTypes.has(pChange.type) &&
|
37
37
|
pExtensions.has(extname(pChange.name)),
|
38
38
|
)
|
39
39
|
.map(({ name }) => name.replace(/\\/g, "\\\\").replace(/\./g, "[.]"))
|
package/dist/main.js
CHANGED
@@ -1,22 +1,25 @@
|
|
1
1
|
import { parseDiffLines } from "./parse-diff-lines.js";
|
2
2
|
import { parseStatusLines } from "./parse-status-lines.js";
|
3
3
|
import * as primitives from "./git-primitives.js";
|
4
|
-
|
5
|
-
|
6
|
-
const lOldRevision = pOldRevision || (await primitives.getSHA());
|
4
|
+
export async function list(pOptions) {
|
5
|
+
const lOldRevision = pOptions?.oldRevision || (await primitives.getSHA());
|
7
6
|
const lOptions = pOptions || {};
|
8
7
|
const [lDiffLines, lStatusLines] = await Promise.all([
|
9
|
-
primitives.getDiffLines(lOldRevision,
|
8
|
+
primitives.getDiffLines(lOldRevision, pOptions?.newRevision),
|
10
9
|
!lOptions.trackedOnly ? primitives.getStatusShort() : "",
|
11
10
|
]);
|
12
11
|
let lChanges = parseDiffLines(lDiffLines);
|
13
12
|
if (!lOptions.trackedOnly) {
|
14
13
|
lChanges = lChanges.concat(
|
15
14
|
parseStatusLines(lStatusLines).filter(
|
16
|
-
({ changeType }) => changeType === "untracked",
|
15
|
+
({ type: changeType }) => changeType === "untracked",
|
17
16
|
),
|
18
17
|
);
|
19
18
|
}
|
19
|
+
if (!lOptions.outputType) {
|
20
|
+
return lChanges;
|
21
|
+
}
|
22
|
+
const { format } = await import("./format/format.js");
|
20
23
|
return format(lChanges, lOptions.outputType);
|
21
24
|
}
|
22
25
|
export function getSHA() {
|
package/dist/parse-diff-lines.js
CHANGED
@@ -7,15 +7,15 @@ export function parseDiffLines(pString) {
|
|
7
7
|
.split(EOL)
|
8
8
|
.filter(Boolean)
|
9
9
|
.map(parseDiffLine)
|
10
|
-
.filter(
|
10
|
+
.filter(
|
11
|
+
({ name, type: changeType }) => Boolean(name) && Boolean(changeType),
|
12
|
+
);
|
11
13
|
}
|
12
14
|
export function parseDiffLine(pString) {
|
13
15
|
const lMatchResult = pString.match(DIFF_NAME_STATUS_LINE_PATTERN);
|
14
16
|
const lReturnValue = {};
|
15
17
|
if (lMatchResult?.groups) {
|
16
|
-
lReturnValue.
|
17
|
-
lMatchResult.groups.changeType,
|
18
|
-
);
|
18
|
+
lReturnValue.type = changeChar2ChangeType(lMatchResult.groups.changeType);
|
19
19
|
if (lMatchResult.groups.newName) {
|
20
20
|
lReturnValue.name = lMatchResult.groups.newName;
|
21
21
|
lReturnValue.oldName = lMatchResult.groups.name;
|
@@ -7,7 +7,9 @@ export function parseStatusLines(pString) {
|
|
7
7
|
.split(EOL)
|
8
8
|
.filter(Boolean)
|
9
9
|
.map(parseStatusLine)
|
10
|
-
.filter(
|
10
|
+
.filter(
|
11
|
+
({ name, type: changeType }) => Boolean(name) && Boolean(changeType),
|
12
|
+
);
|
11
13
|
}
|
12
14
|
export function parseStatusLine(pString) {
|
13
15
|
const lMatchResult = pString.match(DIFF_SHORT_STATUS_LINE_PATTERN);
|
@@ -19,7 +21,7 @@ export function parseStatusLine(pString) {
|
|
19
21
|
const lUnStagedChangeType = changeChar2ChangeType(
|
20
22
|
lMatchResult.groups.unStagedChangeType,
|
21
23
|
);
|
22
|
-
lReturnValue.
|
24
|
+
lReturnValue.type =
|
23
25
|
lStagedChangeType === "unmodified"
|
24
26
|
? lUnStagedChangeType
|
25
27
|
: lStagedChangeType;
|
package/dist/version.js
CHANGED
@@ -1 +1 @@
|
|
1
|
-
export const VERSION = "
|
1
|
+
export const VERSION = "4.0.0";
|
package/package.json
CHANGED
package/types/watskeburt.d.ts
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
export type
|
1
|
+
export type changeType =
|
2
2
|
| "added"
|
3
3
|
| "copied"
|
4
4
|
| "deleted"
|
@@ -20,86 +20,67 @@ export interface IChange {
|
|
20
20
|
/**
|
21
21
|
* how the file was changed
|
22
22
|
*/
|
23
|
-
|
23
|
+
type: changeType;
|
24
24
|
/**
|
25
25
|
* if the file was renamed: what the old file's name was
|
26
26
|
*/
|
27
27
|
oldName?: string;
|
28
28
|
}
|
29
29
|
|
30
|
-
export type outputTypeType = "regex" | "json"
|
30
|
+
export type outputTypeType = "regex" | "json";
|
31
31
|
|
32
|
-
export interface
|
32
|
+
export interface IBaseOptions {
|
33
33
|
/**
|
34
|
-
* The
|
35
|
-
*
|
34
|
+
* The revision against which to compare. When not passed defaults to the
|
35
|
+
* _current_ commit hash (if there's any)
|
36
36
|
*/
|
37
|
-
|
37
|
+
oldRevision?: string;
|
38
|
+
/**
|
39
|
+
* Newer revision against which to compare. Leave out when you want to
|
40
|
+
* compare against the working tree
|
41
|
+
*/
|
42
|
+
newRevision?: string;
|
38
43
|
/**
|
39
|
-
* When true
|
40
|
-
* When false also takes untracked files into account
|
41
|
-
*
|
42
|
-
* Defaults to false.
|
44
|
+
* When true only takes already tracked files into account.
|
45
|
+
* When false also takes untracked files into account (default)
|
43
46
|
*/
|
44
47
|
trackedOnly?: boolean;
|
45
48
|
}
|
46
49
|
|
47
|
-
export interface
|
50
|
+
export interface IFormatOptions extends IBaseOptions {
|
48
51
|
/**
|
49
|
-
* The type of output to deliver.
|
50
|
-
* the listSync function returns an IChange[] object
|
52
|
+
* The type of output to deliver.
|
51
53
|
*/
|
52
|
-
outputType
|
54
|
+
outputType: "regex" | "json";
|
55
|
+
}
|
56
|
+
|
57
|
+
export interface IInternalOptions extends IBaseOptions {
|
53
58
|
/**
|
54
|
-
*
|
55
|
-
*
|
56
|
-
*
|
57
|
-
* Defaults to false.
|
59
|
+
* The type of output to deliver. undefined/ left out
|
60
|
+
* the outputType defaults to a list of `IChange`s
|
58
61
|
*/
|
59
|
-
|
62
|
+
outputType?: undefined;
|
60
63
|
}
|
61
64
|
|
62
65
|
export type IOptions = IFormatOptions | IInternalOptions;
|
63
66
|
|
64
67
|
/**
|
65
|
-
*
|
68
|
+
* promises a list of files changed since pOldRevision.
|
66
69
|
*
|
67
|
-
* @param pOldRevision The revision against which to compare. E.g. a commit-hash,
|
68
|
-
* a branch or a tag. When not passed defaults to the _current_
|
69
|
-
* commit hash (if there's any)
|
70
|
-
* @param pNewRevision Newer revision against which to compare. Leave out or pass
|
71
|
-
* null when you want to compare against the working tree
|
72
|
-
* @param pOptions Options that influence how the changes are returned and that
|
73
|
-
* filter what is returned and
|
74
70
|
* @throws {Error}
|
75
71
|
*/
|
76
|
-
export function list(
|
77
|
-
pOldRevision?: string,
|
78
|
-
pNewRevision?: string,
|
79
|
-
pOptions?: IInternalOptions,
|
80
|
-
): Promise<IChange[]>;
|
72
|
+
export function list(pOptions?: IInternalOptions): Promise<IChange[]>;
|
81
73
|
|
82
74
|
/**
|
83
|
-
*
|
84
|
-
* string as a pOptions.outputType
|
75
|
+
* promises a list of files changed since pOldRevision, formatted
|
76
|
+
* into a string as a pOptions.outputType
|
85
77
|
*
|
86
|
-
* @param pOldRevision The revision against which to compare. E.g. a commit-hash,
|
87
|
-
* a branch or a tag. When not passed defaults to the _current_
|
88
|
-
* commit hash (if there's any)
|
89
|
-
* @param pNewRevision Newer revision against which to compare. Leave out or pass
|
90
|
-
* null when you want to compare against the working tree
|
91
|
-
* @param pOptions Options that influence how the changes are returned and that
|
92
|
-
* filter what is returned and
|
93
78
|
* @throws {Error}
|
94
79
|
*/
|
95
|
-
export function list(
|
96
|
-
pOldRevision?: string,
|
97
|
-
pNewRevision?: string,
|
98
|
-
pOptions?: IFormatOptions,
|
99
|
-
): Promise<string>;
|
80
|
+
export function list(pOptions?: IFormatOptions): Promise<string>;
|
100
81
|
|
101
82
|
/**
|
102
|
-
*
|
83
|
+
* Promises the SHA1 of the current HEAD
|
103
84
|
*
|
104
85
|
* @throws {Error}
|
105
86
|
*/
|
@@ -1,12 +0,0 @@
|
|
1
|
-
import formatToRegex from "./regex.js";
|
2
|
-
import formatToJSON from "./json.js";
|
3
|
-
const identity = (pX) => pX;
|
4
|
-
const OUTPUT_TYPE_TO_FUNCTION = new Map([
|
5
|
-
["regex", formatToRegex],
|
6
|
-
["json", formatToJSON],
|
7
|
-
]);
|
8
|
-
export default function format(pChanges, pOutputType) {
|
9
|
-
return (OUTPUT_TYPE_TO_FUNCTION.get(pOutputType ?? "unknown") || identity)(
|
10
|
-
pChanges,
|
11
|
-
);
|
12
|
-
}
|