193 lines
5.2 KiB
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")
|
|
}
|