Compare commits

..

70 Commits

Author SHA1 Message Date
Kevin Wan
78ea0769fd feat: simplify httpc (#1748)
* feat: simplify httpc

* chore: fix lint errors

* chore: fix log url issue

* chore: fix log url issue

* refactor: handle resp & err in ResponseHandler

* chore: remove unnecessary var names in return clause
2022-04-03 14:32:27 +08:00
Kevin Wan
e0fa8d820d feat: return original value of setbit in redis (#1746) 2022-04-02 20:25:51 +08:00
Kevin Wan
dfd58c213c fix: model generation bug on with cache (#1743)
* fix: model generation bug on with cache

* chore: refine template

* chore: fix test failure
2022-04-02 15:36:06 +08:00
Kevin Wan
83cacf51b7 chore: update goctl version to 1.3.4 (#1742) 2022-04-02 14:19:34 +08:00
Kevin Wan
6dccfa29fd feat: let model customizable (#1738) 2022-04-01 22:19:52 +08:00
anqiansong
7e0b0ab0b1 Fix zrpc code generation error with --remote (#1739)
Co-authored-by: anqiansong <anqiansong@bytedance.com>
2022-04-01 22:19:33 +08:00
Kevin Wan
ac18cc470d chore: refactor to use const instead of var (#1731) 2022-04-01 15:23:45 +08:00
Fyn
f4471846ff feat(goctl): supports model code 'DO NOT EDIT' (#1728)
Resolves: #1710
2022-04-01 14:48:45 +08:00
anqiansong
9c2d526a11 Fix unit test (#1730)
Co-authored-by: anqiansong <anqiansong@bytedance.com>
2022-04-01 14:46:12 +08:00
Kevin Wan
2b9fc26c38 refactor: guard timeout on API files (#1726) 2022-03-31 21:39:02 +08:00
Xiaoju Jiang
321dc2d410 Added support for setting the parameter size accepted by the interface and custom timeout and maxbytes in API file (#1713)
* Added support for setting the parameter size accepted by the interface

* support custom timeout and maxbytes in API file

* support timeout used unit

* remove goctl maxBytes
2022-03-31 20:20:00 +08:00
Fyn
500bd87c85 fix(goctl): api format with reader input (#1722)
resolves #1721
2022-03-31 00:20:51 +08:00
Kevin Wan
e9620c8c05 chore: refactor code (#1708) 2022-03-24 22:10:15 +08:00
aimuz
70e51bb352 fix: empty slice are set to nil (#1702)
support for empty slce, Same behavior as json.Unmarshal
2022-03-24 21:41:38 +08:00
Kevin Wan
278cd123c8 feat: remove reentrance in redislock, timeout bug (#1704) 2022-03-24 16:17:01 +08:00
Kevin Wan
3febb1a5d0 chore: refactor code (#1700) 2022-03-23 19:09:45 +08:00
Mikael
d8054d8def fix -cache=true insert no clean cache (#1672)
* fix -cache=true insert no clean cache

* fix -cache=true insert no clean cache
2022-03-23 18:55:16 +08:00
Kevin Wan
ec271db7a0 chore: refactor code (#1699) 2022-03-23 18:24:44 +08:00
benqi
bbac994c8a feat: add getset command in redis and kv (#1693) 2022-03-23 18:02:56 +08:00
Kevin Wan
c1d9e6a00b feat: add httpc.Parse (#1698) 2022-03-23 17:58:21 +08:00
anqiansong
0aeb49a6b0 Add verbose flag (#1696)
Co-authored-by: anqiansong <anqiansong@bytedance.com>
2022-03-22 21:00:26 +08:00
Kevin Wan
fe262766b4 chore: fix lint issue (#1694) 2022-03-22 13:31:05 +08:00
Kevin Wan
7181505c8a Update LICENSE 2022-03-21 10:32:41 +08:00
Kevin Wan
f060a226bc refactor: simplify the code (#1670) 2022-03-20 17:26:12 +08:00
Mervin.Wong
93d524b797 fix: the new RawFieldNames considers the tag with options. (#1663)
Co-authored-by: JinfaWang <wangjinfa@iie.ac.cn>
2022-03-20 16:59:19 +08:00
anqiansong
5c169f4f49 Remove debug log (#1669)
Co-authored-by: anqiansong <anqiansong@bytedance.com>
2022-03-20 16:28:36 +08:00
Kevin Wan
d29dfa12e3 feat: support -base to specify base image for goctl docker (#1668)
* feat: support -base to specify base image for goctl docker

* chore: update usage
2022-03-20 11:17:55 +08:00
anqiansong
194f55e08e Remove unused code (#1667)
Co-authored-by: anqiansong <anqiansong@bytedance.com>
2022-03-19 23:15:11 +08:00
Kevin Wan
c0f9892fe3 feat: add Dockerfile for goctl (#1666) 2022-03-19 23:07:17 +08:00
anqiansong
227104d7d7 feat: Remove command goctl rpc proto (#1665)
* Fix goctl completion expression

* Fix code generation error if the pkg of pb/grpc is same to zrpc call client pkg

* Remove deprecated comment on action goctl rpc new

* Remove zrpc code generation on action goctl rpc proto

* Remove zrpc code generation on action goctl rpc proto

* Remove Generator interface

Co-authored-by: anqiansong <anqiansong@bytedance.com>
2022-03-19 22:50:22 +08:00
anqiansong
448029aa4b Mkdir if not exists (#1659)
Co-authored-by: anqiansong <anqiansong@bytedance.com>
2022-03-17 21:44:22 +08:00
Fyn
17e0afeac0 fix(goctl): model method FindOneCtx should be FindOne (#1656) 2022-03-17 17:16:53 +08:00
ronething-bot
18916b5189 [fix] typo (#1655) 2022-03-17 10:00:29 +08:00
Kevin Wan
c11a09be23 chore: remove unnecessary env (#1654) 2022-03-16 17:31:10 +08:00
ronething-bot
56e1ecf2f3 fix: typo (#1646) 2022-03-15 17:46:13 +08:00
Kevin Wan
f9e6013a6c refactor: httpc package for easy to use (#1645) 2022-03-15 14:18:46 +08:00
Kevin Wan
b5d1d8b0d1 refactor: httpc package for easy to use (#1643) 2022-03-14 20:15:14 +08:00
xybingbing
09e6d94f9e FindOneBy 漏 Context (#1642) 2022-03-14 18:56:26 +08:00
Kevin Wan
2a5717d7fb feat: add httpc/Service for convinience (#1641) 2022-03-14 15:36:06 +08:00
Kevin Wan
85cf662c6f feat: add httpc/Get httpc/Post (#1640) 2022-03-13 14:49:14 +08:00
Kevin Wan
3279a7ef0f feat: add rest/httpc to make http requests governacible (#1638)
* feat: change x-trace-id to traceparent to follow opentelemetry

* feat: add rest/httpc to make http requests governacible

* chore: remove blank lines
2022-03-13 14:11:14 +08:00
Kevin Wan
fec908a19b Update ROADMAP.md
update roadmap.
2022-03-13 14:09:11 +08:00
Kevin Wan
f5ed0cda58 Update ROADMAP.md
update roadmap.
2022-03-13 14:08:28 +08:00
anqiansong
cc9d16f505 fix: Update unix-like path regex (#1637)
* Revert import value regex

* Update linux path regex

Co-authored-by: anqiansong <anqiansong@bytedance.com>
2022-03-12 22:21:17 +08:00
Kevin Wan
c05d74b44c feat: support cpu stat on cgroups v2 (#1636)
* feat: cpu stat

* feat: add cpu stat for cgroup2

* feat: add cpu stat for cgroup2, tidy mod

* feat: support cpu stat in cgroup v2
2022-03-12 21:00:04 +08:00
mlr3000
32c88b6352 feat: support oracle :N dynamic parameters (#1552)
* chore:use struct pointer

* feat: support oracle :N dynamic parameters

* Update utils.go

* Update utils.go

* Update utils.go

pg argIndex will not always go up

* Update utils_test.go

* Keep the original

* Update utils_test.go
2022-03-12 18:49:07 +08:00
Kevin Wan
7dabec260f Update readme-cn.md
update readme.
2022-03-12 16:09:18 +08:00
Kevin Wan
4feb88f9b5 Update readme-cn.md
update readme.
2022-03-12 15:23:52 +08:00
Kevin Wan
2776caed0e Update readme.md
update readme.
2022-03-12 15:19:51 +08:00
chensy
c55694d957 Support for referencing types in different API files using format (#1630) 2022-03-12 15:17:31 +08:00
Ziyi Zhang
209ffb934b fix(goctl): kotlin code generation (#1632)
Signed-off-by: Ziyi Zhang <soasurs@gmail.com>
2022-03-11 13:44:18 +08:00
Kevin Wan
26a33932cd feat: support scratch as the base docker image (#1634) 2022-03-11 12:15:38 +08:00
Kevin Wan
d6a692971f chore: reduce the docker image size (#1633)
* chore: reduce the docker image size

* chore: format dockerfile
2022-03-11 11:30:21 +08:00
anqiansong
4624390e54 Fix #1585 #1547 (#1624) 2022-03-09 19:26:35 +08:00
Kevin Wan
63b7d292c1 chore: update goctl version to 1.3.3, change docker build temp dir (#1621) 2022-03-07 14:44:12 +08:00
Fyn
365c569d7c fix(goctl): dart gen user defined struct array (#1620) 2022-03-07 14:11:47 +08:00
anqiansong
68a81fea8a Fix #1609 (#1617) 2022-03-05 22:52:32 +08:00
anqiansong
08a8bd7ef7 Fix #1614 (#1616) 2022-03-05 21:40:41 +08:00
Kevin Wan
b939ce75ba chore: refactor code (#1613) 2022-03-04 17:55:13 +08:00
Kevin Wan
3b7ca86e4f chore: add unit tests (#1615)
* test: add more tests

* test: add more tests
2022-03-04 17:54:09 +08:00
Javen
60760b52ab model中db标签增加'-'符号以支持数据库查询时忽略对应字段. (#1612) 2022-03-04 17:00:46 +08:00
qi
96c128c58a fix: HitQuota should be returned instead of Allowed when limit is equal to 1. (#1581) 2022-03-04 16:14:45 +08:00
Fyn
0c35f39a7d fix: fix(gctl): apiparser_parser auto format (#1607) 2022-03-04 15:36:20 +08:00
Fyn
6a66dde0a1 feat(goctl): api dart support flutter v2 (#1603)
0. support null-safety code gen
1. supports -legacy flag for legacy code gen
2. supports -hostname flag for server hostname
3. use dart official format
4. fix some some bugs

Resolves: #1602
2022-03-04 15:34:13 +08:00
Kevin Wan
36b9fcba44 Update readme-cn.md 2022-03-03 14:35:48 +08:00
Kevin Wan
bf99dda620 Update readme-cn.md 2022-03-03 14:35:10 +08:00
Kevin Wan
511dfcb409 Update readme.md 2022-03-03 14:34:34 +08:00
Kevin Wan
900bc96420 test: add more tests (#1604) 2022-03-02 21:19:04 +08:00
Kevin Wan
be277a7376 Update readme-cn.md
add go-zero users.
2022-03-02 21:18:31 +08:00
Kevin Wan
f15a4f9188 chore: update go-zero to v1.3.1 in goctl (#1599) 2022-03-01 20:56:57 +08:00
148 changed files with 2812 additions and 977 deletions

View File

@@ -1,6 +1,6 @@
MIT License MIT License
Copyright (c) 2020 xiaoheiban_server_go Copyright (c) 2022 zeromicro
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View File

@@ -23,6 +23,6 @@ We hope that the items listed below will inspire further engagement from the com
- [x] Support `context` in redis related methods for timeout and tracing - [x] Support `context` in redis related methods for timeout and tracing
- [x] Support `context` in sql related methods for timeout and tracing - [x] Support `context` in sql related methods for timeout and tracing
- [ ] Support `context` in mongodb related methods for timeout and tracing - [ ] Support `context` in mongodb related methods for timeout and tracing
- [ ] Add `httpx.Client` with governance, like circuit breaker etc. - [x] Add `httpc.Do` with HTTP call governance, like circuit breaker etc.
- [ ] Support `goctl doctor` command to report potential issues for given service - [ ] Support `goctl doctor` command to report potential issues for given service
- [ ] Support `goctl mock` command to start a mocking server with given `.api` file - [ ] Support `goctl mock` command to start a mocking server with given `.api` file

View File

@@ -171,7 +171,7 @@ func (lt loggedThrottle) allow() (Promise, error) {
func (lt loggedThrottle) doReq(req func() error, fallback func(err error) error, acceptable Acceptable) error { func (lt loggedThrottle) doReq(req func() error, fallback func(err error) error, acceptable Acceptable) error {
return lt.logError(lt.internalThrottle.doReq(req, fallback, func(err error) bool { return lt.logError(lt.internalThrottle.doReq(req, fallback, func(err error) bool {
accept := acceptable(err) accept := acceptable(err)
if !accept { if !accept && err != nil {
lt.errWin.add(err.Error()) lt.errWin.add(err.Error())
} }
return accept return accept

View File

@@ -14,8 +14,8 @@ local window = tonumber(ARGV[2])
local current = redis.call("INCRBY", KEYS[1], 1) local current = redis.call("INCRBY", KEYS[1], 1)
if current == 1 then if current == 1 then
redis.call("expire", KEYS[1], window) redis.call("expire", KEYS[1], window)
return 1 end
elseif current < limit then if current < limit then
return 1 return 1
elseif current == limit then elseif current == limit then
return 2 return 2

View File

@@ -65,3 +65,13 @@ func testPeriodLimit(t *testing.T, opts ...PeriodOption) {
assert.Equal(t, 1, hitQuota) assert.Equal(t, 1, hitQuota)
assert.Equal(t, total-quota, overQuota) assert.Equal(t, total-quota, overQuota)
} }
func TestQuotaFull(t *testing.T) {
s, err := miniredis.Run()
assert.Nil(t, err)
l := NewPeriodLimit(1, 1, redis.New(s.Addr()), "periodlimit")
val, err := l.Take("first")
assert.Nil(t, err)
assert.Equal(t, HitQuota, val)
}

View File

@@ -448,7 +448,15 @@ func (u *Unmarshaler) fillSlice(fieldType reflect.Type, value reflect.Value, map
dereffedBaseType := Deref(baseType) dereffedBaseType := Deref(baseType)
dereffedBaseKind := dereffedBaseType.Kind() dereffedBaseKind := dereffedBaseType.Kind()
refValue := reflect.ValueOf(mapValue) refValue := reflect.ValueOf(mapValue)
if refValue.IsNil() {
return nil
}
conv := reflect.MakeSlice(reflect.SliceOf(baseType), refValue.Len(), refValue.Cap()) conv := reflect.MakeSlice(reflect.SliceOf(baseType), refValue.Len(), refValue.Cap())
if refValue.Len() == 0 {
value.Set(conv)
return nil
}
var valid bool var valid bool
for i := 0; i < refValue.Len(); i++ { for i := 0; i < refValue.Len(); i++ {

View File

@@ -198,6 +198,49 @@ func TestUnmarshalIntWithDefault(t *testing.T) {
assert.Equal(t, 1, in.Int) assert.Equal(t, 1, in.Int)
} }
func TestUnmarshalBoolSliceRequired(t *testing.T) {
type inner struct {
Bools []bool `key:"bools"`
}
var in inner
assert.NotNil(t, UnmarshalKey(map[string]interface{}{}, &in))
}
func TestUnmarshalBoolSliceNil(t *testing.T) {
type inner struct {
Bools []bool `key:"bools,optional"`
}
var in inner
assert.Nil(t, UnmarshalKey(map[string]interface{}{}, &in))
assert.Nil(t, in.Bools)
}
func TestUnmarshalBoolSliceNilExplicit(t *testing.T) {
type inner struct {
Bools []bool `key:"bools,optional"`
}
var in inner
assert.Nil(t, UnmarshalKey(map[string]interface{}{
"bools": nil,
}, &in))
assert.Nil(t, in.Bools)
}
func TestUnmarshalBoolSliceEmpty(t *testing.T) {
type inner struct {
Bools []bool `key:"bools,optional"`
}
var in inner
assert.Nil(t, UnmarshalKey(map[string]interface{}{
"bools": []bool{},
}, &in))
assert.Empty(t, in.Bools)
}
func TestUnmarshalBoolSliceWithDefault(t *testing.T) { func TestUnmarshalBoolSliceWithDefault(t *testing.T) {
type inner struct { type inner struct {
Bools []bool `key:"bools,default=[true,false]"` Bools []bool `key:"bools,default=[true,false]"`
@@ -330,28 +373,34 @@ func TestUnmarshalFloat(t *testing.T) {
func TestUnmarshalInt64Slice(t *testing.T) { func TestUnmarshalInt64Slice(t *testing.T) {
var v struct { var v struct {
Ages []int64 `key:"ages"` Ages []int64 `key:"ages"`
Slice []int64 `key:"slice"`
} }
m := map[string]interface{}{ m := map[string]interface{}{
"ages": []int64{1, 2}, "ages": []int64{1, 2},
"slice": []interface{}{},
} }
ast := assert.New(t) ast := assert.New(t)
ast.Nil(UnmarshalKey(m, &v)) ast.Nil(UnmarshalKey(m, &v))
ast.ElementsMatch([]int64{1, 2}, v.Ages) ast.ElementsMatch([]int64{1, 2}, v.Ages)
ast.Equal([]int64{}, v.Slice)
} }
func TestUnmarshalIntSlice(t *testing.T) { func TestUnmarshalIntSlice(t *testing.T) {
var v struct { var v struct {
Ages []int `key:"ages"` Ages []int `key:"ages"`
Slice []int `key:"slice"`
} }
m := map[string]interface{}{ m := map[string]interface{}{
"ages": []int{1, 2}, "ages": []int{1, 2},
"slice": []interface{}{},
} }
ast := assert.New(t) ast := assert.New(t)
ast.Nil(UnmarshalKey(m, &v)) ast.Nil(UnmarshalKey(m, &v))
ast.ElementsMatch([]int{1, 2}, v.Ages) ast.ElementsMatch([]int{1, 2}, v.Ages)
ast.Equal([]int{}, v.Slice)
} }
func TestUnmarshalString(t *testing.T) { func TestUnmarshalString(t *testing.T) {

View File

@@ -11,6 +11,7 @@ const (
mega = 1024 * 1024 mega = 1024 * 1024
) )
// DisplayStats prints the goroutine, memory, GC stats with given interval, default to 5 seconds.
func DisplayStats(interval ...time.Duration) { func DisplayStats(interval ...time.Duration) {
duration := defaultInterval duration := defaultInterval
for _, val := range interval { for _, val := range interval {

View File

@@ -1,78 +1,129 @@
package internal package internal
import ( import (
"bufio"
"fmt" "fmt"
"os" "os"
"path" "path"
"strconv" "strconv"
"strings" "strings"
"sync"
"time"
"github.com/zeromicro/go-zero/core/iox" "github.com/zeromicro/go-zero/core/iox"
"github.com/zeromicro/go-zero/core/lang" "github.com/zeromicro/go-zero/core/lang"
"golang.org/x/sys/unix"
) )
const cgroupDir = "/sys/fs/cgroup" const (
cgroupDir = "/sys/fs/cgroup"
cpuStatFile = cgroupDir + "/cpu.stat"
cpusetFile = cgroupDir + "/cpuset.cpus.effective"
)
type cgroup struct { var (
isUnifiedOnce sync.Once
isUnified bool
inUserNS bool
nsOnce sync.Once
)
type cgroup interface {
cpuQuotaUs() (int64, error)
cpuPeriodUs() (uint64, error)
cpus() ([]uint64, error)
usageAllCpus() (uint64, error)
}
func currentCgroup() (cgroup, error) {
if isCgroup2UnifiedMode() {
return currentCgroupV2()
}
return currentCgroupV1()
}
type cgroupV1 struct {
cgroups map[string]string cgroups map[string]string
} }
func (c *cgroup) acctUsageAllCpus() (uint64, error) { func (c *cgroupV1) cpuQuotaUs() (int64, error) {
data, err := iox.ReadText(path.Join(c.cgroups["cpuacct"], "cpuacct.usage"))
if err != nil {
return 0, err
}
return parseUint(string(data))
}
func (c *cgroup) acctUsagePerCpu() ([]uint64, error) {
data, err := iox.ReadText(path.Join(c.cgroups["cpuacct"], "cpuacct.usage_percpu"))
if err != nil {
return nil, err
}
var usage []uint64
for _, v := range strings.Fields(string(data)) {
u, err := parseUint(v)
if err != nil {
return nil, err
}
usage = append(usage, u)
}
return usage, nil
}
func (c *cgroup) cpuQuotaUs() (int64, error) {
data, err := iox.ReadText(path.Join(c.cgroups["cpu"], "cpu.cfs_quota_us")) data, err := iox.ReadText(path.Join(c.cgroups["cpu"], "cpu.cfs_quota_us"))
if err != nil { if err != nil {
return 0, err return 0, err
} }
return strconv.ParseInt(string(data), 10, 64) return strconv.ParseInt(data, 10, 64)
} }
func (c *cgroup) cpuPeriodUs() (uint64, error) { func (c *cgroupV1) cpuPeriodUs() (uint64, error) {
data, err := iox.ReadText(path.Join(c.cgroups["cpu"], "cpu.cfs_period_us")) data, err := iox.ReadText(path.Join(c.cgroups["cpu"], "cpu.cfs_period_us"))
if err != nil { if err != nil {
return 0, err return 0, err
} }
return parseUint(string(data)) return parseUint(data)
} }
func (c *cgroup) cpus() ([]uint64, error) { func (c *cgroupV1) cpus() ([]uint64, error) {
data, err := iox.ReadText(path.Join(c.cgroups["cpuset"], "cpuset.cpus")) data, err := iox.ReadText(path.Join(c.cgroups["cpuset"], "cpuset.cpus"))
if err != nil { if err != nil {
return nil, err return nil, err
} }
return parseUints(string(data)) return parseUints(data)
} }
func currentCgroup() (*cgroup, error) { func (c *cgroupV1) usageAllCpus() (uint64, error) {
data, err := iox.ReadText(path.Join(c.cgroups["cpuacct"], "cpuacct.usage"))
if err != nil {
return 0, err
}
return parseUint(data)
}
type cgroupV2 struct {
cgroups map[string]string
}
func (c *cgroupV2) cpuQuotaUs() (int64, error) {
data, err := iox.ReadText(path.Join(cgroupDir, "cpu.cfs_quota_us"))
if err != nil {
return 0, err
}
return strconv.ParseInt(data, 10, 64)
}
func (c *cgroupV2) cpuPeriodUs() (uint64, error) {
data, err := iox.ReadText(path.Join(cgroupDir, "cpu.cfs_period_us"))
if err != nil {
return 0, err
}
return parseUint(data)
}
func (c *cgroupV2) cpus() ([]uint64, error) {
data, err := iox.ReadText(cpusetFile)
if err != nil {
return nil, err
}
return parseUints(data)
}
func (c *cgroupV2) usageAllCpus() (uint64, error) {
usec, err := parseUint(c.cgroups["usage_usec"])
if err != nil {
return 0, err
}
return usec * uint64(time.Microsecond), nil
}
func currentCgroupV1() (cgroup, error) {
cgroupFile := fmt.Sprintf("/proc/%d/cgroup", os.Getpid()) cgroupFile := fmt.Sprintf("/proc/%d/cgroup", os.Getpid())
lines, err := iox.ReadTextLines(cgroupFile, iox.WithoutBlank()) lines, err := iox.ReadTextLines(cgroupFile, iox.WithoutBlank())
if err != nil { if err != nil {
@@ -100,11 +151,51 @@ func currentCgroup() (*cgroup, error) {
} }
} }
return &cgroup{ return &cgroupV1{
cgroups: cgroups, cgroups: cgroups,
}, nil }, nil
} }
func currentCgroupV2() (cgroup, error) {
lines, err := iox.ReadTextLines(cpuStatFile, iox.WithoutBlank())
if err != nil {
return nil, err
}
cgroups := make(map[string]string)
for _, line := range lines {
cols := strings.Fields(line)
if len(cols) != 2 {
return nil, fmt.Errorf("invalid cgroupV2 line: %s", line)
}
cgroups[cols[0]] = cols[1]
}
return &cgroupV2{
cgroups: cgroups,
}, nil
}
// isCgroup2UnifiedMode returns whether we are running in cgroup v2 unified mode.
func isCgroup2UnifiedMode() bool {
isUnifiedOnce.Do(func() {
var st unix.Statfs_t
err := unix.Statfs(cgroupDir, &st)
if err != nil {
if os.IsNotExist(err) && runningInUserNS() {
// ignore the "not found" error if running in userns
isUnified = false
return
}
panic(fmt.Sprintf("cannot statfs cgroup root: %s", err))
}
isUnified = st.Type == unix.CGROUP2_SUPER_MAGIC
})
return isUnified
}
func parseUint(s string) (uint64, error) { func parseUint(s string) (uint64, error) {
v, err := strconv.ParseInt(s, 10, 64) v, err := strconv.ParseInt(s, 10, 64)
if err != nil { if err != nil {
@@ -166,3 +257,36 @@ func parseUints(val string) ([]uint64, error) {
return sets, nil return sets, nil
} }
// runningInUserNS detects whether we are currently running in a user namespace.
func runningInUserNS() bool {
nsOnce.Do(func() {
file, err := os.Open("/proc/self/uid_map")
if err != nil {
// This kernel-provided file only exists if user namespaces are supported
return
}
defer file.Close()
buf := bufio.NewReader(file)
l, _, err := buf.ReadLine()
if err != nil {
return
}
line := string(l)
var a, b, c int64
fmt.Sscanf(line, "%d %d %d", &a, &b, &c)
/*
* We assume we are in the initial user namespace if we have a full
* range - 4294967295 uids starting at uid 0.
*/
if a == 0 && b == 0 && c == 4294967295 {
return
}
inUserNS = true
})
return inUserNS
}

View File

@@ -24,7 +24,7 @@ var (
// if /proc not present, ignore the cpu calculation, like wsl linux // if /proc not present, ignore the cpu calculation, like wsl linux
func init() { func init() {
cpus, err := perCpuUsage() cpus, err := cpuSets()
if err != nil { if err != nil {
logx.Error(err) logx.Error(err)
return return
@@ -117,15 +117,6 @@ func cpuSets() ([]uint64, error) {
return cg.cpus() return cg.cpus()
} }
func perCpuUsage() ([]uint64, error) {
cg, err := currentCgroup()
if err != nil {
return nil, err
}
return cg.acctUsagePerCpu()
}
func systemCpuUsage() (uint64, error) { func systemCpuUsage() (uint64, error) {
lines, err := iox.ReadTextLines("/proc/stat", iox.WithoutBlank()) lines, err := iox.ReadTextLines("/proc/stat", iox.WithoutBlank())
if err != nil { if err != nil {
@@ -157,10 +148,10 @@ func systemCpuUsage() (uint64, error) {
} }
func totalCpuUsage() (usage uint64, err error) { func totalCpuUsage() (usage uint64, err error) {
var cg *cgroup var cg cgroup
if cg, err = currentCgroup(); err != nil { if cg, err = currentCgroup(); err != nil {
return return
} }
return cg.acctUsageAllCpus() return cg.usageAllCpus()
} }

View File

@@ -30,18 +30,32 @@ func RawFieldNames(in interface{}, postgresSql ...bool) []string {
for i := 0; i < v.NumField(); i++ { for i := 0; i < v.NumField(); i++ {
// gets us a StructField // gets us a StructField
fi := typ.Field(i) fi := typ.Field(i)
if tagv := fi.Tag.Get(dbTag); tagv != "" { tagv := fi.Tag.Get(dbTag)
if pg { switch tagv {
out = append(out, tagv) case "-":
} else { continue
out = append(out, fmt.Sprintf("`%s`", tagv)) case "":
}
} else {
if pg { if pg {
out = append(out, fi.Name) out = append(out, fi.Name)
} else { } else {
out = append(out, fmt.Sprintf("`%s`", fi.Name)) out = append(out, fmt.Sprintf("`%s`", fi.Name))
} }
default:
// get tag name with the tag opton, e.g.:
// `db:"id"`
// `db:"id,type=char,length=16"`
// `db:",type=char,length=16"`
if strings.Contains(tagv, ",") {
tagv = strings.TrimSpace(strings.Split(tagv, ",")[0])
}
if len(tagv) == 0 {
tagv = fi.Name
}
if pg {
out = append(out, tagv)
} else {
out = append(out, fmt.Sprintf("`%s`", tagv))
}
} }
} }

View File

@@ -22,3 +22,20 @@ func TestFieldNames(t *testing.T) {
assert.Equal(t, expected, out) assert.Equal(t, expected, out)
}) })
} }
type mockedUserWithOptions struct {
ID string `db:"id" json:"id,omitempty"`
UserName string `db:"user_name,type=varchar,length=255" json:"userName,omitempty"`
Sex int `db:"sex" json:"sex,omitempty"`
UUID string `db:",type=varchar,length=16" uuid:"uuid,omitempty"`
Age int `db:"age" json:"age"`
}
func TestFieldNamesWithTagOptions(t *testing.T) {
t.Run("new", func(t *testing.T) {
var u mockedUserWithOptions
out := RawFieldNames(&u)
expected := []string{"`id`", "`user_name`", "`sex`", "`UUID`", "`age`"}
assert.Equal(t, expected, out)
})
}

View File

@@ -24,6 +24,7 @@ type (
Expire(key string, seconds int) error Expire(key string, seconds int) error
Expireat(key string, expireTime int64) error Expireat(key string, expireTime int64) error
Get(key string) (string, error) Get(key string) (string, error)
GetSet(key, value string) (string, error)
Hdel(key, field string) (bool, error) Hdel(key, field string) (bool, error)
Hexists(key, field string) (bool, error) Hexists(key, field string) (bool, error)
Hget(key, field string) (string, error) Hget(key, field string) (string, error)
@@ -459,6 +460,15 @@ func (cs clusterStore) SetnxEx(key, value string, seconds int) (bool, error) {
return node.SetnxEx(key, value, seconds) return node.SetnxEx(key, value, seconds)
} }
func (cs clusterStore) GetSet(key, value string) (string, error) {
node, err := cs.getRedis(key)
if err != nil {
return "", err
}
return node.GetSet(key, value)
}
func (cs clusterStore) Sismember(key string, value interface{}) (bool, error) { func (cs clusterStore) Sismember(key string, value interface{}) (bool, error) {
node, err := cs.getRedis(key) node, err := cs.getRedis(key)
if err != nil { if err != nil {

View File

@@ -490,6 +490,29 @@ func TestRedis_SetExNx(t *testing.T) {
}) })
} }
func TestRedis_Getset(t *testing.T) {
store := clusterStore{dispatcher: hash.NewConsistentHash()}
_, err := store.GetSet("hello", "world")
assert.NotNil(t, err)
runOnCluster(t, func(client Store) {
val, err := client.GetSet("hello", "world")
assert.Nil(t, err)
assert.Equal(t, "", val)
val, err = client.Get("hello")
assert.Nil(t, err)
assert.Equal(t, "world", val)
val, err = client.GetSet("hello", "newworld")
assert.Nil(t, err)
assert.Equal(t, "world", val)
val, err = client.Get("hello")
assert.Nil(t, err)
assert.Equal(t, "newworld", val)
_, err = client.Del("hello")
assert.Nil(t, err)
})
}
func TestRedis_SetGetDelHashField(t *testing.T) { func TestRedis_SetGetDelHashField(t *testing.T) {
store := clusterStore{dispatcher: hash.NewConsistentHash()} store := clusterStore{dispatcher: hash.NewConsistentHash()}
err := store.Hset("key", "field", "value") err := store.Hset("key", "field", "value")

View File

@@ -12,8 +12,8 @@ var (
ErrNotFound = mgo.ErrNotFound ErrNotFound = mgo.ErrNotFound
// can't use one SingleFlight per conn, because multiple conns may share the same cache key. // can't use one SingleFlight per conn, because multiple conns may share the same cache key.
sharedCalls = syncx.NewSingleFlight() singleFlight = syncx.NewSingleFlight()
stats = cache.NewStat("mongoc") stats = cache.NewStat("mongoc")
) )
type ( type (

View File

@@ -34,7 +34,7 @@ func TestCollection_Count(t *testing.T) {
assert.Nil(t, err) assert.Nil(t, err)
defer clean() defer clean()
cach := cache.NewNode(r, sharedCalls, stats, mgo.ErrNotFound) cach := cache.NewNode(r, singleFlight, stats, mgo.ErrNotFound)
c := newCollection(dummyConn{}, cach) c := newCollection(dummyConn{}, cach)
val, err := c.Count("any") val, err := c.Count("any")
assert.Nil(t, err) assert.Nil(t, err)
@@ -98,7 +98,7 @@ func TestStat(t *testing.T) {
assert.Nil(t, err) assert.Nil(t, err)
defer clean() defer clean()
cach := cache.NewNode(r, sharedCalls, stats, mgo.ErrNotFound) cach := cache.NewNode(r, singleFlight, stats, mgo.ErrNotFound)
c := newCollection(dummyConn{}, cach).(*cachedCollection) c := newCollection(dummyConn{}, cach).(*cachedCollection)
for i := 0; i < 10; i++ { for i := 0; i < 10; i++ {
@@ -121,7 +121,7 @@ func TestStatCacheFails(t *testing.T) {
defer log.SetOutput(os.Stdout) defer log.SetOutput(os.Stdout)
r := redis.New("localhost:59999") r := redis.New("localhost:59999")
cach := cache.NewNode(r, sharedCalls, stats, mgo.ErrNotFound) cach := cache.NewNode(r, singleFlight, stats, mgo.ErrNotFound)
c := newCollection(dummyConn{}, cach) c := newCollection(dummyConn{}, cach)
for i := 0; i < 20; i++ { for i := 0; i < 20; i++ {
@@ -142,7 +142,7 @@ func TestStatDbFails(t *testing.T) {
assert.Nil(t, err) assert.Nil(t, err)
defer clean() defer clean()
cach := cache.NewNode(r, sharedCalls, stats, mgo.ErrNotFound) cach := cache.NewNode(r, singleFlight, stats, mgo.ErrNotFound)
c := newCollection(dummyConn{}, cach).(*cachedCollection) c := newCollection(dummyConn{}, cach).(*cachedCollection)
for i := 0; i < 20; i++ { for i := 0; i < 20; i++ {
@@ -164,7 +164,7 @@ func TestStatFromMemory(t *testing.T) {
assert.Nil(t, err) assert.Nil(t, err)
defer clean() defer clean()
cach := cache.NewNode(r, sharedCalls, stats, mgo.ErrNotFound) cach := cache.NewNode(r, singleFlight, stats, mgo.ErrNotFound)
c := newCollection(dummyConn{}, cach).(*cachedCollection) c := newCollection(dummyConn{}, cach).(*cachedCollection)
var all sync.WaitGroup var all sync.WaitGroup

View File

@@ -38,7 +38,7 @@ func MustNewModel(url, collection string, c cache.CacheConf, opts ...cache.Optio
// NewModel returns a Model with a cache cluster. // NewModel returns a Model with a cache cluster.
func NewModel(url, collection string, conf cache.CacheConf, opts ...cache.Option) (*Model, error) { func NewModel(url, collection string, conf cache.CacheConf, opts ...cache.Option) (*Model, error) {
c := cache.New(conf, sharedCalls, stats, mgo.ErrNotFound, opts...) c := cache.New(conf, singleFlight, stats, mgo.ErrNotFound, opts...)
return NewModelWithCache(url, collection, c) return NewModelWithCache(url, collection, c)
} }
@@ -51,7 +51,7 @@ func NewModelWithCache(url, collection string, c cache.Cache) (*Model, error) {
// NewNodeModel returns a Model with a cache node. // NewNodeModel returns a Model with a cache node.
func NewNodeModel(url, collection string, rds *redis.Redis, opts ...cache.Option) (*Model, error) { func NewNodeModel(url, collection string, rds *redis.Redis, opts ...cache.Option) (*Model, error) {
c := cache.NewNode(rds, sharedCalls, stats, mgo.ErrNotFound, opts...) c := cache.NewNode(rds, singleFlight, stats, mgo.ErrNotFound, opts...)
return NewModelWithCache(url, collection, c) return NewModelWithCache(url, collection, c)
} }

View File

@@ -640,6 +640,29 @@ func (s *Redis) GetBitCtx(ctx context.Context, key string, offset int64) (val in
return return
} }
// GetSet is the implementation of redis getset command.
func (s *Redis) GetSet(key, value string) (string, error) {
return s.GetSetCtx(context.Background(), key, value)
}
// GetSetCtx is the implementation of redis getset command.
func (s *Redis) GetSetCtx(ctx context.Context, key, value string) (val string, err error) {
err = s.brk.DoWithAcceptable(func() error {
conn, err := getRedis(s)
if err != nil {
return err
}
if val, err = conn.GetSet(ctx, key, value).Result(); err == red.Nil {
return nil
}
return err
}, acceptable)
return
}
// Hdel is the implementation of redis hdel command. // Hdel is the implementation of redis hdel command.
func (s *Redis) Hdel(key string, fields ...string) (bool, error) { func (s *Redis) Hdel(key string, fields ...string) (bool, error) {
return s.HdelCtx(context.Background(), key, fields...) return s.HdelCtx(context.Background(), key, fields...)
@@ -1381,21 +1404,28 @@ func (s *Redis) ScanCtx(ctx context.Context, cursor uint64, match string, count
} }
// SetBit is the implementation of redis setbit command. // SetBit is the implementation of redis setbit command.
func (s *Redis) SetBit(key string, offset int64, value int) error { func (s *Redis) SetBit(key string, offset int64, value int) (int, error) {
return s.SetBitCtx(context.Background(), key, offset, value) return s.SetBitCtx(context.Background(), key, offset, value)
} }
// SetBitCtx is the implementation of redis setbit command. // SetBitCtx is the implementation of redis setbit command.
func (s *Redis) SetBitCtx(ctx context.Context, key string, offset int64, value int) error { func (s *Redis) SetBitCtx(ctx context.Context, key string, offset int64, value int) (val int, err error) {
return s.brk.DoWithAcceptable(func() error { err = s.brk.DoWithAcceptable(func() error {
conn, err := getRedis(s) conn, err := getRedis(s)
if err != nil { if err != nil {
return err return err
} }
_, err = conn.SetBit(ctx, key, offset, value).Result() v, err := conn.SetBit(ctx, key, offset, value).Result()
return err if err != nil {
return err
}
val = int(v)
return nil
}, acceptable) }, acceptable)
return
} }
// Sscan is the implementation of redis sscan command. // Sscan is the implementation of redis sscan command.

View File

@@ -387,30 +387,33 @@ func TestRedis_Mget(t *testing.T) {
func TestRedis_SetBit(t *testing.T) { func TestRedis_SetBit(t *testing.T) {
runOnRedis(t, func(client *Redis) { runOnRedis(t, func(client *Redis) {
err := New(client.Addr, badType()).SetBit("key", 1, 1) _, err := New(client.Addr, badType()).SetBit("key", 1, 1)
assert.NotNil(t, err) assert.NotNil(t, err)
err = client.SetBit("key", 1, 1) val, err := client.SetBit("key", 1, 1)
assert.Nil(t, err) assert.Nil(t, err)
assert.Equal(t, 0, val)
}) })
} }
func TestRedis_GetBit(t *testing.T) { func TestRedis_GetBit(t *testing.T) {
runOnRedis(t, func(client *Redis) { runOnRedis(t, func(client *Redis) {
err := client.SetBit("key", 2, 1) val, err := client.SetBit("key", 2, 1)
assert.Nil(t, err) assert.Nil(t, err)
assert.Equal(t, 0, val)
_, err = New(client.Addr, badType()).GetBit("key", 2) _, err = New(client.Addr, badType()).GetBit("key", 2)
assert.NotNil(t, err) assert.NotNil(t, err)
val, err := client.GetBit("key", 2) v, err := client.GetBit("key", 2)
assert.Nil(t, err) assert.Nil(t, err)
assert.Equal(t, 1, val) assert.Equal(t, 1, v)
}) })
} }
func TestRedis_BitCount(t *testing.T) { func TestRedis_BitCount(t *testing.T) {
runOnRedis(t, func(client *Redis) { runOnRedis(t, func(client *Redis) {
for i := 0; i < 11; i++ { for i := 0; i < 11; i++ {
err := client.SetBit("key", int64(i), 1) val, err := client.SetBit("key", int64(i), 1)
assert.Nil(t, err) assert.Nil(t, err)
assert.Equal(t, 0, val)
} }
_, err := New(client.Addr, badType()).BitCount("key", 0, -1) _, err := New(client.Addr, badType()).BitCount("key", 0, -1)
@@ -701,6 +704,28 @@ func TestRedis_Set(t *testing.T) {
}) })
} }
func TestRedis_GetSet(t *testing.T) {
runOnRedis(t, func(client *Redis) {
_, err := New(client.Addr, badType()).GetSet("hello", "world")
assert.NotNil(t, err)
val, err := client.GetSet("hello", "world")
assert.Nil(t, err)
assert.Equal(t, "", val)
val, err = client.Get("hello")
assert.Nil(t, err)
assert.Equal(t, "world", val)
val, err = client.GetSet("hello", "newworld")
assert.Nil(t, err)
assert.Equal(t, "world", val)
val, err = client.Get("hello")
assert.Nil(t, err)
assert.Equal(t, "newworld", val)
ret, err := client.Del("hello")
assert.Nil(t, err)
assert.Equal(t, 1, ret)
})
}
func TestRedis_SetGetDel(t *testing.T) { func TestRedis_SetGetDel(t *testing.T) {
runOnRedis(t, func(client *Redis) { runOnRedis(t, func(client *Redis) {
err := New(client.Addr, badType()).Set("hello", "world") err := New(client.Addr, badType()).Set("hello", "world")

View File

@@ -2,6 +2,7 @@ package redis
import ( import (
"math/rand" "math/rand"
"strconv"
"sync/atomic" "sync/atomic"
"time" "time"
@@ -11,19 +12,26 @@ import (
) )
const ( const (
randomLen = 16
tolerance = 500 // milliseconds
millisPerSecond = 1000
lockCommand = `if redis.call("GET", KEYS[1]) == ARGV[1] then
redis.call("SET", KEYS[1], ARGV[1], "PX", ARGV[2])
return "OK"
else
return redis.call("SET", KEYS[1], ARGV[1], "NX", "PX", ARGV[2])
end`
delCommand = `if redis.call("GET", KEYS[1]) == ARGV[1] then delCommand = `if redis.call("GET", KEYS[1]) == ARGV[1] then
return redis.call("DEL", KEYS[1]) return redis.call("DEL", KEYS[1])
else else
return 0 return 0
end` end`
randomLen = 16
) )
// A RedisLock is a redis lock. // A RedisLock is a redis lock.
type RedisLock struct { type RedisLock struct {
store *Redis store *Redis
seconds uint32 seconds uint32
count int32
key string key string
id string id string
} }
@@ -43,35 +51,30 @@ func NewRedisLock(store *Redis, key string) *RedisLock {
// Acquire acquires the lock. // Acquire acquires the lock.
func (rl *RedisLock) Acquire() (bool, error) { func (rl *RedisLock) Acquire() (bool, error) {
newCount := atomic.AddInt32(&rl.count, 1) seconds := atomic.LoadUint32(&rl.seconds)
if newCount > 1 { resp, err := rl.store.Eval(lockCommand, []string{rl.key}, []string{
rl.id, strconv.Itoa(int(seconds)*millisPerSecond + tolerance),
})
if err == red.Nil {
return false, nil
} else if err != nil {
logx.Errorf("Error on acquiring lock for %s, %s", rl.key, err.Error())
return false, err
} else if resp == nil {
return false, nil
}
reply, ok := resp.(string)
if ok && reply == "OK" {
return true, nil return true, nil
} }
seconds := atomic.LoadUint32(&rl.seconds) logx.Errorf("Unknown reply when acquiring lock for %s: %v", rl.key, resp)
ok, err := rl.store.SetnxEx(rl.key, rl.id, int(seconds+1)) // +1s for tolerance return false, nil
if err == red.Nil {
atomic.AddInt32(&rl.count, -1)
return false, nil
} else if err != nil {
atomic.AddInt32(&rl.count, -1)
logx.Errorf("Error on acquiring lock for %s, %s", rl.key, err.Error())
return false, err
} else if !ok {
atomic.AddInt32(&rl.count, -1)
return false, nil
}
return true, nil
} }
// Release releases the lock. // Release releases the lock.
func (rl *RedisLock) Release() (bool, error) { func (rl *RedisLock) Release() (bool, error) {
newCount := atomic.AddInt32(&rl.count, -1)
if newCount > 0 {
return true, nil
}
resp, err := rl.store.Eval(delCommand, []string{rl.key}, []string{rl.id}) resp, err := rl.store.Eval(delCommand, []string{rl.key}, []string{rl.id})
if err != nil { if err != nil {
return false, err return false, err

View File

@@ -29,25 +29,5 @@ func TestRedisLock(t *testing.T) {
endAcquire, err := secondLock.Acquire() endAcquire, err := secondLock.Acquire()
assert.Nil(t, err) assert.Nil(t, err)
assert.True(t, endAcquire) assert.True(t, endAcquire)
endAcquire, err = secondLock.Acquire()
assert.Nil(t, err)
assert.True(t, endAcquire)
release, err = secondLock.Release()
assert.Nil(t, err)
assert.True(t, release)
againAcquire, err = firstLock.Acquire()
assert.Nil(t, err)
assert.False(t, againAcquire)
release, err = secondLock.Release()
assert.Nil(t, err)
assert.True(t, release)
firstAcquire, err = firstLock.Acquire()
assert.Nil(t, err)
assert.True(t, firstAcquire)
}) })
} }

View File

@@ -25,6 +25,7 @@ type (
// A BulkInserter is used to batch insert records. // A BulkInserter is used to batch insert records.
// Postgresql is not supported yet, because of the sql is formated with symbol `$`. // Postgresql is not supported yet, because of the sql is formated with symbol `$`.
// Oracle is not supported yet, because of the sql is formated with symbol `:`.
BulkInserter struct { BulkInserter struct {
executor *executors.PeriodicalExecutor executor *executors.PeriodicalExecutor
inserter *dbInserter inserter *dbInserter

View File

@@ -67,7 +67,7 @@ func format(query string, args ...interface{}) (string, error) {
writeValue(&b, args[argIndex]) writeValue(&b, args[argIndex])
argIndex++ argIndex++
case '$': case ':', '$':
var j int var j int
for j = i + 1; j < bytes; j++ { for j = i + 1; j < bytes; j++ {
char := query[j] char := query[j]
@@ -75,16 +75,18 @@ func format(query string, args ...interface{}) (string, error) {
break break
} }
} }
if j > i+1 { if j > i+1 {
index, err := strconv.Atoi(query[i+1 : j]) index, err := strconv.Atoi(query[i+1 : j])
if err != nil { if err != nil {
return "", err return "", err
} }
// index starts from 1 for pg // index starts from 1 for pg or oracle
if index > argIndex { if index > argIndex {
argIndex = index argIndex = index
} }
index-- index--
if index < 0 || numArgs <= index { if index < 0 || numArgs <= index {
return "", fmt.Errorf("error: wrong index %d in sql", index) return "", fmt.Errorf("error: wrong index %d in sql", index)

View File

@@ -73,6 +73,30 @@ func TestFormat(t *testing.T) {
args: []interface{}{"133", false}, args: []interface{}{"133", false},
hasErr: true, hasErr: true,
}, },
{
name: "oracle normal",
query: "select name, age from users where bool=:1 and phone=:2",
args: []interface{}{true, "133"},
expect: "select name, age from users where bool=1 and phone='133'",
},
{
name: "oracle normal reverse",
query: "select name, age from users where bool=:2 and phone=:1",
args: []interface{}{"133", false},
expect: "select name, age from users where bool=0 and phone='133'",
},
{
name: "oracle error not number",
query: "select name, age from users where bool=:a and phone=:1",
args: []interface{}{"133", false},
hasErr: true,
},
{
name: "oracle error more args",
query: "select name, age from users where bool=:2 and phone=:1 and nickname=:3",
args: []interface{}{"133", false},
hasErr: true,
},
} }
for _, test := range tests { for _, test := range tests {

View File

@@ -90,14 +90,14 @@ func TestParseFullMethod(t *testing.T) {
semconv.RPCMethodKey.String("theMethod"), semconv.RPCMethodKey.String("theMethod"),
}, },
}, { }, {
fullMethod: "/pkg.srv", fullMethod: "/pkg.svr",
name: "pkg.srv", name: "pkg.svr",
attr: []attribute.KeyValue(nil), attr: []attribute.KeyValue(nil),
}, { }, {
fullMethod: "/pkg.srv/", fullMethod: "/pkg.svr/",
name: "pkg.srv/", name: "pkg.svr/",
attr: []attribute.KeyValue{ attr: []attribute.KeyValue{
semconv.RPCServiceKey.String("pkg.srv"), semconv.RPCServiceKey.String("pkg.svr"),
}, },
}, },
} }

9
go.mod
View File

@@ -42,13 +42,20 @@ require (
github.com/fatih/color v1.10.0 // indirect github.com/fatih/color v1.10.0 // indirect
github.com/go-logr/stdr v1.2.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-redis/redis/v8 v8.11.4 github.com/go-redis/redis/v8 v8.11.4
github.com/google/gofuzz v1.2.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/mattn/go-runewidth v0.0.13 // indirect github.com/mattn/go-runewidth v0.0.13 // indirect
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 // indirect
github.com/openzipkin/zipkin-go v0.4.0 // indirect github.com/openzipkin/zipkin-go v0.4.0 // indirect
github.com/prometheus/common v0.30.0 // indirect
github.com/prometheus/procfs v0.7.3 // indirect
go.uber.org/atomic v1.9.0 // indirect go.uber.org/atomic v1.9.0 // indirect
go.uber.org/multierr v1.8.0 // indirect go.uber.org/multierr v1.8.0 // indirect
go.uber.org/zap v1.21.0 // indirect go.uber.org/zap v1.21.0 // indirect
golang.org/x/net v0.0.0-20220225172249-27dd8689420f // indirect golang.org/x/net v0.0.0-20220225172249-27dd8689420f // indirect
golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9 // indirect golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f // indirect
golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9
google.golang.org/appengine v1.6.7 // indirect
google.golang.org/genproto v0.0.0-20220228195345-15d65a4533f7 // indirect google.golang.org/genproto v0.0.0-20220228195345-15d65a4533f7 // indirect
k8s.io/klog/v2 v2.40.1 // indirect k8s.io/klog/v2 v2.40.1 // indirect
) )

110
go.sum
View File

@@ -9,17 +9,27 @@ cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6T
cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4=
cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M=
cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc=
cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk=
cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs=
cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc=
cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY=
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=
cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=
cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=
cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=
cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU=
cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=
cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24=
github.com/Azure/go-autorest/autorest v0.11.1/go.mod h1:JFgpikqFJ/MleTTxwepExTKnFUKKszPS8UavbQYUMuw= github.com/Azure/go-autorest/autorest v0.11.1/go.mod h1:JFgpikqFJ/MleTTxwepExTKnFUKKszPS8UavbQYUMuw=
@@ -52,6 +62,7 @@ github.com/alicebob/miniredis/v2 v2.17.0 h1:EwLdrIS50uczw71Jc7iVSxZluTKj5nfSP8n7
github.com/alicebob/miniredis/v2 v2.17.0/go.mod h1:gquAfGbzn92jvtrSC69+6zZnwSODVXVpYDRaGhWaL6I= github.com/alicebob/miniredis/v2 v2.17.0/go.mod h1:gquAfGbzn92jvtrSC69+6zZnwSODVXVpYDRaGhWaL6I=
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8=
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
@@ -164,6 +175,8 @@ github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfb
github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc=
github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
@@ -171,6 +184,7 @@ github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5y
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
@@ -189,21 +203,27 @@ github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5a
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ= github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ=
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g=
github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
@@ -238,8 +258,9 @@ github.com/jmoiron/sqlx v1.2.0/go.mod h1:1FEQNm3xlJgrMD+FBdI9+xvCksHtbpVBBw5dYhB
github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/json-iterator/go v1.1.11 h1:uVUAXhF2To8cbw/3xN3pxj6kk7TYKs98NIrTqPlMWAQ=
github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
@@ -274,15 +295,17 @@ github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m
github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU= github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU=
github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 h1:I0XW9+e1XWDxdcEniV4rQAIOPUGDq67JSCiRCgGCZLI=
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI=
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
@@ -332,13 +355,15 @@ github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2
github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
github.com/prometheus/common v0.26.0 h1:iMAkS2TDoNWnKM+Kopnx/8tnEStIfpYA0ur0xQzzhMQ=
github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc=
github.com/prometheus/common v0.30.0 h1:JEkYlQnpzrzQFxi6gnukFPdQ+ac82oRhzMcIduJu/Ug=
github.com/prometheus/common v0.30.0/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls=
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
github.com/prometheus/procfs v0.6.0 h1:mxy4L2jP6qMonqmq+aTtOx1ifVWUgG/TAmntgbh3xv4=
github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
github.com/prometheus/procfs v0.7.3 h1:4jVXhlkAyzOScmCkXBTOLRLTz8EeU+eyjrwB/EPq0VU=
github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
github.com/rabbitmq/amqp091-go v1.1.0/go.mod h1:ogQDLSOACsLPsIq0NpbtiifNZi2YOz0VTJ0kHRghqbM= github.com/rabbitmq/amqp091-go v1.1.0/go.mod h1:ogQDLSOACsLPsIq0NpbtiifNZi2YOz0VTJ0kHRghqbM=
github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
@@ -372,27 +397,24 @@ github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/X
github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI=
github.com/xdg-go/scram v1.0.2/go.mod h1:1WAq6h33pAW+iRreB34OORO2Nf7qel3VV3fjBj+hCSs= github.com/xdg-go/scram v1.0.2/go.mod h1:1WAq6h33pAW+iRreB34OORO2Nf7qel3VV3fjBj+hCSs=
github.com/xdg-go/stringprep v1.0.2/go.mod h1:8F9zXuvzgwmyT5DUm4GUfZGDdT3W+LCvS6+da4O5kxM= github.com/xdg-go/stringprep v1.0.2/go.mod h1:8F9zXuvzgwmyT5DUm4GUfZGDdT3W+LCvS6+da4O5kxM=
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
github.com/yuin/gopher-lua v0.0.0-20200816102855-ee81675732da h1:NimzV1aGyq29m5ukMK0AMWEhFaL/lrEOaephfuoiARg= github.com/yuin/gopher-lua v0.0.0-20200816102855-ee81675732da h1:NimzV1aGyq29m5ukMK0AMWEhFaL/lrEOaephfuoiARg=
github.com/yuin/gopher-lua v0.0.0-20200816102855-ee81675732da/go.mod h1:E1AXubJBdNmFERAOucpDIxNzeGfLzg0mYh+UfMWdChA= github.com/yuin/gopher-lua v0.0.0-20200816102855-ee81675732da/go.mod h1:E1AXubJBdNmFERAOucpDIxNzeGfLzg0mYh+UfMWdChA=
go.etcd.io/etcd/api/v3 v3.5.1 h1:v28cktvBq+7vGyJXF8G+rWJmj+1XUmMtqcLnH8hDocM=
go.etcd.io/etcd/api/v3 v3.5.1/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs=
go.etcd.io/etcd/api/v3 v3.5.2 h1:tXok5yLlKyuQ/SXSjtqHc4uzNaMqZi2XsoSPr/LlJXI= go.etcd.io/etcd/api/v3 v3.5.2 h1:tXok5yLlKyuQ/SXSjtqHc4uzNaMqZi2XsoSPr/LlJXI=
go.etcd.io/etcd/api/v3 v3.5.2/go.mod h1:5GB2vv4A4AOn3yk7MftYGHkUfGtDHnEraIjym4dYz5A= go.etcd.io/etcd/api/v3 v3.5.2/go.mod h1:5GB2vv4A4AOn3yk7MftYGHkUfGtDHnEraIjym4dYz5A=
go.etcd.io/etcd/client/pkg/v3 v3.5.1 h1:XIQcHCFSG53bJETYeRJtIxdLv2EWRGxcfzR8lSnTH4E=
go.etcd.io/etcd/client/pkg/v3 v3.5.1/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g=
go.etcd.io/etcd/client/pkg/v3 v3.5.2 h1:4hzqQ6hIb3blLyQ8usCU4h3NghkqcsohEQ3o3VetYxE= go.etcd.io/etcd/client/pkg/v3 v3.5.2 h1:4hzqQ6hIb3blLyQ8usCU4h3NghkqcsohEQ3o3VetYxE=
go.etcd.io/etcd/client/pkg/v3 v3.5.2/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= go.etcd.io/etcd/client/pkg/v3 v3.5.2/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g=
go.etcd.io/etcd/client/v3 v3.5.1 h1:oImGuV5LGKjCqXdjkMHCyWa5OO1gYKCnC/1sgdfj1Uk=
go.etcd.io/etcd/client/v3 v3.5.1/go.mod h1:OnjH4M8OnAotwaB2l9bVgZzRFKru7/ZMoS46OtKyd3Q=
go.etcd.io/etcd/client/v3 v3.5.2 h1:WdnejrUtQC4nCxK0/dLTMqKOB+U5TP/2Ya0BJL+1otA= go.etcd.io/etcd/client/v3 v3.5.2 h1:WdnejrUtQC4nCxK0/dLTMqKOB+U5TP/2Ya0BJL+1otA=
go.etcd.io/etcd/client/v3 v3.5.2/go.mod h1:kOOaWFFgHygyT0WlSmL8TJiXmMysO/nNUlEsSsN6W4o= go.etcd.io/etcd/client/v3 v3.5.2/go.mod h1:kOOaWFFgHygyT0WlSmL8TJiXmMysO/nNUlEsSsN6W4o=
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opentelemetry.io/otel v1.3.0 h1:APxLf0eiBwLl+SOXiJJCVYzA1OOJNyAoV8C5RNRyy7Y= go.opentelemetry.io/otel v1.3.0 h1:APxLf0eiBwLl+SOXiJJCVYzA1OOJNyAoV8C5RNRyy7Y=
go.opentelemetry.io/otel v1.3.0/go.mod h1:PWIKzi6JCp7sM0k9yZ43VX+T345uNbAkDKwHVjb2PTs= go.opentelemetry.io/otel v1.3.0/go.mod h1:PWIKzi6JCp7sM0k9yZ43VX+T345uNbAkDKwHVjb2PTs=
go.opentelemetry.io/otel/exporters/jaeger v1.3.0 h1:HfydzioALdtcB26H5WHc4K47iTETJCdloL7VN579/L0= go.opentelemetry.io/otel/exporters/jaeger v1.3.0 h1:HfydzioALdtcB26H5WHc4K47iTETJCdloL7VN579/L0=
@@ -404,7 +426,6 @@ go.opentelemetry.io/otel/sdk v1.3.0/go.mod h1:rIo4suHNhQwBIPg9axF8V9CA72Wz2mKF1t
go.opentelemetry.io/otel/trace v1.3.0 h1:doy8Hzb1RJ+I3yFhtDmwNc7tIyw1tNMOIsyPzp1NOGY= go.opentelemetry.io/otel/trace v1.3.0 h1:doy8Hzb1RJ+I3yFhtDmwNc7tIyw1tNMOIsyPzp1NOGY=
go.opentelemetry.io/otel/trace v1.3.0/go.mod h1:c/VDhno8888bvQYmbYLqe41/Ldmr/KKunbvWM4/fEjk= go.opentelemetry.io/otel/trace v1.3.0/go.mod h1:c/VDhno8888bvQYmbYLqe41/Ldmr/KKunbvWM4/fEjk=
go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw=
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE= go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE=
go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
@@ -413,11 +434,9 @@ go.uber.org/automaxprocs v1.4.0/go.mod h1:/mTEdr7LvHhs0v7mjdxDreTz1OG5zdZGqgOnhW
go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
go.uber.org/goleak v1.1.12 h1:gZAh5/EyT/HQwlpkCy6wTpqfH9H8Lz8zbm3dZh+OyzA= go.uber.org/goleak v1.1.12 h1:gZAh5/EyT/HQwlpkCy6wTpqfH9H8Lz8zbm3dZh+OyzA=
go.uber.org/goleak v1.1.12/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/goleak v1.1.12/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4=
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
go.uber.org/multierr v1.8.0 h1:dg6GjLku4EH+249NNmoIciG9N/jURbDG+pFlTkhzIC8= go.uber.org/multierr v1.8.0 h1:dg6GjLku4EH+249NNmoIciG9N/jURbDG+pFlTkhzIC8=
go.uber.org/multierr v1.8.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak= go.uber.org/multierr v1.8.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak=
go.uber.org/zap v1.17.0 h1:MTjgFu6ZLKvY6Pvaqk97GlxNBuMpV4Hy/3P6tRGlI2U=
go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo= go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo=
go.uber.org/zap v1.21.0 h1:WefMeulhovoZ2sYXz7st6K0sLj7bBhpiFaud4r4zST8= go.uber.org/zap v1.21.0 h1:WefMeulhovoZ2sYXz7st6K0sLj7bBhpiFaud4r4zST8=
go.uber.org/zap v1.21.0/go.mod h1:wjWOCqI0f2ZZrJF/UufIOkiC8ii6tm1iqIsLo76RfJw= go.uber.org/zap v1.21.0/go.mod h1:wjWOCqI0f2ZZrJF/UufIOkiC8ii6tm1iqIsLo76RfJw=
@@ -479,6 +498,7 @@ golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
@@ -488,31 +508,39 @@ golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLL
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk=
golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20210917221730-978cfadd31cf/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210917221730-978cfadd31cf/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd h1:O7DYs+zxREGLKzKoMQrtrEacpb0ZVXA5rIwylE2Xchk=
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.0.0-20220225172249-27dd8689420f h1:oA4XRj0qtSt8Yo1Zms0CUlsT3KG69V2UGQWPBxujDmc= golang.org/x/net v0.0.0-20220225172249-27dd8689420f h1:oA4XRj0qtSt8Yo1Zms0CUlsT3KG69V2UGQWPBxujDmc=
golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d h1:TzXSXBo42m9gQenoE3b9BGiEpg5IG2JkU5FkPIawgtw=
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f h1:Qmd2pbz05z7z6lm0DrgQVVPuBm92jqujBKMHMOlOQEw=
golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -547,8 +575,14 @@ golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201112073958-5cba982894dd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201112073958-5cba982894dd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -562,8 +596,6 @@ golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220209214540-3681064d5158 h1:rm+CHSpPEEW2IsXUib1ThaHIjuBVZjxNgSKmBLFfD4c=
golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9 h1:nhht2DYV/Sn3qOayu8lM+cU1ii9sTLUeBQwQQfUHtrs= golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9 h1:nhht2DYV/Sn3qOayu8lM+cU1ii9sTLUeBQwQQfUHtrs=
golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
@@ -614,8 +646,18 @@ golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapK
golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
@@ -636,13 +678,21 @@ google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsb
google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM=
google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
google.golang.org/appengine v1.6.5 h1:tycE03LOZYQNhDpS27tcQdAzLCVMaj7QT2SXxebnpCM=
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
@@ -660,12 +710,20 @@ google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvx
google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA=
google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U=
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA=
google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=
google.golang.org/genproto v0.0.0-20220211171837-173942840c17 h1:2X+CNIheCutWRyKRte8szGxrE5ggtV4U+NKAbh/oLhg=
google.golang.org/genproto v0.0.0-20220211171837-173942840c17/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI=
google.golang.org/genproto v0.0.0-20220228195345-15d65a4533f7 h1:ntPPoHzFW6Xp09ueznmahONZufyoSakK/piXnr2BU3I= google.golang.org/genproto v0.0.0-20220228195345-15d65a4533f7 h1:ntPPoHzFW6Xp09ueznmahONZufyoSakK/piXnr2BU3I=
google.golang.org/genproto v0.0.0-20220228195345-15d65a4533f7/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= google.golang.org/genproto v0.0.0-20220228195345-15d65a4533f7/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
@@ -676,6 +734,10 @@ google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQ
google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60=
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0=
google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
@@ -690,6 +752,7 @@ google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzi
google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
@@ -729,6 +792,7 @@ honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWh
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
k8s.io/api v0.20.12 h1:LfRpmRkJLwPP8eaYehsVVmIIfg1yCBIIUHaSsdqCgHA= k8s.io/api v0.20.12 h1:LfRpmRkJLwPP8eaYehsVVmIIfg1yCBIIUHaSsdqCgHA=
k8s.io/api v0.20.12/go.mod h1:A2brwyEkVLM3wQGNnzoAa5JsQRzHK0uoOQ+bsnv7V68= k8s.io/api v0.20.12/go.mod h1:A2brwyEkVLM3wQGNnzoAa5JsQRzHK0uoOQ+bsnv7V68=
k8s.io/apimachinery v0.20.12 h1:2c0LIVNMvB8k2Ozstmhl2zGeCEcPazznuLYEwxFdNjM= k8s.io/apimachinery v0.20.12 h1:2c0LIVNMvB8k2Ozstmhl2zGeCEcPazznuLYEwxFdNjM=

View File

@@ -2,6 +2,8 @@
# go-zero # go-zero
***缩短从需求到上线的距离***
[English](readme.md) | 简体中文 [English](readme.md) | 简体中文
[![Go](https://github.com/zeromicro/go-zero/workflows/Go/badge.svg?branch=master)](https://github.com/zeromicro/go-zero/actions) [![Go](https://github.com/zeromicro/go-zero/workflows/Go/badge.svg?branch=master)](https://github.com/zeromicro/go-zero/actions)
@@ -11,17 +13,13 @@
[![Release](https://img.shields.io/github/v/release/zeromicro/go-zero.svg?style=flat-square)](https://github.com/zeromicro/go-zero) [![Release](https://img.shields.io/github/v/release/zeromicro/go-zero.svg?style=flat-square)](https://github.com/zeromicro/go-zero)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
> ***缩短从需求到上线的距离***
**为了满足开源基金会要求go-zero 从好未来tal-tech组织下迁移至中立的 GitHub 组织zeromicro**
> ***注意:*** > ***注意:***
> >
> 从 v1.3.0 之前版本升级请执行以下命令: > 从 v1.3.0 之前版本升级请执行以下命令:
> >
> GOPROXY=https://goproxy.cn/,direct go install github.com/zeromicro/go-zero/tools/goctl@latest > `GOPROXY=https://goproxy.cn/,direct go install github.com/zeromicro/go-zero/tools/goctl@latest`
> >
> goctl migrate —verbose —version v1.3.0 > `goctl migrate —verbose —version v1.3.1`
## 0. go-zero 介绍 ## 0. go-zero 介绍
@@ -252,6 +250,8 @@ go-zero 已被许多公司用于生产部署,接入场景如在线教育、电
>56. 时代脉搏网络科技(云浮市)有限公司 >56. 时代脉搏网络科技(云浮市)有限公司
>57. 店有帮 >57. 店有帮
>58. 七牛云 >58. 七牛云
>59. 费芮网络
>60. 51CTO
如果贵公司也已使用 go-zero欢迎在 [登记地址](https://github.com/zeromicro/go-zero/issues/602) 登记,仅仅为了推广,不做其它用途。 如果贵公司也已使用 go-zero欢迎在 [登记地址](https://github.com/zeromicro/go-zero/issues/602) 登记,仅仅为了推广,不做其它用途。
@@ -281,3 +281,9 @@ go-zero 收录在 [CNCF Cloud Native 云原生技术全景图](https://landscape
加群之前有劳点一下 ***star***,一个小小的 ***star*** 是作者们回答海量问题的动力!🤝 加群之前有劳点一下 ***star***,一个小小的 ***star*** 是作者们回答海量问题的动力!🤝
<img src="https://raw.githubusercontent.com/zeromicro/zero-doc/main/doc/images/wechat.jpg" alt="wechat" width="300" /> <img src="https://raw.githubusercontent.com/zeromicro/zero-doc/main/doc/images/wechat.jpg" alt="wechat" width="300" />
## 12. 赞助一下👍
如果觉得项目有帮助,可以请作者喝杯咖啡 🍹
<img src="https://raw.githubusercontent.com/zeromicro/zero-doc/main/doc/images/sponsor.png" alt="wechat" width="300" />

View File

@@ -12,15 +12,13 @@ English | [简体中文](readme-cn.md)
[![Discord](https://img.shields.io/discord/794530774463414292?label=chat&logo=discord)](https://discord.gg/4JQvC5A4Fe) [![Discord](https://img.shields.io/discord/794530774463414292?label=chat&logo=discord)](https://discord.gg/4JQvC5A4Fe)
<a href="https://www.producthunt.com/posts/go-zero?utm_source=badge-featured&utm_medium=badge&utm_souce=badge-go&#0045;zero" target="_blank"><img src="https://api.producthunt.com/widgets/embed-image/v1/featured.svg?post_id=334030&theme=light" alt="go&#0045;zero - A&#0032;web&#0032;&#0038;&#0032;rpc&#0032;framework&#0032;written&#0032;in&#0032;Go&#0046; | Product Hunt" style="width: 250px; height: 54px;" width="250" height="54" /></a> <a href="https://www.producthunt.com/posts/go-zero?utm_source=badge-featured&utm_medium=badge&utm_souce=badge-go&#0045;zero" target="_blank"><img src="https://api.producthunt.com/widgets/embed-image/v1/featured.svg?post_id=334030&theme=light" alt="go&#0045;zero - A&#0032;web&#0032;&#0038;&#0032;rpc&#0032;framework&#0032;written&#0032;in&#0032;Go&#0046; | Product Hunt" style="width: 250px; height: 54px;" width="250" height="54" /></a>
**Note: To meet the requirements of Open Source Foundation, we moved go-zero from tal-tech to zeromicro (a neutral GitHub organization).**
> ***Important!*** > ***Important!***
> >
> To upgrade from previous versions, run the following commands. > To upgrade from versions eariler than v1.3.0, run the following commands.
> >
> `go install github.com/zeromicro/go-zero/tools/goctl@latest` > `go install github.com/zeromicro/go-zero/tools/goctl@latest`
> >
> `goctl migrate —verbose —version v1.3.0` > `goctl migrate —verbose —version v1.3.1`
## 0. what is go-zero ## 0. what is go-zero

View File

@@ -35,16 +35,16 @@ type engine struct {
} }
func newEngine(c RestConf) *engine { func newEngine(c RestConf) *engine {
srv := &engine{ svr := &engine{
conf: c, conf: c,
} }
if c.CpuThreshold > 0 { if c.CpuThreshold > 0 {
srv.shedder = load.NewAdaptiveShedder(load.WithCpuThreshold(c.CpuThreshold)) svr.shedder = load.NewAdaptiveShedder(load.WithCpuThreshold(c.CpuThreshold))
srv.priorityShedder = load.NewAdaptiveShedder(load.WithCpuThreshold( svr.priorityShedder = load.NewAdaptiveShedder(load.WithCpuThreshold(
(c.CpuThreshold + topCpuUsage) >> 1)) (c.CpuThreshold + topCpuUsage) >> 1))
} }
return srv return svr
} }
func (ng *engine) addRoutes(r featuredRoutes) { func (ng *engine) addRoutes(r featuredRoutes) {
@@ -94,7 +94,7 @@ func (ng *engine) bindRoute(fr featuredRoutes, router httpx.Router, metrics *sta
handler.TimeoutHandler(ng.checkedTimeout(fr.timeout)), handler.TimeoutHandler(ng.checkedTimeout(fr.timeout)),
handler.RecoverHandler, handler.RecoverHandler,
handler.MetricHandler(metrics), handler.MetricHandler(metrics),
handler.MaxBytesHandler(ng.conf.MaxBytes), handler.MaxBytesHandler(ng.checkedMaxBytes(fr.maxBytes)),
handler.GunzipHandler, handler.GunzipHandler,
) )
chain = ng.appendAuthHandler(fr, chain, verifier) chain = ng.appendAuthHandler(fr, chain, verifier)
@@ -119,6 +119,14 @@ func (ng *engine) bindRoutes(router httpx.Router) error {
return nil return nil
} }
func (ng *engine) checkedMaxBytes(bytes int64) int64 {
if bytes > 0 {
return bytes
}
return ng.conf.MaxBytes
}
func (ng *engine) checkedTimeout(timeout time.Duration) time.Duration { func (ng *engine) checkedTimeout(timeout time.Duration) time.Duration {
if timeout > 0 { if timeout > 0 {
return timeout return timeout
@@ -238,9 +246,9 @@ func (ng *engine) start(router httpx.Router) error {
} }
return internal.StartHttps(ng.conf.Host, ng.conf.Port, ng.conf.CertFile, return internal.StartHttps(ng.conf.Host, ng.conf.Port, ng.conf.CertFile,
ng.conf.KeyFile, router, func(srv *http.Server) { ng.conf.KeyFile, router, func(svr *http.Server) {
if ng.tlsConfig != nil { if ng.tlsConfig != nil {
srv.TLSConfig = ng.tlsConfig svr.TLSConfig = ng.tlsConfig
} }
}) })
} }

View File

@@ -194,6 +194,41 @@ func TestEngine_checkedTimeout(t *testing.T) {
} }
} }
func TestEngine_checkedMaxBytes(t *testing.T) {
tests := []struct {
name string
maxBytes int64
expect int64
}{
{
name: "not set",
expect: 1000,
},
{
name: "less",
maxBytes: 500,
expect: 500,
},
{
name: "equal",
maxBytes: 1000,
expect: 1000,
},
{
name: "more",
maxBytes: 1500,
expect: 1500,
},
}
ng := newEngine(RestConf{
MaxBytes: 1000,
})
for _, test := range tests {
assert.Equal(t, test.expect, ng.checkedMaxBytes(test.maxBytes))
}
}
func TestEngine_notFoundHandler(t *testing.T) { func TestEngine_notFoundHandler(t *testing.T) {
logx.Disable() logx.Disable()

View File

@@ -32,11 +32,7 @@ func TracingHandler(serviceName, path string) func(http.Handler) http.Handler {
defer span.End() defer span.End()
// convenient for tracking error messages // convenient for tracking error messages
sc := span.SpanContext() propagator.Inject(spanCtx, propagation.HeaderCarrier(w.Header()))
if sc.HasTraceID() {
w.Header().Set(trace.TraceIdKey, sc.TraceID().String())
}
next.ServeHTTP(w, r.WithContext(spanCtx)) next.ServeHTTP(w, r.WithContext(spanCtx))
}) })
} }

View File

@@ -0,0 +1,8 @@
package internal
import "net/http"
type (
Interceptor func(r *http.Request) (*http.Request, ResponseHandler)
ResponseHandler func(resp *http.Response, err error)
)

View File

@@ -0,0 +1,34 @@
package internal
import (
"net/http"
"github.com/zeromicro/go-zero/core/logx"
"github.com/zeromicro/go-zero/core/timex"
"go.opentelemetry.io/otel/propagation"
)
func LogInterceptor(r *http.Request) (*http.Request, ResponseHandler) {
start := timex.Now()
return r, func(resp *http.Response, err error) {
duration := timex.Since(start)
if err != nil {
logger := logx.WithContext(r.Context()).WithDuration(duration)
logger.Errorf("[HTTP] %s %s - %v", r.Method, r.URL, err)
return
}
var tc propagation.TraceContext
ctx := tc.Extract(r.Context(), propagation.HeaderCarrier(resp.Header))
logger := logx.WithContext(ctx).WithDuration(duration)
if isOkResponse(resp.StatusCode) {
logger.Infof("[HTTP] %d - %s %s", resp.StatusCode, r.Method, r.URL)
} else {
logger.Errorf("[HTTP] %d - %s %s", resp.StatusCode, r.Method, r.URL)
}
}
}
func isOkResponse(code int) bool {
return code < http.StatusBadRequest
}

View File

@@ -0,0 +1,51 @@
package internal
import (
"net/http"
"net/http/httptest"
"testing"
"github.com/stretchr/testify/assert"
)
func TestLogInterceptor(t *testing.T) {
svr := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
}))
defer svr.Close()
req, err := http.NewRequest(http.MethodGet, svr.URL, nil)
assert.Nil(t, err)
req, handler := LogInterceptor(req)
resp, err := http.DefaultClient.Do(req)
handler(resp, err)
assert.Nil(t, err)
assert.Equal(t, http.StatusOK, resp.StatusCode)
}
func TestLogInterceptorServerError(t *testing.T) {
svr := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusInternalServerError)
}))
defer svr.Close()
req, err := http.NewRequest(http.MethodGet, svr.URL, nil)
assert.Nil(t, err)
req, handler := LogInterceptor(req)
resp, err := http.DefaultClient.Do(req)
handler(resp, err)
assert.Nil(t, err)
assert.Equal(t, http.StatusInternalServerError, resp.StatusCode)
}
func TestLogInterceptorServerClosed(t *testing.T) {
svr := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusInternalServerError)
}))
defer svr.Close()
req, err := http.NewRequest(http.MethodGet, svr.URL, nil)
assert.Nil(t, err)
svr.Close()
req, handler := LogInterceptor(req)
resp, err := http.DefaultClient.Do(req)
handler(resp, err)
assert.NotNil(t, err)
assert.Nil(t, resp)
}

44
rest/httpc/requests.go Normal file
View File

@@ -0,0 +1,44 @@
package httpc
import (
"net/http"
"github.com/zeromicro/go-zero/rest/httpc/internal"
)
var interceptors = []internal.Interceptor{
internal.LogInterceptor,
}
// DoRequest sends an HTTP request and returns an HTTP response.
func DoRequest(r *http.Request) (*http.Response, error) {
return request(r, defaultClient{})
}
type (
client interface {
do(r *http.Request) (*http.Response, error)
}
defaultClient struct{}
)
func (c defaultClient) do(r *http.Request) (*http.Response, error) {
return http.DefaultClient.Do(r)
}
func request(r *http.Request, cli client) (*http.Response, error) {
var respHandlers []internal.ResponseHandler
for _, interceptor := range interceptors {
var h internal.ResponseHandler
r, h = interceptor(r)
respHandlers = append(respHandlers, h)
}
resp, err := cli.do(r)
for i := len(respHandlers) - 1; i >= 0; i-- {
respHandlers[i](resp, err)
}
return resp, err
}

View File

@@ -0,0 +1,41 @@
package httpc
import (
"net/http"
"net/http/httptest"
"testing"
"github.com/stretchr/testify/assert"
)
func TestDo(t *testing.T) {
svr := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
}))
defer svr.Close()
req, err := http.NewRequest(http.MethodGet, svr.URL, nil)
assert.Nil(t, err)
resp, err := DoRequest(req)
assert.Nil(t, err)
assert.Equal(t, http.StatusOK, resp.StatusCode)
}
func TestDoNotFound(t *testing.T) {
svr := httptest.NewServer(http.NotFoundHandler())
defer svr.Close()
req, err := http.NewRequest(http.MethodPost, svr.URL, nil)
assert.Nil(t, err)
req.Header.Set("Content-Type", "application/json")
resp, err := DoRequest(req)
assert.Nil(t, err)
assert.Equal(t, http.StatusNotFound, resp.StatusCode)
}
func TestDoMoved(t *testing.T) {
svr := httptest.NewServer(http.RedirectHandler("/foo", http.StatusMovedPermanently))
defer svr.Close()
req, err := http.NewRequest(http.MethodGet, svr.URL, nil)
assert.Nil(t, err)
_, err = DoRequest(req)
// too many redirects
assert.NotNil(t, err)
}

36
rest/httpc/responses.go Normal file
View File

@@ -0,0 +1,36 @@
package httpc
import (
"net/http"
"strings"
"github.com/zeromicro/go-zero/core/mapping"
"github.com/zeromicro/go-zero/rest/internal/encoding"
)
// Parse parses the response.
func Parse(resp *http.Response, val interface{}) error {
if err := ParseHeaders(resp, val); err != nil {
return err
}
return ParseJsonBody(resp, val)
}
// ParseHeaders parses the rsponse headers.
func ParseHeaders(resp *http.Response, val interface{}) error {
return encoding.ParseHeaders(resp.Header, val)
}
// ParseJsonBody parses the rsponse body, which should be in json content type.
func ParseJsonBody(resp *http.Response, val interface{}) error {
if withJsonBody(resp) {
return mapping.UnmarshalJsonReader(resp.Body, val)
}
return mapping.UnmarshalJsonMap(nil, val)
}
func withJsonBody(r *http.Response) bool {
return r.ContentLength > 0 && strings.Contains(r.Header.Get(contentType), applicationJson)
}

View File

@@ -0,0 +1,64 @@
package httpc
import (
"net/http"
"net/http/httptest"
"testing"
"github.com/stretchr/testify/assert"
)
func TestParse(t *testing.T) {
var val struct {
Foo string `header:"foo"`
Name string `json:"name"`
Value int `json:"value"`
}
svr := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("foo", "bar")
w.Header().Set(contentType, applicationJson)
w.Write([]byte(`{"name":"kevin","value":100}`))
}))
defer svr.Close()
req, err := http.NewRequest(http.MethodGet, svr.URL, nil)
assert.Nil(t, err)
resp, err := DoRequest(req)
assert.Nil(t, err)
assert.Nil(t, Parse(resp, &val))
assert.Equal(t, "bar", val.Foo)
assert.Equal(t, "kevin", val.Name)
assert.Equal(t, 100, val.Value)
}
func TestParseHeaderError(t *testing.T) {
var val struct {
Foo int `header:"foo"`
}
svr := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("foo", "bar")
w.Header().Set(contentType, applicationJson)
}))
defer svr.Close()
req, err := http.NewRequest(http.MethodGet, svr.URL, nil)
assert.Nil(t, err)
resp, err := DoRequest(req)
assert.Nil(t, err)
assert.NotNil(t, Parse(resp, &val))
}
func TestParseNoBody(t *testing.T) {
var val struct {
Foo string `header:"foo"`
}
svr := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("foo", "bar")
w.Header().Set(contentType, applicationJson)
}))
defer svr.Close()
req, err := http.NewRequest(http.MethodGet, svr.URL, nil)
assert.Nil(t, err)
resp, err := DoRequest(req)
assert.Nil(t, err)
assert.Nil(t, Parse(resp, &val))
assert.Equal(t, "bar", val.Foo)
}

61
rest/httpc/service.go Normal file
View File

@@ -0,0 +1,61 @@
package httpc
import (
"net/http"
"github.com/zeromicro/go-zero/core/breaker"
)
type (
// Option is used to customize the *http.Client.
Option func(r *http.Request) *http.Request
// Service represents a remote HTTP service.
Service interface {
// DoRequest sends a HTTP request to the service.
DoRequest(r *http.Request) (*http.Response, error)
}
namedService struct {
name string
cli *http.Client
opts []Option
}
)
// NewService returns a remote service with the given name.
// opts are used to customize the *http.Client.
func NewService(name string, opts ...Option) Service {
return NewServiceWithClient(name, http.DefaultClient, opts...)
}
// NewServiceWithClient returns a remote service with the given name.
// opts are used to customize the *http.Client.
func NewServiceWithClient(name string, cli *http.Client, opts ...Option) Service {
return namedService{
name: name,
cli: cli,
opts: opts,
}
}
// DoRequest sends an HTTP request to the service.
func (s namedService) DoRequest(r *http.Request) (*http.Response, error) {
return request(r, s)
}
func (s namedService) do(r *http.Request) (resp *http.Response, err error) {
for _, opt := range s.opts {
r = opt(r)
}
brk := breaker.GetBreaker(s.name)
err = brk.DoWithAcceptable(func() error {
resp, err = s.cli.Do(r)
return err
}, func(err error) bool {
return err == nil && resp.StatusCode < http.StatusInternalServerError
})
return
}

View File

@@ -0,0 +1,49 @@
package httpc
import (
"net/http"
"net/http/httptest"
"testing"
"github.com/stretchr/testify/assert"
)
func TestNamedService_Do(t *testing.T) {
svr := httptest.NewServer(http.RedirectHandler("/foo", http.StatusMovedPermanently))
defer svr.Close()
req, err := http.NewRequest(http.MethodGet, svr.URL, nil)
assert.Nil(t, err)
service := NewService("foo")
_, err = service.DoRequest(req)
// too many redirects
assert.NotNil(t, err)
}
func TestNamedService_Get(t *testing.T) {
svr := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("foo", r.Header.Get("foo"))
}))
defer svr.Close()
service := NewService("foo", func(r *http.Request) *http.Request {
r.Header.Set("foo", "bar")
return r
})
req, err := http.NewRequest(http.MethodGet, svr.URL, nil)
assert.Nil(t, err)
resp, err := service.DoRequest(req)
assert.Nil(t, err)
assert.Equal(t, http.StatusOK, resp.StatusCode)
assert.Equal(t, "bar", resp.Header.Get("foo"))
}
func TestNamedService_Post(t *testing.T) {
svr := httptest.NewServer(http.NotFoundHandler())
defer svr.Close()
service := NewService("foo")
req, err := http.NewRequest(http.MethodPost, svr.URL, nil)
assert.Nil(t, err)
req.Header.Set("Content-Type", "application/json")
resp, err := service.DoRequest(req)
assert.Nil(t, err)
assert.Equal(t, http.StatusNotFound, resp.StatusCode)
}

6
rest/httpc/vars.go Normal file
View File

@@ -0,0 +1,6 @@
package httpc
const (
contentType = "Content-Type"
applicationJson = "application/json"
)

View File

@@ -3,17 +3,16 @@ package httpx
import ( import (
"io" "io"
"net/http" "net/http"
"net/textproto"
"strings" "strings"
"github.com/zeromicro/go-zero/core/mapping" "github.com/zeromicro/go-zero/core/mapping"
"github.com/zeromicro/go-zero/rest/internal/encoding"
"github.com/zeromicro/go-zero/rest/pathvar" "github.com/zeromicro/go-zero/rest/pathvar"
) )
const ( const (
formKey = "form" formKey = "form"
pathKey = "path" pathKey = "path"
headerKey = "header"
maxMemory = 32 << 20 // 32MB maxMemory = 32 << 20 // 32MB
maxBodyLen = 8 << 20 // 8MB maxBodyLen = 8 << 20 // 8MB
separator = ";" separator = ";"
@@ -21,10 +20,8 @@ const (
) )
var ( var (
formUnmarshaler = mapping.NewUnmarshaler(formKey, mapping.WithStringValues()) formUnmarshaler = mapping.NewUnmarshaler(formKey, mapping.WithStringValues())
pathUnmarshaler = mapping.NewUnmarshaler(pathKey, mapping.WithStringValues()) pathUnmarshaler = mapping.NewUnmarshaler(pathKey, mapping.WithStringValues())
headerUnmarshaler = mapping.NewUnmarshaler(headerKey, mapping.WithStringValues(),
mapping.WithCanonicalKeyFunc(textproto.CanonicalMIMEHeaderKey))
) )
// Parse parses the request. // Parse parses the request.
@@ -46,16 +43,7 @@ func Parse(r *http.Request, v interface{}) error {
// ParseHeaders parses the headers request. // ParseHeaders parses the headers request.
func ParseHeaders(r *http.Request, v interface{}) error { func ParseHeaders(r *http.Request, v interface{}) error {
m := map[string]interface{}{} return encoding.ParseHeaders(r.Header, v)
for k, v := range r.Header {
if len(v) == 1 {
m[k] = v[0]
} else {
m[k] = v
}
}
return headerUnmarshaler.Unmarshal(m, v)
} }
// ParseForm parses the form request. // ParseForm parses the form request.

View File

@@ -0,0 +1,27 @@
package encoding
import (
"net/http"
"net/textproto"
"github.com/zeromicro/go-zero/core/mapping"
)
const headerKey = "header"
var headerUnmarshaler = mapping.NewUnmarshaler(headerKey, mapping.WithStringValues(),
mapping.WithCanonicalKeyFunc(textproto.CanonicalMIMEHeaderKey))
// ParseHeaders parses the headers request.
func ParseHeaders(header http.Header, v interface{}) error {
m := map[string]interface{}{}
for k, v := range header {
if len(v) == 1 {
m[k] = v[0]
} else {
m[k] = v
}
}
return headerUnmarshaler.Unmarshal(m, v)
}

View File

@@ -0,0 +1,40 @@
package encoding
import (
"net/http"
"net/http/httptest"
"testing"
"github.com/stretchr/testify/assert"
)
func TestParseHeaders(t *testing.T) {
var val struct {
Foo string `header:"foo"`
Baz int `header:"baz"`
Qux bool `header:"qux,default=true"`
}
r := httptest.NewRequest(http.MethodGet, "/any", nil)
r.Header.Set("foo", "bar")
r.Header.Set("baz", "1")
assert.Nil(t, ParseHeaders(r.Header, &val))
assert.Equal(t, "bar", val.Foo)
assert.Equal(t, 1, val.Baz)
assert.True(t, val.Qux)
}
func TestParseHeadersMulti(t *testing.T) {
var val struct {
Foo []string `header:"foo"`
Baz int `header:"baz"`
Qux bool `header:"qux,default=true"`
}
r := httptest.NewRequest(http.MethodGet, "/any", nil)
r.Header.Set("foo", "bar")
r.Header.Add("foo", "bar1")
r.Header.Set("baz", "1")
assert.Nil(t, ParseHeaders(r.Header, &val))
assert.Equal(t, []string{"bar", "bar1"}, val.Foo)
assert.Equal(t, 1, val.Baz)
assert.True(t, val.Qux)
}

View File

@@ -36,3 +36,8 @@ func TestError(t *testing.T) {
assert.True(t, strings.Contains(val, "third")) assert.True(t, strings.Contains(val, "third"))
assert.True(t, strings.Contains(val, "\n")) assert.True(t, strings.Contains(val, "\n"))
} }
func TestContextKey_String(t *testing.T) {
val := contextKey("foo")
assert.True(t, strings.Contains(val.String(), "foo"))
}

View File

@@ -151,6 +151,8 @@ func TestContentSecurity(t *testing.T) {
return return
} }
encrypted := test.mode != "0"
assert.Equal(t, encrypted, header.Encrypted())
assert.Equal(t, test.code, VerifySignature(r, header, time.Minute)) assert.Equal(t, test.code, VerifySignature(r, header, time.Minute))
}) })
} }

View File

@@ -10,25 +10,25 @@ import (
) )
// StartOption defines the method to customize http.Server. // StartOption defines the method to customize http.Server.
type StartOption func(srv *http.Server) type StartOption func(svr *http.Server)
// StartHttp starts a http server. // StartHttp starts a http server.
func StartHttp(host string, port int, handler http.Handler, opts ...StartOption) error { func StartHttp(host string, port int, handler http.Handler, opts ...StartOption) error {
return start(host, port, handler, func(srv *http.Server) error { return start(host, port, handler, func(svr *http.Server) error {
return srv.ListenAndServe() return svr.ListenAndServe()
}, opts...) }, opts...)
} }
// StartHttps starts a https server. // StartHttps starts a https server.
func StartHttps(host string, port int, certFile, keyFile string, handler http.Handler, func StartHttps(host string, port int, certFile, keyFile string, handler http.Handler,
opts ...StartOption) error { opts ...StartOption) error {
return start(host, port, handler, func(srv *http.Server) error { return start(host, port, handler, func(svr *http.Server) error {
// certFile and keyFile are set in buildHttpsServer // certFile and keyFile are set in buildHttpsServer
return srv.ListenAndServeTLS(certFile, keyFile) return svr.ListenAndServeTLS(certFile, keyFile)
}, opts...) }, opts...)
} }
func start(host string, port int, handler http.Handler, run func(srv *http.Server) error, func start(host string, port int, handler http.Handler, run func(svr *http.Server) error,
opts ...StartOption) (err error) { opts ...StartOption) (err error) {
server := &http.Server{ server := &http.Server{
Addr: fmt.Sprintf("%s:%d", host, port), Addr: fmt.Sprintf("%s:%d", host, port),

View File

@@ -0,0 +1,33 @@
package internal
import (
"net/http"
"net/http/httptest"
"strconv"
"strings"
"testing"
"github.com/stretchr/testify/assert"
)
func TestStartHttp(t *testing.T) {
svr := httptest.NewUnstartedServer(http.NotFoundHandler())
fields := strings.Split(svr.Listener.Addr().String(), ":")
port, err := strconv.Atoi(fields[1])
assert.Nil(t, err)
err = StartHttp(fields[0], port, http.NotFoundHandler(), func(svr *http.Server) {
svr.IdleTimeout = 0
})
assert.NotNil(t, err)
}
func TestStartHttps(t *testing.T) {
svr := httptest.NewTLSServer(http.NotFoundHandler())
fields := strings.Split(svr.Listener.Addr().String(), ":")
port, err := strconv.Atoi(fields[1])
assert.Nil(t, err)
err = StartHttps(fields[0], port, "", "", http.NotFoundHandler(), func(svr *http.Server) {
svr.IdleTimeout = 0
})
assert.NotNil(t, err)
}

View File

@@ -137,6 +137,13 @@ func WithJwtTransition(secret, prevSecret string) RouteOption {
} }
} }
// WithMaxBytes returns a RouteOption to set maxBytes with the given value.
func WithMaxBytes(maxBytes int64) RouteOption {
return func(r *featuredRoutes) {
r.maxBytes = maxBytes
}
}
// WithMiddlewares adds given middlewares to given routes. // WithMiddlewares adds given middlewares to given routes.
func WithMiddlewares(ms []Middleware, rs ...Route) []Route { func WithMiddlewares(ms []Middleware, rs ...Route) []Route {
for i := len(ms) - 1; i >= 0; i-- { for i := len(ms) - 1; i >= 0; i-- {
@@ -225,22 +232,22 @@ func WithTimeout(timeout time.Duration) RouteOption {
// WithTLSConfig returns a RunOption that with given tls config. // WithTLSConfig returns a RunOption that with given tls config.
func WithTLSConfig(cfg *tls.Config) RunOption { func WithTLSConfig(cfg *tls.Config) RunOption {
return func(srv *Server) { return func(svr *Server) {
srv.ngin.setTlsConfig(cfg) svr.ngin.setTlsConfig(cfg)
} }
} }
// WithUnauthorizedCallback returns a RunOption that with given unauthorized callback set. // WithUnauthorizedCallback returns a RunOption that with given unauthorized callback set.
func WithUnauthorizedCallback(callback handler.UnauthorizedCallback) RunOption { func WithUnauthorizedCallback(callback handler.UnauthorizedCallback) RunOption {
return func(srv *Server) { return func(svr *Server) {
srv.ngin.setUnauthorizedCallback(callback) svr.ngin.setUnauthorizedCallback(callback)
} }
} }
// WithUnsignedCallback returns a RunOption that with given unsigned callback set. // WithUnsignedCallback returns a RunOption that with given unsigned callback set.
func WithUnsignedCallback(callback handler.UnsignedCallback) RunOption { func WithUnsignedCallback(callback handler.UnsignedCallback) RunOption {
return func(srv *Server) { return func(svr *Server) {
srv.ngin.setUnsignedCallback(callback) svr.ngin.setUnsignedCallback(callback)
} }
} }

View File

@@ -56,22 +56,22 @@ Port: 54321
} }
for _, test := range tests { for _, test := range tests {
var srv *Server var svr *Server
var err error var err error
if test.fail { if test.fail {
_, err = NewServer(test.c, test.opts...) _, err = NewServer(test.c, test.opts...)
assert.NotNil(t, err) assert.NotNil(t, err)
continue continue
} else { } else {
srv = MustNewServer(test.c, test.opts...) svr = MustNewServer(test.c, test.opts...)
} }
srv.Use(ToMiddleware(func(next http.Handler) http.Handler { svr.Use(ToMiddleware(func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
next.ServeHTTP(w, r) next.ServeHTTP(w, r)
}) })
})) }))
srv.AddRoute(Route{ svr.AddRoute(Route{
Method: http.MethodGet, Method: http.MethodGet,
Path: "/", Path: "/",
Handler: nil, Handler: nil,
@@ -89,12 +89,19 @@ Port: 54321
} }
}() }()
srv.Start() svr.Start()
srv.Stop() svr.Stop()
}() }()
} }
} }
func TestWithMaxBytes(t *testing.T) {
const maxBytes = 1000
var fr featuredRoutes
WithMaxBytes(maxBytes)(&fr)
assert.Equal(t, int64(maxBytes), fr.maxBytes)
}
func TestWithMiddleware(t *testing.T) { func TestWithMiddleware(t *testing.T) {
m := make(map[string]string) m := make(map[string]string)
rt := router.NewRouter() rt := router.NewRouter()
@@ -290,9 +297,9 @@ Port: 54321
} }
for _, testCase := range testCases { for _, testCase := range testCases {
srv, err := NewServer(testCase.c, testCase.opts...) svr, err := NewServer(testCase.c, testCase.opts...)
assert.Nil(t, err) assert.Nil(t, err)
assert.Equal(t, srv.ngin.tlsConfig, testCase.res) assert.Equal(t, svr.ngin.tlsConfig, testCase.res)
} }
} }
@@ -304,11 +311,11 @@ Port: 54321
var cnf RestConf var cnf RestConf
assert.Nil(t, conf.LoadConfigFromYamlBytes([]byte(configYaml), &cnf)) assert.Nil(t, conf.LoadConfigFromYamlBytes([]byte(configYaml), &cnf))
rt := router.NewRouter() rt := router.NewRouter()
srv, err := NewServer(cnf, WithRouter(rt)) svr, err := NewServer(cnf, WithRouter(rt))
assert.Nil(t, err) assert.Nil(t, err)
opt := WithCors("local") opt := WithCors("local")
opt(srv) opt(svr)
} }
func TestWithCustomCors(t *testing.T) { func TestWithCustomCors(t *testing.T) {
@@ -319,7 +326,7 @@ Port: 54321
var cnf RestConf var cnf RestConf
assert.Nil(t, conf.LoadConfigFromYamlBytes([]byte(configYaml), &cnf)) assert.Nil(t, conf.LoadConfigFromYamlBytes([]byte(configYaml), &cnf))
rt := router.NewRouter() rt := router.NewRouter()
srv, err := NewServer(cnf, WithRouter(rt)) svr, err := NewServer(cnf, WithRouter(rt))
assert.Nil(t, err) assert.Nil(t, err)
opt := WithCustomCors(func(header http.Header) { opt := WithCustomCors(func(header http.Header) {
@@ -327,5 +334,5 @@ Port: 54321
}, func(w http.ResponseWriter) { }, func(w http.ResponseWriter) {
w.WriteHeader(http.StatusOK) w.WriteHeader(http.StatusOK)
}, "local") }, "local")
opt(srv) opt(svr)
} }

View File

@@ -36,5 +36,6 @@ type (
jwt jwtSetting jwt jwtSetting
signature signatureSetting signature signatureSetting
routes []Route routes []Route
maxBytes int64
} }
) )

1
tools/goctl/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
.vscode

34
tools/goctl/Dockerfile Normal file
View File

@@ -0,0 +1,34 @@
FROM golang:alpine AS builder
LABEL stage=gobuilder
ENV CGO_ENABLED 0
ENV GOPROXY https://goproxy.cn,direct
RUN apk update --no-cache && apk add --no-cache tzdata
RUN go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
RUN go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest
WORKDIR /build
ADD go.mod .
ADD go.sum .
RUN go mod download
COPY . .
RUN go build -ldflags="-s -w" -o /app/goctl ./goctl.go
FROM alpine
RUN apk update --no-cache && apk add --no-cache protoc
COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt
COPY --from=builder /usr/share/zoneinfo/Asia/Shanghai /usr/share/zoneinfo/Asia/Shanghai
COPY --from=builder /go/bin/protoc-gen-go /usr/bin/protoc-gen-go
COPY --from=builder /go/bin/protoc-gen-go-grpc /usr/bin/protoc-gen-go-grpc
ENV TZ Asia/Shanghai
WORKDIR /app
COPY --from=builder /app/goctl /app/goctl
CMD ["./goctl"]

View File

@@ -55,8 +55,9 @@ func ApiCommand(c *cli.Context) error {
home := c.String("home") home := c.String("home")
remote := c.String("remote") remote := c.String("remote")
branch := c.String("branch")
if len(remote) > 0 { if len(remote) > 0 {
repo, _ := util.CloneIntoGitHome(remote) repo, _ := util.CloneIntoGitHome(remote, branch)
if len(repo) > 0 { if len(repo) > 0 {
home = repo home = repo
} }

View File

@@ -0,0 +1,40 @@
package dartgen
import (
"fmt"
"os"
"os/exec"
)
const dartExec = "dart"
func formatDir(dir string) error {
ok, err := dirctoryExists(dir)
if err != nil {
return err
}
if !ok {
return fmt.Errorf("format failed, directory %q does not exist", dir)
}
_, err = exec.LookPath(dartExec)
if err != nil {
return err
}
cmd := exec.Command(dartExec, "format", dir)
cmd.Env = os.Environ()
cmd.Stderr = os.Stderr
return cmd.Run()
}
func dirctoryExists(dir string) (bool, error) {
_, err := os.Stat(dir)
if err == nil {
return true, nil
}
if os.IsNotExist(err) {
return false, nil
}
return false, err
}

View File

@@ -2,6 +2,7 @@ package dartgen
import ( import (
"errors" "errors"
"fmt"
"strings" "strings"
"github.com/urfave/cli" "github.com/urfave/cli"
@@ -13,12 +14,18 @@ import (
func DartCommand(c *cli.Context) error { func DartCommand(c *cli.Context) error {
apiFile := c.String("api") apiFile := c.String("api")
dir := c.String("dir") dir := c.String("dir")
isLegacy := c.Bool("legacy")
hostname := c.String("hostname")
if len(apiFile) == 0 { if len(apiFile) == 0 {
return errors.New("missing -api") return errors.New("missing -api")
} }
if len(dir) == 0 { if len(dir) == 0 {
return errors.New("missing -dir") return errors.New("missing -dir")
} }
if len(hostname) == 0 {
fmt.Println("you could use '-hostname' flag to specify your server hostname")
hostname = "go-zero.dev"
}
api, err := parser.Parse(apiFile) api, err := parser.Parse(apiFile)
if err != nil { if err != nil {
@@ -30,8 +37,11 @@ func DartCommand(c *cli.Context) error {
dir = dir + "/" dir = dir + "/"
} }
api.Info.Title = strings.Replace(apiFile, ".api", "", -1) api.Info.Title = strings.Replace(apiFile, ".api", "", -1)
logx.Must(genData(dir+"data/", api)) logx.Must(genData(dir+"data/", api, isLegacy))
logx.Must(genApi(dir+"api/", api)) logx.Must(genApi(dir+"api/", api, isLegacy))
logx.Must(genVars(dir + "vars/")) logx.Must(genVars(dir+"vars/", isLegacy, hostname))
if err := formatDir(dir); err != nil {
logx.Errorf("failed to format, %v", err)
}
return nil return nil
} }

View File

@@ -2,13 +2,14 @@ package dartgen
import ( import (
"os" "os"
"strings"
"text/template" "text/template"
"github.com/zeromicro/go-zero/tools/goctl/api/spec" "github.com/zeromicro/go-zero/tools/goctl/api/spec"
) )
const apiTemplate = `import 'api.dart'; const apiTemplate = `import 'api.dart';
import '../data/{{with .Info}}{{.Title}}{{end}}.dart'; import '../data/{{with .Info}}{{getBaseName .Title}}{{end}}.dart';
{{with .Service}} {{with .Service}}
/// {{.Name}} /// {{.Name}}
{{range .Routes}} {{range .Routes}}
@@ -22,24 +23,45 @@ Future {{pathToFuncName .Path}}( {{if ne .Method "get"}}{{with .RequestType}}{{.
Function eventually}) async { Function eventually}) async {
await api{{if eq .Method "get"}}Get{{else}}Post{{end}}('{{.Path}}',{{if ne .Method "get"}}request,{{end}} await api{{if eq .Method "get"}}Get{{else}}Post{{end}}('{{.Path}}',{{if ne .Method "get"}}request,{{end}}
ok: (data) { ok: (data) {
if (ok != null) ok({{with .ResponseType}}{{.Name}}{{end}}.fromJson(data)); if (ok != null) ok({{with .ResponseType}}{{.Name}}.fromJson(data){{end}});
}, fail: fail, eventually: eventually); }, fail: fail, eventually: eventually);
} }
{{end}} {{end}}
{{end}}` {{end}}`
func genApi(dir string, api *spec.ApiSpec) error { const apiTemplateV2 = `import 'api.dart';
import '../data/{{with .Info}}{{getBaseName .Title}}{{end}}.dart';
{{with .Service}}
/// {{.Name}}
{{range .Routes}}
/// --{{.Path}}--
///
/// request: {{with .RequestType}}{{.Name}}{{end}}
/// response: {{with .ResponseType}}{{.Name}}{{end}}
Future {{pathToFuncName .Path}}( {{if ne .Method "get"}}{{with .RequestType}}{{.Name}} request,{{end}}{{end}}
{Function({{with .ResponseType}}{{.Name}}{{end}})? ok,
Function(String)? fail,
Function? eventually}) async {
await api{{if eq .Method "get"}}Get{{else}}Post{{end}}('{{.Path}}',{{if ne .Method "get"}}request,{{end}}
ok: (data) {
if (ok != null) ok({{with .ResponseType}}{{.Name}}.fromJson(data){{end}});
}, fail: fail, eventually: eventually);
}
{{end}}
{{end}}`
func genApi(dir string, api *spec.ApiSpec, isLegacy bool) error {
err := os.MkdirAll(dir, 0o755) err := os.MkdirAll(dir, 0o755)
if err != nil { if err != nil {
return err return err
} }
err = genApiFile(dir) err = genApiFile(dir, isLegacy)
if err != nil { if err != nil {
return err return err
} }
file, err := os.OpenFile(dir+api.Service.Name+".dart", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0o644) file, err := os.OpenFile(dir+strings.ToLower(api.Service.Name+".dart"), os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0o644)
if err != nil { if err != nil {
return err return err
} }
@@ -47,7 +69,11 @@ func genApi(dir string, api *spec.ApiSpec) error {
defer file.Close() defer file.Close()
t := template.New("apiTemplate") t := template.New("apiTemplate")
t = t.Funcs(funcMap) t = t.Funcs(funcMap)
t, err = t.Parse(apiTemplate) tpl := apiTemplateV2
if isLegacy {
tpl = apiTemplate
}
t, err = t.Parse(tpl)
if err != nil { if err != nil {
return err return err
} }
@@ -55,7 +81,7 @@ func genApi(dir string, api *spec.ApiSpec) error {
return t.Execute(file, api) return t.Execute(file, api)
} }
func genApiFile(dir string) error { func genApiFile(dir string, isLegacy bool) error {
path := dir + "api.dart" path := dir + "api.dart"
if fileExists(path) { if fileExists(path) {
return nil return nil
@@ -66,6 +92,10 @@ func genApiFile(dir string) error {
} }
defer apiFile.Close() defer apiFile.Close()
_, err = apiFile.WriteString(apiFileContent) tpl := apiFileContentV2
if isLegacy {
tpl = apiFileContent
}
_, err = apiFile.WriteString(tpl)
return err return err
} }

View File

@@ -2,6 +2,7 @@ package dartgen
import ( import (
"os" "os"
"strings"
"text/template" "text/template"
"github.com/zeromicro/go-zero/tools/goctl/api/spec" "github.com/zeromicro/go-zero/tools/goctl/api/spec"
@@ -31,18 +32,42 @@ class {{.Name}}{
{{end}} {{end}}
` `
func genData(dir string, api *spec.ApiSpec) error { const dataTemplateV2 = `// --{{with .Info}}{{.Title}}{{end}}--
{{ range .Types}}
class {{.Name}} {
{{range .Members}}
{{if .Comment}}{{.Comment}}{{end}}
final {{.Type.Name}} {{lowCamelCase .Name}};
{{end}}{{.Name}}({{if .Members}}{
{{range .Members}} required this.{{lowCamelCase .Name}},
{{end}}}{{end}});
factory {{.Name}}.fromJson(Map<String,dynamic> m) {
return {{.Name}}({{range .Members}}
{{lowCamelCase .Name}}: {{if isDirectType .Type.Name}}m['{{getPropertyFromMember .}}']
{{else if isClassListType .Type.Name}}(m['{{getPropertyFromMember .}}'] as List<dynamic>).map((i) => {{getCoreType .Type.Name}}.fromJson(i)).toList()
{{else}}{{.Type.Name}}.fromJson(m['{{getPropertyFromMember .}}']){{end}},{{end}}
);
}
Map<String,dynamic> toJson() {
return { {{range .Members}}
'{{getPropertyFromMember .}}': {{if isDirectType .Type.Name}}{{lowCamelCase .Name}}{{else if isClassListType .Type.Name}}{{lowCamelCase .Name}}.map((i) => i.toJson()){{else}}{{lowCamelCase .Name}}.toJson(){{end}},{{end}}
};
}
}
{{end}}`
func genData(dir string, api *spec.ApiSpec, isLegacy bool) error {
err := os.MkdirAll(dir, 0o755) err := os.MkdirAll(dir, 0o755)
if err != nil { if err != nil {
return err return err
} }
err = genTokens(dir) err = genTokens(dir, isLegacy)
if err != nil { if err != nil {
return err return err
} }
file, err := os.OpenFile(dir+api.Service.Name+".dart", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0o644) file, err := os.OpenFile(dir+strings.ToLower(api.Service.Name+".dart"), os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0o644)
if err != nil { if err != nil {
return err return err
} }
@@ -50,7 +75,11 @@ func genData(dir string, api *spec.ApiSpec) error {
t := template.New("dataTemplate") t := template.New("dataTemplate")
t = t.Funcs(funcMap) t = t.Funcs(funcMap)
t, err = t.Parse(dataTemplate) tpl := dataTemplateV2
if isLegacy {
tpl = dataTemplate
}
t, err = t.Parse(tpl)
if err != nil { if err != nil {
return err return err
} }
@@ -63,7 +92,7 @@ func genData(dir string, api *spec.ApiSpec) error {
return t.Execute(file, api) return t.Execute(file, api)
} }
func genTokens(dir string) error { func genTokens(dir string, isLeagcy bool) error {
path := dir + "tokens.dart" path := dir + "tokens.dart"
if fileExists(path) { if fileExists(path) {
return nil return nil
@@ -75,7 +104,11 @@ func genTokens(dir string) error {
} }
defer tokensFile.Close() defer tokensFile.Close()
_, err = tokensFile.WriteString(tokensFileContent) tpl := tokensFileContentV2
if isLeagcy {
tpl = tokensFileContent
}
_, err = tokensFile.WriteString(tpl)
return err return err
} }

View File

@@ -1,11 +1,13 @@
package dartgen package dartgen
import ( import (
"fmt"
"io/ioutil" "io/ioutil"
"os" "os"
) )
const varTemplate = `import 'dart:convert'; const (
varTemplate = `import 'dart:convert';
import 'package:shared_preferences/shared_preferences.dart'; import 'package:shared_preferences/shared_preferences.dart';
import '../data/tokens.dart'; import '../data/tokens.dart';
@@ -40,21 +42,59 @@ Future<Tokens> getTokens() async {
} }
` `
func genVars(dir string) error { varTemplateV2 = `import 'dart:convert';
import 'package:shared_preferences/shared_preferences.dart';
import '../data/tokens.dart';
const String _tokenKey = 'tokens';
/// Saves tokens
Future<bool> setTokens(Tokens tokens) async {
var sp = await SharedPreferences.getInstance();
return await sp.setString(_tokenKey, jsonEncode(tokens.toJson()));
}
/// remove tokens
Future<bool> removeTokens() async {
var sp = await SharedPreferences.getInstance();
return sp.remove(_tokenKey);
}
/// Reads tokens
Future<Tokens?> getTokens() async {
try {
var sp = await SharedPreferences.getInstance();
var str = sp.getString('tokens');
if (str.isEmpty) {
return null;
}
return Tokens.fromJson(jsonDecode(str));
} catch (e) {
print(e);
return null;
}
}`
)
func genVars(dir string, isLegacy bool, hostname string) error {
err := os.MkdirAll(dir, 0o755) err := os.MkdirAll(dir, 0o755)
if err != nil { if err != nil {
return err return err
} }
if !fileExists(dir + "vars.dart") { if !fileExists(dir + "vars.dart") {
err = ioutil.WriteFile(dir+"vars.dart", []byte(`const serverHost='demo-crm.xiaoheiban.cn';`), 0o644) err = ioutil.WriteFile(dir+"vars.dart", []byte(fmt.Sprintf(`const serverHost='%s';`, hostname)), 0o644)
if err != nil { if err != nil {
return err return err
} }
} }
if !fileExists(dir + "kv.dart") { if !fileExists(dir + "kv.dart") {
err = ioutil.WriteFile(dir+"kv.dart", []byte(varTemplate), 0o644) tpl := varTemplateV2
if isLegacy {
tpl = varTemplate
}
err = ioutil.WriteFile(dir+"kv.dart", []byte(tpl), 0o644)
if err != nil { if err != nil {
return err return err
} }

View File

@@ -4,6 +4,7 @@ import (
"errors" "errors"
"fmt" "fmt"
"os" "os"
"path"
"strings" "strings"
"github.com/zeromicro/go-zero/tools/goctl/api/spec" "github.com/zeromicro/go-zero/tools/goctl/api/spec"
@@ -34,6 +35,10 @@ func pathToFuncName(path string) string {
return util.ToLower(camel[:1]) + camel[1:] return util.ToLower(camel[:1]) + camel[1:]
} }
func getBaseName(str string) string {
return path.Base(str)
}
func getPropertyFromMember(member spec.Member) string { func getPropertyFromMember(member spec.Member) string {
name, err := member.GetPropertyName() name, err := member.GetPropertyName()
if err != nil { if err != nil {
@@ -123,11 +128,10 @@ func specTypeToDart(tp spec.Type) (string, error) {
} }
s := getBaseType(valueType) s := getBaseType(valueType)
if len(s) == 0 { if len(s) != 0 {
return s, errors.New("unsupported primitive type " + tp.Name()) return s, nil
} }
return fmt.Sprintf("List<%s>", valueType), nil
return s, nil
case spec.InterfaceType: case spec.InterfaceType:
return "Object", nil return "Object", nil
case spec.PointerType: case spec.PointerType:

View File

@@ -37,3 +37,35 @@ func Test_getPropertyFromMember(t *testing.T) {
}) })
} }
} }
func Test_specTypeToDart(t *testing.T) {
tests := []struct {
name string
specType spec.Type
want string
wantErr bool
}{
{
name: "[]string should return List<String>",
specType: spec.ArrayType{RawName: "[]string", Value: spec.PrimitiveType{RawName: "string"}},
want: "List<String>",
},
{
name: "[]Foo should return List<Foo>",
specType: spec.ArrayType{RawName: "[]Foo", Value: spec.DefineStruct{RawName: "Foo"}},
want: "List<Foo>",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := specTypeToDart(tt.specType)
if (err != nil) != tt.wantErr {
t.Errorf("specTypeToDart() error = %v, wantErr %v", err, tt.wantErr)
return
}
if got != tt.want {
t.Errorf("specTypeToDart() = %v, want %v", got, tt.want)
}
})
}
}

View File

@@ -3,6 +3,7 @@ package dartgen
import "text/template" import "text/template"
var funcMap = template.FuncMap{ var funcMap = template.FuncMap{
"getBaseName": getBaseName,
"getPropertyFromMember": getPropertyFromMember, "getPropertyFromMember": getPropertyFromMember,
"isDirectType": isDirectType, "isDirectType": isDirectType,
"isClassListType": isClassListType, "isClassListType": isClassListType,
@@ -99,6 +100,96 @@ Future _apiRequest(String method, String path, dynamic data,
} }
` `
apiFileContentV2 = `import 'dart:io';
import 'dart:convert';
import '../vars/kv.dart';
import '../vars/vars.dart';
/// send request with post method
///
/// data: any request class that will be converted to json automatically
/// ok: is called when request succeeds
/// fail: is called when request fails
/// eventually: is always called until the nearby functions returns
Future apiPost(String path, dynamic data,
{Map<String, String>? header,
Function(Map<String, dynamic>)? ok,
Function(String)? fail,
Function? eventually}) async {
await _apiRequest('POST', path, data,
header: header, ok: ok, fail: fail, eventually: eventually);
}
/// send request with get method
///
/// ok: is called when request succeeds
/// fail: is called when request fails
/// eventually: is always called until the nearby functions returns
Future apiGet(String path,
{Map<String, String>? header,
Function(Map<String, dynamic>)? ok,
Function(String)? fail,
Function? eventually}) async {
await _apiRequest('GET', path, null,
header: header, ok: ok, fail: fail, eventually: eventually);
}
Future _apiRequest(String method, String path, dynamic data,
{Map<String, String>? header,
Function(Map<String, dynamic>)? ok,
Function(String)? fail,
Function? eventually}) async {
var tokens = await getTokens();
try {
var client = HttpClient();
HttpClientRequest r;
if (method == 'POST') {
r = await client.postUrl(Uri.parse('https://' + serverHost + path));
} else {
r = await client.getUrl(Uri.parse('https://' + serverHost + path));
}
r.headers.set('Content-Type', 'application/json');
if (tokens != null) {
r.headers.set('Authorization', tokens.accessToken);
}
if (header != null) {
header.forEach((k, v) {
r.headers.set(k, v);
});
}
var strData = '';
if (data != null) {
strData = jsonEncode(data);
}
r.write(strData);
var rp = await r.close();
var body = await rp.transform(utf8.decoder).join();
print('${rp.statusCode} - $path');
print('-- request --');
print(strData);
print('-- response --');
print('$body \n');
if (rp.statusCode == 404) {
if (fail != null) fail('404 not found');
} else {
Map<String, dynamic> base = jsonDecode(body);
if (rp.statusCode == 200) {
if (base['code'] != 0) {
if (fail != null) fail(base['desc']);
} else {
if (ok != null) ok(base['data']);
}
} else if (base['code'] != 0) {
if (fail != null) fail(base['desc']);
}
}
} catch (e) {
if (fail != null) fail(e.toString());
}
if (eventually != null) eventually();
}`
tokensFileContent = `class Tokens { tokensFileContent = `class Tokens {
/// 用于访问的token, 每次请求都必须带在Header里面 /// 用于访问的token, 每次请求都必须带在Header里面
final String accessToken; final String accessToken;
@@ -132,5 +223,41 @@ Future _apiRequest(String method, String path, dynamic data,
}; };
} }
} }
`
tokensFileContentV2 = `class Tokens {
/// 用于访问的token, 每次请求都必须带在Header里面
final String accessToken;
final int accessExpire;
/// 用于刷新token
final String refreshToken;
final int refreshExpire;
final int refreshAfter;
Tokens({
required this.accessToken,
required this.accessExpire,
required this.refreshToken,
required this.refreshExpire,
required this.refreshAfter
});
factory Tokens.fromJson(Map<String, dynamic> m) {
return Tokens(
accessToken: m['access_token'],
accessExpire: m['access_expire'],
refreshToken: m['refresh_token'],
refreshExpire: m['refresh_expire'],
refreshAfter: m['refresh_after']);
}
Map<String, dynamic> toJson() {
return {
'access_token': accessToken,
'access_expire': accessExpire,
'refresh_token': refreshToken,
'refresh_expire': refreshExpire,
'refresh_after': refreshAfter,
};
}
}
` `
) )

View File

@@ -6,6 +6,7 @@ import (
"fmt" "fmt"
"go/format" "go/format"
"go/scanner" "go/scanner"
"io"
"io/ioutil" "io/ioutil"
"os" "os"
"path/filepath" "path/filepath"
@@ -28,14 +29,15 @@ const (
// GoFormatApi format api file // GoFormatApi format api file
func GoFormatApi(c *cli.Context) error { func GoFormatApi(c *cli.Context) error {
useStdin := c.Bool("stdin") useStdin := c.Bool("stdin")
skipCheckDeclare := c.Bool("declare")
dir := c.String("dir")
var be errorx.BatchError var be errorx.BatchError
if useStdin { if useStdin {
if err := apiFormatByStdin(); err != nil { if err := apiFormatReader(os.Stdin, dir, skipCheckDeclare); err != nil {
be.Add(err) be.Add(err)
} }
} else { } else {
dir := c.String("dir")
if len(dir) == 0 { if len(dir) == 0 {
return errors.New("missing -dir") return errors.New("missing -dir")
} }
@@ -47,7 +49,7 @@ func GoFormatApi(c *cli.Context) error {
err = filepath.Walk(dir, func(path string, fi os.FileInfo, errBack error) (err error) { err = filepath.Walk(dir, func(path string, fi os.FileInfo, errBack error) (err error) {
if strings.HasSuffix(path, ".api") { if strings.HasSuffix(path, ".api") {
if err := ApiFormatByPath(path); err != nil { if err := ApiFormatByPath(path, skipCheckDeclare); err != nil {
be.Add(util.WrapErr(err, fi.Name())) be.Add(util.WrapErr(err, fi.Name()))
} }
} }
@@ -64,13 +66,14 @@ func GoFormatApi(c *cli.Context) error {
return be.Err() return be.Err()
} }
func apiFormatByStdin() error { // apiFormatReader
data, err := ioutil.ReadAll(os.Stdin) // filename is needed when there are `import` literals.
func apiFormatReader(reader io.Reader, filename string, skipCheckDeclare bool) error {
data, err := ioutil.ReadAll(reader)
if err != nil { if err != nil {
return err return err
} }
result, err := apiFormat(string(data), skipCheckDeclare, filename)
result, err := apiFormat(string(data))
if err != nil { if err != nil {
return err return err
} }
@@ -80,7 +83,7 @@ func apiFormatByStdin() error {
} }
// ApiFormatByPath format api from file path // ApiFormatByPath format api from file path
func ApiFormatByPath(apiFilePath string) error { func ApiFormatByPath(apiFilePath string, skipCheckDeclare bool) error {
data, err := ioutil.ReadFile(apiFilePath) data, err := ioutil.ReadFile(apiFilePath)
if err != nil { if err != nil {
return err return err
@@ -91,12 +94,12 @@ func ApiFormatByPath(apiFilePath string) error {
return err return err
} }
result, err := apiFormat(string(data), abs) result, err := apiFormat(string(data), skipCheckDeclare, abs)
if err != nil { if err != nil {
return err return err
} }
_, err = parser.ParseContent(result, abs) _, err = parser.ParseContentWithParserSkipCheckTypeDeclaration(result, abs)
if err != nil { if err != nil {
return err return err
} }
@@ -104,8 +107,13 @@ func ApiFormatByPath(apiFilePath string) error {
return ioutil.WriteFile(apiFilePath, []byte(result), os.ModePerm) return ioutil.WriteFile(apiFilePath, []byte(result), os.ModePerm)
} }
func apiFormat(data string, filename ...string) (string, error) { func apiFormat(data string, skipCheckDeclare bool, filename ...string) (string, error) {
_, err := parser.ParseContent(data, filename...) var err error
if skipCheckDeclare {
_, err = parser.ParseContentWithParserSkipCheckTypeDeclaration(data, filename...)
} else {
_, err = parser.ParseContent(data, filename...)
}
if err != nil { if err != nil {
return "", err return "", err
} }

View File

@@ -1,18 +1,25 @@
package format package format
import ( import (
"fmt"
"io/fs"
"io/ioutil"
"os"
"path"
"testing" "testing"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
) )
const ( const (
notFormattedStr = ` notFormattedStr = `
type Request struct { type Request struct {
Name string ` + "`" + `path:"name,options=you|me"` + "`" + ` Name string ` + "`" + `path:"name,options=you|me"` + "`" + `
} }
type Response struct { type Response struct {
Message string ` + "`" + `json:"message"` + "`" + ` Message string ` + "`" + `json:"message"` + "`" + `
Students []Student ` + "`" + `json:"students"` + "`" + `
} }
service A-api { service A-api {
@server( @server(
@@ -26,7 +33,8 @@ handler: GreetHandler
Name string ` + "`" + `path:"name,options=you|me"` + "`" + ` Name string ` + "`" + `path:"name,options=you|me"` + "`" + `
} }
type Response { type Response {
Message string ` + "`" + `json:"message"` + "`" + ` Message string ` + "`" + `json:"message"` + "`" + `
Students []Student ` + "`" + `json:"students"` + "`" + `
} }
service A-api { service A-api {
@server( @server(
@@ -37,7 +45,32 @@ service A-api {
) )
func TestFormat(t *testing.T) { func TestFormat(t *testing.T) {
r, err := apiFormat(notFormattedStr) r, err := apiFormat(notFormattedStr, true)
assert.Nil(t, err) assert.Nil(t, err)
assert.Equal(t, formattedStr, r) assert.Equal(t, formattedStr, r)
_, err = apiFormat(notFormattedStr, false)
assert.Errorf(t, err, " line 7:13 can not found declaration 'Student' in context")
}
func Test_apiFormatReader_issue1721(t *testing.T) {
dir, err := os.MkdirTemp("", "goctl-api-format")
require.NoError(t, err)
defer os.RemoveAll(dir)
subDir := path.Join(dir, "sub")
err = os.MkdirAll(subDir, fs.ModePerm)
require.NoError(t, err)
importedFilename := path.Join(dir, "foo.api")
err = ioutil.WriteFile(importedFilename, []byte{}, fs.ModePerm)
require.NoError(t, err)
filename := path.Join(subDir, "bar.api")
err = ioutil.WriteFile(filename, []byte(fmt.Sprintf(`import "%s"`, importedFilename)), 0644)
require.NoError(t, err)
f, err := os.Open(filename)
require.NoError(t, err)
err = apiFormatReader(f, filename, false)
assert.NoError(t, err)
} }

View File

@@ -33,8 +33,9 @@ func GoCommand(c *cli.Context) error {
namingStyle := c.String("style") namingStyle := c.String("style")
home := c.String("home") home := c.String("home")
remote := c.String("remote") remote := c.String("remote")
branch := c.String("branch")
if len(remote) > 0 { if len(remote) > 0 {
repo, _ := util.CloneIntoGitHome(remote) repo, _ := util.CloneIntoGitHome(remote, branch)
if len(repo) > 0 { if len(repo) > 0 {
home = repo home = repo
} }
@@ -85,7 +86,7 @@ func DoGenProject(apiFile, dir, style string) error {
return err return err
} }
if err := apiformat.ApiFormatByPath(apiFile); err != nil { if err := apiformat.ApiFormatByPath(apiFile, false); err != nil {
return err return err
} }

View File

@@ -7,6 +7,7 @@ import (
"sort" "sort"
"strings" "strings"
"text/template" "text/template"
"time"
"github.com/zeromicro/go-zero/core/collection" "github.com/zeromicro/go-zero/core/collection"
"github.com/zeromicro/go-zero/tools/goctl/api/spec" "github.com/zeromicro/go-zero/tools/goctl/api/spec"
@@ -23,7 +24,8 @@ const (
package handler package handler
import ( import (
"net/http" "net/http"{{if .hasTimeout}}
"time"{{end}}
{{.importPackages}} {{.importPackages}}
) )
@@ -34,9 +36,10 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
` `
routesAdditionTemplate = ` routesAdditionTemplate = `
server.AddRoutes( server.AddRoutes(
{{.routes}} {{.jwt}}{{.signature}} {{.prefix}} {{.routes}} {{.jwt}}{{.signature}} {{.prefix}} {{.timeout}}
) )
` `
timeoutThreshold = time.Millisecond
) )
var mapping = map[string]string{ var mapping = map[string]string{
@@ -57,6 +60,7 @@ type (
jwtEnabled bool jwtEnabled bool
signatureEnabled bool signatureEnabled bool
authName string authName string
timeout string
middlewares []string middlewares []string
prefix string prefix string
jwtTrans string jwtTrans string
@@ -80,6 +84,7 @@ func genRoutes(dir, rootPkg string, cfg *config.Config, api *spec.ApiSpec) error
return err return err
} }
var hasTimeout bool
gt := template.Must(template.New("groupTemplate").Parse(templateText)) gt := template.Must(template.New("groupTemplate").Parse(templateText))
for _, g := range groups { for _, g := range groups {
var gbuilder strings.Builder var gbuilder strings.Builder
@@ -110,6 +115,22 @@ func genRoutes(dir, rootPkg string, cfg *config.Config, api *spec.ApiSpec) error
rest.WithPrefix("%s"),`, g.prefix) rest.WithPrefix("%s"),`, g.prefix)
} }
var timeout string
if len(g.timeout) > 0 {
duration, err := time.ParseDuration(g.timeout)
if err != nil {
return err
}
// why we check this, maybe some users set value 1, it's 1ns, not 1s.
if duration < timeoutThreshold {
return fmt.Errorf("timeout should not less than 1ms, now %v", duration)
}
timeout = fmt.Sprintf("rest.WithTimeout(%d * time.Millisecond),", duration/time.Millisecond)
hasTimeout = true
}
var routes string var routes string
if len(g.middlewares) > 0 { if len(g.middlewares) > 0 {
gbuilder.WriteString("\n}...,") gbuilder.WriteString("\n}...,")
@@ -130,6 +151,7 @@ rest.WithPrefix("%s"),`, g.prefix)
"jwt": jwt, "jwt": jwt,
"signature": signature, "signature": signature,
"prefix": prefix, "prefix": prefix,
"timeout": timeout,
}); err != nil { }); err != nil {
return err return err
} }
@@ -139,8 +161,8 @@ rest.WithPrefix("%s"),`, g.prefix)
if err != nil { if err != nil {
return err return err
} }
routeFilename = routeFilename + ".go"
routeFilename = routeFilename + ".go"
filename := path.Join(dir, handlerDir, routeFilename) filename := path.Join(dir, handlerDir, routeFilename)
os.Remove(filename) os.Remove(filename)
@@ -152,7 +174,8 @@ rest.WithPrefix("%s"),`, g.prefix)
category: category, category: category,
templateFile: routesTemplateFile, templateFile: routesTemplateFile,
builtinTemplate: routesTemplate, builtinTemplate: routesTemplate,
data: map[string]string{ data: map[string]interface{}{
"hasTimeout": hasTimeout,
"importPackages": genRouteImports(rootPkg, api), "importPackages": genRouteImports(rootPkg, api),
"routesAdditions": strings.TrimSpace(builder.String()), "routesAdditions": strings.TrimSpace(builder.String()),
}, },
@@ -171,7 +194,8 @@ func genRouteImports(parentPkg string, api *spec.ApiSpec) string {
continue continue
} }
} }
importSet.AddStr(fmt.Sprintf("%s \"%s\"", toPrefix(folder), pathx.JoinPackages(parentPkg, handlerDir, folder))) importSet.AddStr(fmt.Sprintf("%s \"%s\"", toPrefix(folder),
pathx.JoinPackages(parentPkg, handlerDir, folder)))
} }
} }
imports := importSet.KeysStr() imports := importSet.KeysStr()
@@ -205,6 +229,8 @@ func getRoutes(api *spec.ApiSpec) ([]group, error) {
}) })
} }
groupedRoutes.timeout = g.GetAnnotation("timeout")
jwt := g.GetAnnotation("jwt") jwt := g.GetAnnotation("jwt")
if len(jwt) > 0 { if len(jwt) > 0 {
groupedRoutes.authName = jwt groupedRoutes.authName = jwt

View File

@@ -80,7 +80,7 @@ import com.google.gson.Gson
object {{with .Info}}{{.Title}}{{end}}{ object {{with .Info}}{{.Title}}{{end}}{
{{range .Types}} {{range .Types}}
data class {{.Name}}({{$length := (len .Members)}}{{range $i,$item := .Members}} data class {{.Name}}({{$length := (len .Members)}}{{range $i,$item := .Members}}
val {{with $item}}{{lowCamelCase .Name}}: {{parseType .Type}}{{end}}{{if ne $i (add $length -1)}},{{end}}{{end}} val {{with $item}}{{lowCamelCase .Name}}: {{parseType .Type.Name}}{{end}}{{if ne $i (add $length -1)}},{{end}}{{end}}
){{end}} ){{end}}
{{with .Service}} {{with .Service}}
{{range .Routes}}suspend fun {{routeToFuncName .Method .Path}}({{with .RequestType}}{{if ne .Name ""}} {{range .Routes}}suspend fun {{routeToFuncName .Method .Path}}({{with .RequestType}}{{if ne .Name ""}}

View File

@@ -67,8 +67,9 @@ func CreateServiceCommand(c *cli.Context) error {
home := c.String("home") home := c.String("home")
remote := c.String("remote") remote := c.String("remote")
branch := c.String("branch")
if len(remote) > 0 { if len(remote) > 0 {
repo, _ := util.CloneIntoGitHome(remote) repo, _ := util.CloneIntoGitHome(remote, branch)
if len(repo) > 0 { if len(repo) > 0 {
home = repo home = repo
} }

View File

@@ -19,7 +19,8 @@ type (
debug bool debug bool
log console.Console log console.Console
antlr.DefaultErrorListener antlr.DefaultErrorListener
src string src string
skipCheckTypeDeclaration bool
} }
// ParserOption defines an function with argument Parser // ParserOption defines an function with argument Parser
@@ -136,9 +137,11 @@ func (p *Parser) parse(filename, content string) (*Api, error) {
apiAstList = append(apiAstList, nestedApi) apiAstList = append(apiAstList, nestedApi)
} }
err = p.checkTypeDeclaration(apiAstList) if !p.skipCheckTypeDeclaration {
if err != nil { err = p.checkTypeDeclaration(apiAstList)
return nil, err if err != nil {
return nil, err
}
} }
allApi := p.memberFill(apiAstList) allApi := p.memberFill(apiAstList)
@@ -483,3 +486,9 @@ func WithParserPrefix(prefix string) ParserOption {
p.linePrefix = prefix p.linePrefix = prefix
} }
} }
func WithParserSkipCheckTypeDeclaration() ParserOption {
return func(p *Parser) {
p.skipCheckTypeDeclaration = true
}
}

View File

@@ -648,19 +648,19 @@ func (s *TypeStruct) Equal(dt interface{}) bool {
return false return false
} }
var expected, acual []*TypeField var expected, actual []*TypeField
expected = append(expected, s.Fields...) expected = append(expected, s.Fields...)
acual = append(acual, v.Fields...) actual = append(actual, v.Fields...)
sort.Slice(expected, func(i, j int) bool { sort.Slice(expected, func(i, j int) bool {
return expected[i].DataType.Expr().Line() < expected[j].DataType.Expr().Line() return expected[i].DataType.Expr().Line() < expected[j].DataType.Expr().Line()
}) })
sort.Slice(acual, func(i, j int) bool { sort.Slice(actual, func(i, j int) bool {
return acual[i].DataType.Expr().Line() < acual[j].DataType.Expr().Line() return actual[i].DataType.Expr().Line() < actual[j].DataType.Expr().Line()
}) })
for index, each := range expected { for index, each := range expected {
ac := acual[index] ac := actual[index]
if !each.Equal(ac) { if !each.Equal(ac) {
return false return false
} }

View File

@@ -12,7 +12,7 @@ import (
const ( const (
versionRegex = `(?m)"v[1-9][0-9]*"` versionRegex = `(?m)"v[1-9][0-9]*"`
importValueRegex = `(?m)"\/?(([a-zA-Z0-9.]+)+(\/?){1})+([a-zA-Z0-9]+)+\.api"` importValueRegex = `(?m)"\/?(?:[^/]+\/)*[^/]+.api"`
tagRegex = `(?m)\x60[a-z]+:".+"\x60` tagRegex = `(?m)\x60[a-z]+:".+"\x60`
) )

View File

@@ -21,8 +21,8 @@ func TestImportRegex(t *testing.T) {
{`"../foo/bar.api"`, true}, {`"../foo/bar.api"`, true},
{`"../../foo/bar.api"`, true}, {`"../../foo/bar.api"`, true},
{`"bar..api"`, false},
{`"//bar.api"`, false}, {`"//bar.api"`, false},
{`"/foo/foo_bar.api"`, true},
} }
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.value, func(t *testing.T) { t.Run(tt.value, func(t *testing.T) {

View File

@@ -8,6 +8,7 @@ import (
"bufio" "bufio"
"bytes" "bytes"
"fmt" "fmt"
"go/format"
"io/ioutil" "io/ioutil"
"log" "log"
"os" "os"
@@ -61,7 +62,12 @@ import "github.com/zeromicro/antlr"
} }
} }
err = ioutil.WriteFile(fp, buffer.Bytes(), os.ModePerm) src, err := format.Source(buffer.Bytes())
if err != nil {
fmt.Printf("%+v\n", err)
break
}
err = ioutil.WriteFile(fp, src, os.ModePerm)
if err != nil { if err != nil {
fmt.Printf("%+v\n", err) fmt.Printf("%+v\n", err)
} }

View File

@@ -33,9 +33,13 @@ func Parse(filename string) (*spec.ApiSpec, error) {
return spec, nil return spec, nil
} }
// ParseContent parses the api content func parseContent(content string, skipCheckTypeDeclaration bool, filename ...string) (*spec.ApiSpec, error) {
func ParseContent(content string, filename ...string) (*spec.ApiSpec, error) { var astParser *ast.Parser
astParser := ast.NewParser() if skipCheckTypeDeclaration {
astParser = ast.NewParser(ast.WithParserSkipCheckTypeDeclaration())
} else {
astParser = ast.NewParser()
}
ast, err := astParser.ParseContent(content, filename...) ast, err := astParser.ParseContent(content, filename...)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -51,6 +55,16 @@ func ParseContent(content string, filename ...string) (*spec.ApiSpec, error) {
return spec, nil return spec, nil
} }
// ParseContent parses the api content
func ParseContent(content string, filename ...string) (*spec.ApiSpec, error) {
return parseContent(content, false, filename...)
}
// ParseContentWithParserSkipCheckTypeDeclaration parses the api content with skip check type declaration
func ParseContentWithParserSkipCheckTypeDeclaration(content string, filename ...string) (*spec.ApiSpec, error) {
return parseContent(content, true, filename...)
}
func (p parser) convert2Spec() error { func (p parser) convert2Spec() error {
p.fillInfo() p.fillInfo()
p.fillSyntax() p.fillSyntax()

View File

@@ -557,7 +557,7 @@ service foo-api{
## 隐藏通道 ## 隐藏通道
隐藏通道目前主要为空符号,换行符号以及注释,这里我们只说注释,因为空白符号和换行符号我们目前拿来也无用。 隐藏通道目前主要为空符号,换行符号以及注释,这里我们只说注释,因为空白符号和换行符号我们目前拿来也无用。
### 单行注释 ### 单行注释
@@ -679,4 +679,4 @@ service foo-api{
*/ */
post /foo (Foo) returns (Foo) // route comment post /foo (Foo) returns (Foo) // route comment
} }
``` ```

View File

@@ -48,17 +48,15 @@ func Completion(c *cli.Context) error {
flag := magic flag := magic
err = ioutil.WriteFile(zshF, zsh, os.ModePerm) err = ioutil.WriteFile(zshF, zsh, os.ModePerm)
if err != nil { if err == nil {
return err flag |= flagZsh
} }
flag |= flagZsh
err = ioutil.WriteFile(bashF, bash, os.ModePerm) err = ioutil.WriteFile(bashF, bash, os.ModePerm)
if err != nil { if err == nil {
return err flag |= flagBash
} }
flag |= flagBash
buffer.WriteString(aurora.BrightGreen("generation auto completion success!\n").String()) buffer.WriteString(aurora.BrightGreen("generation auto completion success!\n").String())
buffer.WriteString(aurora.BrightGreen("executes the following script to setting shell:\n").String()) buffer.WriteString(aurora.BrightGreen("executes the following script to setting shell:\n").String())
switch flag { switch flag {

View File

@@ -24,14 +24,17 @@ const (
// Docker describes a dockerfile // Docker describes a dockerfile
type Docker struct { type Docker struct {
Chinese bool Chinese bool
GoRelPath string GoRelPath string
GoFile string GoFile string
ExeFile string ExeFile string
HasPort bool BaseImage string
Port int HasPort bool
Argument string Port int
Version string Argument string
Version string
HasTimezone bool
Timezone string
} }
// DockerCommand provides the entry for goctl docker // DockerCommand provides the entry for goctl docker
@@ -46,8 +49,10 @@ func DockerCommand(c *cli.Context) (err error) {
home := c.String("home") home := c.String("home")
version := c.String("version") version := c.String("version")
remote := c.String("remote") remote := c.String("remote")
branch := c.String("branch")
timezone := c.String("tz")
if len(remote) > 0 { if len(remote) > 0 {
repo, _ := util.CloneIntoGitHome(remote) repo, _ := util.CloneIntoGitHome(remote, branch)
if len(repo) > 0 { if len(repo) > 0 {
home = repo home = repo
} }
@@ -69,9 +74,10 @@ func DockerCommand(c *cli.Context) (err error) {
return fmt.Errorf("file %q not found", goFile) return fmt.Errorf("file %q not found", goFile)
} }
base := c.String("base")
port := c.Int("port") port := c.Int("port")
if _, err := os.Stat(etcDir); os.IsNotExist(err) { if _, err := os.Stat(etcDir); os.IsNotExist(err) {
return generateDockerfile(goFile, port, version) return generateDockerfile(goFile, base, port, version, timezone)
} }
cfg, err := findConfig(goFile, etcDir) cfg, err := findConfig(goFile, etcDir)
@@ -79,7 +85,7 @@ func DockerCommand(c *cli.Context) (err error) {
return err return err
} }
if err := generateDockerfile(goFile, port, version, "-f", "etc/"+cfg); err != nil { if err := generateDockerfile(goFile, base, port, version, timezone, "-f", "etc/"+cfg); err != nil {
return err return err
} }
@@ -120,7 +126,7 @@ func findConfig(file, dir string) (string, error) {
return files[0], nil return files[0], nil
} }
func generateDockerfile(goFile string, port int, version string, args ...string) error { func generateDockerfile(goFile, base string, port int, version, timezone string, args ...string) error {
projPath, err := getFilePath(filepath.Dir(goFile)) projPath, err := getFilePath(filepath.Dir(goFile))
if err != nil { if err != nil {
return err return err
@@ -149,14 +155,17 @@ func generateDockerfile(goFile string, port int, version string, args ...string)
_, offset := time.Now().Zone() _, offset := time.Now().Zone()
t := template.Must(template.New("dockerfile").Parse(text)) t := template.Must(template.New("dockerfile").Parse(text))
return t.Execute(out, Docker{ return t.Execute(out, Docker{
Chinese: offset == cstOffset, Chinese: offset == cstOffset,
GoRelPath: projPath, GoRelPath: projPath,
GoFile: goFile, GoFile: goFile,
ExeFile: pathx.FileNameWithoutExt(filepath.Base(goFile)), ExeFile: pathx.FileNameWithoutExt(filepath.Base(goFile)),
HasPort: port > 0, BaseImage: base,
Port: port, HasPort: port > 0,
Argument: builder.String(), Port: port,
Version: version, Argument: builder.String(),
Version: version,
HasTimezone: len(timezone) > 0,
Timezone: timezone,
}) })
} }

View File

@@ -13,10 +13,11 @@ const (
LABEL stage=gobuilder LABEL stage=gobuilder
ENV CGO_ENABLED 0 ENV CGO_ENABLED 0
ENV GOOS linux
{{if .Chinese}}ENV GOPROXY https://goproxy.cn,direct {{if .Chinese}}ENV GOPROXY https://goproxy.cn,direct
{{end}}{{if .HasTimezone}}
RUN apk update --no-cache && apk add --no-cache tzdata
{{end}} {{end}}
WORKDIR /build/zero WORKDIR /build
ADD go.mod . ADD go.mod .
ADD go.sum . ADD go.sum .
@@ -26,11 +27,12 @@ COPY . .
{{end}}RUN go build -ldflags="-s -w" -o /app/{{.ExeFile}} {{.GoRelPath}}/{{.GoFile}} {{end}}RUN go build -ldflags="-s -w" -o /app/{{.ExeFile}} {{.GoRelPath}}/{{.GoFile}}
FROM alpine FROM {{.BaseImage}}
RUN apk update --no-cache && apk add --no-cache ca-certificates tzdata
ENV TZ Asia/Shanghai
COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt
{{if .HasTimezone}}COPY --from=builder /usr/share/zoneinfo/{{.Timezone}} /usr/share/zoneinfo/{{.Timezone}}
ENV TZ {{.Timezone}}
{{end}}
WORKDIR /app WORKDIR /app
COPY --from=builder /app/{{.ExeFile}} /app/{{.ExeFile}}{{if .Argument}} COPY --from=builder /app/{{.ExeFile}} /app/{{.ExeFile}}{{if .Argument}}
COPY --from=builder /app/etc /app/etc{{end}} COPY --from=builder /app/etc /app/etc{{end}}

View File

@@ -40,51 +40,53 @@ var bins = []bin{
func Check(ctx *cli.Context) error { func Check(ctx *cli.Context) error {
install := ctx.Bool("install") install := ctx.Bool("install")
force := ctx.Bool("force") force := ctx.Bool("force")
return check(install, force) verbose := ctx.Bool("verbose")
return Prepare(install, force, verbose)
} }
func check(install, force bool) error { func Prepare(install, force, verbose bool) error {
log := console.NewColorConsole(verbose)
pending := true pending := true
console.Info("[goctl-env]: preparing to check env") log.Info("[goctl-env]: preparing to check env")
defer func() { defer func() {
if p := recover(); p != nil { if p := recover(); p != nil {
console.Error("%+v", p) log.Error("%+v", p)
return return
} }
if pending { if pending {
console.Success("\n[goctl-env]: congratulations! your goctl environment is ready!") log.Success("\n[goctl-env]: congratulations! your goctl environment is ready!")
} else { } else {
console.Error(` log.Error(`
[goctl-env]: check env finish, some dependencies is not found in PATH, you can execute [goctl-env]: check env finish, some dependencies is not found in PATH, you can execute
command 'goctl env check --install' or 'goctl env install' to install it, for details, command 'goctl env check --install' to install it, for details, please execute command
please see 'goctl env check --help' or 'goctl env install --help'`) 'goctl env check --help'`)
} }
}() }()
for _, e := range bins { for _, e := range bins {
time.Sleep(200 * time.Millisecond) time.Sleep(200 * time.Millisecond)
console.Info("") log.Info("")
console.Info("[goctl-env]: looking up %q", e.name) log.Info("[goctl-env]: looking up %q", e.name)
if e.exists { if e.exists {
console.Success("[goctl-env]: %q is installed", e.name) log.Success("[goctl-env]: %q is installed", e.name)
continue continue
} }
console.Warning("[goctl-env]: %q is not found in PATH", e.name) log.Warning("[goctl-env]: %q is not found in PATH", e.name)
if install { if install {
install := func() { install := func() {
console.Info("[goctl-env]: preparing to install %q", e.name) log.Info("[goctl-env]: preparing to install %q", e.name)
path, err := e.get(env.Get(env.GoctlCache)) path, err := e.get(env.Get(env.GoctlCache))
if err != nil { if err != nil {
console.Error("[goctl-env]: an error interrupted the installation: %+v", err) log.Error("[goctl-env]: an error interrupted the installation: %+v", err)
pending = false pending = false
} else { } else {
console.Success("[goctl-env]: %q is already installed in %q", e.name, path) log.Success("[goctl-env]: %q is already installed in %q", e.name, path)
} }
} }
if force { if force {
install() install()
continue continue
} }
console.Info("[goctl-env]: do you want to install %q [y: YES, n: No]", e.name) log.Info("[goctl-env]: do you want to install %q [y: YES, n: No]", e.name)
for { for {
var in string var in string
fmt.Scanln(&in) fmt.Scanln(&in)
@@ -95,10 +97,10 @@ please see 'goctl env check --help' or 'goctl env install --help'`)
brk = true brk = true
case strings.EqualFold(in, "n"): case strings.EqualFold(in, "n"):
pending = false pending = false
console.Info("[goctl-env]: %q installation is ignored", e.name) log.Info("[goctl-env]: %q installation is ignored", e.name)
brk = true brk = true
default: default:
console.Error("[goctl-env]: invalid input, input 'y' for yes, 'n' for no") log.Error("[goctl-env]: invalid input, input 'y' for yes, 'n' for no")
} }
if brk { if brk {
break break

View File

@@ -13,5 +13,5 @@ require (
github.com/urfave/cli v1.22.5 github.com/urfave/cli v1.22.5
github.com/zeromicro/antlr v0.0.1 github.com/zeromicro/antlr v0.0.1
github.com/zeromicro/ddl-parser v1.0.3 github.com/zeromicro/ddl-parser v1.0.3
github.com/zeromicro/go-zero v1.3.0 github.com/zeromicro/go-zero v1.3.1
) )

View File

@@ -36,7 +36,6 @@ github.com/ClickHouse/clickhouse-go v1.5.1/go.mod h1:EaI/sW7Azgz9UATzd5ZdZHRUhHg
github.com/DATA-DOG/go-sqlmock v1.5.0 h1:Shsta01QNfFxHCfpW6YH2STWB0MudeXXEWMr20OEh60= github.com/DATA-DOG/go-sqlmock v1.5.0 h1:Shsta01QNfFxHCfpW6YH2STWB0MudeXXEWMr20OEh60=
github.com/DATA-DOG/go-sqlmock v1.5.0/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= github.com/DATA-DOG/go-sqlmock v1.5.0/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM=
github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ=
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
github.com/Shopify/sarama v1.30.0/go.mod h1:zujlQQx1kzHsh4jfV1USnptCQrHAEZ2Hk8fTKCulPVs= github.com/Shopify/sarama v1.30.0/go.mod h1:zujlQQx1kzHsh4jfV1USnptCQrHAEZ2Hk8fTKCulPVs=
@@ -54,13 +53,15 @@ github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kd
github.com/antlr/antlr4/runtime/Go/antlr v0.0.0-20210521184019-c5ad59b459ec h1:EEyRvzmpEUZ+I8WmD5cw/vY8EqhambkOqy5iFr0908A= github.com/antlr/antlr4/runtime/Go/antlr v0.0.0-20210521184019-c5ad59b459ec h1:EEyRvzmpEUZ+I8WmD5cw/vY8EqhambkOqy5iFr0908A=
github.com/antlr/antlr4/runtime/Go/antlr v0.0.0-20210521184019-c5ad59b459ec/go.mod h1:F7bn7fEU90QkQ3tnmaTx3LTKLEDqnwWODIYppRQ5hnY= github.com/antlr/antlr4/runtime/Go/antlr v0.0.0-20210521184019-c5ad59b459ec/go.mod h1:F7bn7fEU90QkQ3tnmaTx3LTKLEDqnwWODIYppRQ5hnY=
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
github.com/bkaradzic/go-lz4 v1.0.0/go.mod h1:0YdlkowM3VswSROI7qDxhRvJ3sLhlFrRRwjwegp5jy4= github.com/bkaradzic/go-lz4 v1.0.0/go.mod h1:0YdlkowM3VswSROI7qDxhRvJ3sLhlFrRRwjwegp5jy4=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE=
github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
@@ -69,7 +70,6 @@ github.com/cloudflare/golz4 v0.0.0-20150217214814-ef862a3cdc58/go.mod h1:EOBUe0h
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI=
github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
@@ -82,6 +82,8 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM= github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM=
github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE=
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
@@ -97,7 +99,6 @@ github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.m
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ=
github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
@@ -138,8 +139,8 @@ github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL9
github.com/go-openapi/spec v0.19.3/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo= github.com/go-openapi/spec v0.19.3/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo=
github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
github.com/go-redis/redis v6.15.9+incompatible h1:K0pv1D7EQUjfyoMql+r/jZqCLizCGKFlFgcHWWmHQjg= github.com/go-redis/redis/v8 v8.11.4 h1:kHoYkfZP6+pe04aFTnhDH6GDROa5yJdHJVNxV3F46Tg=
github.com/go-redis/redis v6.15.9+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA= github.com/go-redis/redis/v8 v8.11.4/go.mod h1:2Z2wHZXdQpCDXEGzqMockDpNyYvi2l4Pxt6RJr792+w=
github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE= github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE=
github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
@@ -327,7 +328,6 @@ github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPx
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI=
github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
@@ -358,11 +358,11 @@ github.com/zeromicro/antlr v0.0.1 h1:CQpIn/dc0pUjgGQ81y98s/NGOm2Hfru2NNio2I9mQgk
github.com/zeromicro/antlr v0.0.1/go.mod h1:nfpjEwFR6Q4xGDJMcZnCL9tEfQRgszMwu3rDz2Z+p5M= github.com/zeromicro/antlr v0.0.1/go.mod h1:nfpjEwFR6Q4xGDJMcZnCL9tEfQRgszMwu3rDz2Z+p5M=
github.com/zeromicro/ddl-parser v1.0.3 h1:hFecpbt0oPQMhHAbqG1tz78MUepHUnOkFJp1dvRBFyc= github.com/zeromicro/ddl-parser v1.0.3 h1:hFecpbt0oPQMhHAbqG1tz78MUepHUnOkFJp1dvRBFyc=
github.com/zeromicro/ddl-parser v1.0.3/go.mod h1:ISU/8NuPyEpl9pa17Py9TBPetMjtsiHrb9f5XGiYbo8= github.com/zeromicro/ddl-parser v1.0.3/go.mod h1:ISU/8NuPyEpl9pa17Py9TBPetMjtsiHrb9f5XGiYbo8=
github.com/zeromicro/go-zero v1.3.0 h1:Eyn36yBtR043sm4YKmxR6eS3UA/GtZDktQ+UqIJ3Lm0= github.com/zeromicro/go-zero v1.3.1 h1:uVkELq9kosgRZBSERb+eG7+oY2E+BEpOJW5vZZ354Cs=
github.com/zeromicro/go-zero v1.3.0/go.mod h1:Hy4o1VFAt32lXaQMbaBhoFeZjA/rJqJ4PTGNdGsURcc= github.com/zeromicro/go-zero v1.3.1/go.mod h1:JsgCzJSUcjZl487xtqWHzYFa7Wl4f5Gi3lcteOWgNRA=
go.etcd.io/etcd/api/v3 v3.5.1/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs= go.etcd.io/etcd/api/v3 v3.5.2/go.mod h1:5GB2vv4A4AOn3yk7MftYGHkUfGtDHnEraIjym4dYz5A=
go.etcd.io/etcd/client/pkg/v3 v3.5.1/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= go.etcd.io/etcd/client/pkg/v3 v3.5.2/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g=
go.etcd.io/etcd/client/v3 v3.5.1/go.mod h1:OnjH4M8OnAotwaB2l9bVgZzRFKru7/ZMoS46OtKyd3Q= go.etcd.io/etcd/client/v3 v3.5.2/go.mod h1:kOOaWFFgHygyT0WlSmL8TJiXmMysO/nNUlEsSsN6W4o=
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
@@ -377,11 +377,15 @@ go.opentelemetry.io/otel/trace v1.3.0 h1:doy8Hzb1RJ+I3yFhtDmwNc7tIyw1tNMOIsyPzp1
go.opentelemetry.io/otel/trace v1.3.0/go.mod h1:c/VDhno8888bvQYmbYLqe41/Ldmr/KKunbvWM4/fEjk= go.opentelemetry.io/otel/trace v1.3.0/go.mod h1:c/VDhno8888bvQYmbYLqe41/Ldmr/KKunbvWM4/fEjk=
go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
go.uber.org/automaxprocs v1.4.0 h1:CpDZl6aOlLhReez+8S3eEotD7Jx0Os++lemPlMULQP0= go.uber.org/automaxprocs v1.4.0 h1:CpDZl6aOlLhReez+8S3eEotD7Jx0Os++lemPlMULQP0=
go.uber.org/automaxprocs v1.4.0/go.mod h1:/mTEdr7LvHhs0v7mjdxDreTz1OG5zdZGqgOnhWiR/+Q= go.uber.org/automaxprocs v1.4.0/go.mod h1:/mTEdr7LvHhs0v7mjdxDreTz1OG5zdZGqgOnhWiR/+Q=
go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
go.uber.org/goleak v1.1.12/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/goleak v1.1.12/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
go.uber.org/multierr v1.8.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak=
go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo= go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo=
go.uber.org/zap v1.21.0/go.mod h1:wjWOCqI0f2ZZrJF/UufIOkiC8ii6tm1iqIsLo76RfJw=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
@@ -455,8 +459,8 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk=
golang.org/x/net v0.0.0-20210917221730-978cfadd31cf/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210917221730-978cfadd31cf/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220114011407-0dd24b26b47d h1:1n1fc535VhN8SYtD4cDUyNlfpAF2ROMM9+11equK3hs= golang.org/x/net v0.0.0-20220225172249-27dd8689420f h1:oA4XRj0qtSt8Yo1Zms0CUlsT3KG69V2UGQWPBxujDmc=
golang.org/x/net v0.0.0-20220114011407-0dd24b26b47d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@@ -516,9 +520,11 @@ golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220111092808-5a964db01320 h1:0jf+tOCoZ3LyutmCOWpVni1chK4VfFLhRsDK7MhqGRY= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220111092808-5a964db01320/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9 h1:nhht2DYV/Sn3qOayu8lM+cU1ii9sTLUeBQwQQfUHtrs=
golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@@ -610,7 +616,7 @@ google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfG
google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=
google.golang.org/genproto v0.0.0-20220112215332-a9c7c0acf9f2/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20220228195345-15d65a4533f7/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
@@ -622,9 +628,8 @@ google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8
google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0=
google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34=
google.golang.org/grpc v1.41.0/go.mod h1:U3l9uK9J0sini8mHphKoXyaqDA/8VyGnDee1zzIUK6k= google.golang.org/grpc v1.41.0/go.mod h1:U3l9uK9J0sini8mHphKoXyaqDA/8VyGnDee1zzIUK6k=
google.golang.org/grpc v1.43.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= google.golang.org/grpc v1.44.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=

View File

@@ -23,7 +23,6 @@ import (
"github.com/zeromicro/go-zero/tools/goctl/completion" "github.com/zeromicro/go-zero/tools/goctl/completion"
"github.com/zeromicro/go-zero/tools/goctl/docker" "github.com/zeromicro/go-zero/tools/goctl/docker"
"github.com/zeromicro/go-zero/tools/goctl/env" "github.com/zeromicro/go-zero/tools/goctl/env"
"github.com/zeromicro/go-zero/tools/goctl/internal/errorx"
"github.com/zeromicro/go-zero/tools/goctl/internal/version" "github.com/zeromicro/go-zero/tools/goctl/internal/version"
"github.com/zeromicro/go-zero/tools/goctl/kube" "github.com/zeromicro/go-zero/tools/goctl/kube"
"github.com/zeromicro/go-zero/tools/goctl/migrate" "github.com/zeromicro/go-zero/tools/goctl/migrate"
@@ -70,6 +69,10 @@ var commands = []cli.Command{
Name: "force, f", Name: "force, f",
Usage: "silent installation of non-existent dependencies", Usage: "silent installation of non-existent dependencies",
}, },
cli.BoolFlag{
Name: "verbose, v",
Usage: "enable log output",
},
}, },
Action: env.Check, Action: env.Check,
}, },
@@ -111,6 +114,10 @@ var commands = []cli.Command{
"if they are, --remote has higher priority\n\tThe git repo directory must be consistent with the " + "if they are, --remote has higher priority\n\tThe git repo directory must be consistent with the " +
"https://github.com/zeromicro/go-zero-template directory structure", "https://github.com/zeromicro/go-zero-template directory structure",
}, },
cli.StringFlag{
Name: "branch",
Usage: "the branch of the remote repo, it does work with --remote",
},
}, },
Action: apigen.ApiCommand, Action: apigen.ApiCommand,
Subcommands: []cli.Command{ Subcommands: []cli.Command{
@@ -130,6 +137,10 @@ var commands = []cli.Command{
"if they are, --remote has higher priority\n\tThe git repo directory must be consistent with the " + "if they are, --remote has higher priority\n\tThe git repo directory must be consistent with the " +
"https://github.com/zeromicro/go-zero-template directory structure", "https://github.com/zeromicro/go-zero-template directory structure",
}, },
cli.StringFlag{
Name: "branch",
Usage: "the branch of the remote repo, it does work with --remote",
},
cli.StringFlag{ cli.StringFlag{
Name: "style", Name: "style",
Usage: "the file naming format, see [https://github.com/zeromicro/go-zero/blob/master/tools/goctl/config/readme.md]", Usage: "the file naming format, see [https://github.com/zeromicro/go-zero/blob/master/tools/goctl/config/readme.md]",
@@ -152,6 +163,10 @@ var commands = []cli.Command{
Name: "stdin", Name: "stdin",
Usage: "use stdin to input api doc content, press \"ctrl + d\" to send EOF", Usage: "use stdin to input api doc content, press \"ctrl + d\" to send EOF",
}, },
cli.BoolFlag{
Name: "declare",
Usage: "use to skip check api types already declare",
},
}, },
Action: format.GoFormatApi, Action: format.GoFormatApi,
}, },
@@ -209,6 +224,10 @@ var commands = []cli.Command{
"if they are, --remote has higher priority\n\tThe git repo directory must be consistent with the " + "if they are, --remote has higher priority\n\tThe git repo directory must be consistent with the " +
"https://github.com/zeromicro/go-zero-template directory structure", "https://github.com/zeromicro/go-zero-template directory structure",
}, },
cli.StringFlag{
Name: "branch",
Usage: "the branch of the remote repo, it does work with --remote",
},
}, },
Action: gogen.GoCommand, Action: gogen.GoCommand,
}, },
@@ -266,6 +285,14 @@ var commands = []cli.Command{
Name: "api", Name: "api",
Usage: "the api file", Usage: "the api file",
}, },
cli.BoolFlag{
Name: "legacy",
Usage: "legacy generator for flutter v1",
},
cli.StringFlag{
Name: "hostname",
Usage: "hostname of the server",
},
}, },
Action: dartgen.DartCommand, Action: dartgen.DartCommand,
}, },
@@ -321,6 +348,11 @@ var commands = []cli.Command{
Name: "go", Name: "go",
Usage: "the file that contains main function", Usage: "the file that contains main function",
}, },
cli.StringFlag{
Name: "base",
Usage: "the base image to build the docker image, default scratch",
Value: "scratch",
},
cli.IntFlag{ cli.IntFlag{
Name: "port", Name: "port",
Usage: "the port to expose, default none", Usage: "the port to expose, default none",
@@ -337,10 +369,19 @@ var commands = []cli.Command{
"if they are, --remote has higher priority\n\tThe git repo directory must be consistent with the " + "if they are, --remote has higher priority\n\tThe git repo directory must be consistent with the " +
"https://github.com/zeromicro/go-zero-template directory structure", "https://github.com/zeromicro/go-zero-template directory structure",
}, },
cli.StringFlag{
Name: "branch",
Usage: "the branch of the remote repo, it does work with --remote",
},
cli.StringFlag{ cli.StringFlag{
Name: "version", Name: "version",
Usage: "the goctl builder golang image version", Usage: "the goctl builder golang image version",
}, },
cli.StringFlag{
Name: "tz",
Usage: "the timezone of the container",
Value: "Asia/Shanghai",
},
}, },
Action: docker.DockerCommand, Action: docker.DockerCommand,
}, },
@@ -437,6 +478,10 @@ var commands = []cli.Command{
"if they are, --remote has higher priority\n\tThe git repo directory must be consistent with the " + "if they are, --remote has higher priority\n\tThe git repo directory must be consistent with the " +
"https://github.com/zeromicro/go-zero-template directory structure", "https://github.com/zeromicro/go-zero-template directory structure",
}, },
cli.StringFlag{
Name: "branch",
Usage: "the branch of the remote repo, it does work with --remote",
},
cli.StringFlag{ cli.StringFlag{
Name: "serviceAccount", Name: "serviceAccount",
Usage: "the ServiceAccount for the deployment", Usage: "the ServiceAccount for the deployment",
@@ -451,9 +496,8 @@ var commands = []cli.Command{
Usage: "generate rpc code", Usage: "generate rpc code",
Subcommands: []cli.Command{ Subcommands: []cli.Command{
{ {
Name: "new", Name: "new",
Usage: `generate rpc demo service`, Usage: `generate rpc demo service`,
Description: aurora.Yellow(`deprecated: zrpc code generation use "goctl rpc protoc" instead, for the details see "goctl rpc protoc --help"`).String(),
Flags: []cli.Flag{ Flags: []cli.Flag{
cli.StringFlag{ cli.StringFlag{
Name: "style", Name: "style",
@@ -474,6 +518,14 @@ var commands = []cli.Command{
"if they are, --remote has higher priority\n\tThe git repo directory must be consistent with the " + "if they are, --remote has higher priority\n\tThe git repo directory must be consistent with the " +
"https://github.com/zeromicro/go-zero-template directory structure", "https://github.com/zeromicro/go-zero-template directory structure",
}, },
cli.StringFlag{
Name: "branch",
Usage: "the branch of the remote repo, it does work with --remote",
},
cli.BoolFlag{
Name: "verbose, v",
Usage: "enable log output",
},
}, },
Action: rpc.RPCNew, Action: rpc.RPCNew,
}, },
@@ -496,6 +548,10 @@ var commands = []cli.Command{
"if they are, --remote has higher priority\n\tThe git repo directory must be consistent with the " + "if they are, --remote has higher priority\n\tThe git repo directory must be consistent with the " +
"https://github.com/zeromicro/go-zero-template directory structure", "https://github.com/zeromicro/go-zero-template directory structure",
}, },
cli.StringFlag{
Name: "branch",
Usage: "the branch of the remote repo, it does work with --remote",
},
}, },
Action: rpc.RPCTemplate, Action: rpc.RPCTemplate,
}, },
@@ -506,22 +562,30 @@ var commands = []cli.Command{
Description: "for details, see https://go-zero.dev/cn/goctl-rpc.html", Description: "for details, see https://go-zero.dev/cn/goctl-rpc.html",
Action: rpc.ZRPC, Action: rpc.ZRPC,
Flags: []cli.Flag{ Flags: []cli.Flag{
cli.StringFlag{ cli.StringSliceFlag{
Name: "go_out", Name: "go_out",
Hidden: true, Hidden: true,
}, },
cli.StringFlag{ cli.StringSliceFlag{
Name: "go-grpc_out", Name: "go-grpc_out",
Hidden: true, Hidden: true,
}, },
cli.StringFlag{ cli.StringSliceFlag{
Name: "go_opt", Name: "go_opt",
Hidden: true, Hidden: true,
}, },
cli.StringFlag{ cli.StringSliceFlag{
Name: "go-grpc_opt", Name: "go-grpc_opt",
Hidden: true, Hidden: true,
}, },
cli.StringSliceFlag{
Name: "plugin",
Hidden: true,
},
cli.StringSliceFlag{
Name: "proto_path,I",
Hidden: true,
},
cli.StringFlag{ cli.StringFlag{
Name: "zrpc_out", Name: "zrpc_out",
Usage: "the zrpc output directory", Usage: "the zrpc output directory",
@@ -540,50 +604,15 @@ var commands = []cli.Command{
"if they are, --remote has higher priority\n\tThe git repo directory must be consistent with the " + "if they are, --remote has higher priority\n\tThe git repo directory must be consistent with the " +
"https://github.com/zeromicro/go-zero-template directory structure", "https://github.com/zeromicro/go-zero-template directory structure",
}, },
},
},
{
Name: "proto",
Usage: `generate rpc from proto`,
Description: aurora.Yellow(`deprecated: zrpc code generation use "goctl rpc protoc" instead, for the details see "goctl rpc protoc --help"`).String(),
Flags: []cli.Flag{
cli.StringFlag{ cli.StringFlag{
Name: "src, s", Name: "branch",
Usage: "the file path of the proto source file", Usage: "the branch of the remote repo, it does work with --remote",
},
cli.StringSliceFlag{
Name: "proto_path, I",
Usage: `native command of protoc, specify the directory in which to search for imports. [optional]`,
},
cli.StringSliceFlag{
Name: "go_opt",
Usage: `native command of protoc-gen-go, specify the mapping from proto to go, eg --go_opt=proto_import=go_package_import. [optional]`,
},
cli.StringFlag{
Name: "dir, d",
Usage: `the target path of the code`,
},
cli.StringFlag{
Name: "style",
Usage: "the file naming format, see [https://github.com/zeromicro/go-zero/tree/master/tools/goctl/config/readme.md]",
}, },
cli.BoolFlag{ cli.BoolFlag{
Name: "idea", Name: "verbose, v",
Usage: "whether the command execution environment is from idea plugin. [optional]", Usage: "enable log output",
},
cli.StringFlag{
Name: "home",
Usage: "the goctl home path of the template, --home and --remote cannot be set at the same time, " +
"if they are, --remote has higher priority",
},
cli.StringFlag{
Name: "remote",
Usage: "the remote git repo of the template, --home and --remote cannot be set at the same time, " +
"if they are, --remote has higher priority\n\tThe git repo directory must be consistent with the " +
"https://github.com/zeromicro/go-zero-template directory structure",
}, },
}, },
Action: rpc.RPC,
}, },
}, },
}, },
@@ -634,6 +663,10 @@ var commands = []cli.Command{
"if they are, --remote has higher priority\n\tThe git repo directory must be consistent with the " + "if they are, --remote has higher priority\n\tThe git repo directory must be consistent with the " +
"https://github.com/zeromicro/go-zero-template directory structure", "https://github.com/zeromicro/go-zero-template directory structure",
}, },
cli.StringFlag{
Name: "branch",
Usage: "the branch of the remote repo, it does work with --remote",
},
}, },
Action: model.MysqlDDL, Action: model.MysqlDDL,
}, },
@@ -676,6 +709,10 @@ var commands = []cli.Command{
"if they are, --remote has higher priority\n\tThe git repo directory must be consistent with the " + "if they are, --remote has higher priority\n\tThe git repo directory must be consistent with the " +
"https://github.com/zeromicro/go-zero-template directory structure", "https://github.com/zeromicro/go-zero-template directory structure",
}, },
cli.StringFlag{
Name: "branch",
Usage: "the branch of the remote repo, it does work with --remote",
},
}, },
Action: model.MySqlDataSource, Action: model.MySqlDataSource,
}, },
@@ -728,6 +765,10 @@ var commands = []cli.Command{
"if they are, --remote has higher priority\n\tThe git repo directory must be consistent with the " + "if they are, --remote has higher priority\n\tThe git repo directory must be consistent with the " +
"https://github.com/zeromicro/go-zero-template directory structure", "https://github.com/zeromicro/go-zero-template directory structure",
}, },
cli.StringFlag{
Name: "branch",
Usage: "the branch of the remote repo, it does work with --remote",
},
}, },
Action: model.PostgreSqlDataSource, Action: model.PostgreSqlDataSource,
}, },
@@ -764,6 +805,10 @@ var commands = []cli.Command{
"if they are, --remote has higher priority\n\tThe git repo directory must be consistent with the " + "if they are, --remote has higher priority\n\tThe git repo directory must be consistent with the " +
"https://github.com/zeromicro/go-zero-template directory structure", "https://github.com/zeromicro/go-zero-template directory structure",
}, },
cli.StringFlag{
Name: "branch",
Usage: "the branch of the remote repo, it does work with --remote",
},
}, },
Action: mongo.Action, Action: mongo.Action,
}, },
@@ -860,7 +905,7 @@ func main() {
// cli already print error messages. // cli already print error messages.
if err := app.Run(os.Args); err != nil { if err := app.Run(os.Args); err != nil {
fmt.Println(aurora.Red(errorx.Wrap(err).Error())) fmt.Println(aurora.Red(err.Error()))
os.Exit(codeFailure) os.Exit(codeFailure)
} }
} }

View File

@@ -6,7 +6,7 @@ import (
) )
// BuildVersion is the version of goctl. // BuildVersion is the version of goctl.
const BuildVersion = "1.3.2" const BuildVersion = "1.3.4"
var tag = map[string]int{"pre-alpha": 0, "alpha": 1, "pre-bata": 2, "beta": 3, "released": 4, "": 5} var tag = map[string]int{"pre-alpha": 0, "alpha": 1, "pre-bata": 2, "beta": 3, "released": 4, "": 5}

View File

@@ -44,8 +44,9 @@ func DeploymentCommand(c *cli.Context) error {
nodePort := c.Int("nodePort") nodePort := c.Int("nodePort")
home := c.String("home") home := c.String("home")
remote := c.String("remote") remote := c.String("remote")
branch := c.String("branch")
if len(remote) > 0 { if len(remote) > 0 {
repo, _ := util.CloneIntoGitHome(remote) repo, _ := util.CloneIntoGitHome(remote, branch)
if len(repo) > 0 { if len(repo) > 0 {
home = repo home = repo
} }

View File

@@ -20,8 +20,9 @@ func Action(ctx *cli.Context) error {
s := ctx.String("style") s := ctx.String("style")
home := ctx.String("home") home := ctx.String("home")
remote := ctx.String("remote") remote := ctx.String("remote")
branch := ctx.String("branch")
if len(remote) > 0 { if len(remote) > 0 {
repo, _ := file.CloneIntoGitHome(remote) repo, _ := file.CloneIntoGitHome(remote, branch)
if len(repo) > 0 { if len(repo) > 0 {
home = repo home = repo
} }

View File

@@ -30,6 +30,8 @@ const (
flagDatabase = "database" flagDatabase = "database"
flagSchema = "schema" flagSchema = "schema"
flagHome = "home" flagHome = "home"
flagRemote = "remote"
flagBranch = "branch"
) )
var errNotMatched = errors.New("sql not matched") var errNotMatched = errors.New("sql not matched")
@@ -43,9 +45,10 @@ func MysqlDDL(ctx *cli.Context) error {
style := ctx.String(flagStyle) style := ctx.String(flagStyle)
database := ctx.String(flagDatabase) database := ctx.String(flagDatabase)
home := ctx.String(flagHome) home := ctx.String(flagHome)
remote := ctx.String("remote") remote := ctx.String(flagRemote)
branch := ctx.String(flagBranch)
if len(remote) > 0 { if len(remote) > 0 {
repo, _ := file.CloneIntoGitHome(remote) repo, _ := file.CloneIntoGitHome(remote, branch)
if len(repo) > 0 { if len(repo) > 0 {
home = repo home = repo
} }
@@ -68,10 +71,11 @@ func MySqlDataSource(ctx *cli.Context) error {
cache := ctx.Bool(flagCache) cache := ctx.Bool(flagCache)
idea := ctx.Bool(flagIdea) idea := ctx.Bool(flagIdea)
style := ctx.String(flagStyle) style := ctx.String(flagStyle)
home := ctx.String("home") home := ctx.String(flagHome)
remote := ctx.String("remote") remote := ctx.String(flagRemote)
branch := ctx.String(flagBranch)
if len(remote) > 0 { if len(remote) > 0 {
repo, _ := file.CloneIntoGitHome(remote) repo, _ := file.CloneIntoGitHome(remote, branch)
if len(repo) > 0 { if len(repo) > 0 {
home = repo home = repo
} }
@@ -97,10 +101,11 @@ func PostgreSqlDataSource(ctx *cli.Context) error {
idea := ctx.Bool(flagIdea) idea := ctx.Bool(flagIdea)
style := ctx.String(flagStyle) style := ctx.String(flagStyle)
schema := ctx.String(flagSchema) schema := ctx.String(flagSchema)
home := ctx.String("home") home := ctx.String(flagHome)
remote := ctx.String("remote") remote := ctx.String(flagRemote)
branch := ctx.String(flagBranch)
if len(remote) > 0 { if len(remote) > 0 {
repo, _ := file.CloneIntoGitHome(remote) repo, _ := file.CloneIntoGitHome(remote, branch)
if len(repo) > 0 { if len(repo) > 0 {
home = repo home = repo
} }

View File

@@ -20,16 +20,13 @@ import (
"github.com/zeromicro/go-zero/tools/goctl/util/stringx" "github.com/zeromicro/go-zero/tools/goctl/util/stringx"
) )
const ( const pwd = "."
pwd = "."
createTableFlag = `(?m)^(?i)CREATE\s+TABLE` // ignore case
)
type ( type (
defaultGenerator struct { defaultGenerator struct {
// source string
dir string
console.Console console.Console
// source string
dir string
pkg string pkg string
cfg *config.Config cfg *config.Config
isPostgreSql bool isPostgreSql bool
@@ -48,6 +45,12 @@ type (
updateCode string updateCode string
deleteCode string deleteCode string
cacheExtra string cacheExtra string
tableName string
}
codeTuple struct {
modelCode string
modelCustomCode string
} }
) )
@@ -109,7 +112,7 @@ func (g *defaultGenerator) StartFromDDL(filename string, withCache bool, databas
} }
func (g *defaultGenerator) StartFromInformationSchema(tables map[string]*model.Table, withCache bool) error { func (g *defaultGenerator) StartFromInformationSchema(tables map[string]*model.Table, withCache bool) error {
m := make(map[string]string) m := make(map[string]*codeTuple)
for _, each := range tables { for _, each := range tables {
table, err := parser.ConvertDataType(each) table, err := parser.ConvertDataType(each)
if err != nil { if err != nil {
@@ -120,14 +123,21 @@ func (g *defaultGenerator) StartFromInformationSchema(tables map[string]*model.T
if err != nil { if err != nil {
return err return err
} }
customCode, err := g.genModelCustom(*table, withCache)
if err != nil {
return err
}
m[table.Name.Source()] = code m[table.Name.Source()] = &codeTuple{
modelCode: code,
modelCustomCode: customCode,
}
} }
return g.createFile(m) return g.createFile(m)
} }
func (g *defaultGenerator) createFile(modelList map[string]string) error { func (g *defaultGenerator) createFile(modelList map[string]*codeTuple) error {
dirAbs, err := filepath.Abs(g.dir) dirAbs, err := filepath.Abs(g.dir)
if err != nil { if err != nil {
return err return err
@@ -140,20 +150,28 @@ func (g *defaultGenerator) createFile(modelList map[string]string) error {
return err return err
} }
for tableName, code := range modelList { for tableName, codes := range modelList {
tn := stringx.From(tableName) tn := stringx.From(tableName)
modelFilename, err := format.FileNamingFormat(g.cfg.NamingFormat, fmt.Sprintf("%s_model", tn.Source())) modelFilename, err := format.FileNamingFormat(g.cfg.NamingFormat,
fmt.Sprintf("%s_model", tn.Source()))
if err != nil { if err != nil {
return err return err
} }
name := util.SafeString(modelFilename) + ".go" name := util.SafeString(modelFilename) + "_gen.go"
filename := filepath.Join(dirAbs, name) filename := filepath.Join(dirAbs, name)
err = ioutil.WriteFile(filename, []byte(codes.modelCode), os.ModePerm)
if err != nil {
return err
}
name = util.SafeString(modelFilename) + ".go"
filename = filepath.Join(dirAbs, name)
if pathx.FileExists(filename) { if pathx.FileExists(filename) {
g.Warning("%s already exists, ignored.", name) g.Warning("%s already exists, ignored.", name)
continue continue
} }
err = ioutil.WriteFile(filename, []byte(code), os.ModePerm) err = ioutil.WriteFile(filename, []byte(codes.modelCustomCode), os.ModePerm)
if err != nil { if err != nil {
return err return err
} }
@@ -183,8 +201,9 @@ func (g *defaultGenerator) createFile(modelList map[string]string) error {
} }
// ret1: key-table name,value-code // ret1: key-table name,value-code
func (g *defaultGenerator) genFromDDL(filename string, withCache bool, database string) (map[string]string, error) { func (g *defaultGenerator) genFromDDL(filename string, withCache bool, database string) (
m := make(map[string]string) map[string]*codeTuple, error) {
m := make(map[string]*codeTuple)
tables, err := parser.Parse(filename, database) tables, err := parser.Parse(filename, database)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -195,8 +214,15 @@ func (g *defaultGenerator) genFromDDL(filename string, withCache bool, database
if err != nil { if err != nil {
return nil, err return nil, err
} }
customCode, err := g.genModelCustom(*e, withCache)
if err != nil {
return nil, err
}
m[e.Name.Source()] = code m[e.Name.Source()] = &codeTuple{
modelCode: code,
modelCustomCode: customCode,
}
} }
return m, nil return m, nil
@@ -223,7 +249,7 @@ func (g *defaultGenerator) genModel(in parser.Table, withCache bool) (string, er
table.UniqueCacheKey = uniqueKey table.UniqueCacheKey = uniqueKey
table.ContainsUniqueCacheKey = len(uniqueKey) > 0 table.ContainsUniqueCacheKey = len(uniqueKey) > 0
importsCode, err := genImports(withCache, in.ContainsTime(), table) importsCode, err := genImports(table, withCache, in.ContainsTime())
if err != nil { if err != nil {
return "", err return "", err
} }
@@ -261,7 +287,8 @@ func (g *defaultGenerator) genModel(in parser.Table, withCache bool) (string, er
} }
var list []string var list []string
list = append(list, insertCodeMethod, findOneCodeMethod, ret.findOneInterfaceMethod, updateCodeMethod, deleteCodeMethod) list = append(list, insertCodeMethod, findOneCodeMethod, ret.findOneInterfaceMethod,
updateCodeMethod, deleteCodeMethod)
typesCode, err := genTypes(table, strings.Join(modelutil.TrimStringSlice(list), pathx.NL), withCache) typesCode, err := genTypes(table, strings.Join(modelutil.TrimStringSlice(list), pathx.NL), withCache)
if err != nil { if err != nil {
return "", err return "", err
@@ -272,6 +299,11 @@ func (g *defaultGenerator) genModel(in parser.Table, withCache bool) (string, er
return "", err return "", err
} }
tableName, err := genTableName(table)
if err != nil {
return "", err
}
code := &code{ code := &code{
importsCode: importsCode, importsCode: importsCode,
varsCode: varsCode, varsCode: varsCode,
@@ -282,6 +314,7 @@ func (g *defaultGenerator) genModel(in parser.Table, withCache bool) (string, er
updateCode: updateCode, updateCode: updateCode,
deleteCode: deleteCode, deleteCode: deleteCode,
cacheExtra: ret.cacheExtra, cacheExtra: ret.cacheExtra,
tableName: tableName,
} }
output, err := g.executeModel(table, code) output, err := g.executeModel(table, code)
@@ -292,8 +325,30 @@ func (g *defaultGenerator) genModel(in parser.Table, withCache bool) (string, er
return output.String(), nil return output.String(), nil
} }
func (g *defaultGenerator) genModelCustom(in parser.Table, withCache bool) (string, error) {
text, err := pathx.LoadTemplate(category, modelCustomTemplateFile, template.ModelCustom)
if err != nil {
return "", err
}
t := util.With("model-custom").
Parse(text).
GoFmt(true)
output, err := t.Execute(map[string]interface{}{
"pkg": g.pkg,
"withCache": withCache,
"upperStartCamelObject": in.Name.ToCamel(),
"lowerStartCamelObject": stringx.From(in.Name.ToCamel()).Untitle(),
})
if err != nil {
return "", err
}
return output.String(), nil
}
func (g *defaultGenerator) executeModel(table Table, code *code) (*bytes.Buffer, error) { func (g *defaultGenerator) executeModel(table Table, code *code) (*bytes.Buffer, error) {
text, err := pathx.LoadTemplate(category, modelTemplateFile, template.Model) text, err := pathx.LoadTemplate(category, modelGenTemplateFile, template.ModelGen)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -311,6 +366,7 @@ func (g *defaultGenerator) executeModel(table Table, code *code) (*bytes.Buffer,
"update": code.updateCode, "update": code.updateCode,
"delete": code.deleteCode, "delete": code.deleteCode,
"extraMethod": code.cacheExtra, "extraMethod": code.cacheExtra,
"tableName": code.tableName,
"data": table, "data": table,
}) })
if err != nil { if err != nil {

View File

@@ -4,16 +4,19 @@ import (
"database/sql" "database/sql"
"io/ioutil" "io/ioutil"
"os" "os"
"path"
"path/filepath" "path/filepath"
"strings" "strings"
"testing" "testing"
"time" "time"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/zeromicro/go-zero/core/logx" "github.com/zeromicro/go-zero/core/logx"
"github.com/zeromicro/go-zero/core/stringx" "github.com/zeromicro/go-zero/core/stringx"
"github.com/zeromicro/go-zero/tools/goctl/config" "github.com/zeromicro/go-zero/tools/goctl/config"
"github.com/zeromicro/go-zero/tools/goctl/model/sql/builderx" "github.com/zeromicro/go-zero/tools/goctl/model/sql/builderx"
"github.com/zeromicro/go-zero/tools/goctl/model/sql/parser"
"github.com/zeromicro/go-zero/tools/goctl/util/pathx" "github.com/zeromicro/go-zero/tools/goctl/util/pathx"
) )
@@ -121,3 +124,31 @@ func TestFields(t *testing.T) {
assert.Equal(t, "`name`,`age`,`score`", studentRowsExpectAutoSet) assert.Equal(t, "`name`,`age`,`score`", studentRowsExpectAutoSet)
assert.Equal(t, "`name`=?,`age`=?,`score`=?", studentRowsWithPlaceHolder) assert.Equal(t, "`name`=?,`age`=?,`score`=?", studentRowsWithPlaceHolder)
} }
func Test_genPublicModel(t *testing.T) {
var err error
dir := pathx.MustTempDir()
modelDir := path.Join(dir, "model")
err = os.MkdirAll(modelDir, 0777)
require.NoError(t, err)
defer os.RemoveAll(dir)
modelFilename := filepath.Join(modelDir, "foo.sql")
err = ioutil.WriteFile(modelFilename, []byte(source), 0777)
require.NoError(t, err)
g, err := NewDefaultGenerator(modelDir, &config.Config{
NamingFormat: config.DefaultFormat,
})
require.NoError(t, err)
tables, err := parser.Parse(modelFilename, "")
require.Equal(t, 1, len(tables))
code, err := g.genModelCustom(*tables[0], false)
assert.NoError(t, err)
assert.True(t, strings.Contains(code, "package model"))
assert.True(t, strings.Contains(code, "TestUserModel interface {\n\t\ttestUserModel\n\t}\n"))
assert.True(t, strings.Contains(code, "customTestUserModel struct {\n\t\t*defaultTestUserModel\n\t}\n"))
assert.True(t, strings.Contains(code, "func NewTestUserModel(conn sqlx.SqlConn) TestUserModel {"))
}

View File

@@ -6,7 +6,7 @@ import (
"github.com/zeromicro/go-zero/tools/goctl/util/pathx" "github.com/zeromicro/go-zero/tools/goctl/util/pathx"
) )
func genImports(withCache, timeImport bool, table Table) (string, error) { func genImports(table Table, withCache, timeImport bool) (string, error) {
if withCache { if withCache {
text, err := pathx.LoadTemplate(category, importsTemplateFile, template.Imports) text, err := pathx.LoadTemplate(category, importsTemplateFile, template.Imports)
if err != nil { if err != nil {

View File

@@ -55,7 +55,6 @@ func genInsert(table Table, withCache, postgreSql bool) (string, string, error)
Parse(text). Parse(text).
Execute(map[string]interface{}{ Execute(map[string]interface{}{
"withCache": withCache, "withCache": withCache,
"containsIndexCache": table.ContainsUniqueCacheKey,
"upperStartCamelObject": camel, "upperStartCamelObject": camel,
"lowerStartCamelObject": stringx.From(camel).Untitle(), "lowerStartCamelObject": stringx.From(camel).Untitle(),
"expression": strings.Join(expressions, ", "), "expression": strings.Join(expressions, ", "),

View File

@@ -0,0 +1,26 @@
package gen
import (
"github.com/zeromicro/go-zero/tools/goctl/model/sql/template"
"github.com/zeromicro/go-zero/tools/goctl/util"
"github.com/zeromicro/go-zero/tools/goctl/util/pathx"
)
func genTableName(table Table) (string, error) {
text, err := pathx.LoadTemplate(category, tableNameTemplateFile, template.TableName)
if err != nil {
return "", err
}
output, err := util.With("tableName").
Parse(text).
Execute(map[string]interface{}{
"tableName": table.Name.Source(),
"upperStartCamelObject": table.Name.ToCamel(),
})
if err != nil {
return "", nil
}
return output.String(), nil
}

View File

@@ -22,8 +22,10 @@ const (
importsWithNoCacheTemplateFile = "import-no-cache.tpl" importsWithNoCacheTemplateFile = "import-no-cache.tpl"
insertTemplateFile = "insert.tpl" insertTemplateFile = "insert.tpl"
insertTemplateMethodFile = "interface-insert.tpl" insertTemplateMethodFile = "interface-insert.tpl"
modelTemplateFile = "model.tpl" modelGenTemplateFile = "model-gen.tpl"
modelCustomTemplateFile = "model.tpl"
modelNewTemplateFile = "model-new.tpl" modelNewTemplateFile = "model-new.tpl"
tableNameTemplateFile = "table-name.tpl"
tagTemplateFile = "tag.tpl" tagTemplateFile = "tag.tpl"
typesTemplateFile = "types.tpl" typesTemplateFile = "types.tpl"
updateTemplateFile = "update.tpl" updateTemplateFile = "update.tpl"
@@ -45,8 +47,10 @@ var templates = map[string]string{
importsWithNoCacheTemplateFile: template.ImportsNoCache, importsWithNoCacheTemplateFile: template.ImportsNoCache,
insertTemplateFile: template.Insert, insertTemplateFile: template.Insert,
insertTemplateMethodFile: template.InsertMethod, insertTemplateMethodFile: template.InsertMethod,
modelTemplateFile: template.Model, modelGenTemplateFile: template.ModelGen,
modelCustomTemplateFile: template.ModelCustom,
modelNewTemplateFile: template.New, modelNewTemplateFile: template.New,
tableNameTemplateFile: template.TableName,
tagTemplateFile: template.Tag, tagTemplateFile: template.Tag,
typesTemplateFile: template.Types, typesTemplateFile: template.Types,
updateTemplateFile: template.Update, updateTemplateFile: template.Update,
@@ -70,7 +74,7 @@ func GenTemplates(_ *cli.Context) error {
return pathx.InitTemplates(category, templates) return pathx.InitTemplates(category, templates)
} }
// RevertTemplate recovers the delete template files // RevertTemplate reverts the deleted template files
func RevertTemplate(name string) error { func RevertTemplate(name string) error {
content, ok := templates[name] content, ok := templates[name]
if !ok { if !ok {

View File

@@ -4,6 +4,7 @@ import (
"github.com/zeromicro/go-zero/tools/goctl/model/sql/template" "github.com/zeromicro/go-zero/tools/goctl/model/sql/template"
"github.com/zeromicro/go-zero/tools/goctl/util" "github.com/zeromicro/go-zero/tools/goctl/util"
"github.com/zeromicro/go-zero/tools/goctl/util/pathx" "github.com/zeromicro/go-zero/tools/goctl/util/pathx"
"github.com/zeromicro/go-zero/tools/goctl/util/stringx"
) )
func genTypes(table Table, methods string, withCache bool) (string, error) { func genTypes(table Table, methods string, withCache bool) (string, error) {
@@ -24,6 +25,7 @@ func genTypes(table Table, methods string, withCache bool) (string, error) {
"withCache": withCache, "withCache": withCache,
"method": methods, "method": methods,
"upperStartCamelObject": table.Name.ToCamel(), "upperStartCamelObject": table.Name.ToCamel(),
"lowerStartCamelObject": stringx.From(table.Name.ToCamel()).Untitle(),
"fields": fieldsString, "fields": fieldsString,
"data": table, "data": table,
}) })

View File

@@ -1,9 +1,10 @@
package template package template
// Delete defines a delete template const (
var Delete = ` // Delete defines a delete template
Delete = `
func (m *default{{.upperStartCamelObject}}Model) Delete(ctx context.Context, {{.lowerStartCamelPrimaryKey}} {{.dataType}}) error { func (m *default{{.upperStartCamelObject}}Model) Delete(ctx context.Context, {{.lowerStartCamelPrimaryKey}} {{.dataType}}) error {
{{if .withCache}}{{if .containsIndexCache}}data, err:=m.FindOneCtx(ctx, {{.lowerStartCamelPrimaryKey}}) {{if .withCache}}{{if .containsIndexCache}}data, err:=m.FindOne(ctx, {{.lowerStartCamelPrimaryKey}})
if err!=nil{ if err!=nil{
return err return err
} }
@@ -18,5 +19,6 @@ func (m *default{{.upperStartCamelObject}}Model) Delete(ctx context.Context, {{.
} }
` `
// DeleteMethod defines a delete template for interface method // DeleteMethod defines a delete template for interface method
var DeleteMethod = `Delete(ctx context.Context, {{.lowerStartCamelPrimaryKey}} {{.dataType}}) error` DeleteMethod = `Delete(ctx context.Context, {{.lowerStartCamelPrimaryKey}} {{.dataType}}) error`
)

View File

@@ -1,7 +1,7 @@
package template package template
// Error defines an error template // Error defines an error template
var Error = `package {{.pkg}} const Error = `package {{.pkg}}
import "github.com/zeromicro/go-zero/core/stores/sqlx" import "github.com/zeromicro/go-zero/core/stores/sqlx"

View File

@@ -1,4 +1,4 @@
package template package template
// Field defines a filed template for types // Field defines a filed template for types
var Field = `{{.name}} {{.type}} {{.tag}} {{if .hasComment}}// {{.comment}}{{end}}` const Field = `{{.name}} {{.type}} {{.tag}} {{if .hasComment}}// {{.comment}}{{end}}`

View File

@@ -1,7 +1,8 @@
package template package template
// FindOne defines find row by id. const (
var FindOne = ` // FindOne defines find row by id.
FindOne = `
func (m *default{{.upperStartCamelObject}}Model) FindOne(ctx context.Context, {{.lowerStartCamelPrimaryKey}} {{.dataType}}) (*{{.upperStartCamelObject}}, error) { func (m *default{{.upperStartCamelObject}}Model) FindOne(ctx context.Context, {{.lowerStartCamelPrimaryKey}} {{.dataType}}) (*{{.upperStartCamelObject}}, error) {
{{if .withCache}}{{.cacheKey}} {{if .withCache}}{{.cacheKey}}
var resp {{.upperStartCamelObject}} var resp {{.upperStartCamelObject}}
@@ -30,9 +31,9 @@ func (m *default{{.upperStartCamelObject}}Model) FindOne(ctx context.Context, {{
} }
` `
// FindOneByField defines find row by field. // FindOneByField defines find row by field.
var FindOneByField = ` FindOneByField = `
func (m *default{{.upperStartCamelObject}}Model) FindOneBy{{.upperField}}({{.in}}) (*{{.upperStartCamelObject}}, error) { func (m *default{{.upperStartCamelObject}}Model) FindOneBy{{.upperField}}(ctx context.Context, {{.in}}) (*{{.upperStartCamelObject}}, error) {
{{if .withCache}}{{.cacheKey}} {{if .withCache}}{{.cacheKey}}
var resp {{.upperStartCamelObject}} var resp {{.upperStartCamelObject}}
err := m.QueryRowIndexCtx(ctx, &resp, {{.cacheKeyVariable}}, m.formatPrimary, func(ctx context.Context, conn sqlx.SqlConn, v interface{}) (i interface{}, e error) { err := m.QueryRowIndexCtx(ctx, &resp, {{.cacheKeyVariable}}, m.formatPrimary, func(ctx context.Context, conn sqlx.SqlConn, v interface{}) (i interface{}, e error) {
@@ -64,8 +65,8 @@ func (m *default{{.upperStartCamelObject}}Model) FindOneBy{{.upperField}}({{.in}
}{{end}} }{{end}}
` `
// FindOneByFieldExtraMethod defines find row by field with extras. // FindOneByFieldExtraMethod defines find row by field with extras.
var FindOneByFieldExtraMethod = ` FindOneByFieldExtraMethod = `
func (m *default{{.upperStartCamelObject}}Model) formatPrimary(primary interface{}) string { func (m *default{{.upperStartCamelObject}}Model) formatPrimary(primary interface{}) string {
return fmt.Sprintf("%s%v", {{.primaryKeyLeft}}, primary) return fmt.Sprintf("%s%v", {{.primaryKeyLeft}}, primary)
} }
@@ -76,8 +77,9 @@ func (m *default{{.upperStartCamelObject}}Model) queryPrimary(ctx context.Contex
} }
` `
// FindOneMethod defines find row method. // FindOneMethod defines find row method.
var FindOneMethod = `FindOne(ctx context.Context, {{.lowerStartCamelPrimaryKey}} {{.dataType}}) (*{{.upperStartCamelObject}}, error)` FindOneMethod = `FindOne(ctx context.Context, {{.lowerStartCamelPrimaryKey}} {{.dataType}}) (*{{.upperStartCamelObject}}, error)`
// FindOneByFieldMethod defines find row by field method. // FindOneByFieldMethod defines find row by field method.
var FindOneByFieldMethod = `FindOneBy{{.upperField}}(ctx context.Context, {{.in}}) (*{{.upperStartCamelObject}}, error) ` FindOneByFieldMethod = `FindOneBy{{.upperField}}(ctx context.Context, {{.in}}) (*{{.upperStartCamelObject}}, error) `
)

View File

@@ -1,6 +1,6 @@
package template package template
var ( const (
// Imports defines a import template for model in cache case // Imports defines a import template for model in cache case
Imports = `import ( Imports = `import (
"context" "context"

View File

@@ -1,19 +1,19 @@
package template package template
// Insert defines a template for insert code in model const (
var Insert = ` // Insert defines a template for insert code in model
Insert = `
func (m *default{{.upperStartCamelObject}}Model) Insert(ctx context.Context, data *{{.upperStartCamelObject}}) (sql.Result,error) { func (m *default{{.upperStartCamelObject}}Model) Insert(ctx context.Context, data *{{.upperStartCamelObject}}) (sql.Result,error) {
{{if .withCache}}{{if .containsIndexCache}}{{.keys}} {{if .withCache}}{{.keys}}
ret, err := m.ExecCtx(ctx, func(ctx context.Context, conn sqlx.SqlConn) (result sql.Result, err error) { ret, err := m.ExecCtx(ctx, func(ctx context.Context, conn sqlx.SqlConn) (result sql.Result, err error) {
query := fmt.Sprintf("insert into %s (%s) values ({{.expression}})", m.table, {{.lowerStartCamelObject}}RowsExpectAutoSet) query := fmt.Sprintf("insert into %s (%s) values ({{.expression}})", m.table, {{.lowerStartCamelObject}}RowsExpectAutoSet)
return conn.ExecCtx(ctx, query, {{.expressionValues}}) return conn.ExecCtx(ctx, query, {{.expressionValues}})
}, {{.keyValues}}){{else}}query := fmt.Sprintf("insert into %s (%s) values ({{.expression}})", m.table, {{.lowerStartCamelObject}}RowsExpectAutoSet) }, {{.keyValues}}){{else}}query := fmt.Sprintf("insert into %s (%s) values ({{.expression}})", m.table, {{.lowerStartCamelObject}}RowsExpectAutoSet)
ret,err:=m.ExecNoCacheCtx(ctx, query, {{.expressionValues}})
{{end}}{{else}}query := fmt.Sprintf("insert into %s (%s) values ({{.expression}})", m.table, {{.lowerStartCamelObject}}RowsExpectAutoSet)
ret,err:=m.conn.ExecCtx(ctx, query, {{.expressionValues}}){{end}} ret,err:=m.conn.ExecCtx(ctx, query, {{.expressionValues}}){{end}}
return ret,err return ret,err
} }
` `
// InsertMethod defines an interface method template for insert code in model // InsertMethod defines an interface method template for insert code in model
var InsertMethod = `Insert(ctx context.Context, data *{{.upperStartCamelObject}}) (sql.Result,error)` InsertMethod = `Insert(ctx context.Context, data *{{.upperStartCamelObject}}) (sql.Result,error)`
)

Some files were not shown because too many files have changed in this diff Show More