From ae4020fdcfefd3487ec140b815f5542cb8ea726c Mon Sep 17 00:00:00 2001 From: Ankit Patial Date: Thu, 18 Sep 2025 23:22:39 +0530 Subject: [PATCH] go1.25 bumped lib version added in dotenv assign func --- crypto/hash.go | 8 ---- dotenv/assign.go | 82 +++++++++++++++++++++++++++++++++++++++++ dotenv/parser.go | 6 +-- dotenv/read.go | 13 ++++--- dotenv/write.go | 2 +- email/transport_smtp.go | 3 +- go.mod | 15 ++++---- go.sum | 30 ++++++--------- ptr/ptr.go | 2 +- request/pager.go | 17 +++++---- structs/structs.go | 2 +- 11 files changed, 127 insertions(+), 53 deletions(-) create mode 100644 dotenv/assign.go diff --git a/crypto/hash.go b/crypto/hash.go index 504364c..9f1efda 100644 --- a/crypto/hash.go +++ b/crypto/hash.go @@ -17,14 +17,6 @@ func MD5(b []byte) string { return hex.EncodeToString(hash[:]) } -/* -func MD5Int(b []byte) uint64 { - n := new(big.Int) - n.SetString(MD5(b), 16) - return n.Uint64() -} -*/ - // SHA256 Sum256 is generally preferred over md5.hash due to its superior security and resistance to collision attacks func SHA256(b []byte) string { hash := sha256.Sum256(b) diff --git a/dotenv/assign.go b/dotenv/assign.go new file mode 100644 index 0000000..3b65541 --- /dev/null +++ b/dotenv/assign.go @@ -0,0 +1,82 @@ +package dotenv + +import ( + "errors" + "log/slog" + "reflect" + "strconv" + "strings" +) + +// Assign env tag matching values from envMap +func Assign[T any](c *T, envMap map[string]string) error { + if c == nil { + return errors.New("nil arg") + } + + slog.Info("env map", "v", envMap) + + val := reflect.Indirect(reflect.ValueOf(c)) + name := val.Type().Name() + for i := range val.NumField() { + f := val.Type().Field(i) + tag := f.Tag.Get("env") + if tag == "" { + continue + } + + var v string + var ok bool + if multiTag := strings.Split(tag, ","); len(multiTag) > 1 { + // multi tags like env:"DB_URL,PG_DB_URL" + for _, mt := range multiTag { + if v, ok = envMap[strings.TrimSpace(mt)]; ok { + break + } + } + } else { + v, ok = envMap[tag] + } + + if !ok { + continue + } + + field := val.FieldByName(f.Name) + if !field.IsValid() { + continue + } + + switch f.Type.Kind() { + case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int: + if v, err := strconv.ParseInt(v, 10, 64); err != nil { + return err + } else { + field.SetInt(v) + } + case reflect.Float32, reflect.Float64: + if v, err := strconv.ParseFloat(v, 10); err != nil { + return err + } else { + field.SetFloat(v) + } + case reflect.Bool: + if strings.EqualFold(v, "true") { + field.SetBool(true) + } else { + field.SetBool(false) + } + + default: + field.SetString(v) + } + + if name == "" { + slog.Info("override value from env", "field", f.Name) + } else { + slog.Info("override value from env", "type", name, "field", f.Name) + } + } + + return nil +} diff --git a/dotenv/parser.go b/dotenv/parser.go index 1d68e21..5c932af 100644 --- a/dotenv/parser.go +++ b/dotenv/parser.go @@ -23,7 +23,7 @@ const ( ) func parseBytes(src []byte, out map[string]string) error { - src = bytes.Replace(src, []byte("\r\n"), []byte("\n"), -1) + src = bytes.ReplaceAll(src, []byte("\r\n"), []byte("\n")) cutset := src for { cutset = getStatementStart(cutset) @@ -76,8 +76,8 @@ func getStatementStart(src []byte) []byte { func locateKeyName(src []byte) (key string, cutset []byte, err error) { // trim "export" and space at beginning src = bytes.TrimLeftFunc(src, isSpace) - if bytes.HasPrefix(src, []byte(exportPrefix)) { - trimmed := bytes.TrimPrefix(src, []byte(exportPrefix)) + if after, ok := bytes.CutPrefix(src, []byte(exportPrefix)); ok { + trimmed := after if bytes.IndexFunc(trimmed, isSpace) == 0 { src = bytes.TrimLeftFunc(trimmed, isSpace) } diff --git a/dotenv/read.go b/dotenv/read.go index d8595c8..2cc3797 100644 --- a/dotenv/read.go +++ b/dotenv/read.go @@ -22,14 +22,17 @@ func Read(dir string, filenames ...string) (envMap map[string]string, err error) for _, filename := range filenames { slog.Info("read .env", slog.String("file", filepath.Join(dir, filename))) - individualEnvMap, individualErr := readFile(filepath.Join(dir, filename)) - - if individualErr != nil { - err = individualErr + m, er := readFile(filepath.Join(dir, filename)) + if er != nil { + if os.IsNotExist(er) { + slog.Info(".env not found", slog.String("file", filename)) + continue + } + err = er return } - maps.Copy(envMap, individualEnvMap) + maps.Copy(envMap, m) } return diff --git a/dotenv/write.go b/dotenv/write.go index 14f454d..6afb650 100644 --- a/dotenv/write.go +++ b/dotenv/write.go @@ -56,7 +56,7 @@ func doubleQuoteEscape(line string) string { if c == '\r' { toReplace = `\r` } - line = strings.Replace(line, string(c), toReplace, -1) + line = strings.ReplaceAll(line, string(c), toReplace) } return line } diff --git a/email/transport_smtp.go b/email/transport_smtp.go index f7e26fe..7beca77 100644 --- a/email/transport_smtp.go +++ b/email/transport_smtp.go @@ -17,11 +17,12 @@ import ( // SMTP mailer type SMTP struct { Host string - Port int Username string Password string // Domain name for smtp Domain string + + Port int } func (t SMTP) Send(msg *Message) error { diff --git a/go.mod b/go.mod index 70fa883..2a31b9f 100644 --- a/go.mod +++ b/go.mod @@ -1,21 +1,20 @@ module code.patial.tech/go/appcore -go 1.24 +go 1.25 require ( - github.com/go-playground/validator/v10 v10.26.0 - github.com/golang-jwt/jwt/v5 v5.2.2 + github.com/go-playground/validator/v10 v10.27.0 + github.com/golang-jwt/jwt/v5 v5.3.0 github.com/google/uuid v1.6.0 github.com/sqids/sqids-go v0.4.1 - golang.org/x/crypto v0.39.0 + golang.org/x/crypto v0.42.0 ) require ( - github.com/gabriel-vasile/mimetype v1.4.9 // indirect + github.com/gabriel-vasile/mimetype v1.4.10 // indirect github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect github.com/leodido/go-urn v1.4.0 // indirect - golang.org/x/net v0.41.0 // indirect - golang.org/x/sys v0.33.0 // indirect - golang.org/x/text v0.26.0 // indirect + golang.org/x/sys v0.36.0 // indirect + golang.org/x/text v0.29.0 // indirect ) diff --git a/go.sum b/go.sum index 0338ae8..a848989 100644 --- a/go.sum +++ b/go.sum @@ -1,19 +1,17 @@ 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/gabriel-vasile/mimetype v1.4.8 h1:FfZ3gj38NjllZIeJAmMhr+qKL8Wu+nOoI3GqacKw1NM= -github.com/gabriel-vasile/mimetype v1.4.8/go.mod h1:ByKUIKGjh1ODkGM1asKUbQZOLGrPjydw3hYPU2YU9t8= -github.com/gabriel-vasile/mimetype v1.4.9 h1:5k+WDwEsD9eTLL8Tz3L0VnmVh9QxGjRmjBvAG7U/oYY= -github.com/gabriel-vasile/mimetype v1.4.9/go.mod h1:WnSQhFKJuBlRyLiKohA/2DtIlPFAbguNaG7QCHcyGok= +github.com/gabriel-vasile/mimetype v1.4.10 h1:zyueNbySn/z8mJZHLt6IPw0KoZsiQNszIpU+bX4+ZK0= +github.com/gabriel-vasile/mimetype v1.4.10/go.mod h1:d+9Oxyo1wTzWdyVUPMmXFvp4F9tea18J8ufA774AB3s= github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= -github.com/go-playground/validator/v10 v10.26.0 h1:SP05Nqhjcvz81uJaRfEV0YBSSSGMc/iMaVtFbr3Sw2k= -github.com/go-playground/validator/v10 v10.26.0/go.mod h1:I5QpIEbmr8On7W0TktmJAumgzX4CA1XNl4ZmDuVHKKo= -github.com/golang-jwt/jwt/v5 v5.2.2 h1:Rl4B7itRWVtYIHFrSNd7vhTiz9UpLdi6gZhZ3wEeDy8= -github.com/golang-jwt/jwt/v5 v5.2.2/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= +github.com/go-playground/validator/v10 v10.27.0 h1:w8+XrWVMhGkxOaaowyKH35gFydVHOvC0/uWoy2Fzwn4= +github.com/go-playground/validator/v10 v10.27.0/go.mod h1:I5QpIEbmr8On7W0TktmJAumgzX4CA1XNl4ZmDuVHKKo= +github.com/golang-jwt/jwt/v5 v5.3.0 h1:pv4AsKCKKZuqlgs5sUmn4x8UlGa0kEVt/puTpKx9vvo= +github.com/golang-jwt/jwt/v5 v5.3.0/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArsqaEUEa5bE= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= @@ -24,15 +22,11 @@ github.com/sqids/sqids-go v0.4.1 h1:eQKYzmAZbLlRwHeHYPF35QhgxwZHLnlmVj9AkIj/rrw= github.com/sqids/sqids-go v0.4.1/go.mod h1:EMwHuPQgSNFS0A49jESTfIQS+066XQTVhukrzEPScl8= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= -golang.org/x/crypto v0.39.0 h1:SHs+kF4LP+f+p14esP5jAoDpHU8Gu/v9lFRK6IT5imM= -golang.org/x/crypto v0.39.0/go.mod h1:L+Xg3Wf6HoL4Bn4238Z6ft6KfEpN0tJGo53AAPC632U= -golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0= -golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k= -golang.org/x/net v0.41.0 h1:vBTly1HeNPEn3wtREYfy4GZ/NECgw2Cnl+nK6Nz3uvw= -golang.org/x/net v0.41.0/go.mod h1:B/K4NNqkfmg07DQYrbwvSluqCJOOXwUjeb/5lOisjbA= -golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw= -golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= -golang.org/x/text v0.26.0 h1:P42AVeLghgTYr4+xUnTRKDMqpar+PtX7KWuNQL21L8M= -golang.org/x/text v0.26.0/go.mod h1:QK15LZJUUQVJxhz7wXgxSy/CJaTFjd0G+YLonydOVQA= +golang.org/x/crypto v0.42.0 h1:chiH31gIWm57EkTXpwnqf8qeuMUi0yekh6mT2AvFlqI= +golang.org/x/crypto v0.42.0/go.mod h1:4+rDnOTJhQCx2q7/j6rAN5XDw8kPjeaXEUR2eL94ix8= +golang.org/x/sys v0.36.0 h1:KVRy2GtZBrk1cBYA7MKu5bEZFxQk4NIDV6RLVcC8o0k= +golang.org/x/sys v0.36.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/text v0.29.0 h1:1neNs90w9YzJ9BocxfsQNHKuAT4pkghyXc4nhZ6sJvk= +golang.org/x/text v0.29.0/go.mod h1:7MhJOA9CD2qZyOKYazxdYMF85OwPdEr9jTtBpO7ydH4= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/ptr/ptr.go b/ptr/ptr.go index 9820681..cd2e70a 100644 --- a/ptr/ptr.go +++ b/ptr/ptr.go @@ -39,7 +39,7 @@ func StrTrim(v *string) *string { } type N interface { - uint8 | int8 | uint16 | int16 | uint | int | uint32 | int32 | uint64 | int64 | float32 | float64 + uint8 | int8 | uint16 | int16 | uint32 | int32 | uint64 | int64 | uint | int | float32 | float64 } func Number[T N](v T) *T { diff --git a/request/pager.go b/request/pager.go index 6d2e323..30b1f4b 100644 --- a/request/pager.go +++ b/request/pager.go @@ -14,13 +14,16 @@ import ( ) type Pager struct { - Search string - OrderBy *string `json:"orderBy"` - OrderAsc *bool `json:"orderAsc"` - Page int `json:"page"` - Size int `json:"size"` - Total int `json:"total"` - TotalNeeded bool `json:"-"` + OrderBy *string `json:"orderBy"` + OrderAsc *bool `json:"orderAsc"` + + Search string + + Page int `json:"page"` + Size int `json:"size"` + Total int `json:"total"` + + TotalNeeded bool `json:"-"` } func (i *Pager) HasSearch() bool { diff --git a/structs/structs.go b/structs/structs.go index a0b26a2..c36903e 100644 --- a/structs/structs.go +++ b/structs/structs.go @@ -12,7 +12,7 @@ import ( func Map(obj any) map[string]any { result := make(map[string]any) val := reflect.ValueOf(obj) - if val.Kind() == reflect.Ptr { + if val.Kind() == reflect.Pointer { val = val.Elem() }