-
Notifications
You must be signed in to change notification settings - Fork 241
/
scanner.go
100 lines (88 loc) · 2.72 KB
/
scanner.go
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
98
99
100
package scanner
import (
"log"
"os/exec"
"strings"
"talisman/gitrepo"
"talisman/utility"
"os"
"github.com/sirupsen/logrus"
)
type blobDetails struct {
hash, filePath string
}
// BlobsInCommits is a map of blob and list of the commits the blobs is present in.
type BlobsInCommits struct {
commits map[blobDetails][]string
}
// GetAdditions will get all the additions for entire git history
func GetAdditions(ignoreHistory bool, br gitrepo.BatchReader) []gitrepo.Addition {
blobsInCommits := getBlobsInCommit(ignoreHistory)
var additions []gitrepo.Addition
err := br.Start()
if err != nil {
logrus.Errorf("error creating file reader %v", err)
}
defer func() {
err = br.Shutdown()
if err != nil {
logrus.Errorf("error creating file reader %v", err)
}
}()
for blob := range blobsInCommits.commits {
contents, _ := br.Read(blob.hash)
newAddition := gitrepo.NewScannerAddition(blob.filePath, blobsInCommits.commits[blob], contents)
additions = append(additions, newAddition)
}
return additions
}
func getBlobsInCommit(ignoreHistory bool) BlobsInCommits {
progressBar := utility.GetProgressBar(os.Stdout, "Talisman Fetch Blobs")
commits := getAllCommits(ignoreHistory)
progressBar.Start(len(commits) - 1)
blobsInCommits := newBlobsInCommit()
result := make(chan []string, len(commits))
for _, commit := range commits {
go putBlobsInChannel(commit, result)
}
for i := 1; i < len(commits); i++ {
progressBar.Increment()
getBlobsFromChannel(blobsInCommits, result)
}
progressBar.Finish()
return blobsInCommits
}
func putBlobsInChannel(commit string, result chan []string) {
if commit != "" {
blobDetailsBytes, _ := exec.Command("git", "ls-tree", "-r", commit).CombinedOutput()
blobDetailsList := strings.Split(string(blobDetailsBytes), "\n")
blobDetailsList = append(blobDetailsList, commit)
result <- blobDetailsList
}
}
func getBlobsFromChannel(blobsInCommits BlobsInCommits, result chan []string) {
blobEntries := <-result
commit := blobEntries[len(blobEntries)-1]
for _, blobEntry := range blobEntries[:len(blobEntries)-1] {
if blobEntry != "" {
blobHashAndName := strings.Split(strings.Split(blobEntry, " ")[2], "\t")
blob := blobDetails{hash: blobHashAndName[0], filePath: blobHashAndName[1]}
blobsInCommits.commits[blob] = append(blobsInCommits.commits[blob], commit)
}
}
}
func getAllCommits(ignoreHistory bool) []string {
commitRange := "--all"
if ignoreHistory {
commitRange = "--max-count=1"
}
out, err := exec.Command("git", "log", commitRange, "--pretty=%H").CombinedOutput()
if err != nil {
log.Fatal(err)
}
return strings.Split(string(out), "\n")
}
func newBlobsInCommit() BlobsInCommits {
commits := make(map[blobDetails][]string)
return BlobsInCommits{commits: commits}
}