Replace viper with koanf

This commit is contained in:
Kailash Nadh 2019-06-26 16:53:23 +05:30
parent fe9102120c
commit fe4f39f65d
5 changed files with 77 additions and 70 deletions

7
go.mod
View File

@ -1,13 +1,13 @@
module github.com/knadh/listmonk
require (
github.com/BurntSushi/toml v0.3.1 // indirect
github.com/asaskevich/govalidator v0.0.0-20180720115003-f9ffefc3facf
github.com/disintegration/imaging v1.5.0
github.com/jinzhu/gorm v1.9.1
github.com/jmoiron/sqlx v1.2.0
github.com/jordan-wright/email v0.0.0-20181027021455-480bedc4908b
github.com/knadh/goyesql v1.1.1
github.com/knadh/koanf v0.4.2
github.com/knadh/stuffbin v0.0.0-20190103171338-6379e949be48
github.com/labstack/echo v3.3.10+incompatible
github.com/labstack/gommon v0.2.7 // indirect
@ -16,12 +16,11 @@ require (
github.com/mattn/go-isatty v0.0.4 // indirect
github.com/satori/go.uuid v1.2.0
github.com/spf13/pflag v1.0.3
github.com/spf13/viper v1.2.1
github.com/stretchr/testify v1.3.0 // indirect
github.com/valyala/bytebufferpool v1.0.0 // indirect
github.com/valyala/fasttemplate v0.0.0-20170224212429-dcecefd839c4 // indirect
golang.org/x/crypto v0.0.0-20181106171534-e4dc69e5b2fd
golang.org/x/crypto v0.0.0-20181106171534-e4dc69e5b2fd // indirect
golang.org/x/image v0.0.0-20181116024801-cd38e8056d9b // indirect
golang.org/x/sys v0.0.0-20180906133057-8cf3aee42992 // indirect
google.golang.org/appengine v1.4.0 // indirect
gopkg.in/volatiletech/null.v6 v6.0.0-20170828023728-0bef4e07ae1b
)

39
go.sum
View File

@ -1,13 +1,16 @@
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/asaskevich/govalidator v0.0.0-20180720115003-f9ffefc3facf h1:eg0MeVzsP1G42dRafH3vf+al2vQIJU0YHX+1Tw87oco=
github.com/asaskevich/govalidator v0.0.0-20180720115003-f9ffefc3facf/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/disintegration/imaging v1.5.0 h1:uYqUhwNmLU4K1FN44vhqS4TZJRAA4RhBINgbQlKyGi0=
github.com/disintegration/imaging v1.5.0/go.mod h1:9B/deIUIrliYkyMTuXJd6OUFLcrZ2tf+3Qlwnaf/CjU=
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/go-sql-driver/mysql v1.4.0 h1:7LxgVwFb2hIQtMm87NdgAVfXjnt4OePseqT1tKx+opk=
github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
github.com/go-yaml/yaml v2.1.0+incompatible h1:RYi2hDdss1u4YE7GwixGzWwVo47T8UQwnTLB6vQiq+o=
github.com/go-yaml/yaml v2.1.0+incompatible/go.mod h1:w2MrLa16VYP0jy6N7M5kHaCkaLENm+P+Tv+MfurjSw0=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
@ -19,42 +22,34 @@ github.com/jordan-wright/email v0.0.0-20181027021455-480bedc4908b h1:veTPVnbkOij
github.com/jordan-wright/email v0.0.0-20181027021455-480bedc4908b/go.mod h1:1c7szIrayyPPB/987hsnvNzLushdWf4o/79s3P08L8A=
github.com/knadh/goyesql v1.1.1 h1:iQLgsjYI/zC417DhmZYxmJgWmCHhtV4fho5QazWL/1g=
github.com/knadh/goyesql v1.1.1/go.mod h1:W0tSzU8l7lYH1Fihj+bdQzkzOwvirrsMNHwkuY22qoY=
github.com/knadh/koanf v0.4.2 h1:A/bb9+eRoHHHQ57O6y66vzRCYui915CK3FdDYzNs56Q=
github.com/knadh/koanf v0.4.2/go.mod h1:Qd5yvXN39ZzjoRJdXMKN2QqHzQKhSx/K8fU5gyn4LPs=
github.com/knadh/stuffbin v0.0.0-20190103171338-6379e949be48 h1:lRb28d0+iiVwqF7Li25IJXjNRaVCQPH6n/fHwk9Qo+E=
github.com/knadh/stuffbin v0.0.0-20190103171338-6379e949be48/go.mod h1:afUOPBWr6bZ09aS3wbSOqXVGaO6rKcyvXYTcuG9LYpI=
github.com/labstack/echo v3.3.5+incompatible h1:9PfxPUmasKzeJor9uQTaXLT6WUG/r+vSTmvXxvv3JO4=
github.com/labstack/echo v3.3.5+incompatible/go.mod h1:0INS7j/VjnFxD4E2wkz67b8cVwCLbBmJyDaka6Cmk1s=
github.com/labstack/echo v3.3.10+incompatible h1:pGRcYk231ExFAyoAjAfD85kQzRJCRI8bbnE7CX5OEgg=
github.com/labstack/echo v3.3.10+incompatible/go.mod h1:0INS7j/VjnFxD4E2wkz67b8cVwCLbBmJyDaka6Cmk1s=
github.com/labstack/gommon v0.2.7 h1:2qOPq/twXDrQ6ooBGrn3mrmVOC+biLlatwgIu8lbzRM=
github.com/labstack/gommon v0.2.7/go.mod h1:/tj9csK2iPSBvn+3NLM9e52usepMtrd5ilFYA+wQNJ4=
github.com/lib/pq v1.0.0 h1:X5PMW56eZitiTeO7tKzZxFCSpbFZJtkMMooicw2us9A=
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/magiconair/properties v1.8.0 h1:LLgXmsheXeRoUOBOjtwPQCWIYqM/LU1ayDtDePerRcY=
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/mattn/go-colorable v0.0.9 h1:UVL0vNpWh04HeJXV0KLcaT7r06gOH2l4OW6ddYRUIY4=
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
github.com/mattn/go-isatty v0.0.4 h1:bnP0vzxcAdeI1zdubAl5PjU6zsERjGZb7raWodagDYs=
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/mattn/go-sqlite3 v1.9.0 h1:pDRiWfl+++eC2FEFRy6jXmQlvp4Yh3z1MJKg4UeYM/4=
github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
github.com/mitchellh/mapstructure v1.0.0 h1:vVpGvMXJPqSDh2VYHF7gsfQj8Ncx+Xw5Y1KHeTRY+7I=
github.com/mitchellh/mapstructure v1.0.0/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/pelletier/go-toml v1.4.0 h1:u3Z1r+oOXJIkxqw34zVhyPgjBsm6X2wn21NWs/HfSeg=
github.com/pelletier/go-toml v1.4.0/go.mod h1:PN7xzY2wHTK0K9p34ErDQMlFxa51Fk0OUruD3k1mMwo=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww=
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
github.com/spf13/afero v1.1.2 h1:m8/z1t7/fwjysjQRYbP0RD+bUIF/8tJwPdEZsI83ACI=
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
github.com/spf13/cast v1.2.0 h1:HHl1DSRbEQN2i8tJmtS6ViPyHx35+p51amrdsiTCrkg=
github.com/spf13/cast v1.2.0/go.mod h1:r2rcYCSwa1IExKTDiTfzaxqT2FNHs8hODu4LnUfgKEg=
github.com/spf13/jwalterweatherman v1.0.0 h1:XHEdyB+EcvlqZamSM4ZOMGlc93t6AcsBEu9Gc1vn7yk=
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
github.com/spf13/pflag v1.0.2/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg=
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/viper v1.2.1 h1:bIcUwXqLseLF3BDAZduuNfekWG87ibtFxi59Bq+oI9M=
github.com/spf13/viper v1.2.1/go.mod h1:P4AexN0a+C9tGAnUFNwDMYYZv3pjFuvmeiMyKRaNVlI=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
@ -69,9 +64,11 @@ golang.org/x/sys v0.0.0-20180906133057-8cf3aee42992 h1:BH3eQWeGbwRU2+wxxuuPOdFBm
golang.org/x/sys v0.0.0-20180906133057-8cf3aee42992/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
google.golang.org/appengine v1.4.0 h1:/wp5JvzpHIxhs/dumFmF7BXTf3Z+dd4uXta4kVyO508=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/volatiletech/null.v6 v6.0.0-20170828023728-0bef4e07ae1b h1:P+3+n9hUbqSDkSdtusWHVPQRrpRpLiLFzlZ02xXskM0=
gopkg.in/volatiletech/null.v6 v6.0.0-20170828023728-0bef4e07ae1b/go.mod h1:0LRKfykySnChgQpG3Qpk+bkZFWazQ+MMfc5oldQCwnY=
gopkg.in/yaml.v2 v2.2.1 h1:mUhvW9EsL+naU5Q3cakzfE91YhliOondGd6ZrsDBHQE=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=

View File

@ -10,7 +10,6 @@ import (
"github.com/knadh/listmonk/models"
"github.com/lib/pq"
uuid "github.com/satori/go.uuid"
"github.com/spf13/viper"
)
// install runs the first time setup of creating and
@ -19,7 +18,7 @@ func install(app *App, qMap goyesql.Queries) {
fmt.Println("")
fmt.Println("** First time installation **")
fmt.Printf("** IMPORTANT: This will wipe existing listmonk tables and types in the DB '%s' **",
viper.GetString("db.database"))
ko.String("db.database"))
fmt.Println("")
var ok string
@ -84,7 +83,7 @@ func install(app *App, qMap goyesql.Queries) {
}
logger.Printf("Setup complete")
logger.Printf(`Run the program view it at %s`, viper.GetString("app.address"))
logger.Printf(`Run the program view it at %s`, ko.String("app.address"))
}

