watskeburt 0.5.0 → 0.5.1
Sign up to get free protection for your applications and to get access to all the features.
- package/README.md +61 -47
- package/dist/cjs-bundle.js +1 -1
- package/package.json +18 -15
- package/src/formatters/regex.mjs +31 -22
- package/src/version.mjs +1 -1
- package/types/watskeburt.d.ts +1 -1
package/README.md
CHANGED
@@ -1,29 +1,67 @@
|
|
1
1
|
# watskeburt
|
2
2
|
|
3
|
-
|
3
|
+
Get changed files & their statuses since any git _revision_
|
4
4
|
|
5
5
|
## what's this do?
|
6
6
|
|
7
|
-
A micro-lib to retrieve an array of file names that were changed
|
8
|
-
|
9
|
-
sports a cli for use outside of JavaScript c.s.
|
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.
|
10
9
|
|
11
|
-
- :warning:
|
12
|
-
tested + it's using itself - but a bunch of static analysis and a bit of
|
13
|
-
automation still needs be added.
|
14
|
-
- :warning: Interface is stable-ish, but can can change until 1.0.0 is published
|
15
|
-
- :warning: expect some rough edges for e.g. error scenarios
|
10
|
+
- :warning: Interface is stable, but can can change until 1.0.0 is published :warning:
|
16
11
|
|
17
12
|
## why?
|
18
13
|
|
19
|
-
|
20
|
-
|
14
|
+
I needed something simple and robust to support some upcoming features in
|
15
|
+
[dependency-cruiser](https://github.com/sverweij/dependency-cruiser) and to
|
16
|
+
run standalone to use _in combination_ with dependency-cruiser.
|
21
17
|
|
22
|
-
There are a few packages like
|
23
|
-
fallen out of maintenance. More generic packages
|
18
|
+
There are a few specialized packages like this on npm, but it seems they've
|
19
|
+
fallen out of maintenance. More generic packages are still maintained,
|
24
20
|
but for just this simple usage they're a bit overkill.
|
25
21
|
|
26
|
-
## usage
|
22
|
+
## :construction_worker: usage
|
23
|
+
|
24
|
+
### :scroll: API
|
25
|
+
|
26
|
+
```javascript
|
27
|
+
// const { list } = require('watskeburt'); // will work in commonjs contexts as well
|
28
|
+
import { list, getSHA } from "watskeburt";
|
29
|
+
|
30
|
+
// print the SHA1 of the current HEAD
|
31
|
+
console.log(getSHA());
|
32
|
+
|
33
|
+
// list all files that differ between 'main' and the current revision (including
|
34
|
+
// files not staged for commit and files not under revision control)
|
35
|
+
/** @type {import('watskeburt').IChange[]} */
|
36
|
+
const lChangedFiles = list("main");
|
37
|
+
|
38
|
+
// As a second parameter you can pass some options:
|
39
|
+
/** @type {import('watskeburt').IChange[]|string} */
|
40
|
+
const lChangedFiles = list("main", {
|
41
|
+
trackedOnly: false, // when set to true leaves out files not under revision control
|
42
|
+
outputType: "object", // other options: "json" and "regex" (as used in the CLI)
|
43
|
+
});
|
44
|
+
```
|
45
|
+
|
46
|
+
The array of changes this returns looks like this:
|
47
|
+
|
48
|
+
```javascript
|
49
|
+
[
|
50
|
+
{
|
51
|
+
name: "doc/cli.md",
|
52
|
+
changeType: "modified",
|
53
|
+
},
|
54
|
+
{
|
55
|
+
name: "test/thing.spec.mjs",
|
56
|
+
changeType: "renamed",
|
57
|
+
oldName: "test/old-thing.spec.mjs",
|
58
|
+
},
|
59
|
+
{
|
60
|
+
name: "src/not-tracked-yet.mjs",
|
61
|
+
changeType: "untracked",
|
62
|
+
},
|
63
|
+
];
|
64
|
+
```
|
27
65
|
|
28
66
|
### :shell: cli
|
29
67
|
|
@@ -37,7 +75,10 @@ $ npx watskeburt main
|
|
37
75
|
|
38
76
|
By default this returns a regex that contains all changed files that could be
|
39
77
|
source files in the JavaScript ecosystem (.js, .mjs, .ts, .tsx ...) that can
|
40
|
-
be used in e.g. the `--focus`
|
78
|
+
be used in e.g. the `--focus` and `--reaches` filters of dependency-cruiser.
|
79
|
+
|
80
|
+
The JSON output (which looks a lot like the array above) is unfiltered and
|
81
|
+
also contains other extensions.
|
41
82
|
|
42
83
|
```
|
43
84
|
Usage: cli [options] [revision]
|
@@ -53,36 +94,9 @@ Options:
|
|
53
94
|
-h, --help display help for command
|
54
95
|
```
|
55
96
|
|
56
|
-
|
57
|
-
|
58
|
-
```javascript
|
59
|
-
// const { list } = require('watskeburt'); // will work in commonjs contexts as well
|
60
|
-
import { list, getSHA } from "watskeburt";
|
61
|
-
|
62
|
-
// print the SHA1 of the current HEAD
|
63
|
-
console.log(getSHA());
|
64
|
-
|
65
|
-
// list all files that differ between 'main' and
|
66
|
-
/** @type {import('watskeburt').IChange[]} */
|
67
|
-
const lChangedFiles = list("main");
|
68
|
-
```
|
69
|
-
|
70
|
-
An array of changes looks something like this:
|
71
|
-
|
72
|
-
```javascript
|
73
|
-
[
|
74
|
-
{ name: "doc/cli.md", changeType: "modified" },
|
75
|
-
{
|
76
|
-
name: "test/thing.spec.mjs",
|
77
|
-
changeType: "renamed",
|
78
|
-
oldName: "test/old-thing.spec.mjs",
|
79
|
-
},
|
80
|
-
{ name: "src/not-tracked-yet.mjs", changeType: "untracked" },
|
81
|
-
];
|
82
|
-
```
|
83
|
-
|
84
|
-
## 🇳🇱 'watskeburt'??
|
97
|
+
## 🇳🇱 what does 'watskeburt' mean?
|
85
98
|
|
86
|
-
_watskeburt_ is a fast pronunciation of the Dutch
|
87
|
-
(
|
88
|
-
"De Jeugd van Tegenwoordig"
|
99
|
+
_watskeburt_ is a fast pronunciation of the Dutch "wat is er gebeurd?"
|
100
|
+
(_what has happened?_) or "wat er is gebeurd" (_what has happened_). It's
|
101
|
+
also the title of a song by the Dutch band "De Jeugd van Tegenwoordig"
|
102
|
+
(_Youth these days..._).
|
package/dist/cjs-bundle.js
CHANGED
@@ -1 +1 @@
|
|
1
|
-
var a=Object.defineProperty;var
|
1
|
+
"use strict";var a=Object.defineProperty;var x=Object.getOwnPropertyDescriptor;var y=Object.getOwnPropertyNames;var A=Object.prototype.hasOwnProperty;var C=(e,t)=>{for(var n in t)a(e,n,{get:t[n],enumerable:!0})},_=(e,t,n,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of y(t))!A.call(e,r)&&r!==n&&a(e,r,{get:()=>t[r],enumerable:!(o=x(t,r))||o.enumerable});return e};var D=e=>_(a({},"__esModule",{value:!0}),e);var I={};C(I,{getSHA:()=>E,list:()=>F});module.exports=D(I);var u=require("os"),L=/^(?<changeType>[ACDMRTUXB])(?<similarity>[0-9]{3})?[ \t]+(?<name>[^ \t]+)[ \t]*(?<newName>[^ \t]+)?$/,R=/^(?<stagedChangeType>[ ACDMRTUXB?!])(?<unStagedChangeType>[ ACDMRTUXB?!])[ \t]+(?<name>[^ \t]+)(( -> )(?<newName>[^ \t]+))?$/,U={A:"added",C:"copied",D:"deleted",M:"modified",R:"renamed",T:"type changed",U:"unmerged",B:"pairing broken"," ":"unmodified","?":"untracked","!":"ignored"};function i(e){return U[e]||"unknown"}function O(e){let t=e.match(R),n={};if(t){let o=i(t.groups.stagedChangeType),r=i(t.groups.unStagedChangeType);n.changeType=o==="unmodified"?r:o,t.groups.newName?(n.name=t.groups.newName,n.oldName=t.groups.name):n.name=t.groups.name}return n}function v(e){let t=e.match(L),n={};return t&&(n.changeType=i(t.groups.changeType),t.groups.newName?(n.name=t.groups.newName,n.oldName=t.groups.name):n.name=t.groups.name),n}function m(e){return e.split(u.EOL).filter(Boolean).map(O).filter(({changeType:t})=>Boolean(t))}function g(e){return e.split(u.EOL).filter(Boolean).map(v).filter(({changeType:t})=>Boolean(t))}var s=require("child_process");function d(e){return e instanceof Buffer?e.toString("utf8"):e}function j(e){throw e.code==="ENOENT"?new Error("git executable not found"):new Error(`internal spawn error: ${e}`)}function c(e,t,n){let o=n("git",e,{cwd:process.cwd(),env:process.env});if(o.error&&j(o.error),o.status===0)return d(o.stdout);throw new Error(t[o.status]||`internal git error: ${o.status} (${d(o.stderr)})`)}function T(e=s.spawnSync){let t={129:`'${process.cwd()}' does not seem to be a git repository`};return c(["status","--porcelain"],t,e)}function h(e,t=s.spawnSync){let n={128:`revision '${e}' unknown `,129:`'${process.cwd()}' does not seem to be a git repository`};return c(["diff",e,"--name-status"],n,t)}function S(e=s.spawnSync){return c(["rev-parse","HEAD"],{},e).slice(0,40)}var N=require("path"),$=new Set([".cjs",".cjsx",".coffee",".csx",".js",".json",".jsx",".litcoffee",".ls",".mjs",".svelte",".ts",".tsx",".vue",".vuex"]),B=new Set(["modified","added","renamed","copied","untracked"]);function f(e,t=$,n=B){return`^(${e.filter(r=>n.has(r.changeType)).map(({name:r})=>r).filter(r=>t.has((0,N.extname)(r))).join("|")})$`}function p(e){return JSON.stringify(e,null,2)}var H={regex:f,json:p,object:e=>e},M="object";function l(e,t){return H[t||M](e)}function E(){return S()}function F(e,t){let n=e||E(),o=g(h(n)),r=t||{};return r.trackedOnly||(o=o.concat(m(T()).filter(({changeType:w})=>w==="untracked"))),l(o,r.outputType)}0&&(module.exports={getSHA,list});
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "watskeburt",
|
3
|
-
"version": "0.5.
|
3
|
+
"version": "0.5.1",
|
4
4
|
"description": "List files changed since a git revision",
|
5
5
|
"keywords": [
|
6
6
|
"git",
|
@@ -47,19 +47,21 @@
|
|
47
47
|
"commander": "^9.3.0"
|
48
48
|
},
|
49
49
|
"devDependencies": {
|
50
|
-
"@
|
51
|
-
"
|
52
|
-
"
|
53
|
-
"
|
54
|
-
"
|
50
|
+
"@types/mocha": "^9.1.1",
|
51
|
+
"@types/node": "^18.0.6",
|
52
|
+
"@typescript-eslint/eslint-plugin": "^5.30.7",
|
53
|
+
"c8": "^7.12.0",
|
54
|
+
"dependency-cruiser": "^11.12.0",
|
55
|
+
"esbuild": "^0.14.49",
|
56
|
+
"eslint": "^8.20.0",
|
55
57
|
"eslint-config-moving-meadow": "^3.0.0",
|
56
58
|
"eslint-config-prettier": "^8.5.0",
|
57
59
|
"eslint-plugin-budapestian": "^4.0.0",
|
58
60
|
"eslint-plugin-import": "^2.26.0",
|
59
|
-
"eslint-plugin-mocha": "^10.0
|
61
|
+
"eslint-plugin-mocha": "^10.1.0",
|
60
62
|
"eslint-plugin-node": "^11.1.0",
|
61
63
|
"eslint-plugin-security": "^1.5.0",
|
62
|
-
"eslint-plugin-unicorn": "^43.0.
|
64
|
+
"eslint-plugin-unicorn": "^43.0.2",
|
63
65
|
"mocha": "^10.0.0",
|
64
66
|
"npm-run-all": "^4.1.5",
|
65
67
|
"prettier": "^2.7.1",
|
@@ -76,21 +78,22 @@
|
|
76
78
|
"clean": "rm -rf dist",
|
77
79
|
"test": "mocha \"src/**/*.spec.mjs\"",
|
78
80
|
"test:cover": "c8 --check-coverage --statements 100 --branches 100 --functions 100 --lines 100 --exclude \"**/*.spec.mjs\" --reporter text-summary --reporter html --reporter json-summary npm test",
|
79
|
-
"depcruise": "depcruise src --config",
|
80
|
-
"depcruise:graph": "depcruise src --include-only '^(src)' --config --output-type dot | dot -T svg | tee docs/dependency-graph.svg | depcruise-wrap-stream-in-html > docs/dependency-graph.html",
|
81
|
+
"depcruise": "depcruise src types --config",
|
82
|
+
"depcruise:graph": "depcruise src types --include-only '^(src|types)' --config --output-type dot | dot -T svg | tee docs/dependency-graph.svg | depcruise-wrap-stream-in-html > docs/dependency-graph.html",
|
81
83
|
"depcruise:graph:archi": "depcruise src --include-only '^(src)' --config --output-type archi | dot -T svg | depcruise-wrap-stream-in-html > docs/high-level-dependency-graph.html",
|
82
84
|
"depcruise:graph:dev": "depcruise src --include-only '^(src)' --prefix vscode://file/$(pwd)/ --config --output-type dot | dot -T svg | depcruise-wrap-stream-in-html | browser",
|
83
|
-
"depcruise:graph:diff:dev": "depcruise src --include-only '^(src)' --focus \"$(node src/cli.mjs main -T regex)\" --prefix vscode://file/$(pwd)/ --config --output-type dot | dot -T svg | depcruise-wrap-stream-in-html | browser",
|
84
|
-
"depcruise:graph:diff:mermaid": "depcruise src --include-only '^(src)' --config --output-type mermaid --output-to - --focus \"$(node src/cli.mjs $SHA -T regex)\"",
|
85
|
+
"depcruise:graph:diff:dev": "depcruise src types --include-only '^(src|types)' --focus \"$(node src/cli.mjs main -T regex)\" --focus-depth 0 --prefix vscode://file/$(pwd)/ --config --output-type dot | dot -T svg | depcruise-wrap-stream-in-html | browser",
|
86
|
+
"depcruise:graph:diff:mermaid": "depcruise src types --include-only '^(src|types)' --config --output-type mermaid --output-to - --focus \"$(node src/cli.mjs $SHA -T regex)\" --focus-depth 0",
|
85
87
|
"depcruise:html": "depcruise src --progress --config --output-type err-html --output-to dependency-violation-report.html",
|
86
88
|
"depcruise:text": "depcruise src --progress --config --output-type text",
|
87
89
|
"depcruise:focus": "depcruise src --progress --config --output-type text --focus",
|
88
|
-
"lint": "npm-run-all --parallel --aggregate-output lint:format lint:eslint",
|
90
|
+
"lint": "npm-run-all --parallel --aggregate-output lint:format lint:eslint lint:types",
|
89
91
|
"lint:fix": "npm-run-all --parallel --aggregate-output lint:format:fix lint:eslint:fix",
|
90
|
-
"lint:eslint": "eslint src --cache --cache-location node_modules/.cache/eslint/",
|
91
|
-
"lint:eslint:fix": "eslint src tools --fix --cache --cache-location node_modules/.cache/eslint/",
|
92
|
+
"lint:eslint": "eslint src types tools --cache --cache-location node_modules/.cache/eslint/",
|
93
|
+
"lint:eslint:fix": "eslint src types tools --fix --cache --cache-location node_modules/.cache/eslint/",
|
92
94
|
"lint:format": "prettier --check \"{src,tools}/**/*.mjs\" \"types/**/*.ts\" \"*.{json,yml,md,js}\"",
|
93
95
|
"lint:format:fix": "prettier --loglevel warn --write \"{src,tools}/**/*.mjs\" \"types/**/*.ts\" \"*.{json,yml,md,js}\"",
|
96
|
+
"lint:types": "tsc",
|
94
97
|
"scm:stage": "git add .",
|
95
98
|
"version": "npm-run-all --sequential clean build lint depcruise:graph scm:stage"
|
96
99
|
},
|
package/src/formatters/regex.mjs
CHANGED
@@ -1,37 +1,46 @@
|
|
1
1
|
import { extname } from "node:path";
|
2
2
|
|
3
|
+
const DEFAULT_EXTENSIONS = new Set([
|
4
|
+
".cjs",
|
5
|
+
".cjsx",
|
6
|
+
".coffee",
|
7
|
+
".csx",
|
8
|
+
".js",
|
9
|
+
".json",
|
10
|
+
".jsx",
|
11
|
+
".litcoffee",
|
12
|
+
".ls",
|
13
|
+
".mjs",
|
14
|
+
".svelte",
|
15
|
+
".ts",
|
16
|
+
".tsx",
|
17
|
+
".vue",
|
18
|
+
".vuex",
|
19
|
+
]);
|
20
|
+
|
21
|
+
const DEFAULT_CHANGE_TYPES = new Set([
|
22
|
+
"modified",
|
23
|
+
"added",
|
24
|
+
"renamed",
|
25
|
+
"copied",
|
26
|
+
"untracked",
|
27
|
+
]);
|
3
28
|
/**
|
4
29
|
*
|
5
30
|
* @param {import('../types/watskeburt').IChange[]} pChanges
|
6
|
-
* @param {string
|
7
|
-
* @param {import('../types/watskeburt').changeTypeType
|
31
|
+
* @param {Set<string>} pExtensions
|
32
|
+
* @param {Set<import('../types/watskeburt').changeTypeType>} pChangeTypes
|
8
33
|
* @return {string}
|
9
34
|
*/
|
10
35
|
export default function formatToRegex(
|
11
36
|
pChanges,
|
12
|
-
pExtensions =
|
13
|
-
|
14
|
-
".mjs",
|
15
|
-
".cjs",
|
16
|
-
".json",
|
17
|
-
".jsx",
|
18
|
-
".ts",
|
19
|
-
".tsx",
|
20
|
-
".vue",
|
21
|
-
".vuex",
|
22
|
-
".svelte",
|
23
|
-
".coffee",
|
24
|
-
".litcoffee",
|
25
|
-
".csx",
|
26
|
-
".cjsx",
|
27
|
-
".ls",
|
28
|
-
],
|
29
|
-
pChangeTypes = ["modified", "added", "renamed", "copied", "untracked"]
|
37
|
+
pExtensions = DEFAULT_EXTENSIONS,
|
38
|
+
pChangeTypes = DEFAULT_CHANGE_TYPES
|
30
39
|
) {
|
31
40
|
const lChanges = pChanges
|
32
|
-
.filter((pChange) => pChangeTypes.
|
41
|
+
.filter((pChange) => pChangeTypes.has(pChange.changeType))
|
33
42
|
.map(({ name }) => name)
|
34
|
-
.filter((pName) => pExtensions.
|
43
|
+
.filter((pName) => pExtensions.has(extname(pName)))
|
35
44
|
// .replace(/\./g, "\\\\.")
|
36
45
|
.join("|");
|
37
46
|
return `^(${lChanges})$`;
|
package/src/version.mjs
CHANGED
@@ -1 +1 @@
|
|
1
|
-
export const VERSION = "0.5.
|
1
|
+
export const VERSION = "0.5.1";
|
package/types/watskeburt.d.ts
CHANGED
@@ -47,7 +47,7 @@ export interface IOptions {
|
|
47
47
|
/**
|
48
48
|
* returns a list of files changed since pOldRevision.
|
49
49
|
*
|
50
|
-
* @param pOldRevision
|
50
|
+
* @param pOldRevision The revision against which to compare. E.g. a commit-hash,
|
51
51
|
* a branch or a tag. When not passed defaults to the _current_
|
52
52
|
* commit hash (if there's any)
|
53
53
|
* @param pOptions Options that influence how the changes are returned and that
|