Skip to content

Commit

Permalink
Merge branch 'master' of https://github.com/gookit/goutil
Browse files Browse the repository at this point in the history
  • Loading branch information
inhere committed Oct 2, 2024
2 parents f1ad3a6 + b511ebd commit fa6c3da
Show file tree
Hide file tree
Showing 9 changed files with 109 additions and 33 deletions.
16 changes: 8 additions & 8 deletions .github/workflows/go.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ jobs:
strategy:
matrix:
os: [ubuntu-latest, windows-latest]
go_version: [1.19, '1.20', 1.21, 1.22]
go_version: [1.19, '1.20', 1.21, 1.22, 1.23]

steps:
- name: Check out code
Expand All @@ -31,16 +31,16 @@ jobs:
with:
go-version: ${{ matrix.go_version }}

- name: Revive check
uses: morphy2k/revive-action@v2.5.7
if: ${{ matrix.os == 'ubuntu-latest' && matrix.go_version == '1.20' }}
with:
# Exclude patterns, separated by semicolons (optional)
exclude: "./internal/..."
# - name: Revive check
# uses: morphy2k/revive-action@v2.5.10
# if: ${{ matrix.os == 'ubuntu-latest' && matrix.go_version == '1.22' }}
# with:
# # Exclude patterns, separated by semicolons (optional)
# exclude: "./internal/..."

