github.com/matthewdale/lab@v0.14.0/main.go (about) 1 package main 2 3 import ( 4 "log" 5 "os" 6 "os/user" 7 "path" 8 "runtime" 9 "strings" 10 11 "github.com/spf13/viper" 12 "github.com/zaquestion/lab/cmd" 13 "github.com/zaquestion/lab/internal/config" 14 lab "github.com/zaquestion/lab/internal/gitlab" 15 ) 16 17 // version gets set on releases during build by goreleaser. 18 var version = "master" 19 20 func loadConfig() (string, string, string) { 21 var home string 22 switch runtime.GOOS { 23 case "windows": 24 // userprofile works for roaming AD profiles 25 home = os.Getenv("USERPROFILE") 26 default: 27 // Assume linux or osx 28 u, err := user.Current() 29 if err != nil { 30 log.Fatalf("cannot retrieve current user: %v \n", err) 31 } 32 home = u.HomeDir 33 } 34 confpath := path.Join(home, ".config") 35 if _, err := os.Stat(confpath); os.IsNotExist(err) { 36 os.Mkdir(confpath, 0700) 37 } 38 39 viper.SetConfigName("lab") 40 viper.SetConfigType("hcl") 41 viper.AddConfigPath(".") 42 viper.AddConfigPath(confpath) 43 44 viper.SetEnvPrefix("LAB") 45 viper.SetEnvKeyReplacer(strings.NewReplacer(".", "_")) 46 viper.AutomaticEnv() 47 48 host, user, token := viper.GetString("core.host"), viper.GetString("core.user"), viper.GetString("core.token") 49 if host != "" && user != "" && token != "" { 50 return host, user, token 51 } 52 53 // Attempt to auto-configure for GitLab CI 54 host, user, token = config.CI() 55 if host != "" && user != "" && token != "" { 56 return host, user, token 57 } 58 59 if _, ok := viper.ReadInConfig().(viper.ConfigFileNotFoundError); ok { 60 if err := config.New(path.Join(confpath, "lab.hcl"), os.Stdin); err != nil { 61 log.Fatal(err) 62 } 63 64 if err := viper.ReadInConfig(); err != nil { 65 log.Fatal(err) 66 } 67 } 68 69 c := viper.AllSettings()["core"] 70 var cfg map[string]interface{} 71 switch v := c.(type) { 72 // Most run this is the type 73 case []map[string]interface{}: 74 cfg = v[0] 75 // On the first run when the cfg is created it comes in as this type 76 // for whatever reason 77 case map[string]interface{}: 78 cfg = v 79 } 80 81 for _, v := range []string{"host", "user", "token"} { 82 if cv, ok := cfg[v]; !ok { 83 log.Println(cv) 84 log.Fatalf("missing config value core.%s in %s", v, viper.ConfigFileUsed()) 85 } 86 } 87 88 // Set environment overrides 89 // Note: the code below that uses `cfg["host"]` to access these values 90 // is tough to simplify since cfg["host"] is accessing the array "core" 91 // and viper.GetString("core.host") is expecting a non-array so it 92 // doens't match 93 if v := viper.GetString("core.host"); v != "" { 94 cfg["host"] = v 95 } 96 if v := viper.GetString("core.user"); v != "" { 97 cfg["user"] = v 98 } 99 if v := viper.GetString("core.token"); v != "" { 100 cfg["token"] = v 101 } 102 return cfg["host"].(string), cfg["user"].(string), cfg["token"].(string) 103 } 104 105 func main() { 106 log.SetFlags(log.LstdFlags | log.Lshortfile) 107 cmd.Version = version 108 lab.Init(loadConfig()) 109 cmd.Execute() 110 }