-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathscan.go
More file actions
146 lines (126 loc) · 3.32 KB
/
scan.go
File metadata and controls
146 lines (126 loc) · 3.32 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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
package main
import (
"bufio"
"fmt"
"io"
"log"
"os"
"os/user"
"strings"
)
// openFile opens a file located at 'filePath' and creates it if it doesn't exist
func openFile(filepath string) *os.File{
f , err := os.OpenFile(filepath , os.O_APPEND | os.O_WRONLY , 0755)
if err != nil {
if os.IsNotExist(err){
// file does not exist
_ , err = os.Create(filepath)
if err != nil {
panic(err)
}
}else{
panic(err)
}
}
return f
}
// parseFileLinesToSlice gets the content of a file line by line and returns a slice of it
func parseFileLinesToSlice(filePath string) []string {
f := openFile(filePath)
defer f.Close()
var lines []string
// NewScanner returns a scan object to scan the file passed into it
scanner := bufio.NewScanner(f)
for scanner.Scan(){
lines = append(lines, scanner.Text())
}
if err := scanner.Err(); err != nil {
if err != io.EOF{
panic(err)
}
}
return lines
}
// joinSlice adds the element of the 'new' slice into existing slice , only if its not already there
func joinSlice(new []string , exisitng []string) []string {
for _ , i := range new {
if !sliceContains(exisitng, i){
exisitng = append(exisitng, i)
}
}
return exisitng
}
// sliceContains to check if 'slice' contains 'value'
func sliceContains(slice []string , value string) bool{
for _, v := range slice{
if v == value{
return true
}
}
return false
}
// dumpStringToFile writes the content to the file in 'filepath'
func dumpStringSliceToFile(repos []string, filePath string) {
content := strings.Join(repos,"\n")
os.WriteFile(filePath, []byte(content) , 0755)
}
// addNewSliceElementsToFile given a slice of string paths stores them in a file
func addNewSliceElementsToFile(filePath string , newRepos []string){
existingRepos := parseFileLinesToSlice(filePath)
repos := joinSlice(newRepos, existingRepos)
dumpStringSliceToFile(repos , filePath)
}
// Gives the path of the dotfile which has thew database of the repos path
func getDotFiles() string{
usr ,err := user.Current()
if err != nil {
log.Fatal(err)
}
dotFile := usr.HomeDir + "/.gogitlocalstats"
return dotFile
}
func recursiveScanFolder(folder string) []string {
return scanGitFolders(make([]string, 0) , folder)
}
// Scans a list of subfolders of a folder ending with '.git'
// Searches recursively
func scanGitFolders(folders []string, folder string) []string{
// trim the last '/' form file name
folder = strings.TrimSuffix(folder,"/")
// os.Open opens the directory?
f, err := os.Open(folder)
if err != nil {
log.Fatal(err)
}
// -1 in Readdir means we want to read all the contents of the directory
files , err := f.Readdir(-1)
f.Close()
if err != nil {
log.Fatal(err)
}
var path string
for _, file := range files{
if file.IsDir(){
path = folder + "/" + file.Name()
if file.Name() == ".git"{
path = strings.TrimSuffix(path, "/.git")
fmt.Println(path)
folders =append(folders, path)
continue
}
if file.Name() == "vendor" || file.Name() == "node_modules"{
continue
}
folders = scanGitFolders(folders, path)
}
}
return folders
}
// Scans a new folder for git repository
func scan(folder string){
fmt.Printf("Found folders:\n\n")
repositories := recursiveScanFolder(folder)
filePath := getDotFiles()
addNewSliceElementsToFile(filePath, repositories)
fmt.Printf("\n\nSuccessfully added\n\n")
}