forked from todogroup/repolinter
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathgit-list-tree.js
More file actions
97 lines (83 loc) · 2.5 KB
/
git-list-tree.js
File metadata and controls
97 lines (83 loc) · 2.5 KB
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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
// Copyright 2017 TODO Group. All rights reserved.
// SPDX-License-Identifier: Apache-2.0
const spawnSync = require('child_process').spawnSync
const Result = require('../lib/result')
// eslint-disable-next-line no-unused-vars
const FileSystem = require('../lib/file_system')
function gitAllCommits(targetDir) {
const args = ['-C', targetDir, 'rev-list', '--all']
return spawnSync('git', args).stdout.toString().split('\n')
}
/**
* @param targetDir
* @param commit
* @ignore
*/
function gitFilesAtCommit(targetDir, commit) {
const args = ['-C', targetDir, 'ls-tree', '-r', '--name-only', commit]
return spawnSync('git', args).stdout.toString().split('\n')
}
/**
* @param fileSystem
* @param options
* @ignore
*/
function listFiles(fileSystem, options) {
const files = []
const pattern = new RegExp(
'(' + options.denylist.join('|') + ')',
options.ignoreCase ? 'i' : ''
)
const commits = gitAllCommits(fileSystem.targetDir)
commits.forEach(commit => {
const includedFiles = gitFilesAtCommit(fileSystem.targetDir, commit)
.filter(file => file.match(pattern))
.filter(file => fileSystem.shouldInclude(file))
includedFiles.forEach(path => {
const existingFile = files.find(f => f.path === path)
if (existingFile) {
existingFile.commits.push(commit)
} else {
files.push({ path: path, commits: [commit] })
}
})
})
return files
}
/**
*
* @param {FileSystem} fs A filesystem object configured with filter paths and target directories
* @param {object} options The rule configuration
* @returns {Result} The lint rule result
* @ignore
*/
function gitListTree(fs, options) {
// backwards compatibility with blacklist
options.denylist = options.denylist || options.blacklist
const files = listFiles(fs, options)
const targets = files.map(file => {
const [firstCommit, ...rest] = file.commits
const restMessage =
rest.length > 0 ? `, and ${rest.length} more commits` : ''
const message = [
`denylisted path (${file.path}) found in commit ${firstCommit.substr(
0,
7
)}${restMessage}.`,
`\tdenylist: ${options.denylist.join(', ')}`
].join('\n')
return {
passed: false,
path: file.path,
message
}
})
if (targets.length === 0) {
const message = `No denylisted paths found in any commits.\n\tdenylist: ${options.denylist.join(
', '
)}`
return new Result(message, [], true)
}
return new Result('', targets, false)
}
module.exports = gitListTree