82
main.go
View File

@ -12,13 +12,16 @@ import (
_ "github.com/jinzhu/gorm/dialects/postgres"
"github.com/jmoiron/sqlx"
"github.com/knadh/goyesql"
"github.com/knadh/koanf"
"github.com/knadh/koanf/parsers/toml"
"github.com/knadh/koanf/providers/file"
"github.com/knadh/koanf/providers/posflag"
"github.com/knadh/listmonk/manager"
"github.com/knadh/listmonk/messenger"
"github.com/knadh/listmonk/subimporter"
"github.com/knadh/stuffbin"
"github.com/labstack/echo"
flag "github.com/spf13/pflag"
"github.com/spf13/viper"
)
type constants struct {
@ -45,39 +48,42 @@ type App struct {
Messenger messenger.Messenger
}
var logger *log.Logger
var (
// Global logger.
logger = log.New(os.Stdout, "", log.Ldate|log.Ltime|log.Lshortfile)
func init() {
logger = log.New(os.Stdout, "SYS: ", log.Ldate|log.Ltime|log.Lshortfile)
// Global configuration reader.
ko = koanf.New(".")
)
func initConfig(ko *koanf.Koanf) error {
// Register --help handler.
flagSet := flag.NewFlagSet("config", flag.ContinueOnError)
flagSet.Usage = func() {
fmt.Println(flagSet.FlagUsages())
f := flag.NewFlagSet("config", flag.ContinueOnError)
f.Usage = func() {
fmt.Println(f.FlagUsages())
os.Exit(0)
}
// Setup the default configuration.
viper.SetConfigName("config")
flagSet.StringSlice("config", []string{"config.toml"},
f.StringSlice("config", []string{"config.toml"},
"Path to one or more config files (will be merged in order)")
flagSet.Bool("install", false, "Run first time installation")
flagSet.Bool("version", false, "Current version of the build")
f.Bool("install", false, "Run first time installation")
f.Bool("version", false, "Current version of the build")
// Process flags.
flagSet.Parse(os.Args[1:])
viper.BindPFlags(flagSet)
f.Parse(os.Args[1:])
// Read the config files.
cfgs := viper.GetStringSlice("config")
for _, c := range cfgs {
logger.Printf("reading config: %s", c)
viper.SetConfigFile(c)
if err := viper.MergeInConfig(); err != nil {
logger.Fatalf("error reading config: %s", err)
// Load config files.
cFiles, _ := f.GetStringSlice("config")
for _, f := range cFiles {
log.Printf("reading config: %s", f)
if err := ko.Load(file.Provider(f), toml.Parser()); err != nil {
return err
}
}
ko.Load(posflag.Provider(f, ".", ko), nil)
return nil
}
// initFileSystem initializes the stuffbin FileSystem to provide
@ -116,14 +122,14 @@ func initFileSystem(binPath string) (stuffbin.FileSystem, error) {
func initMessengers(r *manager.Manager) messenger.Messenger {
// Load SMTP configurations for the default e-mail Messenger.
var srv []messenger.Server
for name := range viper.GetStringMapString("smtp") {
if !viper.GetBool(fmt.Sprintf("smtp.%s.enabled", name)) {
for _, name := range ko.MapKeys("smtp") {
if !ko.Bool(fmt.Sprintf("smtp.%s.enabled", name)) {
logger.Printf("skipped SMTP: %s", name)
continue
}
var s messenger.Server
viper.UnmarshalKey("smtp."+name, &s)
ko.Unmarshal("smtp."+name, &s)
s.Name = name
s.SendTimeout = s.SendTimeout * time.Millisecond
srv = append(srv, s)
@ -143,20 +149,26 @@ func initMessengers(r *manager.Manager) messenger.Messenger {
}
func main() {
// Load config into the global conf.
if err := initConfig(ko); err != nil {
logger.Printf("error reading config: %v", err)
os.Exit(1)
}
// Connect to the DB.
db, err := connectDB(viper.GetString("db.host"),
viper.GetInt("db.port"),
viper.GetString("db.user"),
viper.GetString("db.password"),
viper.GetString("db.database"),
viper.GetString("db.ssl_mode"))
db, err := connectDB(ko.String("db.host"),
ko.Int("db.port"),
ko.String("db.user"),
ko.String("db.password"),
ko.String("db.database"),
ko.String("db.ssl_mode"))
if err != nil {
logger.Fatalf("error connecting to DB: %v", err)
}
defer db.Close()
var c constants
viper.UnmarshalKey("app", &c)
ko.Unmarshal("app", &c)
c.RootURL = strings.TrimRight(c.RootURL, "/")
c.UploadURI = filepath.Clean(c.UploadURI)
c.UploadPath = filepath.Clean(c.UploadPath)
@ -187,7 +199,7 @@ func main() {
}
// Run the first time installation.
if viper.GetBool("install") {
if ko.Bool("install") {
install(app, qMap)
return
}
@ -222,8 +234,8 @@ func main() {
return sendNotification(notifTplCampaign, subject, data, app)
}
m := manager.New(manager.Config{
Concurrency: viper.GetInt("app.concurrency"),
MaxSendErrors: viper.GetInt("app.max_send_errors"),
Concurrency: ko.Int("app.concurrency"),
MaxSendErrors: ko.Int("app.max_send_errors"),
FromEmail: app.Constants.FromEmail,
// url.com/unsubscribe/{campaign_uuid}/{subscriber_uuid}
@ -273,5 +285,5 @@ func main() {
srv.GET("/frontend/*", echo.WrapHandler(fSrv))
srv.Static(c.UploadURI, c.UploadURI)
registerHandlers(srv)
srv.Logger.Fatal(srv.Start(viper.GetString("app.address")))
srv.Logger.Fatal(srv.Start(ko.String("app.address")))
}

View File

@ -14,13 +14,13 @@ const emName = "email"
// Server represents an SMTP server's credentials.
type Server struct {
Name string
Host string `mapstructure:"host"`
Port int `mapstructure:"port"`
AuthProtocol string `mapstructure:"auth_protocol"`
Username string `mapstructure:"username"`
Password string `mapstructure:"password"`
SendTimeout time.Duration `mapstructure:"send_timeout"`
MaxConns int `mapstructure:"max_conns"`
Host string `koanf:"host"`
Port int `koanf:"port"`
AuthProtocol string `koanf:"auth_protocol"`
Username string `koanf:"username"`
Password string `koanf:"password"`
SendTimeout time.Duration `koanf:"send_timeout"`
MaxConns int `koanf:"max_conns"`
mailer *email.Pool
}