forked from zaquestion/lab
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.go
145 lines (128 loc) · 3.35 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
package main
import (
"crypto/sha1"
"encoding/json"
"fmt"
"log"
"os"
"os/user"
"path"
"runtime"
"strings"
"github.com/spf13/viper"
gitlab "github.com/xanzy/go-gitlab"
"github.com/zaquestion/lab/cmd"
"github.com/zaquestion/lab/internal/config"
lab "github.com/zaquestion/lab/internal/gitlab"
)
// version gets set on releases during build by goreleaser.
var version = "master"
func loadConfig() (string, string, string) {
var home string
switch runtime.GOOS {
case "windows":
// userprofile works for roaming AD profiles
home = os.Getenv("USERPROFILE")
default:
// Assume linux or osx
home = os.Getenv("HOME")
if home == "" {
u, err := user.Current()
if err != nil {
log.Fatalf("cannot retrieve current user: %v \n", err)
}
home = u.HomeDir
}
}
// Try XDG_CONFIG_HOME which is declared in XDG base directory specification
confpath := os.Getenv("XDG_CONFIG_HOME")
if confpath == "" {
confpath = path.Join(home, ".config")
}
if _, err := os.Stat(confpath); os.IsNotExist(err) {
os.Mkdir(confpath, 0700)
}
viper.SetConfigName("lab")
viper.SetConfigType("yaml")
viper.AddConfigPath(".")
viper.AddConfigPath(confpath)
viper.SetEnvPrefix("LAB")
viper.SetEnvKeyReplacer(strings.NewReplacer(".", "_"))
viper.AutomaticEnv()
host, user, token := viper.GetString("core.host"), viper.GetString("core.user"), viper.GetString("core.token")
if host != "" && user != "" && token != "" {
return host, user, token
} else if host != "" && token != "" {
return host, getUser(), token
}
// Attempt to auto-configure for GitLab CI
host, user, token = config.CI()
if host != "" && user != "" && token != "" {
return host, user, token
}
err := viper.ReadInConfig()
if err != nil {
switch err.(type) {
case viper.ConfigFileNotFoundError:
if err := config.New(path.Join(confpath, "lab.yaml"), os.Stdin); err != nil {
log.Fatal(err)
}
if err := viper.ReadInConfig(); err != nil {
log.Fatal(err)
}
default:
log.Fatal(err)
}
}
for _, path := range []string{"core.host", "core.token"} {
if viper.GetString(path) == "" {
log.Fatalf("missing required config value %s in %s", path, viper.ConfigFileUsed())
}
}
user = getUser()
viper.Set("core.user", user)
return viper.GetString("core.host"), user, viper.GetString("core.token")
}
func getUser() string {
lab.InitCache()
host := viper.GetString("core.host")
token := viper.GetString("core.token")
lab.CmdLogger().Debugf("Getting username for %s", host)
client := gitlab.NewClient(nil, token)
client.SetBaseURL(host + "/api/v4")
hash := sha1.Sum([]byte(fmt.Sprintf("%s:%s", host, token)))
filename := fmt.Sprintf("user-%x.json", hash)
inCache, bytes, err := lab.ReadCacheTouch(filename, true)
if inCache && err == nil {
user := gitlab.User{}
err := json.Unmarshal(bytes, &user)
if err == nil {
lab.CmdLogger().Debugf("Found user in cache for %s", filename)
return user.Username
}
}
lab.CmdLogger().Debugf("Fetching user")
u, _, err := client.Users.CurrentUser()
if err != nil {
log.Fatal(err)
}
bytes, err = json.Marshal(u)
if err == nil {
lab.WriteCache(filename, bytes)
}
return u.Username
}
func main() {
log.SetFlags(log.LstdFlags | log.Lshortfile)
cmd.Version = version
if !skipInit() {
lab.Init(loadConfig())
}
cmd.Execute()
}
func skipInit() bool {
if len(os.Args) <= 1 {
return false
}
return os.Args[1] == "completion"
}