Skip to content

Commit d926b06

Browse files
committed
Initial code
1 parent a816768 commit d926b06

File tree

4 files changed

+91
-0
lines changed

4 files changed

+91
-0
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,3 +102,4 @@ dist
102102

103103
# TernJS port file
104104
.tern-port
105+
package-lock.json

package.json

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
"name": "status-matrix",
3+
"version": "0.0.0",
4+
"description": "",
5+
"engines": {
6+
"node": ">15"
7+
},
8+
"main": "statusMatrix.mjs",
9+
"scripts": {
10+
"test": "node test.mjs"
11+
},
12+
"keywords": [],
13+
"author": "William Hilton <[email protected]>",
14+
"license": "MIT",
15+
"dependencies": {
16+
"isomorphic-git": "^1.0.0"
17+
}
18+
}

statusMatrix.mjs

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
import { STAGE, TREE, WORKDIR, walk } from 'isomorphic-git'
2+
3+
export function statusMatrix({
4+
fs,
5+
dir,
6+
gitdir = dir + '/.git',
7+
ref = 'HEAD',
8+
filepaths = ['.'],
9+
filter = (filepath) => true,
10+
cache = {},
11+
}) {
12+
return walk({
13+
fs,
14+
cache,
15+
dir,
16+
gitdir,
17+
trees: [TREE({ ref }), WORKDIR(), STAGE()],
18+
map: async function(filepath, [head, workdir, stage]) {
19+
// match against base paths
20+
if (!filepaths.some(base => worthWalking(filepath, base))) {
21+
return null
22+
}
23+
// Late filter against file names
24+
if (filter) {
25+
if (!filter(filepath)) return
26+
}
27+
28+
// For now, just bail on directories
29+
const headType = head && (await head.type())
30+
if (headType === 'tree' || headType === 'special') return
31+
if (headType === 'commit') return null
32+
33+
const workdirType = workdir && (await workdir.type())
34+
if (workdirType === 'tree' || workdirType === 'special') return
35+
36+
const stageType = stage && (await stage.type())
37+
if (stageType === 'commit') return null
38+
if (stageType === 'tree' || stageType === 'special') return
39+
40+
// Figure out the oids, using the staged oid for the working dir oid if the stats match.
41+
const headOid = head ? await head.oid() : undefined
42+
const stageOid = stage ? await stage.oid() : undefined
43+
let workdirOid
44+
if (!head && workdir && !stage) {
45+
// We don't actually NEED the sha. Any sha will do
46+
// TODO: update this logic to handle N trees instead of just 3.
47+
workdirOid = '42'
48+
} else if (workdir) {
49+
workdirOid = await workdir.oid()
50+
}
51+
const entry = [undefined, headOid, workdirOid, stageOid]
52+
const result = entry.map(value => entry.indexOf(value))
53+
result.shift() // remove leading undefined entry
54+
return [filepath, ...result]
55+
},
56+
})
57+
}
58+
59+
const worthWalking = (filepath, root) => {
60+
if (filepath === '.' || root == null || root.length === 0 || root === '.') {
61+
return true
62+
}
63+
if (root.length >= filepath.length) {
64+
return root.startsWith(filepath)
65+
} else {
66+
return filepath.startsWith(root)
67+
}
68+
}

test.mjs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
import { statusMatrix } from './statusMatrix.mjs'
2+
import * as fs from 'fs';
3+
4+
console.log(await statusMatrix({ fs, dir: '.' }))

0 commit comments

Comments
 (0)