github.com/lelandbatey/lab@v0.12.1-0.20180712064405-55bfd303a5f0/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  	if _, ok := viper.ReadInConfig().(viper.ConfigFileNotFoundError); ok {
    49  		if err := config.New(path.Join(confpath, "lab.hcl"), os.Stdin); err != nil {
    50  			log.Fatal(err)
    51  		}
    52  
    53  		if err := viper.ReadInConfig(); err != nil {
    54  			log.Fatal(err)
    55  		}
    56  	}
    57  
    58  	c := viper.AllSettings()["core"]
    59  	var cfg map[string]interface{}
    60  	switch v := c.(type) {
    61  	// Most run this is the type
    62  	case []map[string]interface{}:
    63  		cfg = v[0]
    64  	// On the first run when the cfg is created it comes in as this type
    65  	// for whatever reason
    66  	case map[string]interface{}:
    67  		cfg = v
    68  	}
    69  
    70  	for _, v := range []string{"host", "user", "token"} {
    71  		if cv, ok := cfg[v]; !ok {
    72  			log.Println(cv)
    73  			log.Fatalf("missing config value core.%s in %s", v, viper.ConfigFileUsed())
    74  		}
    75  	}
    76  
    77  	// Set environment overrides
    78  	// Note: the code below that uses `cfg["host"]` to access these values
    79  	// is tough to simplify since cfg["host"] is accessing the array "core"
    80  	// and viper.GetString("core.host") is expecting a non-array so it
    81  	// doens't match
    82  	if v := viper.GetString("core.host"); v != "" {
    83  		cfg["host"] = v
    84  	}
    85  	if v := viper.GetString("core.user"); v != "" {
    86  		cfg["user"] = v
    87  	}
    88  	if v := viper.GetString("core.token"); v != "" {
    89  		cfg["token"] = v
    90  	}
    91  	return cfg["host"].(string), cfg["user"].(string), cfg["token"].(string)
    92  }
    93  
    94  func main() {
    95  	log.SetFlags(log.LstdFlags | log.Lshortfile)
    96  	cmd.Version = version
    97  	lab.Init(loadConfig())
    98  	cmd.Execute()
    99  }