mirror of
https://gitee.com/johng/gf
synced 2026-07-07 06:15:15 +08:00
fix: disable specific staticcheck rules and update lint config (#4396)
fix: disable specific staticcheck rules and update lint config - Disabled staticcheck rules SA1029, SA1019, S1000, and related checks in `.golangci.yml` to filter out unwanted linter errors. - Updated staticcheck checks list for more precise linting control. - Clarified configuration for easier maintenance and future updates. --------- Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> Co-authored-by: hailaz <739476267@qq.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
2
.github/workflows/golangci-lint.yml
vendored
2
.github/workflows/golangci-lint.yml
vendored
@ -4,7 +4,7 @@
|
||||
# If a copy of the MIT was not distributed with this file,
|
||||
# You can obtain one at https://github.com/gogf/gf.
|
||||
|
||||
name: GolangCI Lint
|
||||
name: golangci-lint
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
version: "2"
|
||||
run:
|
||||
concurrency: 4
|
||||
go: "1.23"
|
||||
go: "1.25"
|
||||
modules-download-mode: readonly
|
||||
issues-exit-code: 2
|
||||
tests: false
|
||||
@ -188,7 +188,7 @@ formatters:
|
||||
- blank
|
||||
- default
|
||||
- dot
|
||||
- prefix(github.com/gogf/gf)
|
||||
- prefix(github.com/gogf/gf/v2)
|
||||
- prefix(github.com/gogf/gf/cmd)
|
||||
- prefix(github.com/gogf/gfcontrib)
|
||||
- prefix(github.com/gogf/gf/example)
|
||||
|
||||
@ -378,7 +378,7 @@ func Test_Gen_Dao_Issue3459(t *testing.T) {
|
||||
filepath.FromSlash(testPath + "/model/do/table_user.go"),
|
||||
filepath.FromSlash(testPath + "/model/entity/table_user.go"),
|
||||
}
|
||||
for i, _ := range files {
|
||||
for i := range files {
|
||||
//_ = gfile.PutContents(expectFiles[i], gfile.GetContents(files[i]))
|
||||
t.Assert(gfile.GetContents(files[i]), gfile.GetContents(expectFiles[i]))
|
||||
}
|
||||
@ -450,7 +450,7 @@ func Test_Gen_Dao_Issue3749(t *testing.T) {
|
||||
filepath.FromSlash(testPath + "/model/do/table_user.go"),
|
||||
filepath.FromSlash(testPath + "/model/entity/table_user.go"),
|
||||
}
|
||||
for i, _ := range files {
|
||||
for i := range files {
|
||||
//_ = gfile.PutContents(expectFiles[i], gfile.GetContents(files[i]))
|
||||
t.Assert(gfile.GetContents(files[i]), gfile.GetContents(expectFiles[i]))
|
||||
}
|
||||
|
||||
@ -107,7 +107,7 @@ func Test_Gen_Dao_Default(t *testing.T) {
|
||||
filepath.FromSlash(testPath + "/model/do/table_user.go"),
|
||||
filepath.FromSlash(testPath + "/model/entity/table_user.go"),
|
||||
}
|
||||
for i, _ := range files {
|
||||
for i := range files {
|
||||
t.Assert(gfile.GetContents(files[i]), gfile.GetContents(expectFiles[i]))
|
||||
}
|
||||
})
|
||||
@ -208,7 +208,7 @@ func Test_Gen_Dao_TypeMapping(t *testing.T) {
|
||||
filepath.FromSlash(testPath + "/model/do/table_user.go"),
|
||||
filepath.FromSlash(testPath + "/model/entity/table_user.go"),
|
||||
}
|
||||
for i, _ := range files {
|
||||
for i := range files {
|
||||
//_ = gfile.PutContents(expectFiles[i], gfile.GetContents(files[i]))
|
||||
t.Assert(gfile.GetContents(files[i]), gfile.GetContents(expectFiles[i]))
|
||||
}
|
||||
@ -311,7 +311,7 @@ func Test_Gen_Dao_FieldMapping(t *testing.T) {
|
||||
filepath.FromSlash(testPath + "/model/do/table_user.go"),
|
||||
filepath.FromSlash(testPath + "/model/entity/table_user.go"),
|
||||
}
|
||||
for i, _ := range files {
|
||||
for i := range files {
|
||||
//_ = gfile.PutContents(expectFiles[i], gfile.GetContents(files[i]))
|
||||
t.Assert(gfile.GetContents(files[i]), gfile.GetContents(expectFiles[i]))
|
||||
}
|
||||
@ -403,7 +403,7 @@ func Test_Gen_Dao_Sqlite3(t *testing.T) {
|
||||
filepath.FromSlash(testPath + "/model/do/table_user.go"),
|
||||
filepath.FromSlash(testPath + "/model/entity/table_user.go"),
|
||||
}
|
||||
for i, _ := range files {
|
||||
for i := range files {
|
||||
//_ = gfile.PutContents(expectFiles[i], gfile.GetContents(files[i]))
|
||||
t.Assert(gfile.GetContents(files[i]), gfile.GetContents(expectFiles[i]))
|
||||
}
|
||||
|
||||
@ -9,13 +9,14 @@ package genctrl
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/gogf/gf/cmd/gf/v2/internal/utility/mlog"
|
||||
"github.com/gogf/gf/v2/container/gset"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/os/gfile"
|
||||
"github.com/gogf/gf/v2/os/gtime"
|
||||
"github.com/gogf/gf/v2/util/gconv"
|
||||
"github.com/gogf/gf/v2/util/gtag"
|
||||
|
||||
"github.com/gogf/gf/cmd/gf/v2/internal/utility/mlog"
|
||||
)
|
||||
|
||||
const (
|
||||
|
||||
@ -13,8 +13,6 @@ import (
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
|
||||
"github.com/gogf/gf/cmd/gf/v2/internal/utility/mlog"
|
||||
"github.com/gogf/gf/cmd/gf/v2/internal/utility/utils"
|
||||
"github.com/gogf/gf/v2/container/garray"
|
||||
"github.com/gogf/gf/v2/container/gmap"
|
||||
"github.com/gogf/gf/v2/container/gset"
|
||||
@ -25,6 +23,9 @@ import (
|
||||
"github.com/gogf/gf/v2/text/gstr"
|
||||
"github.com/gogf/gf/v2/util/gconv"
|
||||
"github.com/gogf/gf/v2/util/gtag"
|
||||
|
||||
"github.com/gogf/gf/cmd/gf/v2/internal/utility/mlog"
|
||||
"github.com/gogf/gf/cmd/gf/v2/internal/utility/utils"
|
||||
)
|
||||
|
||||
const (
|
||||
|
||||
@ -12,12 +12,13 @@ import (
|
||||
|
||||
"golang.org/x/tools/imports"
|
||||
|
||||
"github.com/gogf/gf/cmd/gf/v2/internal/consts"
|
||||
"github.com/gogf/gf/cmd/gf/v2/internal/utility/mlog"
|
||||
"github.com/gogf/gf/v2/os/gfile"
|
||||
"github.com/gogf/gf/v2/os/gproc"
|
||||
"github.com/gogf/gf/v2/text/gregex"
|
||||
"github.com/gogf/gf/v2/text/gstr"
|
||||
|
||||
"github.com/gogf/gf/cmd/gf/v2/internal/consts"
|
||||
"github.com/gogf/gf/cmd/gf/v2/internal/utility/mlog"
|
||||
)
|
||||
|
||||
// GoFmt formats the source file and adds or removes import statements as necessary.
|
||||
|
||||
@ -498,13 +498,9 @@ func (a *SortedArray) Unique() *SortedArray {
|
||||
if len(a.array) == 0 {
|
||||
return a
|
||||
}
|
||||
i := 0
|
||||
for {
|
||||
if i == len(a.array)-1 {
|
||||
break
|
||||
}
|
||||
for i := 0; i < len(a.array)-1; {
|
||||
if a.getComparator()(a.array[i], a.array[i+1]) == 0 {
|
||||
a.array = append(a.array[:i+1], a.array[i+1+1:]...)
|
||||
a.array = append(a.array[:i+1], a.array[i+2:]...)
|
||||
} else {
|
||||
i++
|
||||
}
|
||||
|
||||
@ -496,13 +496,9 @@ func (a *SortedIntArray) Unique() *SortedIntArray {
|
||||
if len(a.array) == 0 {
|
||||
return a
|
||||
}
|
||||
i := 0
|
||||
for {
|
||||
if i == len(a.array)-1 {
|
||||
break
|
||||
}
|
||||
for i := 0; i < len(a.array)-1; {
|
||||
if a.getComparator()(a.array[i], a.array[i+1]) == 0 {
|
||||
a.array = append(a.array[:i+1], a.array[i+1+1:]...)
|
||||
a.array = append(a.array[:i+1], a.array[i+2:]...)
|
||||
} else {
|
||||
i++
|
||||
}
|
||||
|
||||
@ -498,13 +498,9 @@ func (a *SortedStrArray) Unique() *SortedStrArray {
|
||||
if len(a.array) == 0 {
|
||||
return a
|
||||
}
|
||||
i := 0
|
||||
for {
|
||||
if i == len(a.array)-1 {
|
||||
break
|
||||
}
|
||||
for i := 0; i < len(a.array)-1; {
|
||||
if a.getComparator()(a.array[i], a.array[i+1]) == 0 {
|
||||
a.array = append(a.array[:i+1], a.array[i+1+1:]...)
|
||||
a.array = append(a.array[:i+1], a.array[i+2:]...)
|
||||
} else {
|
||||
i++
|
||||
}
|
||||
|
||||
@ -545,7 +545,7 @@ func (m ListMap) MarshalJSON() (jsonBytes []byte, err error) {
|
||||
if buffer.Len() > 1 {
|
||||
buffer.WriteByte(',')
|
||||
}
|
||||
buffer.WriteString(fmt.Sprintf(`"%v":%s`, key, valueBytes))
|
||||
fmt.Fprintf(buffer, `"%v":%s`, key, valueBytes)
|
||||
return true
|
||||
})
|
||||
buffer.WriteByte('}')
|
||||
|
||||
@ -166,10 +166,7 @@ func (p *Pool) checkExpireItems(ctx context.Context) {
|
||||
// by comparing with this timestamp. It is not accurate comparison for
|
||||
// every item expired, but high performance.
|
||||
var timestampMilli = gtime.TimestampMilli()
|
||||
for {
|
||||
if latestExpire > timestampMilli {
|
||||
break
|
||||
}
|
||||
for latestExpire <= timestampMilli {
|
||||
if r := p.list.PopFront(); r != nil {
|
||||
item := r.(*poolItem)
|
||||
latestExpire = item.expireAt
|
||||
|
||||
@ -1508,7 +1508,7 @@ func Test_Issue3968(t *testing.T) {
|
||||
return nil, err
|
||||
}
|
||||
if result != nil {
|
||||
for i, _ := range result {
|
||||
for i := range result {
|
||||
result[i]["location"] = gvar.New("ny")
|
||||
}
|
||||
}
|
||||
|
||||
@ -598,11 +598,7 @@ func formatWhereHolder(ctx context.Context, db DB, in formatWhereHolderInput) (n
|
||||
// Regular string and parameter place holder handling.
|
||||
// Eg:
|
||||
// Where("id in(?) and name=?", g.Slice{1,2,3}, "john")
|
||||
i := 0
|
||||
for {
|
||||
if i >= len(in.Args) {
|
||||
break
|
||||
}
|
||||
for i := 0; i < len(in.Args); i++ {
|
||||
// ===============================================================
|
||||
// Sub query, which is always used along with a string condition.
|
||||
// ===============================================================
|
||||
@ -621,7 +617,6 @@ func formatWhereHolder(ctx context.Context, db DB, in formatWhereHolderInput) (n
|
||||
in.Args = gutil.SliceDelete(in.Args, i)
|
||||
continue
|
||||
}
|
||||
i++
|
||||
}
|
||||
buffer.WriteString(whereStr)
|
||||
}
|
||||
@ -858,18 +853,18 @@ func handleSliceAndStructArgsForSql(
|
||||
|
||||
// Special struct handling.
|
||||
case reflect.Struct:
|
||||
switch oldArg.(type) {
|
||||
switch v := oldArg.(type) {
|
||||
// The underlying driver supports time.Time/*time.Time types.
|
||||
case time.Time, *time.Time:
|
||||
newArgs = append(newArgs, oldArg)
|
||||
continue
|
||||
|
||||
case gtime.Time:
|
||||
newArgs = append(newArgs, oldArg.(gtime.Time).Time)
|
||||
newArgs = append(newArgs, v.Time)
|
||||
continue
|
||||
|
||||
case *gtime.Time:
|
||||
newArgs = append(newArgs, oldArg.(*gtime.Time).Time)
|
||||
newArgs = append(newArgs, v.Time)
|
||||
continue
|
||||
|
||||
default:
|
||||
|
||||
@ -185,7 +185,7 @@ func checkGetSliceElementInfoForScanList(structSlicePointer any, bindToAttrName
|
||||
}
|
||||
if reflectKind == reflect.Slice || reflectKind == reflect.Array {
|
||||
reflectType = reflectType.Elem()
|
||||
reflectKind = reflectType.Kind()
|
||||
// reflectKind = reflectType.Kind()
|
||||
}
|
||||
out.BindToAttrType = reflectType
|
||||
return
|
||||
@ -342,7 +342,7 @@ func doScanList(in doScanListInput) (err error) {
|
||||
arrayElemValue = reflect.New(arrayItemType.Elem()).Elem()
|
||||
arrayValue.Index(i).Set(arrayElemValue.Addr())
|
||||
}
|
||||
} else {
|
||||
// } else {
|
||||
// Like: []Entity
|
||||
}
|
||||
bindToAttrValue = arrayElemValue.FieldByName(in.BindToAttrName)
|
||||
|
||||
@ -52,14 +52,14 @@ const errorNilAdapter = `redis adapter is not set, missing configuration or adap
|
||||
// initGroup initializes the group object of redis.
|
||||
func (r *Redis) initGroup() *Redis {
|
||||
r.localGroup = localGroup{
|
||||
localGroupGeneric: r.localAdapter.GroupGeneric(),
|
||||
localGroupHash: r.localAdapter.GroupHash(),
|
||||
localGroupList: r.localAdapter.GroupList(),
|
||||
localGroupPubSub: r.localAdapter.GroupPubSub(),
|
||||
localGroupScript: r.localAdapter.GroupScript(),
|
||||
localGroupSet: r.localAdapter.GroupSet(),
|
||||
localGroupSortedSet: r.localAdapter.GroupSortedSet(),
|
||||
localGroupString: r.localAdapter.GroupString(),
|
||||
localGroupGeneric: r.GroupGeneric(),
|
||||
localGroupHash: r.GroupHash(),
|
||||
localGroupList: r.GroupList(),
|
||||
localGroupPubSub: r.GroupPubSub(),
|
||||
localGroupScript: r.GroupScript(),
|
||||
localGroupSet: r.GroupSet(),
|
||||
localGroupSortedSet: r.GroupSortedSet(),
|
||||
localGroupString: r.GroupString(),
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
@ -67,7 +67,7 @@ func StackWithFilters(filters []string, skip ...int) string {
|
||||
if index > 9 {
|
||||
space = " "
|
||||
}
|
||||
buffer.WriteString(fmt.Sprintf("%d.%s%s\n %s:%d\n", index, space, name, file, line))
|
||||
fmt.Fprintf(buffer, "%d.%s%s\n %s:%d\n", index, space, name, file, line)
|
||||
index++
|
||||
} else {
|
||||
break
|
||||
|
||||
@ -17,7 +17,7 @@ import (
|
||||
|
||||
// Zlib compresses `data` with zlib algorithm.
|
||||
func Zlib(data []byte) ([]byte, error) {
|
||||
if data == nil || len(data) < 13 {
|
||||
if len(data) < 13 {
|
||||
return data, nil
|
||||
}
|
||||
var (
|
||||
@ -39,7 +39,7 @@ func Zlib(data []byte) ([]byte, error) {
|
||||
|
||||
// UnZlib decompresses `data` with zlib algorithm.
|
||||
func UnZlib(data []byte) ([]byte, error) {
|
||||
if data == nil || len(data) < 13 {
|
||||
if len(data) < 13 {
|
||||
return data, nil
|
||||
}
|
||||
var (
|
||||
|
||||
@ -89,12 +89,12 @@ func Encode(data map[string]any) (res []byte, err error) {
|
||||
for section, item := range data {
|
||||
// Section key-value pairs.
|
||||
if m, ok = item.(map[string]any); ok {
|
||||
n, err = w.WriteString(fmt.Sprintf("[%s]\n", section))
|
||||
n, err = fmt.Fprintf(w, "[%s]\n", section)
|
||||
if err != nil || n == 0 {
|
||||
return nil, gerror.Wrapf(err, "w.WriteString failed")
|
||||
}
|
||||
for k, v := range m {
|
||||
if n, err = w.WriteString(fmt.Sprintf("%s=%v\n", k, v)); err != nil || n == 0 {
|
||||
if n, err = fmt.Fprintf(w, "%s=%v\n", k, v); err != nil || n == 0 {
|
||||
return nil, gerror.Wrapf(err, "w.WriteString failed")
|
||||
}
|
||||
}
|
||||
@ -102,7 +102,7 @@ func Encode(data map[string]any) (res []byte, err error) {
|
||||
}
|
||||
// Simple key-value pairs.
|
||||
for k, v := range data {
|
||||
if n, err = w.WriteString(fmt.Sprintf("%s=%v\n", k, v)); err != nil || n == 0 {
|
||||
if n, err = fmt.Fprintf(w, "%s=%v\n", k, v); err != nil || n == 0 {
|
||||
return nil, gerror.Wrapf(err, "w.WriteString failed")
|
||||
}
|
||||
}
|
||||
|
||||
@ -103,7 +103,7 @@ func filterLinesOfStackInfos(infos []*stackInfo) {
|
||||
func formatStackInfos(infos []*stackInfo) string {
|
||||
buffer := bytes.NewBuffer(nil)
|
||||
for i, info := range infos {
|
||||
buffer.WriteString(fmt.Sprintf("%d. %s\n", i+1, info.Message))
|
||||
fmt.Fprintf(buffer, "%d. %s\n", i+1, info.Message)
|
||||
if info.Lines != nil && info.Lines.Len() > 0 {
|
||||
formatStackLines(buffer, info.Lines)
|
||||
}
|
||||
@ -124,10 +124,11 @@ func formatStackLines(buffer *bytes.Buffer, lines *list.List) string {
|
||||
if i >= 9 {
|
||||
space = " "
|
||||
}
|
||||
buffer.WriteString(fmt.Sprintf(
|
||||
fmt.Fprintf(
|
||||
buffer,
|
||||
" %d).%s%s\n %s\n",
|
||||
i+1, space, line.Function, line.FileLine,
|
||||
))
|
||||
)
|
||||
}
|
||||
return buffer.String()
|
||||
}
|
||||
|
||||
@ -37,7 +37,7 @@ func MiddlewareHandlerResponse(r *Request) {
|
||||
r.Middleware.Next()
|
||||
|
||||
// There's custom buffer content, it then exits current handler.
|
||||
if r.Response.BufferLength() > 0 || r.Response.Writer.BytesWritten() > 0 {
|
||||
if r.Response.BufferLength() > 0 || r.Response.BytesWritten() > 0 {
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@ -63,7 +63,7 @@ func (s *Server) getHandlersWithCache(r *Request) (parsedItems []*HandlerItemPar
|
||||
// Special http method OPTIONS handling.
|
||||
// It searches the handler with the request method instead of OPTIONS method.
|
||||
if method == http.MethodOptions {
|
||||
if v := r.Request.Header.Get("Access-Control-Request-Method"); v != "" {
|
||||
if v := r.Header.Get("Access-Control-Request-Method"); v != "" {
|
||||
method = v
|
||||
}
|
||||
}
|
||||
|
||||
@ -326,7 +326,7 @@ func Test_Router_Handler_Standard_WithGeneric(t *testing.T) {
|
||||
})
|
||||
s.BindHandler("/test1_slice", func(ctx context.Context, req *TestReq) (res []Test1Res, err error) {
|
||||
return []Test1Res{
|
||||
Test1Res{
|
||||
{
|
||||
Age: TestGeneric[int]{
|
||||
Test: req.Age,
|
||||
},
|
||||
@ -341,7 +341,7 @@ func Test_Router_Handler_Standard_WithGeneric(t *testing.T) {
|
||||
|
||||
s.BindHandler("/test2_slice", func(ctx context.Context, req *TestReq) (res []Test2Res, err error) {
|
||||
return []Test2Res{
|
||||
Test2Res{
|
||||
{
|
||||
Test: req.Age,
|
||||
},
|
||||
}, nil
|
||||
@ -359,7 +359,7 @@ func Test_Router_Handler_Standard_WithGeneric(t *testing.T) {
|
||||
|
||||
s.BindHandler("/test3_slice", func(ctx context.Context, req *TestReq) (res []TestGenericRes[int], err error) {
|
||||
return []TestGenericRes[int]{
|
||||
TestGenericRes[int]{
|
||||
{
|
||||
Test: req.Age,
|
||||
},
|
||||
}, nil
|
||||
|
||||
@ -24,7 +24,7 @@ func GetIpArray() (ips []string, err error) {
|
||||
}
|
||||
for _, address := range interfaceAddr {
|
||||
ipNet, isValidIpNet := address.(*net.IPNet)
|
||||
if !(isValidIpNet && !ipNet.IP.IsLoopback()) {
|
||||
if !isValidIpNet || ipNet.IP.IsLoopback() {
|
||||
continue
|
||||
}
|
||||
if ipNet.IP.To4() != nil {
|
||||
|
||||
@ -85,7 +85,7 @@ func (oai *OpenApiV3) addPath(in addPathInput) error {
|
||||
}
|
||||
|
||||
var (
|
||||
mime string
|
||||
// mime string
|
||||
path = Path{XExtensions: make(XExtensions)}
|
||||
inputMetaMap = gmeta.Data(inputObject.Interface())
|
||||
outputMetaMap = gmeta.Data(outputObject.Interface())
|
||||
@ -152,9 +152,9 @@ func (oai *OpenApiV3) addPath(in addPathInput) error {
|
||||
return err
|
||||
}
|
||||
// Allowed request mime.
|
||||
if mime = inputMetaMap[gtag.Mime]; mime == "" {
|
||||
mime = inputMetaMap[gtag.Consumes]
|
||||
}
|
||||
// if mime = inputMetaMap[gtag.Mime]; mime == "" {
|
||||
// mime = inputMetaMap[gtag.Consumes]
|
||||
// }
|
||||
}
|
||||
|
||||
// path security
|
||||
|
||||
@ -472,7 +472,6 @@ func (c *AdapterMemory) handleLruKey(ctx context.Context, keys ...any) {
|
||||
_, _ = c.doRemove(ctx, evictedKeys...)
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// clearByKey deletes the key-value pair with given `key`.
|
||||
|
||||
@ -56,20 +56,20 @@ func (a *AdapterFile) SetPath(directoryPath string) (err error) {
|
||||
if realPath == "" {
|
||||
buffer := bytes.NewBuffer(nil)
|
||||
if a.searchPaths.Len() > 0 {
|
||||
buffer.WriteString(fmt.Sprintf(
|
||||
fmt.Fprintf(buffer,
|
||||
`SetPath failed: cannot find directory "%s" in following paths:`,
|
||||
directoryPath,
|
||||
))
|
||||
)
|
||||
a.searchPaths.RLockFunc(func(array []string) {
|
||||
for k, v := range array {
|
||||
buffer.WriteString(fmt.Sprintf("\n%d. %s", k+1, v))
|
||||
fmt.Fprintf(buffer, "\n%d. %s", k+1, v)
|
||||
}
|
||||
})
|
||||
} else {
|
||||
buffer.WriteString(fmt.Sprintf(
|
||||
fmt.Fprintf(buffer,
|
||||
`SetPath failed: path "%s" does not exist`,
|
||||
directoryPath,
|
||||
))
|
||||
)
|
||||
}
|
||||
return gerror.New(buffer.String())
|
||||
}
|
||||
@ -136,20 +136,18 @@ func (a *AdapterFile) doAddPath(directoryPath string) (err error) {
|
||||
if realPath == "" {
|
||||
buffer := bytes.NewBuffer(nil)
|
||||
if a.searchPaths.Len() > 0 {
|
||||
buffer.WriteString(fmt.Sprintf(
|
||||
fmt.Fprintf(buffer,
|
||||
`AddPath failed: cannot find directory "%s" in following paths:`,
|
||||
directoryPath,
|
||||
))
|
||||
directoryPath)
|
||||
a.searchPaths.RLockFunc(func(array []string) {
|
||||
for k, v := range array {
|
||||
buffer.WriteString(fmt.Sprintf("\n%d. %s", k+1, v))
|
||||
fmt.Fprintf(buffer, "\n%d. %s", k+1, v)
|
||||
}
|
||||
})
|
||||
} else {
|
||||
buffer.WriteString(fmt.Sprintf(
|
||||
fmt.Fprintf(buffer,
|
||||
`AddPath failed: path "%s" does not exist`,
|
||||
directoryPath,
|
||||
))
|
||||
directoryPath)
|
||||
}
|
||||
return gerror.New(buffer.String())
|
||||
}
|
||||
@ -269,34 +267,30 @@ func (a *AdapterFile) GetFilePath(fileNameOrPath ...string) (filePath string, er
|
||||
var buffer = bytes.NewBuffer(nil)
|
||||
if a.searchPaths.Len() > 0 {
|
||||
if !gstr.InArray(supportedFileTypes, fileExtName) {
|
||||
buffer.WriteString(fmt.Sprintf(
|
||||
fmt.Fprintf(buffer,
|
||||
`possible config files "%s" or "%s" not found in resource manager or following system searching paths:`,
|
||||
usedFileNameOrPath, fmt.Sprintf(`%s.%s`, usedFileNameOrPath, gstr.Join(supportedFileTypes, "/")),
|
||||
))
|
||||
usedFileNameOrPath, fmt.Sprintf(`%s.%s`, usedFileNameOrPath, gstr.Join(supportedFileTypes, "/")))
|
||||
} else {
|
||||
buffer.WriteString(fmt.Sprintf(
|
||||
fmt.Fprintf(buffer,
|
||||
`specified config file "%s" not found in resource manager or following system searching paths:`,
|
||||
usedFileNameOrPath,
|
||||
))
|
||||
usedFileNameOrPath)
|
||||
}
|
||||
a.searchPaths.RLockFunc(func(array []string) {
|
||||
index := 1
|
||||
for _, searchPath := range array {
|
||||
searchPath = gstr.TrimRight(searchPath, `\/`)
|
||||
for _, tryFolder := range localSystemTryFolders {
|
||||
buffer.WriteString(fmt.Sprintf(
|
||||
fmt.Fprintf(buffer,
|
||||
"\n%d. %s",
|
||||
index, gfile.Join(searchPath, tryFolder),
|
||||
))
|
||||
index, gfile.Join(searchPath, tryFolder))
|
||||
index++
|
||||
}
|
||||
}
|
||||
})
|
||||
} else {
|
||||
buffer.WriteString(fmt.Sprintf(
|
||||
fmt.Fprintf(buffer,
|
||||
`cannot find config file "%s" with no filePath configured`,
|
||||
usedFileNameOrPath,
|
||||
))
|
||||
usedFileNameOrPath)
|
||||
}
|
||||
err = gerror.NewCode(gcode.CodeNotFound, buffer.String())
|
||||
}
|
||||
|
||||
@ -46,14 +46,14 @@ func (c *Command) RunWithValue(ctx context.Context) (value any) {
|
||||
buffer = bytes.NewBuffer(nil)
|
||||
)
|
||||
if code.Code() == gcode.CodeNotFound.Code() {
|
||||
buffer.WriteString(fmt.Sprintf("ERROR: %s\n", gstr.Trim(err.Error())))
|
||||
fmt.Fprintf(buffer, "ERROR: %s\n", gstr.Trim(err.Error()))
|
||||
if lastCmd, ok := detail.(*Command); ok {
|
||||
lastCmd.PrintTo(buffer)
|
||||
} else {
|
||||
c.PrintTo(buffer)
|
||||
}
|
||||
} else {
|
||||
buffer.WriteString(fmt.Sprintf("%+v\n", err))
|
||||
fmt.Fprintf(buffer, "%+v\n", err)
|
||||
}
|
||||
if gtrace.GetTraceID(ctx) == "" {
|
||||
fmt.Println(buffer.String())
|
||||
|
||||
@ -19,30 +19,26 @@ func (s *cronSchedule) getAndUpdateLastCheckTimestamp(ctx context.Context, t tim
|
||||
currentTimestamp = t.Unix()
|
||||
lastCheckTimestamp = s.lastCheckTimestamp.Val()
|
||||
)
|
||||
switch {
|
||||
switch lastCheckTimestamp {
|
||||
// Often happens, timer triggers in the same second, but the millisecond is different.
|
||||
// Example:
|
||||
// lastCheckTimestamp: 2024-03-26 19:47:34.000
|
||||
// currentTimestamp: 2024-03-26 19:47:34.999
|
||||
case
|
||||
lastCheckTimestamp == currentTimestamp:
|
||||
case currentTimestamp:
|
||||
lastCheckTimestamp += 1
|
||||
|
||||
// Often happens, no latency.
|
||||
// Example:
|
||||
// lastCheckTimestamp: 2024-03-26 19:47:34.000
|
||||
// currentTimestamp: 2024-03-26 19:47:35.000
|
||||
case
|
||||
lastCheckTimestamp == currentTimestamp-1:
|
||||
case currentTimestamp - 1:
|
||||
lastCheckTimestamp = currentTimestamp
|
||||
|
||||
// Latency in 3 seconds, which can be tolerant.
|
||||
// Example:
|
||||
// lastCheckTimestamp: 2024-03-26 19:47:31.000、2024-03-26 19:47:32.000
|
||||
// currentTimestamp: 2024-03-26 19:47:34.000
|
||||
case
|
||||
lastCheckTimestamp == currentTimestamp-2,
|
||||
lastCheckTimestamp == currentTimestamp-3:
|
||||
case currentTimestamp - 2, currentTimestamp - 3:
|
||||
lastCheckTimestamp += 1
|
||||
|
||||
// Too much latency, it ignores the fix, the cron job might not be triggered.
|
||||
|
||||
@ -46,10 +46,10 @@ func Search(name string, prioritySearchPaths ...string) (realPath string, err er
|
||||
// If it fails searching, it returns formatted error.
|
||||
if realPath == "" {
|
||||
buffer := bytes.NewBuffer(nil)
|
||||
buffer.WriteString(fmt.Sprintf(`cannot find "%s" in following paths:`, name))
|
||||
fmt.Fprintf(buffer, `cannot find "%s" in following paths:`, name)
|
||||
array.RLockFunc(func(array []string) {
|
||||
for k, v := range array {
|
||||
buffer.WriteString(fmt.Sprintf("\n%d. %s", k+1, v))
|
||||
fmt.Fprintf(buffer, "\n%d. %s", k+1, v)
|
||||
}
|
||||
})
|
||||
err = gerror.New(buffer.String())
|
||||
|
||||
@ -63,7 +63,7 @@ func doZipPathWriter(srcPath string, zipWriter *zip.Writer, option ...Option) er
|
||||
files = []string{absolutePath}
|
||||
}
|
||||
headerPrefix := usedOption.Prefix
|
||||
if !(headerPrefix == "/") {
|
||||
if headerPrefix != "/" {
|
||||
headerPrefix = strings.TrimRight(headerPrefix, `\/`)
|
||||
}
|
||||
if headerPrefix != "" && gfile.IsDir(absolutePath) {
|
||||
@ -124,8 +124,7 @@ func zipFile(path string, prefix string, zw *zip.Writer) error {
|
||||
prefix = strings.ReplaceAll(prefix, `//`, `/`)
|
||||
file, err := os.Open(path)
|
||||
if err != nil {
|
||||
err = gerror.Wrapf(err, `os.Open failed for path "%s"`, path)
|
||||
return nil
|
||||
return gerror.Wrapf(err, `os.Open failed for path "%s"`, path)
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
|
||||
@ -52,9 +52,7 @@ func New(path string, cache bool) *SPath {
|
||||
sp.cache = gmap.NewStrStrMap(true)
|
||||
}
|
||||
if len(path) > 0 {
|
||||
if _, err := sp.Add(path); err != nil {
|
||||
// intlog.Print(err)
|
||||
}
|
||||
_, _ = sp.Add(path)
|
||||
}
|
||||
return sp
|
||||
}
|
||||
|
||||
@ -31,7 +31,7 @@ const (
|
||||
H = time.Hour
|
||||
M = time.Minute
|
||||
S = time.Second
|
||||
MS = time.Millisecond
|
||||
MS = time.Millisecond //nolint:staticcheck
|
||||
US = time.Microsecond
|
||||
NS = time.Nanosecond
|
||||
|
||||
|
||||
@ -460,7 +460,7 @@ func (t *Time) StartOfHalf() *Time {
|
||||
func (t *Time) StartOfYear() *Time {
|
||||
y, _, _ := t.Date()
|
||||
newTime := t.Clone()
|
||||
newTime.Time = time.Date(y, time.January, 1, 0, 0, 0, 0, newTime.Time.Location())
|
||||
newTime.Time = time.Date(y, time.January, 1, 0, 0, 0, 0, newTime.Location())
|
||||
return newTime
|
||||
}
|
||||
|
||||
@ -487,7 +487,7 @@ func (t *Time) EndOfDay(withNanoPrecision ...bool) *Time {
|
||||
y, m, d := t.Date()
|
||||
newTime := t.Clone()
|
||||
newTime.Time = time.Date(
|
||||
y, m, d, 23, 59, 59, int(time.Second-getPrecisionDelta(withNanoPrecision...)), newTime.Time.Location(),
|
||||
y, m, d, 23, 59, 59, int(time.Second-getPrecisionDelta(withNanoPrecision...)), newTime.Location(),
|
||||
)
|
||||
return newTime
|
||||
}
|
||||
|
||||
@ -81,7 +81,7 @@ func SetTimeZone(zone string) (err error) {
|
||||
// ToLocation converts current time to specified location.
|
||||
func (t *Time) ToLocation(location *time.Location) *Time {
|
||||
newTime := t.Clone()
|
||||
newTime.Time = newTime.Time.In(location)
|
||||
newTime.Time = newTime.In(location)
|
||||
return newTime
|
||||
}
|
||||
|
||||
|
||||
@ -86,9 +86,9 @@ func (view *View) SetConfigWithMap(m map[string]any) error {
|
||||
_, v1 := gutil.MapPossibleItemByKey(m, "paths")
|
||||
_, v2 := gutil.MapPossibleItemByKey(m, "path")
|
||||
if v1 == nil && v2 != nil {
|
||||
switch v2.(type) {
|
||||
switch v2 := v2.(type) {
|
||||
case string:
|
||||
m["paths"] = []string{v2.(string)}
|
||||
m["paths"] = []string{v2}
|
||||
case []string:
|
||||
m["paths"] = v2
|
||||
}
|
||||
|
||||
@ -444,22 +444,21 @@ func (view *View) searchFile(ctx context.Context, file string) (path string, fol
|
||||
if path == "" {
|
||||
buffer := bytes.NewBuffer(nil)
|
||||
if view.searchPaths.Len() > 0 {
|
||||
buffer.WriteString(fmt.Sprintf("cannot find template file \"%s\" in following paths:", file))
|
||||
fmt.Fprintf(buffer, "cannot find template file \"%s\" in following paths:", file)
|
||||
view.searchPaths.RLockFunc(func(array []string) {
|
||||
index := 1
|
||||
for _, searchPath := range array {
|
||||
searchPath = gstr.TrimRight(searchPath, `\/`)
|
||||
for _, tryFolder := range localSystemTryFolders {
|
||||
buffer.WriteString(fmt.Sprintf(
|
||||
fmt.Fprintf(buffer,
|
||||
"\n%d. %s",
|
||||
index, gfile.Join(searchPath, tryFolder),
|
||||
))
|
||||
index, gfile.Join(searchPath, tryFolder))
|
||||
index++
|
||||
}
|
||||
}
|
||||
})
|
||||
} else {
|
||||
buffer.WriteString(fmt.Sprintf("cannot find template file \"%s\" with no path set/add", file))
|
||||
fmt.Fprintf(buffer, "cannot find template file \"%s\" with no path set/add", file)
|
||||
}
|
||||
if errorPrint() {
|
||||
glog.Error(ctx, buffer.String())
|
||||
|
||||
@ -9,7 +9,6 @@ package gstr
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"math"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
@ -135,30 +134,57 @@ func Shuffle(str string) string {
|
||||
// HideStr replaces part of the string `str` to `hide` by `percentage` from the `middle`.
|
||||
// It considers parameter `str` as unicode string.
|
||||
func HideStr(str string, percent int, hide string) string {
|
||||
array := strings.Split(str, "@")
|
||||
if len(array) > 1 {
|
||||
str = array[0]
|
||||
// Handle email case
|
||||
var suffix string
|
||||
if idx := strings.IndexByte(str, '@'); idx >= 0 {
|
||||
suffix = str[idx:]
|
||||
str = str[:idx]
|
||||
}
|
||||
var (
|
||||
rs = []rune(str)
|
||||
length = len(rs)
|
||||
mid = math.Floor(float64(length / 2))
|
||||
hideLen = int(math.Floor(float64(length) * (float64(percent) / 100)))
|
||||
start = int(mid - math.Floor(float64(hideLen)/2))
|
||||
hideStr = []rune("")
|
||||
hideRune = []rune(hide)
|
||||
)
|
||||
for i := 0; i < hideLen; i++ {
|
||||
hideStr = append(hideStr, hideRune...)
|
||||
|
||||
// Early return for edge cases
|
||||
if str == "" || percent <= 0 {
|
||||
return str + suffix
|
||||
}
|
||||
buffer := bytes.NewBuffer(nil)
|
||||
buffer.WriteString(string(rs[0:start]))
|
||||
buffer.WriteString(string(hideStr))
|
||||
buffer.WriteString(string(rs[start+hideLen:]))
|
||||
if len(array) > 1 {
|
||||
buffer.WriteString("@" + array[1])
|
||||
if percent >= 100 {
|
||||
return strings.Repeat(hide, len([]rune(str))) + suffix
|
||||
}
|
||||
return buffer.String()
|
||||
|
||||
rs := []rune(str)
|
||||
length := len(rs)
|
||||
if length == 0 {
|
||||
return str + suffix
|
||||
}
|
||||
|
||||
// Calculate hideLen using the same logic as original (with floor)
|
||||
hideLen := (length * percent) / 100
|
||||
if hideLen == 0 {
|
||||
return str + suffix
|
||||
}
|
||||
|
||||
// Calculate start position: mid - hideLen/2
|
||||
// This matches the original algorithm behavior
|
||||
mid := length / 2
|
||||
start := max(mid-hideLen/2, 0)
|
||||
|
||||
end := start + hideLen
|
||||
if end > length {
|
||||
end = length
|
||||
start = max(length-hideLen, 0)
|
||||
}
|
||||
|
||||
// Pre-calculate capacity to avoid reallocations
|
||||
var builder strings.Builder
|
||||
builder.Grow(len(str) + len(hide)*hideLen + len(suffix))
|
||||
|
||||
// Build result string efficiently
|
||||
builder.WriteString(string(rs[:start]))
|
||||
if hide != "" {
|
||||
builder.WriteString(strings.Repeat(hide, hideLen))
|
||||
}
|
||||
builder.WriteString(string(rs[end:]))
|
||||
builder.WriteString(suffix)
|
||||
|
||||
return builder.String()
|
||||
}
|
||||
|
||||
// Nl2Br inserts HTML line breaks(`br`|<br />) before all newlines in a string:
|
||||
@ -207,9 +233,8 @@ func WordWrap(str string, width int, br string) string {
|
||||
wordBuf, spaceBuf bytes.Buffer
|
||||
init = make([]byte, 0, len(str))
|
||||
buf = bytes.NewBuffer(init)
|
||||
strRunes = []rune(str)
|
||||
)
|
||||
for _, char := range strRunes {
|
||||
for _, char := range str {
|
||||
switch {
|
||||
case char == '\n':
|
||||
if wordBuf.Len() == 0 {
|
||||
|
||||
@ -29,7 +29,7 @@ func CountI(s, substr string) int {
|
||||
func CountWords(str string) map[string]int {
|
||||
m := make(map[string]int)
|
||||
buffer := bytes.NewBuffer(nil)
|
||||
for _, r := range []rune(str) {
|
||||
for _, r := range str {
|
||||
if unicode.IsSpace(r) {
|
||||
if buffer.Len() > 0 {
|
||||
m[buffer.String()]++
|
||||
@ -46,14 +46,11 @@ func CountWords(str string) map[string]int {
|
||||
}
|
||||
|
||||
// CountChars returns information about chars' count used in a string.
|
||||
// It considers parameter `str` as unicode string.
|
||||
// It considers parameter `str` as Unicode string.
|
||||
func CountChars(str string, noSpace ...bool) map[string]int {
|
||||
m := make(map[string]int)
|
||||
countSpace := true
|
||||
if len(noSpace) > 0 && noSpace[0] {
|
||||
countSpace = false
|
||||
}
|
||||
for _, r := range []rune(str) {
|
||||
countSpace := len(noSpace) == 0 || !noSpace[0]
|
||||
for _, r := range str {
|
||||
if !countSpace && unicode.IsSpace(r) {
|
||||
continue
|
||||
}
|
||||
|
||||
@ -25,7 +25,6 @@ func Levenshtein(str1, str2 string, costIns, costRep, costDel int) int {
|
||||
return -1
|
||||
}
|
||||
|
||||
tmp := make([]int, l2+1)
|
||||
p1 := make([]int, l2+1)
|
||||
p2 := make([]int, l2+1)
|
||||
var c0, c1, c2 int
|
||||
@ -51,9 +50,7 @@ func Levenshtein(str1, str2 string, costIns, costRep, costDel int) int {
|
||||
}
|
||||
p2[i2+1] = c0
|
||||
}
|
||||
tmp = p1
|
||||
p1 = p2
|
||||
p2 = tmp
|
||||
p1, p2 = p2, p1
|
||||
}
|
||||
c0 = p1[l2]
|
||||
|
||||
|
||||
@ -9,6 +9,9 @@ package gstr
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"golang.org/x/text/cases"
|
||||
"golang.org/x/text/language"
|
||||
|
||||
"github.com/gogf/gf/v2/internal/utils"
|
||||
)
|
||||
|
||||
@ -40,7 +43,7 @@ func LcFirst(s string) string {
|
||||
|
||||
// UcWords uppercase the first character of each word in a string.
|
||||
func UcWords(str string) string {
|
||||
return strings.Title(str)
|
||||
return cases.Title(language.Und).String(str)
|
||||
}
|
||||
|
||||
// IsLetterLower tests whether the given byte b is in lower case.
|
||||
|
||||
@ -54,7 +54,7 @@ func Test_LcFirst(t *testing.T) {
|
||||
func Test_UcWords(t *testing.T) {
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
s1 := "我爱GF: i love go frame"
|
||||
e1 := "我爱GF: I Love Go Frame"
|
||||
e1 := "我爱Gf: I Love Go Frame"
|
||||
t.Assert(gstr.UcWords(s1), e1)
|
||||
})
|
||||
}
|
||||
@ -178,9 +178,9 @@ func Test_SplitAndTrim(t *testing.T) {
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
s := `
|
||||
|
||||
010
|
||||
010
|
||||
|
||||
020
|
||||
020
|
||||
|
||||
`
|
||||
a := gstr.SplitAndTrim(s, "\n", "0")
|
||||
@ -321,6 +321,35 @@ func Test_HideStr(t *testing.T) {
|
||||
t.Assert(gstr.HideStr("张三", 50, "*"), "张*")
|
||||
t.Assert(gstr.HideStr("张小三", 50, "*"), "张*三")
|
||||
t.Assert(gstr.HideStr("欧阳小三", 50, "*"), "欧**三")
|
||||
|
||||
// 边界与特殊用例扩展
|
||||
// 1) 空字符串与非正百分比
|
||||
t.Assert(gstr.HideStr("", 50, "*"), "")
|
||||
t.Assert(gstr.HideStr("abcdef", 0, "*"), "abcdef")
|
||||
t.Assert(gstr.HideStr("abcdef", -1, "*"), "abcdef")
|
||||
|
||||
// 2) 百分比为100(完全隐藏),邮箱仅隐藏本地部分
|
||||
t.Assert(gstr.HideStr("abcdef", 100, "*"), "******")
|
||||
t.Assert(gstr.HideStr("user@example.com", 100, "*"), "****@example.com")
|
||||
|
||||
// 3) 极短字符串
|
||||
t.Assert(gstr.HideStr("a", 100, "*"), "*")
|
||||
t.Assert(gstr.HideStr("ab", 50, "*"), "a*")
|
||||
// 百分比太小时(四舍五入前为0),应保持不变
|
||||
t.Assert(gstr.HideStr("ab", 10, "*"), "ab")
|
||||
|
||||
// 4) 隐藏字符为空:相当于删除中间片段
|
||||
t.Assert(gstr.HideStr("abcdef", 50, ""), "abf")
|
||||
t.Assert(gstr.HideStr("john@kohg.cn", 50, ""), "jn@kohg.cn")
|
||||
|
||||
// 5) 多字符隐藏串
|
||||
t.Assert(gstr.HideStr("abcde", 40, "##"), "a####de")
|
||||
|
||||
// 6) Unicode/emoji
|
||||
t.Assert(gstr.HideStr("你好🙂世界", 40, "*"), "你**世界")
|
||||
|
||||
// 7) 多个@的字符串,按第一个@处理
|
||||
t.Assert(gstr.HideStr("a@b@c", 100, "*"), "*@b@c")
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@ -271,7 +271,7 @@ func doScanList(
|
||||
arrayElemValue = reflect.New(arrayItemType.Elem()).Elem()
|
||||
arrayValue.Index(i).Set(arrayElemValue.Addr())
|
||||
}
|
||||
} else {
|
||||
// } else {
|
||||
// Like: []Entity
|
||||
}
|
||||
bindToAttrValue = arrayElemValue.FieldByName(bindToAttrName)
|
||||
|
||||
@ -108,10 +108,11 @@ func (c *Converter) Int64(anyInput any) (int64, error) {
|
||||
isMinus = false
|
||||
)
|
||||
if len(s) > 0 {
|
||||
if s[0] == '-' {
|
||||
switch s[0] {
|
||||
case '-':
|
||||
isMinus = true
|
||||
s = s[1:]
|
||||
} else if s[0] == '+' {
|
||||
case '+':
|
||||
s = s[1:]
|
||||
}
|
||||
}
|
||||
|
||||
@ -67,6 +67,7 @@ func (c *Converter) Scan(srcValue any, dstPointer any, option ...ScanOption) (er
|
||||
if dstPointerReflectValue.CanAddr() {
|
||||
dstPointerReflectValue = dstPointerReflectValue.Addr()
|
||||
dstPointerReflectType = dstPointerReflectValue.Type()
|
||||
// dstPointerReflectKind = dstPointerReflectType.Kind()
|
||||
} else {
|
||||
// If dstPointer is not a pointer and cannot be addressed, return an error
|
||||
return gerror.NewCodef(
|
||||
|
||||
@ -111,7 +111,7 @@ func (p *Page) LastPage() string {
|
||||
|
||||
// PageBar returns the HTML page bar content with link and span tags.
|
||||
func (p *Page) PageBar() string {
|
||||
plus := int(math.Ceil(float64(p.PageBarNum / 2)))
|
||||
plus := p.PageBarNum / 2
|
||||
if p.PageBarNum-plus+p.CurrentPage > p.TotalPage {
|
||||
plus = p.PageBarNum - p.TotalPage + p.CurrentPage
|
||||
}
|
||||
|
||||
@ -176,13 +176,13 @@ func doDump(value any, indent string, buffer *bytes.Buffer, option doDumpOption)
|
||||
doDumpNumber(exportInternalInput)
|
||||
|
||||
case reflect.Chan:
|
||||
buffer.WriteString(fmt.Sprintf(`<%s>`, reflectValue.Type().String()))
|
||||
fmt.Fprintf(buffer, `<%s>`, reflectValue.Type().String())
|
||||
|
||||
case reflect.Func:
|
||||
if reflectValue.IsNil() || !reflectValue.IsValid() {
|
||||
buffer.WriteString(`<nil>`)
|
||||
} else {
|
||||
buffer.WriteString(fmt.Sprintf(`<%s>`, reflectValue.Type().String()))
|
||||
fmt.Fprintf(buffer, `<%s>`, reflectValue.Type().String())
|
||||
}
|
||||
|
||||
case reflect.Interface:
|
||||
@ -209,14 +209,9 @@ type doDumpInternalInput struct {
|
||||
func doDumpSlice(in doDumpInternalInput) {
|
||||
if b, ok := in.Value.([]byte); ok {
|
||||
if !in.Option.WithType {
|
||||
in.Buffer.WriteString(fmt.Sprintf(`"%s"`, addSlashesForString(string(b))))
|
||||
fmt.Fprintf(in.Buffer, `"%s"`, addSlashesForString(string(b)))
|
||||
} else {
|
||||
in.Buffer.WriteString(fmt.Sprintf(
|
||||
`%s(%d) "%s"`,
|
||||
in.ReflectTypeName,
|
||||
len(string(b)),
|
||||
string(b),
|
||||
))
|
||||
fmt.Fprintf(in.Buffer, `%s(%d) "%s"`, in.ReflectTypeName, len(string(b)), string(b))
|
||||
}
|
||||
return
|
||||
}
|
||||
@ -224,21 +219,21 @@ func doDumpSlice(in doDumpInternalInput) {
|
||||
if !in.Option.WithType {
|
||||
in.Buffer.WriteString("[]")
|
||||
} else {
|
||||
in.Buffer.WriteString(fmt.Sprintf("%s(0) []", in.ReflectTypeName))
|
||||
fmt.Fprintf(in.Buffer, "%s(0) []", in.ReflectTypeName)
|
||||
}
|
||||
return
|
||||
}
|
||||
if !in.Option.WithType {
|
||||
in.Buffer.WriteString("[\n")
|
||||
} else {
|
||||
in.Buffer.WriteString(fmt.Sprintf("%s(%d) [\n", in.ReflectTypeName, in.ReflectValue.Len()))
|
||||
fmt.Fprintf(in.Buffer, "%s(%d) [\n", in.ReflectTypeName, in.ReflectValue.Len())
|
||||
}
|
||||
for i := 0; i < in.ReflectValue.Len(); i++ {
|
||||
in.Buffer.WriteString(in.NewIndent)
|
||||
doDump(in.ReflectValue.Index(i), in.NewIndent, in.Buffer, in.Option)
|
||||
in.Buffer.WriteString(",\n")
|
||||
}
|
||||
in.Buffer.WriteString(fmt.Sprintf("%s]", in.Indent))
|
||||
fmt.Fprintf(in.Buffer, "%s]", in.Indent)
|
||||
}
|
||||
|
||||
func doDumpMap(in doDumpInternalInput) {
|
||||
@ -254,7 +249,7 @@ func doDumpMap(in doDumpInternalInput) {
|
||||
if !in.Option.WithType {
|
||||
in.Buffer.WriteString("{}")
|
||||
} else {
|
||||
in.Buffer.WriteString(fmt.Sprintf("%s(0) {}", in.ReflectTypeName))
|
||||
fmt.Fprintf(in.Buffer, "%s(0) {}", in.ReflectTypeName)
|
||||
}
|
||||
return
|
||||
}
|
||||
@ -272,7 +267,7 @@ func doDumpMap(in doDumpInternalInput) {
|
||||
if !in.Option.WithType {
|
||||
in.Buffer.WriteString("{\n")
|
||||
} else {
|
||||
in.Buffer.WriteString(fmt.Sprintf("%s(%d) {\n", in.ReflectTypeName, len(mapKeys)))
|
||||
fmt.Fprintf(in.Buffer, "%s(%d) {\n", in.ReflectTypeName, len(mapKeys))
|
||||
}
|
||||
for _, mapKey := range mapKeys {
|
||||
tmpSpaceNum = len(fmt.Sprintf(`%v`, mapKey.Interface()))
|
||||
@ -283,32 +278,34 @@ func doDumpMap(in doDumpInternalInput) {
|
||||
}
|
||||
// Map key and indent string dump.
|
||||
if !in.Option.WithType {
|
||||
in.Buffer.WriteString(fmt.Sprintf(
|
||||
fmt.Fprintf(
|
||||
in.Buffer,
|
||||
"%s%v:%s",
|
||||
in.NewIndent,
|
||||
mapKeyStr,
|
||||
strings.Repeat(" ", maxSpaceNum-tmpSpaceNum+1),
|
||||
))
|
||||
)
|
||||
} else {
|
||||
in.Buffer.WriteString(fmt.Sprintf(
|
||||
fmt.Fprintf(
|
||||
in.Buffer,
|
||||
"%s%s(%v):%s",
|
||||
in.NewIndent,
|
||||
mapKey.Type().String(),
|
||||
mapKeyStr,
|
||||
strings.Repeat(" ", maxSpaceNum-tmpSpaceNum+1),
|
||||
))
|
||||
)
|
||||
}
|
||||
// Map value dump.
|
||||
doDump(in.ReflectValue.MapIndex(mapKey), in.NewIndent, in.Buffer, in.Option)
|
||||
in.Buffer.WriteString(",\n")
|
||||
}
|
||||
in.Buffer.WriteString(fmt.Sprintf("%s}", in.Indent))
|
||||
fmt.Fprintf(in.Buffer, "%s}", in.Indent)
|
||||
}
|
||||
|
||||
func doDumpStruct(in doDumpInternalInput) {
|
||||
if in.PtrAddress != "" {
|
||||
if _, ok := in.DumpedPointerSet[in.PtrAddress]; ok {
|
||||
in.Buffer.WriteString(fmt.Sprintf(`<cycle dump %s>`, in.PtrAddress))
|
||||
fmt.Fprintf(in.Buffer, `<cycle dump %s>`, in.PtrAddress)
|
||||
return
|
||||
}
|
||||
}
|
||||
@ -355,12 +352,13 @@ func doDumpStruct(in doDumpInternalInput) {
|
||||
if !in.Option.WithType {
|
||||
in.Buffer.WriteString(structContentStr)
|
||||
} else {
|
||||
in.Buffer.WriteString(fmt.Sprintf(
|
||||
fmt.Fprintf(
|
||||
in.Buffer,
|
||||
"%s(%s) %s",
|
||||
in.ReflectTypeName,
|
||||
attributeCountStr,
|
||||
structContentStr,
|
||||
))
|
||||
)
|
||||
}
|
||||
return
|
||||
}
|
||||
@ -382,37 +380,39 @@ dumpStructFields:
|
||||
if !in.Option.WithType {
|
||||
in.Buffer.WriteString("{\n")
|
||||
} else {
|
||||
in.Buffer.WriteString(fmt.Sprintf("%s(%d) {\n", in.ReflectTypeName, len(structFields)))
|
||||
fmt.Fprintf(in.Buffer, "%s(%d) {\n", in.ReflectTypeName, len(structFields))
|
||||
}
|
||||
for _, field := range structFields {
|
||||
if in.ExportedOnly && !field.IsExported() {
|
||||
continue
|
||||
}
|
||||
tmpSpaceNum = len(fmt.Sprintf(`%v`, field.Name()))
|
||||
in.Buffer.WriteString(fmt.Sprintf(
|
||||
fmt.Fprintf(
|
||||
in.Buffer,
|
||||
"%s%s:%s",
|
||||
in.NewIndent,
|
||||
field.Name(),
|
||||
strings.Repeat(" ", maxSpaceNum-tmpSpaceNum+1),
|
||||
))
|
||||
)
|
||||
doDump(field.Value, in.NewIndent, in.Buffer, in.Option)
|
||||
in.Buffer.WriteString(",\n")
|
||||
}
|
||||
in.Buffer.WriteString(fmt.Sprintf("%s}", in.Indent))
|
||||
fmt.Fprintf(in.Buffer, "%s}", in.Indent)
|
||||
}
|
||||
|
||||
func doDumpNumber(in doDumpInternalInput) {
|
||||
if v, ok := in.Value.(iString); ok {
|
||||
s := v.String()
|
||||
if !in.Option.WithType {
|
||||
in.Buffer.WriteString(fmt.Sprintf(`"%v"`, addSlashesForString(s)))
|
||||
fmt.Fprintf(in.Buffer, `"%v"`, addSlashesForString(s))
|
||||
} else {
|
||||
in.Buffer.WriteString(fmt.Sprintf(
|
||||
`%s(%d) "%v"`,
|
||||
fmt.Fprintf(
|
||||
in.Buffer,
|
||||
"%s(%d) %s",
|
||||
in.ReflectTypeName,
|
||||
len(s),
|
||||
addSlashesForString(s),
|
||||
))
|
||||
fmt.Sprintf(`"%v"`, addSlashesForString(s)),
|
||||
)
|
||||
}
|
||||
} else {
|
||||
doDumpDefault(in)
|
||||
@ -422,14 +422,15 @@ func doDumpNumber(in doDumpInternalInput) {
|
||||
func doDumpString(in doDumpInternalInput) {
|
||||
s := in.ReflectValue.String()
|
||||
if !in.Option.WithType {
|
||||
in.Buffer.WriteString(fmt.Sprintf(`"%v"`, addSlashesForString(s)))
|
||||
fmt.Fprintf(in.Buffer, `"%v"`, addSlashesForString(s))
|
||||
} else {
|
||||
in.Buffer.WriteString(fmt.Sprintf(
|
||||
fmt.Fprintf(
|
||||
in.Buffer,
|
||||
`%s(%d) "%v"`,
|
||||
in.ReflectTypeName,
|
||||
len(s),
|
||||
addSlashesForString(s),
|
||||
))
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@ -458,7 +459,7 @@ func doDumpDefault(in doDumpInternalInput) {
|
||||
if !in.Option.WithType {
|
||||
in.Buffer.WriteString(s)
|
||||
} else {
|
||||
in.Buffer.WriteString(fmt.Sprintf("%s(%s)", in.ReflectTypeName, s))
|
||||
fmt.Fprintf(in.Buffer, "%s(%s)", in.ReflectTypeName, s)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user