bladerunner/arrange/arrange.go

193 lines
5.2 KiB
Go

// arrange will be used to initialize and manage a toml configuration file for our application
package arrange
import (
"bytes"
"github.com/rs/zerolog"
"github.com/spf13/viper"
"io/ioutil"
"strings"
//"io"
"os"
)
// Define config variables here so that the scope will be easily accessible from main.go
var Debug bool
var LogDir string
////////////////////////////////////
var f *os.File
var err error
var forcedebug bool
var customconfig bool
//////////// Application version information //
var Version string = "0.0"
var Title string = "changeme"
var appLabel string = Title + " " + Version
///////////////////////////////////////////////
var Config *viper.Viper
var log zerolog.Logger
//////// Configuration file details
var configLocations []string
var home string
func acquireClue() {
// define proper console output before we determine a log file location
log = PreLog()
if home, err = os.UserHomeDir(); err != nil {
log.Fatal().Err(err).Msg("failed to determine user's home directory, we will not be able to load our configuration if it is stored there!")
}
///////////////////////////////////////////////////////////////////
// define locations we will look for our toml configuration file //
///////////////////////////////////////////////////////////////////
// var titles = []string{Title, "config", "default"}
// e.g: /home/fuckhole/.jonesapp/config.toml
configLocations = append(configLocations, home+"/."+Title+"/")
// e.g: /home/fuckhole/.config/jonesapp.toml
configLocations = append(configLocations, home+"/."+Title+"/")
// e.g: /etc/jonesapp/config.toml
configLocations = append(configLocations, "/etc/"+Title+"/")
// e.g: /home/fuckhole/Workshop/jonesapp/config.toml
configLocations = append(configLocations, "./")
// e.g: /home/fuckhole/Workshop/jonesapp/.config/config.toml
configLocations = append(configLocations, "./.config/")
///////////////////////////////////////////////////////////////////
}
// Prelog is to temporarily define pretty printing before we finish initializing our json logger
func PreLog() zerolog.Logger {
return zerolog.New(zerolog.ConsoleWriter{Out: os.Stderr}).With().Timestamp().Logger()
}
// Blueprint will initialize our toml configuration engine and define our default configuration values which can be written to a new configuration file if desired
func Blueprint() {
acquireClue()
Config = viper.New()
///////////////////// defaults //////
defName := Title
defGlobal := map[string]interface{}{
"debug": true,
"log_directory": "./.logs",
}
/*
// here we are defining a generic category as an example
defCategory := map[string]interface{}{
"shouldistay": true,
"shouldigo": false,
"optics": "ironsights",
"fucksgiven": 0,
// e.g: /home/fuckhole/.jonesapp/config.toml
//"admins": []string{"Satan", "Yahweh", "FuckholeJones"},
}
*/
/////////////////////////////////////
Config.SetDefault("name", defName)
Config.SetDefault("global", defGlobal)
//Config.SetDefault("category", defCategory)
// handle command line override of the config file location
// e.g: ./app -c /home/fuckhole/jones.toml
for i, arg := range os.Args {
switch arg {
case "-c":
if len(os.Args) <= i-1 {
log.Fatal().
Msg("syntax error! expected file after -c")
}
log.Warn().
Str("config", os.Args[i+1]).
Msg("[OVERRIDE] using config file: " + os.Args[i+1])
if f, err = os.Open(os.Args[i+1]); err != nil {
log.Fatal().Err(err).
Str("target_file", os.Args[i+1]).
Msg("Error using specified logfile")
}
buf, _ := ioutil.ReadAll(f)
if err = Config.ReadConfig(bytes.NewBuffer(buf)); err != nil {
log.Fatal().Err(err).
Str("target_file", os.Args[i+1]).
Msg("Error using specified logfile")
}
customconfig = true
case "-d":
forcedebug = true
Debug = true
}
}
if customconfig {
goto fin
}
Config.SetConfigType("toml")
Config.SetConfigName("config")
// iter through our previously defined configuration file locations and add them to the paths searched by viper
for _, loc := range configLocations {
Config.AddConfigPath(loc)
}
// locate and read the config file
err = Config.ReadInConfig()
// if we can't locate a config file, write one in the same directory as we're executing in based on the maps we defined above
if err != nil {
if strings.Contains(err.Error(), "Not Found in") {
log.Warn().
Msg("Config file not found! Writing new config to config.toml")
}
if err := Config.SafeWriteConfigAs("./config.toml"); err != nil {
log.Fatal().Err(err).Msg("Error writing new configuration file")
}
}
fin:
associate()
}
// Assignments is where we assign the values of our variables with our configuration values from defaults and/or the config file
func associate() {
// define loglevel of application
if (!Config.GetBool("global.debug") && !forcedebug) {
Debug = false
zerolog.SetGlobalLevel(zerolog.InfoLevel)
} else {
Debug = true
zerolog.SetGlobalLevel(zerolog.DebugLevel)
}
log.Info().Str("config", Config.ConfigFileUsed()).Msg("loading configuration directives")
for _, key := range Config.AllKeys() {
log.Debug().Str("key", key).Msg("LOAD_CONFIG_DIRECTIVE")
}
// location for our log files generated at runtime
LogDir = Config.GetString("global.log_directory")
}