Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
110 changes: 58 additions & 52 deletions .github/workflows/go.yml
Original file line number Diff line number Diff line change
@@ -1,63 +1,69 @@
# This workflow will build a golang project
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-go
name: Lint & Test
name: Run Tests

on:
push:
branches: [ "master" ]
branches:
- main
pull_request:
branches: [ "master" ]
branches:
- main

permissions:
contents: read

jobs:
build:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3

- name: Set up Go
uses: actions/setup-go@v3
with:
go-version: 1.18

- name: Run gofmt
run: |
gofmt -s -l . | tee .gofmt.log
test `cat .gofmt.log | wc -l` -eq 0
rm .gofmt.log

- name: Run govet
run: go vet ./...

- name: Run golint
run: |
golint ./... | tee .golint.log
test `cat .golint.log | wc -l` -eq 0
rm .golint.log
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: "^1"
- name: Setup golangci-lint
uses: golangci/golangci-lint-action@v8
with:
version: v2.1.6
args: --verbose
test:
needs: lint
strategy:
matrix:
os: [ubuntu-latest, macos-latest]
go: ["1.23", "1.24"]
include:
- os: ubuntu-latest
go-build: ~/.cache/go-build
- os: macos-latest
go-build: ~/Library/Caches/go-build
name: ${{ matrix.os }} @ Go ${{ matrix.go }}
runs-on: ${{ matrix.os }}
env:
GO111MODULE: on
GOPROXY: https://proxy.golang.org
steps:
- name: Set up Go ${{ matrix.go }}
uses: actions/setup-go@v5
with:
go-version: ${{ matrix.go }}
cache: false

- name: Run golangci-lint
# You may pin to the exact commit or the version.
# uses: golangci/golangci-lint-action@08e2f20817b15149a52b5b3ebe7de50aff2ba8c5
uses: golangci/golangci-lint-action@v3.4.0
with:
# version of golangci-lint to use in form of v1.2 or v1.2.3 or `latest` to use the latest version
version: latest # optional
# # golangci-lint command line arguments
# args: # optional, default is
# # golangci-lint working directory, default is project root
# working-directory: # optional
# # the token is used for fetching patch of a pull request to show only new issues
# github-token: # optional, default is ${{ github.token }}
# # if set to true and the action runs on a pull request - the action outputs only newly found issues
# only-new-issues: # optional
# # if set to true then the all caching functionality will be complete disabled, takes precedence over all other caching options.
# skip-cache: # optional
# # if set to true then the action doesn't cache or restore ~/go/pkg.
# skip-pkg-cache: # optional
# # if set to true then the action doesn't cache or restore ~/.cache/go-build.
# skip-build-cache: # optional
- name: Checkout Code
uses: actions/checkout@v4
with:
ref: ${{ github.ref }}

# - name: Build
# run: go build -v ./...
- uses: actions/cache@v4
with:
path: |
${{ matrix.go-build }}
~/go/pkg/mod
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
restore-keys: |
${{ runner.os }}-go-

- name: Test
run: go test -v -coverprofile=coverage.txt -covermode=atomic ./...
- name: Run Tests
run: make test
85 changes: 85 additions & 0 deletions .golangci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
version: "2"
linters:
enable:
- asciicheck
- copyloopvar
- dogsled
- durationcheck
- errorlint
- gosec
- misspell
- nakedret
- nilerr
- nolintlint
- perfsprint
- revive
- testifylint
- usestdlibvars
- wastedassign
settings:
gosec:
includes:
- G102
- G106
- G108
- G109
- G111
- G112
- G201
- G203
perfsprint:
int-conversion: true
err-error: true
errorf: true
sprintf1: true
strconcat: true
testifylint:
enable-all: true
exclusions:
generated: lax
presets:
- comments
- common-false-positives
- legacy
- std-error-handling
rules:
- linters:
- structcheck
- unused
text: "`data` is unused"
- linters:
- staticcheck
text: "SA1019:"
- linters:
- revive
text: "var-naming:"
- linters:
- revive
text: "exported:"
- linters:
- gosec
path: _test\.go
- linters:
- revive
path: _test\.go
paths:
- third_party$
- builtin$
- examples$
formatters:
enable:
- gofmt
- gofumpt
- goimports
settings:
gofmt:
rewrite-rules:
- pattern: "interface{}"
replacement: "any"
exclusions:
generated: lax
paths:
- third_party$
- builtin$
- examples$
- gin.go
11 changes: 4 additions & 7 deletions binding.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,7 @@ var bodyBinders = map[string]binding.BindingBody{
}

