Skip to content

Commit

Permalink
Merge pull request #80 from osspkg/fix-DI
Browse files Browse the repository at this point in the history
Fix di
  • Loading branch information
markus621 authored Jan 15, 2024
2 parents f33fdd6 + 7ca75d0 commit f71f2a6
Show file tree
Hide file tree
Showing 23 changed files with 167 additions and 80 deletions.
5 changes: 1 addition & 4 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,8 @@ build:
tests:
devtool test

.PHONY: pre-commite
pre-commite: setup lint build tests

.PHONY: ci
ci: install setup lint build tests
ci: install setup license lint build tests

.PHONY: go_work
go_work:
Expand Down
38 changes: 38 additions & 0 deletions app/container_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ func TestUnit_EmptyDI(t *testing.T) {

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

type SimpleString string

type SimpleDI1_A struct {
A string
}
Expand Down Expand Up @@ -334,6 +336,42 @@ func TestUnit_DI_Default(t *testing.T) {
wantErr: false,
wantErrString: "",
},
{
name: "Case24",
register: []interface{}{
func() *SimpleDI1_Service {
return &SimpleDI1_Service{}
},
func(_ *SimpleDI1_Service) error {
return nil
},
},
wantErr: false,
wantErrString: "",
},
{
name: "Case25",
register: []interface{}{
&SimpleDI1_A{A: "123"},
SimpleDI1_Struct{},
func(s SimpleDI1_Struct) error {
return fmt.Errorf(s.AA.A)
},
},
wantErr: true,
wantErrString: "123",
},
{
name: "Case26",
register: []interface{}{
SimpleString("QWERT"),
func(s SimpleString) error {
return fmt.Errorf(string(s))
},
},
wantErr: true,
wantErrString: "QWERT",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
Expand Down
21 changes: 15 additions & 6 deletions app/reflect.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,19 +19,28 @@ func getReflectAddress(t reflect.Type, v interface{}) (string, bool) {
return fmt.Sprintf("%s.%s", t.PkgPath(), t.Name()), true
}
switch t.Kind() {
case reflect.Array, reflect.Chan, reflect.Map, reflect.Ptr, reflect.Slice:
case reflect.Func:
if v == nil {
return t.String(), false
}
p := reflect.ValueOf(v).Pointer()
return fmt.Sprintf("0x%x.%s", p, t.String()), true
case reflect.Ptr:
if t.Implements(errType) {
return errName, false
}
if len(t.Elem().PkgPath()) > 0 {
return fmt.Sprintf("%s.%s", t.Elem().PkgPath(), t.Elem().Name()), true
}
case reflect.Func:
if v == nil {
return t.String(), false
case reflect.Bool,
reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64,
reflect.Float32, reflect.Float64,
reflect.Array, reflect.Chan, reflect.Map, reflect.Slice, reflect.String,
reflect.Struct:
if len(t.PkgPath()) > 0 {
return fmt.Sprintf("%s.%s", t.PkgPath(), t.Elem().Name()), true
}
p := reflect.ValueOf(v).Pointer()
return fmt.Sprintf("0x%x.%s", p, t.String()), true
}
return t.String(), false
}
Expand Down
16 changes: 8 additions & 8 deletions app/reflect_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,17 +38,17 @@ func TestUnit_getReflectAddress(t *testing.T) {
want string
ok bool
}{
{name: "Case1", args: reflect.TypeOf(a), obj: a, want: "int"},
{name: "Case2", args: reflect.TypeOf(b), obj: b, want: "string"},
{name: "Case3", args: reflect.TypeOf(c), obj: c, want: "bool"},
{name: "Case1", args: reflect.TypeOf(a), obj: a, want: "int", ok: false},
{name: "Case2", args: reflect.TypeOf(b), obj: b, want: "string", ok: false},
{name: "Case3", args: reflect.TypeOf(c), obj: c, want: "bool", ok: false},
{name: "Case4", args: reflect.TypeOf(d), obj: d, want: "go.osspkg.com/goppy/app.aa", ok: true},
{name: "Case5", args: reflect.TypeOf(e), obj: e, want: "go.osspkg.com/goppy/app.ff", ok: true},
{name: "Case6", args: reflect.TypeOf(f), obj: f, want: "func(string) bool", ok: true},
{name: "Case6", args: reflect.TypeOf(f), obj: nil, want: "func(string) bool", ok: false},
{name: "Case7", args: reflect.TypeOf(g), obj: g, want: "error"},
{name: "Case8", args: reflect.TypeOf(h), obj: h, want: "[]string"},
{name: "Case9", args: reflect.TypeOf(j), obj: j, want: "go.osspkg.com/goppy/app.bb", ok: true},
{name: "Case10", args: reflect.TypeOf(k), obj: k, want: "struct {}"},
{name: "Case7", args: reflect.TypeOf(f), obj: nil, want: "func(string) bool", ok: false},
{name: "Case8", args: reflect.TypeOf(g), obj: g, want: "error", ok: false},
{name: "Case9", args: reflect.TypeOf(h), obj: h, want: "[]string", ok: false},
{name: "Case10", args: reflect.TypeOf(j), obj: j, want: "go.osspkg.com/goppy/app.bb", ok: true},
{name: "Case11", args: reflect.TypeOf(k), obj: k, want: "struct {}", ok: false},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
Expand Down
4 changes: 2 additions & 2 deletions auth/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ require (
go.osspkg.com/goppy/encryption v0.3.0
go.osspkg.com/goppy/errors v0.3.0
go.osspkg.com/goppy/ioutil v0.3.0
go.osspkg.com/goppy/plugins v0.3.0
go.osspkg.com/goppy/plugins v0.3.1
go.osspkg.com/goppy/random v0.3.0
go.osspkg.com/goppy/web v0.3.0
go.osspkg.com/goppy/web v0.3.1
go.osspkg.com/goppy/xtest v0.3.0
golang.org/x/oauth2 v0.16.0
)
Expand Down
4 changes: 2 additions & 2 deletions auth/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
go.osspkg.com/goppy/syscall v0.1.3 h1:22P17r+oBbHuSKWjhayfjTZlcDcOPFqu1TrSLrMzeMA=
go.osspkg.com/goppy/syscall v0.1.3/go.mod h1:8MsNFOYAzNzGI6FE+0hmqLINQ5cxVkhqHUyirzENG9A=
go.osspkg.com/goppy/syscall v0.3.0 h1:2PcpkqC1ol14HTOC+XyG+3lsuQ9pnG9ueE4xFywoSdE=
go.osspkg.com/goppy/syscall v0.3.0/go.mod h1:Vz1BCzM8MmyC/26SjiVh6OGcAkky1y4xalSWbVceiL4=
go.osspkg.com/static v1.4.0 h1:2uy4/11c0QP+QLMucKQZbAU+e6lhVHKw5dWJPTk/DBg=
go.osspkg.com/static v1.4.0/go.mod h1:94YydVU3qUtb1J534486lpm+qg6CviQjqtxKlkpSppM=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
Expand Down
36 changes: 18 additions & 18 deletions examples/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -38,26 +38,26 @@ replace (

require (
go.osspkg.com/goppy v0.0.0-00010101000000-000000000000
go.osspkg.com/goppy/app v0.1.12
go.osspkg.com/goppy/app v0.3.0
go.osspkg.com/goppy/auth v0.0.0-00010101000000-000000000000
go.osspkg.com/goppy/console v0.1.2
go.osspkg.com/goppy/console v0.3.0
go.osspkg.com/goppy/geoip v0.0.0-00010101000000-000000000000
go.osspkg.com/goppy/iosync v0.1.5
go.osspkg.com/goppy/iosync v0.3.0
go.osspkg.com/goppy/metrics v0.0.0-00010101000000-000000000000
go.osspkg.com/goppy/ormmysql v0.0.0-00010101000000-000000000000
go.osspkg.com/goppy/ormpgsql v0.0.0-00010101000000-000000000000
go.osspkg.com/goppy/ormsqlite v0.0.0-00010101000000-000000000000
go.osspkg.com/goppy/plugins v0.1.2
go.osspkg.com/goppy/routine v0.1.6
go.osspkg.com/goppy/syscall v0.1.3
go.osspkg.com/goppy/plugins v0.3.0
go.osspkg.com/goppy/routine v0.3.0
go.osspkg.com/goppy/syscall v0.3.0
go.osspkg.com/goppy/tcp v0.0.0-00010101000000-000000000000
go.osspkg.com/goppy/udp v0.0.0-00010101000000-000000000000
go.osspkg.com/goppy/unixsocket v0.0.0-00010101000000-000000000000
go.osspkg.com/goppy/web v0.1.11
go.osspkg.com/goppy/web v0.3.0
go.osspkg.com/goppy/ws v0.0.0-00010101000000-000000000000
go.osspkg.com/goppy/xc v0.1.1
go.osspkg.com/goppy/xc v0.3.0
go.osspkg.com/goppy/xdns v0.0.0-00010101000000-000000000000
go.osspkg.com/goppy/xlog v0.1.7
go.osspkg.com/goppy/xlog v0.3.0
)

require (
Expand All @@ -81,15 +81,15 @@ require (
github.com/prometheus/common v0.45.0 // indirect
github.com/prometheus/procfs v0.12.0 // indirect
go.osspkg.com/algorithms v1.3.1 // indirect
go.osspkg.com/goppy/encryption v0.1.6 // indirect
go.osspkg.com/goppy/env v0.1.2 // indirect
go.osspkg.com/goppy/errors v0.1.2 // indirect
go.osspkg.com/goppy/iofile v0.1.7 // indirect
go.osspkg.com/goppy/ioutil v0.1.3 // indirect
go.osspkg.com/goppy/orm v0.1.9 // indirect
go.osspkg.com/goppy/random v0.1.2 // indirect
go.osspkg.com/goppy/sqlcommon v0.1.8 // indirect
go.osspkg.com/goppy/xnet v0.1.3 // indirect
go.osspkg.com/goppy/encryption v0.3.0 // indirect
go.osspkg.com/goppy/env v0.3.0 // indirect
go.osspkg.com/goppy/errors v0.3.0 // indirect
go.osspkg.com/goppy/iofile v0.3.0 // indirect
go.osspkg.com/goppy/ioutil v0.3.0 // indirect
go.osspkg.com/goppy/orm v0.3.0 // indirect
go.osspkg.com/goppy/random v0.3.0 // indirect
go.osspkg.com/goppy/sqlcommon v0.3.0 // indirect
go.osspkg.com/goppy/xnet v0.3.0 // indirect
go.osspkg.com/static v1.4.0 // indirect
golang.org/x/mod v0.12.0 // indirect
golang.org/x/net v0.20.0 // indirect
Expand Down
4 changes: 2 additions & 2 deletions geoip/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ replace (

require (
github.com/oschwald/geoip2-golang v1.9.0
go.osspkg.com/goppy/plugins v0.3.0
go.osspkg.com/goppy/web v0.3.0
go.osspkg.com/goppy/plugins v0.3.1
go.osspkg.com/goppy/web v0.3.1
)

require (
Expand Down
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,12 @@ replace (
)

require (
go.osspkg.com/goppy/app v0.3.0
go.osspkg.com/goppy/app v0.3.1
go.osspkg.com/goppy/console v0.3.0
go.osspkg.com/goppy/env v0.3.0
go.osspkg.com/goppy/errors v0.3.0
go.osspkg.com/goppy/iofile v0.3.0
go.osspkg.com/goppy/plugins v0.3.0
go.osspkg.com/goppy/plugins v0.3.1
go.osspkg.com/goppy/xlog v0.3.0
gopkg.in/yaml.v3 v3.0.1
)
Expand Down
19 changes: 8 additions & 11 deletions goppy.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,16 +77,15 @@ func (v *_app) Logger(l xlog.Logger) {
// Plugins setting the list of plugins to initialize
func (v *_app) Plugins(args ...plugins.Plugin) {
for _, arg := range args {
reflectResolve(arg.Config, reflect.Ptr, func(in interface{}) {
reflectResolve(arg.Config, plugins.AllowedKindConfig, func(in interface{}) {
v.configs = append(v.configs, in)
}, "Plugin.Config can only be a reference to an object")
reflectResolve(arg.Inject, reflect.Func, func(in interface{}) {
})
reflectResolve(arg.Inject, plugins.AllowedKindInject, func(in interface{}) {
v.plugins = append(v.plugins, in)
}, "Plugin.Inject can only be a function that accepts "+
"dependencies and returns a reference to the initialized service")
reflectResolve(arg.Resolve, reflect.Func, func(in interface{}) {
})
reflectResolve(arg.Resolve, plugins.AllowedKindResolve, func(in interface{}) {
v.plugins = append(v.plugins, in)
}, "Plugin.Resolve can only be a function that accepts dependencies")
})
}
}

Expand Down Expand Up @@ -118,13 +117,11 @@ func (v *_app) Run() {
apps.Run()
}

func reflectResolve(arg interface{}, k reflect.Kind, call func(interface{}), comment string) {
func reflectResolve(arg interface{}, k plugins.AllowedKind, call func(interface{})) {
if arg == nil {
return
}
if reflect.TypeOf(arg).Kind() != k {
panic(comment)
}
k.MustValidate(arg)
call(arg)
}

Expand Down
4 changes: 2 additions & 2 deletions metrics/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@ require (
github.com/prometheus/client_golang v1.18.0
github.com/prometheus/client_model v0.5.0
go.osspkg.com/goppy/env v0.3.0
go.osspkg.com/goppy/plugins v0.3.0
go.osspkg.com/goppy/plugins v0.3.1
go.osspkg.com/goppy/syscall v0.3.0
go.osspkg.com/goppy/web v0.3.0
go.osspkg.com/goppy/web v0.3.1
go.osspkg.com/goppy/xc v0.3.0
go.osspkg.com/goppy/xlog v0.3.0
go.osspkg.com/goppy/xnet v0.3.0
Expand Down
2 changes: 1 addition & 1 deletion ormmysql/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ require (
github.com/go-sql-driver/mysql v1.7.1
go.osspkg.com/goppy/errors v0.3.0
go.osspkg.com/goppy/orm v0.3.0
go.osspkg.com/goppy/plugins v0.3.0
go.osspkg.com/goppy/plugins v0.3.1
go.osspkg.com/goppy/routine v0.3.0
go.osspkg.com/goppy/sqlcommon v0.3.0
go.osspkg.com/goppy/xc v0.3.0
Expand Down
2 changes: 1 addition & 1 deletion ormpgsql/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ require (
github.com/lib/pq v1.10.9
go.osspkg.com/goppy/errors v0.3.0
go.osspkg.com/goppy/orm v0.3.0
go.osspkg.com/goppy/plugins v0.3.0
go.osspkg.com/goppy/plugins v0.3.1
go.osspkg.com/goppy/routine v0.3.0
go.osspkg.com/goppy/sqlcommon v0.3.0
go.osspkg.com/goppy/xc v0.3.0
Expand Down
2 changes: 1 addition & 1 deletion ormsqlite/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ require (
go.osspkg.com/goppy/errors v0.3.0
go.osspkg.com/goppy/iofile v0.3.0
go.osspkg.com/goppy/orm v0.3.0
go.osspkg.com/goppy/plugins v0.3.0
go.osspkg.com/goppy/plugins v0.3.1
go.osspkg.com/goppy/routine v0.3.0
go.osspkg.com/goppy/sqlcommon v0.3.0
go.osspkg.com/goppy/xc v0.3.0
Expand Down
58 changes: 58 additions & 0 deletions plugins/allowed_kind.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/*
* Copyright (c) 2022-2024 Mikhail Knyazhev <[email protected]>. All rights reserved.
* Use of this source code is governed by a BSD 3-Clause license that can be found in the LICENSE file.
*/

package plugins

import (
"fmt"
"os"
"reflect"
)

type AllowedKind struct {
kind []reflect.Kind
typed []reflect.Kind
errMessage string
}

var (
AllowedKindConfig = AllowedKind{
kind: []reflect.Kind{reflect.Ptr},
errMessage: "Plugin.Config can only be a reference to an object",
}
AllowedKindInject = AllowedKind{
kind: []reflect.Kind{reflect.Ptr, reflect.Func},
typed: []reflect.Kind{
reflect.Bool,
reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64,
reflect.Float32, reflect.Float64,
reflect.Array, reflect.Chan, reflect.Map, reflect.Slice, reflect.String, reflect.Struct,
},
errMessage: "Plugin.Inject unsupported",
}
AllowedKindResolve = AllowedKind{
kind: []reflect.Kind{reflect.Func},
errMessage: "Plugin.Resolve can only be a function that accepts dependencies",
}
)

func (v AllowedKind) MustValidate(in interface{}) {
into := reflect.TypeOf(in)
for _, k := range v.kind {
if into.Kind() == k {
return
}
}
if v.typed != nil {
for _, k := range v.typed {
if into.Kind() == k && into.Name() != k.String() {
return
}
}
}
fmt.Printf("%s, but got `%T`\n", v.errMessage, in)
os.Exit(1)
}
Loading

0 comments on commit f71f2a6

Please sign in to comment.