use github.com/alimy/cfg as features configure help library

pull/195/head
Michael Li 2 years ago
parent 6738df8913
commit 72136a2266
No known key found for this signature in database

@ -5,6 +5,7 @@ go 1.18
require (
github.com/Masterminds/semver/v3 v3.1.1
github.com/afocus/captcha v0.0.0-20191010092841-4bd1f21c8868
github.com/alimy/cfg v0.1.0
github.com/aliyun/aliyun-oss-go-sdk v2.2.2+incompatible
github.com/allegro/bigcache/v3 v3.0.2
github.com/bytedance/sonic v1.5.0

@ -142,6 +142,8 @@ github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRF
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=
github.com/alexflint/go-filemutex v0.0.0-20171022225611-72bdc8eae2ae/go.mod h1:CgnQgUtFrFz9mxFNtED3jI5tLDjKlOM+oUF/sTk6ps0=
github.com/alexflint/go-filemutex v1.1.0/go.mod h1:7P4iRhttt/nUvUOrYIhcpMzv2G6CY9UnI16Z+UJqRyk=
github.com/alimy/cfg v0.1.0 h1:J7KDLEoVIjEBMGlQJb2ljad/d49gJ4Tsl2ogZ9XNhaY=
github.com/alimy/cfg v0.1.0/go.mod h1:rOxbasTH2srl6StAjNF5Vyi8bfrdkl3fLGmOYtSw81c=
github.com/aliyun/aliyun-oss-go-sdk v2.2.2+incompatible h1:9gWa46nstkJ9miBReJcN8Gq34cBFbzSpQZVVT9N09TM=
github.com/aliyun/aliyun-oss-go-sdk v2.2.2+incompatible/go.mod h1:T/Aws4fEfogEE9v+HPhhw+CntffsBHJ8nXQCwKr0/g8=
github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM=

@ -5,7 +5,7 @@ import (
"sync"
"time"
"github.com/rocboss/paopao-ce/pkg/cfg"
"github.com/alimy/cfg"
)
var (
@ -48,7 +48,7 @@ func setupSetting(suite []string, noDefault bool) error {
// initialize features configure
ss, kv := setting.featuresInfoFrom("Features")
cfg.Initialize(ss, kv)
cfg.Initial(ss, kv)
if len(suite) > 0 {
cfg.Use(suite, noDefault)
}

@ -4,8 +4,8 @@ import (
"sync"
"time"
"github.com/alimy/cfg"
"github.com/go-redis/redis/v8"
"github.com/rocboss/paopao-ce/pkg/cfg"
"github.com/sirupsen/logrus"
"gorm.io/driver/mysql"
"gorm.io/driver/postgres"

@ -3,7 +3,7 @@ package conf
import (
"io"
"github.com/rocboss/paopao-ce/pkg/cfg"
"github.com/alimy/cfg"
"github.com/sirupsen/logrus"
"gopkg.in/natefinch/lumberjack.v2"
)

@ -3,13 +3,13 @@ package dao
import (
"sync"
"github.com/alimy/cfg"
"github.com/rocboss/paopao-ce/internal/core"
"github.com/rocboss/paopao-ce/internal/dao/jinzhu"
"github.com/rocboss/paopao-ce/internal/dao/sakila"
"github.com/rocboss/paopao-ce/internal/dao/search"
"github.com/rocboss/paopao-ce/internal/dao/slonik"
"github.com/rocboss/paopao-ce/internal/dao/storage"
"github.com/rocboss/paopao-ce/pkg/cfg"
"github.com/sirupsen/logrus"
)

@ -6,11 +6,11 @@ package jinzhu
import (
"github.com/Masterminds/semver/v3"
"github.com/alimy/cfg"
"github.com/rocboss/paopao-ce/internal/conf"
"github.com/rocboss/paopao-ce/internal/core"
"github.com/rocboss/paopao-ce/internal/dao/cache"
"github.com/rocboss/paopao-ce/internal/dao/security"
"github.com/rocboss/paopao-ce/pkg/cfg"
"github.com/sirupsen/logrus"
)

@ -8,13 +8,13 @@ import (
"strconv"
"time"
"github.com/alimy/cfg"
"github.com/aliyun/aliyun-oss-go-sdk/oss"
"github.com/huaweicloud/huaweicloud-sdk-go-obs/obs"
"github.com/minio/minio-go/v7"
"github.com/minio/minio-go/v7/pkg/credentials"
"github.com/rocboss/paopao-ce/internal/conf"
"github.com/rocboss/paopao-ce/internal/core"
"github.com/rocboss/paopao-ce/pkg/cfg"
"github.com/sirupsen/logrus"
"github.com/tencentyun/cos-go-sdk-v5"
)

@ -1,10 +1,10 @@
package middleware
import (
"github.com/alimy/cfg"
"github.com/gin-gonic/gin"
"github.com/rocboss/paopao-ce/internal/model"
"github.com/rocboss/paopao-ce/pkg/app"
"github.com/rocboss/paopao-ce/pkg/cfg"
"github.com/rocboss/paopao-ce/pkg/errcode"
)

@ -4,7 +4,7 @@
package migration
import (
"github.com/rocboss/paopao-ce/pkg/cfg"
"github.com/alimy/cfg"
"github.com/sirupsen/logrus"
)

@ -6,6 +6,7 @@ package migration
import (
"database/sql"
"github.com/alimy/cfg"
"github.com/golang-migrate/migrate/v4"
"github.com/golang-migrate/migrate/v4/database"
"github.com/golang-migrate/migrate/v4/database/mysql"
@ -14,7 +15,6 @@ import (
"github.com/golang-migrate/migrate/v4/source"
"github.com/golang-migrate/migrate/v4/source/iofs"
"github.com/rocboss/paopao-ce/internal/conf"
"github.com/rocboss/paopao-ce/pkg/cfg"
"github.com/rocboss/paopao-ce/scripts/migration"
"github.com/sirupsen/logrus"
)

@ -1,10 +1,10 @@
package api
import (
"github.com/alimy/cfg"
"github.com/rocboss/paopao-ce/internal/conf"
"github.com/rocboss/paopao-ce/internal/core"
"github.com/rocboss/paopao-ce/internal/dao"
"github.com/rocboss/paopao-ce/pkg/cfg"
"github.com/sirupsen/logrus"
"github.com/smartwalle/alipay/v3"
)

@ -4,9 +4,9 @@
package routers
import (
"github.com/alimy/cfg"
"github.com/gin-gonic/gin"
"github.com/rocboss/paopao-ce/docs/openapi"
"github.com/rocboss/paopao-ce/pkg/cfg"
)
// registerDocs register docs asset route

@ -4,12 +4,12 @@ import (
"net/http"
"path/filepath"
"github.com/alimy/cfg"
"github.com/gin-contrib/cors"
"github.com/gin-gonic/gin"
"github.com/rocboss/paopao-ce/internal/conf"
"github.com/rocboss/paopao-ce/internal/middleware"
"github.com/rocboss/paopao-ce/internal/routers/api"
"github.com/rocboss/paopao-ce/pkg/cfg"
"github.com/sirupsen/logrus"
)

@ -1,10 +1,10 @@
package service
import (
"github.com/alimy/cfg"
"github.com/rocboss/paopao-ce/internal/core"
"github.com/rocboss/paopao-ce/internal/dao"
"github.com/rocboss/paopao-ce/internal/model"
"github.com/rocboss/paopao-ce/pkg/cfg"
"github.com/sirupsen/logrus"
)

@ -1,41 +0,0 @@
package cfg
var (
_features = newEmptyFeatures()
// Use alias of Features.Use func
Use = _features.Use
// UseDeafult alias of Features.UseDefault func
UseDefault = _features.UseDefault
// As alias of Features.Cfg func
As = _features.Cfg
// If alias of Features.CfgIf func
If = _features.CfgIf
// In alias of Features.CfgIn func
In = _features.CfgIn
// Be alias of Feaures.CfgBe func
Be = _features.CfgBe
// Not alias of Features.CfgNot func
Not = _features.CfgNot
)
// Initialize initialize features in cfg pkg
func Initialize(suites map[string][]string, kv map[string]string) {
_features = NewFeatures(suites, kv)
{
// must re-assign variable below
Use = _features.Use
UseDefault = _features.UseDefault
As = _features.Cfg
If = _features.CfgIf
In = _features.CfgIn
Be = _features.CfgBe
Not = _features.CfgNot
}
}

@ -1,78 +0,0 @@
package cfg
import (
"testing"
)
func TestCfg(t *testing.T) {
suites := map[string][]string{
"default": {"Sms", "Alipay", "Zinc", "MySQL", "Redis", "AliOSS", "LogZinc"},
"develop": {"Zinc", "MySQL", "AliOSS", "LogFile"},
"slim": {"Zinc", "MySQL", "Redis", "AliOSS", "LogFile"},
}
kv := map[string]string{
"sms": "SmsJuhe",
}
Initialize(suites, kv)
UseDefault()
if !If("Sms") {
t.Error(`want If("Sms") == true but not`)
}
if v, exist := As("Sms"); exist && v != "SmsJuhe" {
t.Errorf(`want As("Sms") == "SmsJuhe", true but got: "%s", "%t"`, v, exist)
}
matched := false
Be("Alipay", func() {
matched = true
})
if !matched {
t.Error(`want Be("Alipay", ...) matched but not`)
}
matched = false
Not("LogFile", func() {
matched = true
})
if !matched {
t.Error(`want Not("LogFile", ...) matched but not`)
}
var m1, m2, m3, m4 bool
In(Actions{
"Sms": func() {
m1 = true
},
"Alipay": func() {
m2 = true
},
"Meili": func() {
m4 = true
},
}, func() {
m3 = true
})
if !m1 || !m2 || m3 || m4 {
t.Errorf(`In("Sms", "Alipay", "Meili", ...) not correct -> m1: %t m2:%t m3:%t m4:%t`, m1, m2, m3, m4)
}
m1 = false
m2 = false
m3 = false
In(Actions{
"LogFile": func() {
m1 = true
},
"Meili": func() {
m2 = true
},
}, func() {
m3 = true
})
if m1 || m2 || !m3 {
t.Errorf(`In("Zinc", "MySQL", ...) not correct -> m1: %t m2:%t m3:%t`, m1, m2, m3)
}
}

@ -1,149 +0,0 @@
package cfg
import (
"strings"
"github.com/rocboss/paopao-ce/pkg/types"
)
// Features fetures info struct
type Features struct {
kv map[string]string
suites map[string][]string
features map[string]string
}
// Actions feature-func map alias type
type Actions map[string]types.Fn
// NewFeatures create new Features instance
func NewFeatures(suites map[string][]string, kv map[string]string) *Features {
f := newEmptyFeatures()
for k, v := range suites {
if len(k) > 0 {
for i := 0; i < len(v); i++ {
// ignore empty string
if len(v[i]) == 0 {
lastIdx := len(v) - 1
v[i] = v[lastIdx]
v = v[:lastIdx]
i--
}
}
if len(v) > 0 {
f.suites[k] = v
}
}
}
for k, v := range kv {
if len(k) > 0 && len(v) > 0 {
f.kv[k] = v
}
}
f.UseDefault()
return f
}
func newEmptyFeatures() *Features {
return &Features{
suites: make(map[string][]string),
kv: make(map[string]string),
features: make(map[string]string),
}
}
// UseDefault use default suite for features
func (f *Features) UseDefault() {
f.Use([]string{"default"}, true)
}
// Use use custom suite for features
func (f *Features) Use(suite []string, noDefault bool) {
if noDefault && len(f.features) != 0 {
f.features = make(map[string]string)
}
features := f.flatFeatures(suite)
for _, feature := range features {
if len(feature) == 0 {
continue
}
f.features[feature] = f.kv[feature]
}
}
func (f *Features) flatFeatures(suite []string) []string {
features := make([]string, 0, len(suite)+10)
for s := suite[:]; len(s) > 0; s = s[:len(s)-1] {
item := strings.TrimSpace(strings.ToLower(s[0]))
if len(item) > 0 {
if items, exist := f.suites[item]; exist {
s = append(s, items...)
}
features = append(features, item)
}
s[0] = s[len(s)-1]
}
return features
}
// Cfg get value by key if exist
func (f *Features) Cfg(key string) (string, bool) {
key = strings.ToLower(key)
value, exist := f.features[key]
return value, exist
}
// CfgIf check expression is true. if expression just have a string like
// `Sms` is mean `Sms` whether define in suite feature settings. expression like
// `Sms = SmsJuhe` is mean whether `Sms` define in suite feature settings and value
// is `SmsJuhe`
func (f *Features) CfgIf(expression string) bool {
kv := strings.Split(expression, "=")
key := strings.Trim(strings.ToLower(kv[0]), " ")
v, ok := f.features[key]
if len(kv) == 2 && ok && strings.Trim(kv[1], " ") == v {
return true
} else if len(kv) == 1 && ok {
return true
}
return false
}
// CfgIn range actions to check item's expression is true then do the handle, defFn will handle
// if all items are not matched,
func (f *Features) CfgIn(actions Actions, defAct ...types.Fn) {
itemMatched := false
for expression, handle := range actions {
if f.CfgIf(expression) && handle != nil {
handle()
itemMatched = true
}
}
if !itemMatched && len(defAct) > 0 {
for _, handle := range defAct {
if handle != nil {
handle()
}
}
}
}
// CfgBe check expression is true then do the handle. if expression just have a string like
// `Sms` is mean `Sms` whether defined in suite feature settings. expression like
// `Sms = SmsJuhe` is mean whether `Sms` define in suite feature settings and value
// is `SmsJuhe`
func (f *Features) CfgBe(expression string, handle types.Fn) {
if f.CfgIf(expression) && handle != nil {
handle()
}
}
// CfgNot check expression is not true then do the handle. if expression just have a string like
// `Sms` is mean `Sms` whether defined in suite feature settings. expression like
// `Sms = SmsJuhe` is mean whether `Sms` define in suite feature settings and value
// is `SmsJuhe`
func (f *Features) CfgNot(expression string, handle func()) {
if !f.CfgIf(expression) {
handle()
}
}

@ -1,114 +0,0 @@
package cfg
import (
"testing"
)
func TestUseDefault(t *testing.T) {
suites := map[string][]string{
"default": {"Sms", "Alipay", "Zinc", "MySQL", "Redis", "AliOSS", "LogZinc"},
"develop": {"Zinc", "MySQL", "AliOSS", "LogFile"},
"slim": {"Zinc", "MySQL", "Redis", "AliOSS", "LogFile"},
}
kv := map[string]string{
"sms": "SmsJuhe",
}
f := NewFeatures(suites, kv)
for _, data := range []struct {
key string
expect string
exist bool
}{
{"Sms", "SmsJuhe", true},
{"Alipay", "", true},
{"Zinc", "", true},
{"Redis", "", true},
{"Database", "", false},
} {
if v, ok := f.Cfg(data.key); ok != data.exist || v != data.expect {
t.Errorf("key: %s expect: %s exist: %t got v: %s ok: %t", data.key, data.expect, data.exist, v, ok)
}
}
for exp, res := range map[string]bool{
"Sms": true,
"Sms = SmsJuhe": true,
"SmsJuhe": false,
"default": true,
} {
if ok := f.CfgIf(exp); res != ok {
t.Errorf("CfgIf(%s) want %t got %t", exp, res, ok)
}
}
}
func TestUse(t *testing.T) {
suites := map[string][]string{
"default": {"Sms", "Alipay", "Zinc", "MySQL", "Redis", "AliOSS", "LogZinc"},
"develop": {"Zinc", "MySQL", "AliOSS", "LogFile"},
"slim": {"Zinc", "MySQL", "Redis", "AliOSS", "LogFile"},
}
kv := map[string]string{
"sms": "SmsJuhe",
}
f := NewFeatures(suites, kv)
f.Use([]string{"develop"}, true)
for _, data := range []struct {
key string
expect string
exist bool
}{
{"Sms", "", false},
{"Alipay", "", false},
{"Zinc", "", true},
{"Redis", "", false},
{"Database", "", false},
} {
if v, ok := f.Cfg(data.key); ok != data.exist || v != data.expect {
t.Errorf("key: %s expect: %s exist: %t got v: %s ok: %t", data.key, data.expect, data.exist, v, ok)
}
}
for exp, res := range map[string]bool{
"Sms": false,
"Sms = SmsJuhe": false,
"SmsJuhe": false,
"default": false,
"develop": true,
} {
if ok := f.CfgIf(exp); res != ok {
t.Errorf("CfgIf(%s) want %t got %t", exp, res, ok)
}
}
f.UseDefault()
f.Use([]string{"slim", "", "demo"}, false)
for _, data := range []struct {
key string
expect string
exist bool
}{
{"Sms", "SmsJuhe", true},
{"Alipay", "", true},
{"Zinc", "", true},
{"Redis", "", true},
{"Database", "", false},
{"demo", "", true},
} {
if v, ok := f.Cfg(data.key); ok != data.exist || v != data.expect {
t.Errorf("key: %s expect: %s exist: %t got v: %s ok: %t", data.key, data.expect, data.exist, v, ok)
}
}
for exp, res := range map[string]bool{
"Sms": true,
"Sms = SmsJuhe": true,
"SmsJuhe": false,
"default": true,
"develop": false,
"slim": true,
"demo": true,
} {
if ok := f.CfgIf(exp); res != ok {
t.Errorf("CfgIf(%s) want %t got %t", exp, res, ok)
}
}
}
Loading…
Cancel
Save