diff options
| -rw-r--r-- | appname.go | 24 | ||||
| -rw-r--r-- | formatENV.go | 51 | ||||
| -rw-r--r-- | init.go | 26 | ||||
| -rw-r--r-- | key.proto | 18 | ||||
| -rw-r--r-- | load.go | 92 | ||||
| -rw-r--r-- | panic.go | 23 | ||||
| -rw-r--r-- | save.go | 88 | ||||
| -rw-r--r-- | structs.go | 20 | ||||
| -rw-r--r-- | verbose.go | 55 |
9 files changed, 390 insertions, 7 deletions
diff --git a/appname.go b/appname.go new file mode 100644 index 0000000..98d8dcc --- /dev/null +++ b/appname.go @@ -0,0 +1,24 @@ +package ENV + +import ( + "errors" + "os/user" +) + +func GetAppname() (string, error) { + if APPNAME != "" { + return APPNAME, nil + } + return "", errors.New("your application must setup config.Init()") +} + +func GetUsername() string { + if Get("username") != "" { + return Get("username") + } + usr, _ := user.Current() + if usr.Username != "" { + return usr.Username + } + return "notsure" // OS Idiocracy +} diff --git a/formatENV.go b/formatENV.go new file mode 100644 index 0000000..0d1efc3 --- /dev/null +++ b/formatENV.go @@ -0,0 +1,51 @@ +package ENV + +import ( + "errors" + "fmt" + "strings" + + "go.wit.com/log" +) + +func formatENV() (string, error) { + if envPB == nil { + return "", errors.New("envPB not initialized") + } + + var out string + uniques := make(map[string]*Key) // check to make sure there are no duplicate entries + + for c := range envPB.IterAll() { + key := strings.ToLower(c.Var) + if len(strings.Fields(key)) != 1 { + log.Info("dropping invalid key = ", c.Var, "value =", c.Value) + continue + } + found := findByLower(key) + if found == nil { + log.Info("findByKey() got nil for key:", key) + } + // todo: warn about duplicates? + uniques[key] = found + } + + for key, c := range uniques { + if c == nil { + log.Info("key has nil c", key) + continue + } + line := fmt.Sprintf("%s=%s", c.Var, c.Value) + out += line + "\n" + } + return out, nil +} + +func findByLower(lookingFor string) *Key { + for c := range envPB.IterAll() { + if strings.ToLower(c.Var) == strings.ToLower(lookingFor) { + return c + } + } + return nil +} @@ -0,0 +1,26 @@ +package ENV + +// this is an experiment at this point to +// see how this turns out + +func Init(appname, version, buildtime string, fromargv []string) error { + APPNAME = appname + VERSION = version + BUILDTIME = buildtime + argv = fromargv + + err := loadENV() + if err == nil { + envPB.Init = true + } + return err +} + +func InitValid() bool { + if envPB == nil { + // todo: track that the application did not init + envPB = NewKeys() + return false + } + return envPB.Init +} @@ -4,13 +4,17 @@ syntax = "proto3"; package ENV; -message Key { // - string var = 1; // ENV var name `autogenpb:unique` `autogenpb:sort` - string value = 2; // ENV value name +message Key { // + string var = 1; // ENV var name `autogenpb:unique` `autogenpb:sort` + string value = 2; // ENV value name + bool global = 3; // was defined in application OS settings + string help = 4; // text for explaining the ENV key/value } -message Keys { // `autogenpb:marshal` `autogenpb:nomutex` - string uuid = 1; // `autogenpb:uuid:7a8aaf7f-9851-42f0-89eb-434d2e51f5bb` - string version = 2; // `autogenpb:version:v0.0.1 go.wit.com/lib/ENV` - repeated Key keys = 3; +message Keys { // `autogenpb:marshal` `autogenpb:nomutex` + string uuid = 1; // `autogenpb:uuid:7a8aaf7f-9851-42f0-89eb-434d2e51f5bb` + string version = 2; // `autogenpb:version:v0.0.1 go.wit.com/lib/ENV` + repeated Key keys = 3; + string filename = 4; // can store where the filename is so that saves can be automated + bool init = 5; // can store where the filename is so that saves can be automated } @@ -0,0 +1,92 @@ +package ENV + +import ( + "errors" + "os" + "path/filepath" + "strings" + + "go.wit.com/log" +) + +func loadENV() error { + if envPB != nil { + log.Info("envPB already loaded") + return errors.New("envPB already loaded") + } + filename, err := getConfigFilenameENV() + if err != nil { + return err + } + // log.Info("loadENV()", filename) + stuff, err := os.ReadFile(filename) + if err != nil { + return err + } + saveMu.Lock() + defer saveMu.Unlock() + envPB = NewKeys() + for _, line := range strings.Split(string(stuff), "\n") { + line = strings.TrimSpace(line) + if line == "" { + continue + } + parts := strings.Split(line, "=") + if len(parts) != 2 { + // log.Info("INVALID LINE:", i, line) + continue + } + c := new(Key) + c.Var = parts[0] + c.Value = parts[1] + envPB.Append(c) + // log.Printf("ENV LINE: (%v)\n", c) + } + + return err +} + +func getConfigFilenameENV() (string, error) { + appname, err := GetAppname() // already configured by your application + if err != nil { + return "", err + } + + configdir, err := getConfigDir() + if err != nil { + return "", err + } + + filename := filepath.Join(configdir, appname+".ENV") + return filename, nil +} + +func getCacheDir() (string, error) { + if Get("cacheDir") != "" { + return Get("cacheDir"), nil + } + + cacheDir, _ := os.UserCacheDir() + + appname, err := GetAppname() // application should have already configured this + if err != nil { + return cacheDir, err + } + + return filepath.Join(cacheDir, appname), nil +} + +func getConfigDir() (string, error) { + if Get("configDir") != "" { + return Get("configDir"), nil + } + + configDir, _ := os.UserConfigDir() + + appname, err := GetAppname() // application should have already configured this + if err != nil { + return configDir, err + } + + return filepath.Join(configDir, appname), nil +} diff --git a/panic.go b/panic.go new file mode 100644 index 0000000..488cee9 --- /dev/null +++ b/panic.go @@ -0,0 +1,23 @@ +package ENV + +func GetPanic(flag string) string { + saveMu.Lock() + defer saveMu.Unlock() + if envPB == nil { + envPanic(flag) + } + found := envPB.FindByVar(flag) + if found == nil { + envPanic(flag) + } + return found.Value +} + +func envPanic(varname string) { + saveMu.Lock() + defer saveMu.Unlock() + if envPB == nil { + panic("config file is nil") + } + panic("config name '" + varname + "' not found") +} @@ -0,0 +1,88 @@ +package ENV + +import ( + "os" + "strings" + + "go.wit.com/log" +) + +// saves your applications config file +func Save() error { + return saveENV() +} + +func saveENV() error { + filename, err := getConfigFilenameENV() + if err != nil { + return err + } + saveMu.Lock() + defer saveMu.Unlock() + return saveENVnolock(filename) +} + +func saveENVnolock(filename string) error { + outENV, err := formatENV() + if err == nil { + log.Info("SAVEENV IS RUNNING") + log.Info("SAVEENV IS RUNNING") + log.Info("SAVEENV IS RUNNING") + log.Info(outENV) + } + return os.WriteFile(filename, []byte(outENV), 0644) +} + +func Get(flag string) string { + saveMu.Lock() + defer saveMu.Unlock() + if envPB == nil { + return "" + } + c := findByLower(flag) + if c == nil { + return "" + } + + return c.Value +} + +func True(flag string) bool { + saveMu.Lock() + defer saveMu.Unlock() + if envPB == nil { + return false + } + found := envPB.FindByVar(flag) + if found == nil { + return false + } + if strings.ToLower(found.Value) == "true" { + return true + } + return false +} + +func Set(varname string, newValue string) error { + filename, err := getConfigFilenameENV() + if err != nil { + return err + } + saveMu.Lock() + defer saveMu.Unlock() + if envPB == nil { + return NotInitialized + } + found := envPB.FindByVar(varname) + if found != nil { + found.Value = newValue + saveENVnolock(filename) + } + + newvar := new(Key) + newvar.Var = varname + newvar.Value = newValue + envPB.Append(newvar) + saveENVnolock(filename) + return nil +} diff --git a/structs.go b/structs.go new file mode 100644 index 0000000..89c5177 --- /dev/null +++ b/structs.go @@ -0,0 +1,20 @@ +package ENV + +import ( + "errors" + sync "sync" +) + +var envPB *Keys + +// lock access to the PB +var saveMu sync.RWMutex + +// these are normally what are sent from ldflags +var APPNAME string +var BUILDTIME string +var VERSION string + +var argv []string + +var NotInitialized error = errors.New("your application config not initialized") diff --git a/verbose.go b/verbose.go new file mode 100644 index 0000000..31dd0f7 --- /dev/null +++ b/verbose.go @@ -0,0 +1,55 @@ +package ENV + +// this is an experiment at this point to +// see how this turns out + +func Verbose() bool { + // always use the ENV value first + if envPB != nil { + found := envPB.FindByVar("Verbose") + if found == nil { + // Verbose isn't in the ENV. do nothing here + } else { + // return what the ENV has + // fmt.Println("returning from the ENV:" + found.Value) + if found.Value == "true" { + return true + } + return false + } + } + + // nothing in the ENV. check argv + for _, v := range argv { + if v == "--verbose" { + return true + } + } + return false +} + +func If(key string) bool { + // always use the ENV value first + if envPB != nil { + found := envPB.FindByVar(key) + if found == nil { + // Verbose isn't in the ENV. do nothing here + } else { + // return what the ENV has + // fmt.Println("returning from the ENV:" + found.Value) + if found.Value == "true" { + return true + } + return false + } + } + + // nothing in the ENV. check argv + // todo: turn key to lowercase and check here + for _, v := range argv { + if v == "--verbose" { + return true + } + } + return false +} |
