forked from beaugunderson/codeowners
-
Notifications
You must be signed in to change notification settings - Fork 0
/
codeowners.js
executable file
·75 lines (60 loc) · 2.05 KB
/
codeowners.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
// @ts-check
'use strict';
const findUp = require('find-up');
const fs = require('fs');
const ignore = require('ignore');
const isDirectory = require('is-directory');
const path = require('path');
const trueCasePath = require('true-case-path');
function ownerMatcher(pathString) {
const matcher = ignore().add(pathString);
return matcher.ignores.bind(matcher);
}
function Codeowners(currentPath, fileName = 'CODEOWNERS') {
if (!currentPath) {
currentPath = process.cwd();
}
this.codeownersFilePath = trueCasePath(findUp.sync([
`.github/${fileName}`, `.gitlab/${fileName}`, `docs/${fileName}`, `${fileName}`
], {cwd: currentPath}));
this.codeownersDirectory = path.dirname(this.codeownersFilePath);
// We might have found a bare codeowners file or one inside the three supported subdirectories.
// In the latter case the project root is up another level.
if (this.codeownersDirectory.match(/\/(.github|.gitlab|docs)$/i)) {
this.codeownersDirectory = path.dirname(this.codeownersDirectory);
}
const codeownersFile = path.basename(this.codeownersFilePath);
if (codeownersFile !== fileName) {
throw new Error(`Found a ${fileName} file but it was lower-cased: ${this.codeownersFilePath}`);
}
if (isDirectory.sync(this.codeownersFilePath)) {
throw new Error(`Found a ${fileName} but it's a directory: ${this.codeownersFilePath}`);
}
const lines = fs.readFileSync(this.codeownersFilePath).toString().split('\n');
const ownerEntries = [];
for (const line of lines) {
if (!line) {
continue;
}
if (line.startsWith('#')) {
continue;
}
const [pathString, ...usernames] = line.split(/\s+/);
ownerEntries.push({
path: pathString,
usernames: usernames,
match: ownerMatcher(pathString)
});
}
this.ownerEntries = ownerEntries;
}
Codeowners.prototype.getOwner = function (filePath) {
let owners = [];
for (const entry of this.ownerEntries) {
if (entry.match(filePath)) {
owners = entry.usernames;
}
}
return owners.slice();
};
module.exports = Codeowners;