This repository has been archived by the owner on Oct 16, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.go
239 lines (225 loc) · 7.83 KB
/
main.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
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
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
package main
import (
"bufio"
"bytes"
"fmt"
"io/ioutil"
"log"
"os"
"path"
"sync"
"github.com/BurntSushi/toml"
"github.com/k0pernicus/goyave/configurationFile"
"github.com/k0pernicus/goyave/consts"
"github.com/k0pernicus/goyave/gitManip"
"github.com/k0pernicus/goyave/traces"
"github.com/k0pernicus/goyave/utils"
"github.com/k0pernicus/goyave/walk"
"github.com/spf13/cobra"
)
var configurationFileStructure configurationFile.ConfigurationFile
var configurationFilePath string
var userHomeDir string
/*initialize get the configuration file existing in the system (or create it), and return
*a pointer to his content.
*/
func initialize(configurationFileStructure *configurationFile.ConfigurationFile) {
// Initialize all different traces structures
traces.InitTraces(os.Stdout, os.Stderr, os.Stdout, os.Stdout)
// Get the user home directory
userHomeDir = utils.GetUserHomeDir()
if len(userHomeDir) == 0 {
log.Fatalf("can't get the user home dir\n")
}
// Set the configuration path file
configurationFilePath = path.Join(userHomeDir, consts.ConfigurationFileName)
filePointer, err := os.OpenFile(configurationFilePath, os.O_RDWR|os.O_CREATE, 0755)
if err != nil {
log.Fatalf("can't open the file %s, due to error '%s'\n", configurationFilePath, err)
}
defer filePointer.Close()
var bytesArray []byte
// Get the content of the goyave configuration file
configurationFile.GetConfigurationFileContent(filePointer, &bytesArray)
if _, err = toml.Decode(string(bytesArray[:]), configurationFileStructure); err != nil {
log.Fatalln(err)
}
configurationFileStructure.Process()
}
/*kill saves the current state of the configuration structure in the configuration file
*/
func kill() {
var outputBuffer bytes.Buffer
if err := configurationFileStructure.Encode(&outputBuffer); err != nil {
log.Fatalln("can't save the current configurationFile structure")
}
if err := ioutil.WriteFile(configurationFilePath, outputBuffer.Bytes(), 0777); err != nil {
log.Fatalln("can't access to your file to save the configurationFile structure")
}
}
func main() {
/*rootCmd defines the global app, and some actions to run before and after the command running
*/
var rootCmd = &cobra.Command{
Use: "goyave",
Short: "Goyave is a tool to take a look at your local git repositories",
// Initialize the structure
PersistentPreRun: func(cmd *cobra.Command, args []string) {
initialize(&configurationFileStructure)
},
// Save the current configuration file structure, in the configuration file
PersistentPostRun: func(cmd *cobra.Command, args []string) {
kill()
},
}
/*addCmd is a subcommand to add the current working directory as a VISIBLE one
*/
var addCmd = &cobra.Command{
Use: "add",
Short: "Add the current path as a VISIBLE repository",
Run: func(cmd *cobra.Command, args []string) {
// Get the path where the command has been executed
currentDir, err := os.Getwd()
if err != nil {
log.Fatalln("There was a problem retrieving the current directory")
}
if utils.IsGitRepository(currentDir) {
log.Fatalf("%s is not a git repository!\n", currentDir)
}
// If the path is/contains a .git directory, add this one as a VISIBLE repository
if err := configurationFileStructure.AddRepository(currentDir, consts.VisibleFlag); err != nil {
traces.WarningTracer.Printf("[%s] %s\n", currentDir, err)
}
},
}
/*crawlCmd is a subcommand to crawl your hard drive in order to get and save new git repositories
*/
var crawlCmd = &cobra.Command{
Use: "crawl",
Short: "Crawl the hard drive in order to find git repositories",
Run: func(cmd *cobra.Command, args []string) {
var wg sync.WaitGroup
// Get all git paths, and display them
gitPaths, err := walk.RetrieveGitRepositories(userHomeDir)
if err != nil {
log.Fatalf("there was an error retrieving your git repositories: '%s'\n", err)
}
// For each git repository, check if it exists, and if not add it to the default target visibility
for _, gitPath := range gitPaths {
wg.Add(1)
go func(gitPath string) {
defer wg.Done()
if utils.IsGitRepository(gitPath) {
configurationFileStructure.AddRepository(gitPath, configurationFileStructure.Local.DefaultTarget)
}
}(gitPath)
}
wg.Wait()
},
}
/*loadCmd permits to load visible repositories from the goyave configuration file
*/
var loadCmd = &cobra.Command{
Use: "load",
Short: "Load the configuration file to restore your previous work space",
Run: func(cmd *cobra.Command, args []string) {
currentHostname := utils.GetHostname()
traces.InfoTracer.Printf("Current hostname is %s\n", currentHostname)
for {
_, ok := configurationFileStructure.Groups[currentHostname]
if !ok {
traces.WarningTracer.Printf("Your current local host (%s) has not been found!", currentHostname)
fmt.Println("Please to choose one of those, to load the configuration file:")
for group := range configurationFileStructure.Groups {
traces.WarningTracer.Printf("\t%s\n", group)
}
scanner := bufio.NewScanner(os.Stdin)
currentHostname = scanner.Text()
continue
} else {
traces.InfoTracer.Println("Hostname found!")
}
break
}
var wg sync.WaitGroup
for _, repository := range configurationFileStructure.Repositories {
wg.Add(1)
go func(repository configurationFile.GitRepository) {
defer wg.Done()
cName := repository.Name
cPath := repository.Paths[currentHostname].Path
cURL := repository.URL
if _, err := os.Stat(cPath); err == nil {
traces.InfoTracer.Printf("the repository \"%s\" already exists as a local git repository\n", cName)
return
}
traces.InfoTracer.Printf("importing %s...\n", cName)
if err := gitManip.Clone(cPath, cURL); err != nil {
traces.ErrorTracer.Printf("the repository \"%s\" can't be cloned: %s\n", cName, err)
}
}(repository)
}
wg.Wait()
},
}
/*pathCmd is a subcommand to get the path of a given git repository.
*This subcommand is useful to change directory, like `cd $(goyave path mygitrepo)`
*/
var pathCmd = &cobra.Command{
Use: "path",
Short: "Get the path of a given repository, if this one exists",
Run: func(cmd *cobra.Command, args []string) {
if len(args) == 0 {
log.Fatalln("Needs a repository name!")
}
repo := args[0]
repoPath, found := configurationFileStructure.GetPath(repo)
if !found {
log.Fatalf("repository %s not found\n", repo)
} else {
fmt.Println(repoPath)
}
},
}
/*stateCmd is a subcommand to list the state of each local git repository.
*/
var stateCmd = &cobra.Command{
Use: "state",
Example: "goyave state\ngoyave state myRepositoryName\ngoyave state myRepositoryName1 myRepositoryName2",
Short: "Get the state of each local visible git repository",
Long: "Check only visible git repositories.\nIf some repository names have been setted, goyave will only check those repositories, otherwise it checks all visible repositories of your system.",
Run: func(cmd *cobra.Command, args []string) {
var paths []string
// Append repositories to check
if len(args) == 0 {
for _, p := range configurationFileStructure.VisibleRepositories {
paths = append(paths, p)
}
} else {
for _, repository := range args {
repoPath, ok := configurationFileStructure.VisibleRepositories[repository]
if ok {
paths = append(paths, repoPath)
} else {
traces.WarningTracer.Printf("%s cannot be found in your visible repositories\n", repository)
}
}
}
var wg sync.WaitGroup
for _, repository := range paths {
wg.Add(1)
go func(repoPath string) {
defer wg.Done()
cGitObj := gitManip.New(repoPath)
cGitObj.Status()
}(repository)
}
wg.Wait()
},
}
rootCmd.AddCommand(addCmd, crawlCmd, loadCmd, pathCmd, stateCmd)
if err := rootCmd.Execute(); err != nil {
fmt.Println(err)
os.Exit(1)
}
}