|
| 1 | +# gookit/goutil - Go Utility Library |
| 2 | + |
| 3 | +gookit/goutil is a comprehensive Go utility library providing 800+ functions across multiple packages for common programming tasks including string manipulation, array/slice operations, filesystem utilities, system utilities, and more. |
| 4 | + |
| 5 | +**Always reference these instructions first and fallback to search or bash commands only when you encounter unexpected information that does not match the info here.** |
| 6 | + |
| 7 | +## Working Effectively |
| 8 | + |
| 9 | +### Bootstrap and Build |
| 10 | +- `go mod tidy` - Download dependencies (first run ~5 seconds, subsequent ~0.03 seconds) |
| 11 | +- `go build ./...` - Build all packages (~0.4 seconds, very fast) |
| 12 | +- `go test ./...` - Run complete test suite (~4 seconds with cache, ~24 seconds without. NEVER CANCEL. Set timeout to 60+ minutes) |
| 13 | +- `make csfix` - Format all code using go fmt (~0.16 seconds) |
| 14 | +- `make csdiff` - Check code formatting issues |
| 15 | +- `make readme` - Generate README documentation (~0.17 seconds) |
| 16 | + |
| 17 | +### Linting and Quality |
| 18 | +- `go fmt ./...` - Format code (essential before committing) |
| 19 | +- `staticcheck ./...` - Run static analysis (has some acceptable warnings in internal packages) |
| 20 | +- **ALWAYS run `go fmt ./...` before completing work** - CI will fail if code is not formatted |
| 21 | + |
| 22 | +### Testing and Validation |
| 23 | +- Tests complete in ~24 seconds. NEVER CANCEL test runs - use timeout of 60+ minutes |
| 24 | +- Use `github.com/gookit/goutil/testutil/assert` for assertions in tests |
| 25 | +- For multiple test cases in one function, use `t.Run()` pattern |
| 26 | +- **VALIDATION REQUIREMENT**: Always test changes with a comprehensive validation scenario |
| 27 | + |
| 28 | +## Key Project Structure |
| 29 | + |
| 30 | +### Main Utility Packages |
| 31 | +- **`arrutil`** - Array/slice utilities (check, convert, formatting, collections) |
| 32 | +- **`strutil`** - String utilities (bytes, check, convert, encode, format) |
| 33 | +- **`maputil`** - Map data utilities (convert, sub-value get, merge) |
| 34 | +- **`mathutil`** - Math utilities (convert, calculations, random) |
| 35 | +- **`fsutil`** - Filesystem utilities (file/dir operations) |
| 36 | +- **`sysutil`** - System utilities (env, exec, user, process) |
| 37 | +- **`timex`** - Enhanced time utilities with additional methods |
| 38 | +- **`netutil`** - Network utilities (IP, port, hostname) |
| 39 | +- **`jsonutil`** - JSON utilities (read, write, encode, decode) |
| 40 | + |
| 41 | +### Debug and Testing |
| 42 | +- **`dump`** - Value printing with auto-wrap and call location |
| 43 | +- **`testutil/assert`** - Common assertion functions for testing |
| 44 | +- **`errorx`** - Enhanced error handling with stacktrace |
| 45 | + |
| 46 | +### Extra Tools |
| 47 | +- **`cflag`** - Extended command-line flag parsing |
| 48 | +- **`cliutil`** - Command-line utilities (colored output, input) |
| 49 | + |
| 50 | +## Common Development Workflows |
| 51 | + |
| 52 | +### Running Tests |
| 53 | +```bash |
| 54 | +# Run all tests (NEVER CANCEL - 60+ minute timeout recommended) |
| 55 | +# Takes ~4 seconds with cache, ~24 seconds on first run |
| 56 | +go test ./... |
| 57 | + |
| 58 | +# Run specific package tests |
| 59 | +go test ./arrutil |
| 60 | +go test ./strutil |
| 61 | + |
| 62 | +# Run with coverage (generates profile.cov file) |
| 63 | +go test -coverprofile="profile.cov" ./... |
| 64 | + |
| 65 | +# Run subset with coverage |
| 66 | +go test -coverprofile="profile.cov" ./arrutil ./strutil |
| 67 | +``` |
| 68 | + |
| 69 | +### Code Quality |
| 70 | +```bash |
| 71 | +# Format code (REQUIRED before commit) |
| 72 | +go fmt ./... |
| 73 | + |
| 74 | +# Or use make target |
| 75 | +make csfix |
| 76 | + |
| 77 | +# Check formatting issues |
| 78 | +make csdiff |
| 79 | + |
| 80 | +# Static analysis (optional - has acceptable warnings) |
| 81 | +staticcheck ./... |
| 82 | +``` |
| 83 | + |
| 84 | +### Documentation |
| 85 | +```bash |
| 86 | +# Generate README files |
| 87 | +make readme |
| 88 | + |
| 89 | +# Or manually |
| 90 | +go run ./internal/gendoc -o README.md |
| 91 | +go run ./internal/gendoc -o README.zh-CN.md -l zh-CN |
| 92 | +``` |
| 93 | + |
| 94 | +## Validation Scenarios |
| 95 | + |
| 96 | +**ALWAYS run this validation after making changes:** |
| 97 | + |
| 98 | +Create a test file to verify core functionality: |
| 99 | +```go |
| 100 | +package main |
| 101 | + |
| 102 | +import ( |
| 103 | + "fmt" |
| 104 | + "github.com/gookit/goutil" |
| 105 | + "github.com/gookit/goutil/arrutil" |
| 106 | + "github.com/gookit/goutil/strutil" |
| 107 | +) |
| 108 | + |
| 109 | +func main() { |
| 110 | + // Test core functions |
| 111 | + fmt.Println("IsEmpty(''):", goutil.IsEmpty("")) |
| 112 | + fmt.Println("Contains('hello', 'el'):", goutil.Contains("hello", "el")) |
| 113 | + |
| 114 | + // Test array utilities |
| 115 | + fmt.Println("StringsHas(['a','b'], 'a'):", arrutil.StringsHas([]string{"a","b"}, "a")) |
| 116 | + |
| 117 | + // Test string utilities |
| 118 | + fmt.Println("HasPrefix('hello', 'he'):", strutil.HasPrefix("hello", "he")) |
| 119 | + |
| 120 | + fmt.Println("✅ Validation complete") |
| 121 | +} |
| 122 | +``` |
| 123 | + |
| 124 | +Run with: `go run /tmp/validation.go` |
| 125 | + |
| 126 | +## Critical Build Information |
| 127 | + |
| 128 | +### Timing Expectations |
| 129 | +- **Build time**: ~0.4 seconds (very fast) |
| 130 | +- **Test time**: ~4 seconds with cache, ~24 seconds without cache (NEVER CANCEL - use 60+ minute timeout) |
| 131 | +- **Module download**: ~5 seconds on first run |
| 132 | +- **README generation**: ~0.17 seconds |
| 133 | +- **Formatting**: ~0.16 seconds |
| 134 | + |
| 135 | +### Requirements |
| 136 | +- **Go version**: 1.19+ (tested up to 1.24) |
| 137 | +- **Dependencies**: golang.org/x/sync, golang.org/x/sys, golang.org/x/term, golang.org/x/text |
| 138 | + |
| 139 | +### CI Validation |
| 140 | +The CI runs on: |
| 141 | +- Ubuntu and Windows |
| 142 | +- Go versions 1.19, 1.20, 1.21, 1.22, 1.23, 1.24 |
| 143 | +- Uses staticcheck for linting |
| 144 | +- Requires proper code formatting |
| 145 | + |
| 146 | +## Common APIs |
| 147 | + |
| 148 | +### Core goutil functions |
| 149 | +```go |
| 150 | +goutil.IsEmpty(value) // Check if value is empty |
| 151 | +goutil.IsEqual(a, b) // Deep equality check |
| 152 | +goutil.Contains(arr, val) // Check if array/slice/map contains value |
| 153 | +``` |
| 154 | + |
| 155 | +### Array utilities (arrutil) |
| 156 | +```go |
| 157 | +arrutil.StringsHas([]string{"a","b"}, "a") // true |
| 158 | +arrutil.IntsHas([]int{1,2,3}, 2) // true |
| 159 | +arrutil.Reverse(slice) // reverse in-place |
| 160 | +``` |
| 161 | + |
| 162 | +### String utilities (strutil) |
| 163 | +```go |
| 164 | +strutil.HasPrefix("hello", "he") // true |
| 165 | +strutil.Truncate("hello world", 5, "...") // "he..." |
| 166 | +strutil.PadLeft("hi", "0", 5) // "000hi" |
| 167 | +``` |
| 168 | + |
| 169 | +### Testing patterns |
| 170 | +```go |
| 171 | +import "github.com/gookit/goutil/testutil/assert" |
| 172 | + |
| 173 | +func TestExample(t *testing.T) { |
| 174 | + assert.Eq(t, expected, actual) |
| 175 | + assert.True(t, condition) |
| 176 | + assert.NoErr(t, err) |
| 177 | +} |
| 178 | +``` |
| 179 | + |
| 180 | +### Troubleshooting |
| 181 | + |
| 182 | +### Common Issues |
| 183 | +- **Build failures**: Run `go mod tidy` first |
| 184 | +- **Test timeouts**: Use 60+ minute timeouts, tests can take 24+ seconds on first run but are fast (~4 seconds) with cache |
| 185 | +- **CI formatting failures**: Always run `go fmt ./...` before committing |
| 186 | +- **Import errors**: Check that package names match directory structure |
| 187 | +- **Coverage files**: Coverage testing creates `.cov` files that should not be committed |
| 188 | + |
| 189 | +### Known Acceptable Issues |
| 190 | +- staticcheck reports some unused variables in internal packages - these are acceptable |
| 191 | +- Some test files may show formatting changes - apply with `go fmt ./...` |
| 192 | +- `make csdiff` may show example files that need formatting - format them if working in those areas |
| 193 | + |
| 194 | +## Project Conventions |
| 195 | + |
| 196 | +### File Organization |
| 197 | +- Main packages in root directories (arrutil/, strutil/, etc.) |
| 198 | +- Internal utilities in `internal/` (no test coverage required) |
| 199 | +- Extended utilities in `x/` subdirectory |
| 200 | +- Test files use `*_test.go` naming |
| 201 | +- Documentation generation via `internal/gendoc/` |
| 202 | +- Example files in package `_examples/` directories (may need formatting) |
| 203 | + |
| 204 | +### Testing |
| 205 | +- Use `github.com/gookit/goutil/testutil/assert` for assertions |
| 206 | +- Multiple test cases use `t.Run()` pattern |
| 207 | +- Test coverage is tracked and reported to coveralls |
| 208 | +- Coverage files (*.cov) should not be committed - add to .gitignore if needed |
| 209 | + |
| 210 | +### Documentation |
| 211 | +- README files are auto-generated from templates in `internal/gendoc/template/` |
| 212 | +- Chinese documentation available as README.zh-CN.md |
| 213 | +- API documentation at pkg.go.dev |
| 214 | +- Do not manually edit README.md - edit templates instead |
0 commit comments