gookit/goutil
An extended library of Go's common functionality. Contains: number, string, slice/array, Map, struct, reflection, text, file, error, time and date, test, CLI, command run, system information, formatting, common information acquisition, etc.
Github: https://github.com/gookit/goutil
v0.6.10 change log
Full changelog v0.6.9...v0.6.10
✨ New features
✨ feat: testutil - adds a new child package
fakeobj
to create fake objects for testing✨ feat: testutil - adds a new function NewEchoServer() to start the echo server
✨ feat: byteutil - Buffer adds more useful methods for ease of use
✨ feat: dump - Special handling of custom int, uint type values, will print instructions in String format
✨ feat: fsutil - adds a new function to Glob() quickly list matching files
♻️ feat: httpreq - Refactoring the built-in HTTP client httpreq logic
? Update Adjustments
? up: structs - Update and support InitDefaults() for struct slice fields that are not null
? up: maputil -
SimpleMerge()
Supports deep merging of map[string]any data
Other adjustments
✅ test: Update some documentation and fix some unit tests
⬆️ dep: Update golang.org/x depends on the latest version
Some feature usage examples
dump - prints custom types
dump - special handles custom int, uint type values, and will print instructions in String format
![dump custom_type.png](https://habrastorage.org/getpro/habr/upload_files/f6c/716/02d/f6c71602d6341cd075b912ad7034161a.png)
Initialize the struct
Support for initializing the use of environment variables
Support initializing slice fields and nesting structs
type ExtraDefault struct {
City string `default:"some where"`
Github string `default:"${ GITHUB_ADDR }"`
}
type User struct {
Name string `default:"inhere"`
Age int `default:"300"`
Extra *ExtraDefault `default:""` // mark: need init
}
optFn := func(opt *structs.InitOptions) {
opt.ParseEnv = true
}
obj := &User{}
err := structs.InitDefaults(obj, optFn)
goutil.PanicErr(err)
dump.P(obj)
** Initialization result:**
&structs_test.User {
Name: string("inhere"), #len=6
Age: int(300),
Extra: &structs_test.ExtraDefault {
City: string("some where"), #len=10
Github: string("https://some .... url"), #len=21
},
},
Test with Echo Server
Use testutil.NewEchoServer()
to quickly create an HTTP echo server. Convenient for testing HTTP requests, responses, etc.
Usage examples:
var testSrvAddr string
func TestMain(m *testing.M) {
s := testutil.NewEchoServer()
defer s.Close()
testSrvAddr = "http://" + s.Listener.Addr().String()
fmt.Println("server addr:", testSrvAddr)
m.Run()
}
func TestNewEchoServer(t *testing.T) {
// can direct request the echo server
r, err := http.Post(testSrvAddr, "text/plain", strings.NewReader("hello!"))
assert.NoErr(t, err)
// binding response to the testutil.EchoReply
rr := testutil.ParseRespToReply(r)
dump.P(rr)
assert.Eq(t, "POST", rr.Method)
assert.Eq(t, "text/plain", rr.ContentType())
assert.Eq(t, "hello!", rr.Body)
}
v0.6.9 change log
Full changelog v0.6.8...v0.6.9
✨ New features
strutil - Added
ToByteSize(),SafeByteSize()
for converting size string (eg: 5MB) to byte sizestrutil has added
ParseSizeRange()
to facilitate and quickly parse string size range expressions eg:200kb~50mb
strutil - Added new utility functions:
DatetimeNo(), RandWithTpl(), SimpleMatch()
byteutil - Add new utility functions:
Random()
,AppendAny()
fsutil - Add new utility functions:
ReadOrErr()
,ReadStringOrErr()
cliutil - Add new utility functions:
Confirm()
,ReadAsBool()
errorx - Add new utility functions
Err(), Errf()
for easy creation of errorstructs -
InitDefaults()
enhanced to support nested structure pointer initializationstructs -
SetValues()
enhanced to support setting and processing structure pointer valuesstructs - Add
ToSMap(), TryToSMap(), TryToSMap()
to convert structure to string maptestutil/assert new assertion methods
NotContainsKey()
,NotContainsKeys()
Reflects new utility methods
UnexportedValue()
,SetUnexportedValue()
maputil new tool functions
HasOneKey(), CombineToMap(), TryAnyMap()
Added utility functions
AnyToSlice(), CombineToMap()
in arrutiljsonutil has added tool methods
IsJSON(), IsJSONFast()
to check whether it is JSON♻️ fsutil/finder file and directory search reconstruction, enhanced functions, more convenient to use
timex new utility functions
NowAddSec(), IsDuration(), InRange()
timex
ToDuration()
enhanced, support unit d, w and long unit hour, min, secmathutil new tool methods
InRange()
,OutRange()
,InUintRange()
fsutil new tool method
RemoveSub()
to quickly delete subdirectories and filesmaputil
GetByPath()
is enhanced to support matching paths similar totop.*.field
to get values
? Update adjustments
strutil optimization
ToByteSize()
andGlobMatch()
logicstruts -
InitDefaults()
supports initializing non-zero ptr substructure fields? struts -
InitDefaults()
To initialize a substructure, the field must be marked withdefault:""
Other adjustments
? doc: README documentation updated, some subpackages added README
✅ test: Added and fixed some unit tests
⬆️ dep: update golang.org/x dependencies to latest version
Some feature usage examples
finder 文件查找使用
fsutil/finder
Provides a simple and fast way to find matching files and directories.
Built-in support Name, extension, suffix, prefix, glob, path, etc. include or exclude
Support matching file size, modification time (ModTime) and other extended matching methods
ff := finder.NewFinder("/path/to/dir/").
// OnlyFindDir(). // default find files
UseAbsPath().
WithoutDotDir().
WithDirName("testdata").
Include(finder.HumanModTime("<10m")). // latest 10 minutes, to Now
Include(finder.HumanSize("500kb~10mb")) // limit file size
// Find() returns chan, can be for handling
for el := range f.Find() {
fmt.Println(el.Path())
}
strutil.ParseSizeRange
It is easy to parse the string size range to byte size.
opt := &strutil.ParseSizeOpt{}
mix, max, err := strutil.ParseSizeRange("1kb~1mb", opt)
goutil.PanicErr(err)
fmt.Println(min, max) // OUTPUT: 1024, 1048576
Examples of supported expression formats:
"1KB~2MB" => 1KB to 2MB
"-1KB" => <1KB
"~1MB" => <1MB
"< 1KB" => <1KB
"1KB" => >1KB
"1KB~" => >1KB
">1KB" => >1KB
"+1KB" => >1KB
timex.ParseRange()
timex.ParseRange()
It is easy to quickly parse the relative time size range or keyword into time.Time
start, end, err := ParseRange("-1h~1h", nil)
goutil.PanicErr(err)
fmt.Println(start, end)
Examples of supported expression formats:
"-5h~-1h" => 5 hours ago to 1 hour ago
"1h~5h" => 1 hour after to 5 hours after
"-1h~1h" => 1 hour ago to 1 hour after
"-1h" => 1 hour ago to feature. eq "-1h~"
"-1h~0" => 1 hour ago to now.
"< -1h" OR "~-1h" => 1 hour ago.
"> 1h" OR "1h" => 1 hour after to feature
// keyword: now, today, yesterday, tomorrow
"today" => today start to today end
"yesterday" => yesterday start to yesterday end
"tomorrow" => tomorrow start to tomorrow end
More usage
For more instructions, see Unit tests for README and related methods
Github: https://github.com/gookit/goutil