- name: Run staticcheck
uses: reviewdog/action-staticcheck@v1
if: ${{ matrix.os == 'ubuntu-latest' && matrix.go_version == '1.20' }}
if: ${{ matrix.os == 'ubuntu-latest' && matrix.go_version == '1.22' }}
with:
github_token: ${{ secrets.github_token }}
# Change reviewdog reporter if you need [github-pr-check,github-check,github-pr-review].
Expand Down
7 changes: 6 additions & 1 deletion dump/dumper.go
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,12 @@ func (d *Dumper) printRValue(t reflect.Type, v reflect.Value) {

// up: special handel time.Time struct
if t == timeType {
timeStr := v.Interface().(time.Time).Format(time.RFC3339)
var timeStr string
if v.CanInterface() {
timeStr = v.Interface().(time.Time).Format(time.RFC3339)
} else {
timeStr = v.String()
}
d.printf("time.Time(%s),\n", d.ColorTheme.string(timeStr))
break
}
Expand Down
19 changes: 11 additions & 8 deletions dump/dumper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"os"
"reflect"
"testing"
"time"
"unsafe"

"github.com/gookit/color"
Expand Down Expand Up @@ -425,17 +426,19 @@ func TestStruct_WithNested(_ *testing.T) {

func TestDumper_Dump_userType(_ *testing.T) {
type testSt struct {
name string
mod fs.FileMode
Mod2 fs.FileMode
Age int
name string
mod fs.FileMode
Mod2 fs.FileMode
Age int
createdAt time.Time
}

st := testSt{
name: "inhere",
mod: 0777,
Mod2: 0775,
Age: 23,
name: "inhere",
mod: 0777,
Mod2: 0775,
Age: 23,
createdAt: time.Now(),
}

fmt.Println("------ use dumper ------")
Expand Down
8 changes: 4 additions & 4 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ go 1.19

require (
github.com/gookit/color v1.5.4
golang.org/x/sync v0.7.0
golang.org/x/sys v0.22.0
golang.org/x/term v0.22.0
golang.org/x/text v0.16.0
golang.org/x/sync v0.8.0
golang.org/x/sys v0.25.0
golang.org/x/term v0.24.0
golang.org/x/text v0.18.0
)

require github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect
16 changes: 8 additions & 8 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@ github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcU
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no=
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM=
golang.org/x/exp v0.0.0-20220909182711-5c715a9e8561 h1:MDc5xs78ZrZr3HMQugiXOAkSZtfTpbJLDr/lwfgO53E=
golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI=
golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.22.0 h1:BbsgPEJULsl2fV/AT3v15Mjva5yXKQDyKf+TbDz7QJk=
golang.org/x/term v0.22.0/go.mod h1:F3qCibpT5AMpCRfhfT53vVJwhLtIVHhB9XDjfFvnMI4=
golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4=
golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=
golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34=
golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.24.0 h1:Mh5cbb+Zk2hqqXNO7S1iTjEphVL+jb8ZWaqh/g+JWkM=
golang.org/x/term v0.24.0/go.mod h1:lOBK/LVxemqiMij05LGJ0tzNr8xlmwBRJ81PX6wVLH8=
golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224=
golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
4 changes: 4 additions & 0 deletions structs/convert.go
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,10 @@ func structToMap(obj reflect.Value, opt *MapOptions, mp map[string]any) (map[str
}

field := reflect.Indirect(obj.Field(i))
if !field.IsValid() {
continue
}

if field.Kind() == reflect.Struct {
// collect anonymous struct values to parent.
if ft.Anonymous && opt.MergeAnonymous {
Expand Down
44 changes: 44 additions & 0 deletions structs/convert_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -217,3 +217,47 @@ func TestTryToMap_customTag(t *testing.T) {

assert.ContainsKeys(t, mp, []string{"name", "age", "full_name"})
}

// https://github.com/gookit/goutil/issues/192
func TestIssue192(t *testing.T) {
// go code
type Structure struct {
// I don't want to expose too many infos, but here it goes only a set of float64 numbers, without any complex type or pointers
}

type MyStruct struct {
ID string `json:"id" gorm:"column:id"`
RefId int `json:"ref_id" gorm:"column:ref_id"`
PhotoURL string `json:"photoURL" gorm:"column:photo_url"`
Year int `json:"year" gorm:"column:year"`
SomeDate string `json:"someDate" gorm:"column:some_date"`
Trim string `json:"trim" gorm:"column:trim"`
Type string `json:"type" gorm:"column:type"`
BodyType string `json:"bodyType" gorm:"column:body_type"`
Counter int `json:"counter" gorm:"column:counter"`
Used bool `json:"used" gorm:"column:used"`
Price float64 `json:"price" gorm:"column:price"`
Value float64 `json:"value" gorm:"column:value"`
Amount float64 `json:"amount" gorm:"-:all"`
MaxAmount float64 `json:"maxAmount" gorm:"column:max_amount"`
StockNo string `json:"stockNo" gorm:"column:stock_no"`
ExpiresAt *string `json:"expiresAt" gorm:"column:expires_at"`
UpdatedBy *string `json:"updatedBy" gorm:"column:updated_by"`
Location string `json:"location" gorm:"column:location"`
IsFavorite bool `json:"is_favorite,omitempty" gorm:"-"`
Structure *Structure `json:"structure,omitempty" gorm:"-:all"`
}

data := MyStruct{
ID: "ABC123",
RefId: 1,
Year: 1990,
SomeDate: "2020-01-03 15:02:15",
Counter: 9001,
Price: 20,
}

toMap, err := structs.TryToMap(data) // <- it panics!
assert.NoErr(t, err)
dump.P(toMap)
}
14 changes: 10 additions & 4 deletions structs/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ type InitOptFunc func(opt *InitOptions)
// InitOptions struct
type InitOptions struct {
// TagName default value tag name. tag: default
TagName string
TagName string
EnvPrefixTagName string
// ParseEnv var name on default value. eg: `default:"${APP_ENV}"`
//
Expand Down Expand Up @@ -181,15 +181,15 @@ func initDefaults(rv reflect.Value, opt *InitOptions, envPrefix string) error {
func enhanceDefaultVar(val string, envPrefix string) string {
cleaned_var := strings.TrimSpace(val)
if strings.HasPrefix(cleaned_var, "${") && strings.HasSuffix(cleaned_var, "}") {
parts := strings.SplitN(cleaned_var[2 : len(cleaned_var) - 1], "|", 2)
parts := strings.SplitN(cleaned_var[2:len(cleaned_var)-1], "|", 2)
if len(parts) > 0 {
env := strings.TrimSpace(parts[0])
if env != "" {
if len(parts) == 1 {
return fmt.Sprintf("${%s%s}", envPrefix, env)
} else {
return fmt.Sprintf("${%s%s|%s}", envPrefix, env, parts[1])
}
}
}
}
}
Expand All @@ -214,7 +214,13 @@ func initDefaultValue(fv reflect.Value, val string, parseEnv bool, envPrefix str
ss := strutil.SplitTrimmed(val, ",")
valRv, err := reflects.ConvSlice(reflect.ValueOf(ss), fv.Type().Elem())
if err == nil {
reflects.SetRValue(fv, valRv)
if fv.Kind() == reflect.Array {
for i := 0; i < valRv.Len(); i++ {
fv.Index(i).Set(valRv.Index(i))
}
} else {
reflects.SetRValue(fv, valRv)
}
}
return err
}
Expand Down
14 changes: 14 additions & 0 deletions structs/init_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -261,3 +261,17 @@ func TestInitDefaults_ptrField(t *testing.T) {
assert.Eq(t, 30, *u.Age)
assert.Eq(t, "sh", u.City)
}

// https://github.com/gookit/goutil/issues/172
// panic: reflect.Set: value of type []int is not assignable to type [3]int
func TestIssues172(t *testing.T) {
type Config struct {
Ints [3]int `default:"1,2,3"`
}

var c Config

err := structs.InitDefaults(&c)
assert.NoErr(t, err)
assert.Eq(t, [3]int{1, 2, 3}, c.Ints)
}

0 comments on commit fa6c3da

Please sign in to comment.