package config import ( "os" "path" "path/filepath" "coopcloud.tech/abra/pkg/log" "gopkg.in/yaml.v3" ) // LoadAbraConfig returns the abra configuration. It tries to find a abra // configuration file (see findAbraConfig for lookup logic). When no // configuration was found it returns the default config. func LoadAbraConfig() Abra { wd, _ := os.Getwd() configFile := findAbraConfig(wd) if configFile == "" { log.Debugf("no config file found") return Abra{} } data, err := os.ReadFile(configFile) if err != nil { // Do nothing, when an error occurs log.Debugf("error reading config file: %s", err) return Abra{} } config := Abra{} err = yaml.Unmarshal(data, &config) if err != nil { // Do nothing, when an error occurs log.Debugf("error loading config file: %s", err) return Abra{} } log.Debugf("config file loaded from: %s", configFile) config.configPath = filepath.Dir(configFile) return config } // findAbraConfig recursively looks for a abra.y(a)ml file in the given directory. // When the file was not found it calls the function again with the parent // directory until the home directory is hit. When no abra config was found it // returns an empty string. func findAbraConfig(dir string) string { dir, err := filepath.Abs(dir) if err != nil { return "" } if dir == os.ExpandEnv("$HOME") || dir == "/" { return "" } p := path.Join(dir, "abra.yaml") if _, err := os.Stat(p); err == nil { return p } p = path.Join(dir, "abra.yml") if _, err := os.Stat(p); err == nil { return p } return findAbraConfig(filepath.Dir(dir)) } // Abra defines the configuration file for abra. type Abra struct { configPath string AbraDir string `yaml:"abraDir"` } // GetAbraDir returns the abra dir. It has the following logic: // 1. check if $ABRA_DIR is set // 2. check if abraDir was set in a config file // 3. use $HOME/.abra when above two options failed func (a Abra) GetAbraDir() string { if dir, exists := os.LookupEnv("ABRA_DIR"); exists && dir != "" { log.Debug("read abra dir from $ABRA_DIR") return dir } if a.AbraDir != "" { log.Debug("read abra dir from config file") if path.IsAbs(a.AbraDir) { return a.AbraDir } // Make the path absolute return path.Join(a.configPath, a.AbraDir) } log.Debug("using default abra dir") return os.ExpandEnv("$HOME/.abra") } func (a Abra) GetServersDir() string { return path.Join(a.GetAbraDir(), "servers") } func (a Abra) GetRecipesDir() string { return path.Join(a.GetAbraDir(), "recipes") } func (a Abra) GetLogsDir() string { return path.Join(a.GetAbraDir(), "logs") } func (a Abra) GetVendorDir() string { return path.Join(a.GetAbraDir(), "vendor") } func (a Abra) GetBackupDir() string { return path.Join(a.GetAbraDir(), "backups") } func (a Abra) GetCatalogueDir() string { return path.Join(a.GetAbraDir(), "catalogue") } var config = LoadAbraConfig() var ( ABRA_DIR = config.GetAbraDir() SERVERS_DIR = config.GetServersDir() RECIPES_DIR = config.GetRecipesDir() LOGS_DIR = config.GetLogsDir() VENDOR_DIR = config.GetVendorDir() BACKUP_DIR = config.GetBackupDir() CATALOGUE_DIR = config.GetCatalogueDir() RECIPES_JSON = path.Join(config.GetCatalogueDir(), "recipes.json") REPOS_BASE_URL = "https://git.coopcloud.tech/coop-cloud" CATALOGUE_JSON_REPO_NAME = "recipes-catalogue-json" TOOLSHED_SSH_URL_TEMPLATE = "ssh://git@git.coopcloud.tech:2222/toolshed/%s.git" RECIPES_SSH_URL_TEMPLATE = "ssh://git@git.coopcloud.tech:2222/coop-cloud/%s.git" // NOTE(d1): please note, this was done purely out of laziness on our part // AFAICR. it's easy to punt the value into the label because that is what is // expects. it's not particularly useful in terms of UI/UX but hey, nobody // complained yet! CHAOS_DEFAULT = "false" DIRTY_DEFAULT = "+U" NO_DOMAIN_DEFAULT = "N/A" NO_VERSION_DEFAULT = "N/A" UNKNOWN_DEFAULT = "unknown" )