Initial commit

This commit is contained in:
2024-08-30 11:25:28 +12:00
commit 0cd89c0707
31 changed files with 1470 additions and 0 deletions

View File

@@ -0,0 +1,66 @@
package config
import (
"github.com/spf13/viper"
"hub.cybercinch.nz/guisea/go-template/internal/config/key"
)
// fields is the config fields with their default values and descriptions
var fields = []*Field{
// LOGS
{
key.LogsWrite,
true,
"Write logs to file",
},
{
key.LogsLevel,
"info",
`Logs level.
Available options are: (from less to most verbose)
fatal, error, warn, info, debug`,
},
{
key.LogsReportCaller,
false,
"Whether the logger should report the caller location.",
},
//{
// key.TenantId,
// "some_client_id",
// "The TenantID to use with Xero.",
//},
//{
// key.BankAccountId,
// "a-random-bank-account-id",
// "Guid for the xero account to use.",
//},
// END LOGS
// BEANSTALK
//{
// key.BeanstalkServer,
// "localhost",
// "The Beanstalk Server to use",
//},
//{
// key.BeanstalkPort,
// "11300",
// "The port to communicate with Beanstalk server",
//},
//{
// key.BeanstalkTube,
// "visa-transactions",
// "The tube to use to find our transactions in.",
//},
}
func setDefaults() {
Default = make(map[string]*Field, len(fields))
for _, f := range fields {
Default[f.Key] = f
viper.SetDefault(f.Key, f.DefaultValue)
viper.MustBindEnv(f.Key)
}
}
var Default map[string]*Field

90
internal/config/field.go Normal file
View File

@@ -0,0 +1,90 @@
package config
import (
"fmt"
"reflect"
"strconv"
"strings"
"text/template"
"github.com/charmbracelet/lipgloss"
"github.com/samber/lo"
"github.com/spf13/viper"
"hub.cybercinch.nz/guisea/go-template/internal/app"
"hub.cybercinch.nz/guisea/go-template/internal/color"
)
type Field struct {
Key string
DefaultValue any
Description string
}
// typeName returns the type of the field without reflection
func (f *Field) typeName() string {
switch f.DefaultValue.(type) {
case string:
return "string"
case int:
return "int"
case bool:
return "bool"
case []string:
return "[]string"
case []int:
return "[]int"
default:
return "unknown"
}
}
var prettyTemplate = lo.Must(template.New("pretty").Funcs(template.FuncMap{
"faint": lipgloss.NewStyle().Faint(true).Render,
"bold": lipgloss.NewStyle().Bold(true).Render,
"purple": lipgloss.NewStyle().Foreground(color.Purple).Render,
"blue": lipgloss.NewStyle().Foreground(color.Blue).Render,
"cyan": lipgloss.NewStyle().Foreground(color.Cyan).Render,
"value": func(k string) any { return viper.Get(k) },
"hl": func(v any) string {
switch value := v.(type) {
case bool:
b := strconv.FormatBool(value)
if value {
return lipgloss.NewStyle().Foreground(color.Green).Render(b)
}
return lipgloss.NewStyle().Foreground(color.Red).Render(b)
case string:
return lipgloss.NewStyle().Foreground(color.Yellow).Render(value)
default:
return fmt.Sprint(value)
}
},
"typename": func(v any) string { return reflect.TypeOf(v).String() },
}).Parse(`{{ faint .Description }}
{{ blue "Key:" }} {{ purple .Key }}
{{ blue "Env:" }} {{ .Env }}
{{ blue "Value:" }} {{ hl (value .Key) }}
{{ blue "Default:" }} {{ hl (.DefaultValue) }}
{{ blue "Type:" }} {{ typename .DefaultValue }}`))
func (f *Field) Pretty() string {
var b strings.Builder
lo.Must0(prettyTemplate.Execute(&b, f))
return b.String()
}
func (f *Field) Env() string {
env := strings.ToUpper(EnvKeyReplacer.Replace(f.Key))
appPrefix := strings.ToUpper(app.Name + "_")
if strings.HasPrefix(env, appPrefix) {
return env
}
return appPrefix + env
}

38
internal/config/init.go Normal file
View File

@@ -0,0 +1,38 @@
package config
import (
"strings"
"github.com/spf13/viper"
"hub.cybercinch.nz/guisea/go-template/internal/app"
"hub.cybercinch.nz/guisea/go-template/internal/filesystem"
"hub.cybercinch.nz/guisea/go-template/internal/where"
)
// ConfigFormat is the format of the config file
// Available options are: json, yaml, toml
const ConfigFormat = "yaml"
var EnvKeyReplacer = strings.NewReplacer(".", "_")
func Init() error {
viper.SetConfigName(app.Name)
viper.SetConfigType(ConfigFormat)
viper.SetFs(filesystem.Api())
viper.AddConfigPath(where.Config())
viper.SetTypeByDefaultValue(true)
viper.SetEnvPrefix(app.Name)
viper.SetEnvKeyReplacer(EnvKeyReplacer)
setDefaults()
err := viper.ReadInConfig()
switch err.(type) {
case viper.ConfigFileNotFoundError:
// Use defaults then
return nil
default:
return err
}
}

View File

@@ -0,0 +1,7 @@
package key
const (
LogsWrite = "logs.write"
LogsLevel = "logs.level"
LogsReportCaller = "logs.show_caller"
)