github.com/devcamcar/cli@v0.0.0-20181107134215-706a05759d18/config/config.go (about) 1 package config 2 3 import ( 4 "fmt" 5 "os" 6 "path/filepath" 7 "strings" 8 9 "github.com/fnproject/fn_go/provider" 10 "github.com/spf13/viper" 11 "github.com/urfave/cli" 12 ) 13 14 const ( 15 rootConfigPathName = ".fn" 16 17 contextsPathName = "contexts" 18 configName = "config" 19 contextConfigFileName = "config.yaml" 20 defaultContextFileName = "default.yaml" 21 defaultLocalAPIURL = "http://localhost:8080" 22 DefaultProvider = "default" 23 24 ReadWritePerms = os.FileMode(0755) 25 26 CurrentContext = "current-context" 27 ContextProvider = "provider" 28 CurrentCliVersion = "cli-version" 29 30 EnvFnRegistry = "registry" 31 EnvFnContext = "context" 32 ) 33 34 var defaultRootConfigContents = &ContextMap{CurrentContext: "", CurrentCliVersion: ""} 35 var DefaultContextConfigContents = &ContextMap{ 36 ContextProvider: DefaultProvider, 37 provider.CfgFnAPIURL: defaultLocalAPIURL, 38 EnvFnRegistry: "", 39 } 40 41 type ContextMap map[string]string 42 43 // Init : Initialise/load config direc 44 func Init() error { 45 viper.AutomaticEnv() // read in environment variables that match 46 viper.SetEnvPrefix("fn") 47 48 replacer := strings.NewReplacer("-", "_") 49 viper.SetEnvKeyReplacer(replacer) 50 51 viper.SetDefault(provider.CfgFnAPIURL, defaultLocalAPIURL) 52 53 return ensureConfiguration() 54 } 55 56 // EnsureConfiguration ensures context configuration directory hierarchy is in place, if not 57 // creates it and the default context configuration files 58 func ensureConfiguration() error { 59 home := GetHomeDir() 60 61 rootConfigPath := filepath.Join(home, rootConfigPathName) 62 if _, err := os.Stat(rootConfigPath); os.IsNotExist(err) { 63 if err = os.Mkdir(rootConfigPath, ReadWritePerms); err != nil { 64 return fmt.Errorf("error creating .fn directory %v", err) 65 } 66 } 67 68 contextConfigFilePath := filepath.Join(rootConfigPath, contextConfigFileName) 69 if _, err := os.Stat(contextConfigFilePath); os.IsNotExist(err) { 70 file, err := os.Create(contextConfigFilePath) 71 if err != nil { 72 return fmt.Errorf("error creating config.yaml file %v", err) 73 } 74 75 err = WriteYamlFile(file.Name(), defaultRootConfigContents) 76 if err != nil { 77 return err 78 } 79 } 80 contextsPath := filepath.Join(rootConfigPath, contextsPathName) 81 if _, err := os.Stat(contextsPath); os.IsNotExist(err) { 82 if err = os.Mkdir(contextsPath, ReadWritePerms); err != nil { 83 return fmt.Errorf("error creating contexts directory %v", err) 84 } 85 } 86 87 defaultContextPath := filepath.Join(contextsPath, defaultContextFileName) 88 if _, err := os.Stat(defaultContextPath); os.IsNotExist(err) { 89 _, err = os.Create(defaultContextPath) 90 if err != nil { 91 return fmt.Errorf("error creating default.yaml context file %v", err) 92 } 93 94 err = WriteYamlFile(defaultContextPath, DefaultContextConfigContents) 95 if err != nil { 96 return err 97 } 98 } 99 100 return nil 101 } 102 103 // GetContextsPath : Returns the path to the contexts directory. 104 func GetContextsPath() string { 105 contextsPath := filepath.Join(rootConfigPathName, contextsPathName) 106 return contextsPath 107 } 108 109 func LoadConfiguration(c *cli.Context) error { 110 // Find home directory. 111 home := GetHomeDir() 112 context := "" 113 114 viper.AddConfigPath(filepath.Join(home, rootConfigPathName)) 115 viper.SetConfigName(configName) 116 117 if err := viper.ReadInConfig(); err != nil { 118 return err 119 } 120 121 if context = c.String(EnvFnContext); context == "" { 122 context = viper.GetString(CurrentContext) 123 } 124 125 viper.AddConfigPath(filepath.Join(home, rootConfigPathName, contextsPathName)) 126 viper.SetConfigName(context) 127 128 WriteConfigValueToConfigFile(CurrentCliVersion, Version) 129 130 if err := viper.ReadInConfig(); err != nil { 131 fmt.Printf("%v \n", err) 132 err := WriteConfigValueToConfigFile(CurrentContext, "default") 133 if err != nil { 134 return err 135 } 136 WriteConfigValueToConfigFile(CurrentCliVersion, Version) 137 if err != nil { 138 return err 139 } 140 141 fmt.Println("current context has been set to default") 142 return nil 143 } 144 145 viper.Set(CurrentContext, context) 146 return nil 147 } 148 149 func WriteConfigValueToConfigFile(key, value string) error { 150 home := GetHomeDir() 151 152 configFilePath := filepath.Join(home, rootConfigPathName, contextConfigFileName) 153 f, err := os.OpenFile(configFilePath, os.O_RDWR, ReadWritePerms) 154 if err != nil { 155 return err 156 } 157 defer f.Close() 158 159 file, err := DecodeYAMLFile(f.Name()) 160 if err != nil { 161 return err 162 } 163 164 configValues := ContextMap{} 165 for k, v := range *file { 166 if k == key { 167 configValues[k] = value 168 } else { 169 configValues[k] = v 170 } 171 } 172 configValues[key] = value 173 174 err = WriteYamlFile(f.Name(), &configValues) 175 if err != nil { 176 return err 177 } 178 179 return nil 180 }