// bind request arguments
func bind(ctx *Context, obj any) (err error) {

func bind(ctx *Context, obj any) error {
vPtr := reflect.ValueOf(obj)

if vPtr.Kind() != reflect.Ptr {
Expand All @@ -47,6 +46,7 @@ func bind(ctx *Context, obj any) (err error) {
var (
contentType = filterFlags(ctx.Request.Header.Get("Content-Type"))
body []byte
err error
)

if body, err = ctx.RequestBody(); err != nil {
Expand All @@ -60,15 +60,12 @@ func bind(ctx *Context, obj any) (err error) {

if ctx.Request.Method == http.MethodGet {
err = binding.Form.Bind(ctx.Request, obj)

} else if binder, exists := binders[contentType]; exists {
err = binder.Bind(ctx.Request, obj)

} else if bodyBinder, exists := bodyBinders[contentType]; exists {
if len(body) > 0 {
err = bodyBinder.BindBody(body, obj)
}

} else if DefaultBinder != nil {
if bodyBinder, ok := DefaultBinder.(binding.BindingBody); ok {
if len(body) > 0 {
Expand All @@ -94,10 +91,10 @@ func bind(ctx *Context, obj any) (err error) {
}

if vPtr.Kind() != reflect.Struct {
return
return nil
}

var vType = vPtr.Type()
vType := vPtr.Type()
var hasQueryField, hasURIField, hasHeaderField bool

for i := 0; i < vPtr.NumField(); i++ {
Expand Down
24 changes: 12 additions & 12 deletions binding_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,11 @@ import (
"testing"
"time"

"github.com/fox-gonic/fox/httperrors"
"github.com/gin-gonic/gin"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

"github.com/fox-gonic/fox/httperrors"
)

type AuthInfo struct {
Expand Down Expand Up @@ -62,10 +64,10 @@ func TestBinding(t *testing.T) {
ctx.Set("user_id", int64(123))

err := bind(ctx, obj)
assert.Equal(t, ErrBindNonPointerValue, err)
require.Equal(t, ErrBindNonPointerValue, err)

err = bind(ctx, &obj)
assert.NoError(t, err)
require.NoError(t, err)
assert.Equal(t, 1, obj.Page)
assert.Equal(t, 30, obj.PageSize)
assert.Equal(t, referer, obj.Referer)
Expand Down Expand Up @@ -102,7 +104,7 @@ func TestBindingJSON(t *testing.T) {
}

err := bind(ctx, &obj)
assert.NoError(t, err)
require.NoError(t, err)
assert.Equal(t, 1, obj.Page)
assert.Equal(t, 30, obj.PageSize)
assert.Equal(t, referer, obj.Referer)
Expand All @@ -123,7 +125,7 @@ func TestBindingJSON(t *testing.T) {
}

err = bind(ctx, &obj)
assert.NoError(t, err)
require.NoError(t, err)
}

var ErrPasswordTooShort = &httperrors.Error{
Expand All @@ -149,8 +151,6 @@ func (args *CreateUserArgs) IsValid() error {
}

func TestIsValider(t *testing.T) {
assert := assert.New(t)

req, _ := http.NewRequest(http.MethodPost, "/users/signup", bytes.NewBufferString(`{"name": "Binder"}`))
req.Header.Set("Content-Type", "application/json")

Expand All @@ -161,18 +161,18 @@ func TestIsValider(t *testing.T) {
}

err := bind(ctx, &CreateUserArgs{})
assert.Error(err)
assert.Equal(httperrors.ErrInvalidArguments, err)
require.Error(t, err)
require.Equal(t, httperrors.ErrInvalidArguments, err)

err = bind(ctx, &CreateUserArgs{
Username: "binder",
})
assert.Error(err)
assert.Equal(ErrPasswordTooShort, err)
require.Error(t, err)
require.Equal(t, ErrPasswordTooShort, err)

err = bind(ctx, &CreateUserArgs{
Username: "binder",
Password: "123456",
})
assert.Nil(err)
require.NoError(t, err)
}
1 change: 0 additions & 1 deletion call.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import (
)

func call(ctx *Context, handler HandlerFunc) any {

var (
funcValue = reflect.ValueOf(handler)
funcType = funcValue.Type()
Expand Down
2 changes: 0 additions & 2 deletions context.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ type Context struct {
// RequestBody return request body bytes
// see c.ShouldBindBodyWith
func (c *Context) RequestBody() (body []byte, err error) {

if cb, ok := c.Get(gin.BodyBytesKey); ok {
if cbb, ok := cb.([]byte); ok {
body = cbb
Expand All @@ -46,7 +45,6 @@ func (c *Context) RequestBody() (body []byte, err error) {

// TraceID return request id
func (c *Context) TraceID() string {

if id, exists := c.Get(logger.TraceID); exists {
return id.(string)
}
Expand Down
2 changes: 1 addition & 1 deletion debug.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import (
)

func init() {
gin.DebugPrintRouteFunc = func(httpMethod, absolutePath, handlerName string, nuHandlers int) {}
gin.DebugPrintRouteFunc = func(_, _, _ string, _ int) {}
}

// IsDebugging returns true if the framework is running in debug mode.
Expand Down
5 changes: 1 addition & 4 deletions domain.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ type DomainEngine struct {

// NewDomainEngine new domain engine
func NewDomainEngine(get ...func() *Engine) *DomainEngine {

de := &DomainEngine{}

if len(get) > 0 {
Expand Down Expand Up @@ -55,7 +54,6 @@ func (engine *DomainEngine) DomainRegexp(name string, engineFunc func(subEngine

// server add domain handler
func (engine *DomainEngine) server(name string, isRegexp bool, engineFunc func(*Engine)) {

domain := &domain{
Name: name,
IsRegexp: isRegexp,
Expand All @@ -80,7 +78,6 @@ func (engine *DomainEngine) server(name string, isRegexp bool, engineFunc func(*

// ServeHTTP conforms to the http.Handler interface.
func (engine *DomainEngine) ServeHTTP(w http.ResponseWriter, req *http.Request) {

if len(engine.domains) == 0 {
engine.Engine.ServeHTTP(w, req)
return
Expand All @@ -92,7 +89,7 @@ func (engine *DomainEngine) ServeHTTP(w http.ResponseWriter, req *http.Request)
}

for i := 0; i < len(engine.domains); i++ {
var domain = engine.domains[i]
domain := engine.domains[i]
if domain.IsRegexp && domain.Regexp.MatchString(host) {
domain.Handler.ServeHTTP(w, req)
return
Expand Down
Loading