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  }