补充控制器的日志
This commit is contained in:
parent
ba14513baa
commit
a1bd181212
10
book/v3/application.yaml
Normal file
10
book/v3/application.yaml
Normal file
@ -0,0 +1,10 @@
|
||||
app:
|
||||
host: 127.0.0.1
|
||||
port: 8080
|
||||
mysql:
|
||||
host: 127.0.0.1
|
||||
port: 3306
|
||||
database: go18
|
||||
username: "root"
|
||||
password: "123456"
|
||||
debug: true
|
@ -1,6 +1,5 @@
|
||||
# 程序的配置管理
|
||||
|
||||
|
||||
## 配置的加载
|
||||
```go
|
||||
// 用于加载配置
|
||||
@ -18,3 +17,71 @@ config.C().MySQL.Host
|
||||
|
||||
如何验证我们这个包的 业务逻辑是正确
|
||||
|
||||
```go
|
||||
func TestLoadConfigFromYaml(t *testing.T) {
|
||||
err := config.LoadConfigFromYaml(fmt.Sprintf("%s/book/v2/application.yaml", os.Getenv("workspaceFolder")))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
t.Log(config.C())
|
||||
}
|
||||
|
||||
func TestLoadConfigFromEnv(t *testing.T) {
|
||||
os.Setenv("DATASOURCE_HOST", "localhost")
|
||||
err := config.LoadConfigFromEnv()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
t.Log(config.C())
|
||||
}
|
||||
```
|
||||
|
||||
## 补充日志配置
|
||||
|
||||
```go
|
||||
// 如果是文件,结合该库使用"gopkg.in/natefinch/lumberjack.v2"
|
||||
// 自己的作业: 添加日志轮转配置,结合 gopkg.in/natefinch/lumberjack.v2 使用
|
||||
// 可以参考: https://github.com/infraboard/mcube/blob/master/ioc/config/log/logger.go
|
||||
type Log struct {
|
||||
Level zerolog.Level `json:"level" yaml:"level" toml:"level" env:"LOG_LEVEL"`
|
||||
|
||||
logger *zerolog.Logger
|
||||
lock sync.Mutex
|
||||
}
|
||||
|
||||
func (l *Log) SetLogger(logger zerolog.Logger) {
|
||||
l.logger = &logger
|
||||
}
|
||||
|
||||
func (l *Log) Logger() *zerolog.Logger {
|
||||
l.lock.Lock()
|
||||
defer l.lock.Unlock()
|
||||
|
||||
if l.logger == nil {
|
||||
l.SetLogger(zerolog.New(l.ConsoleWriter()).Level(l.Level).With().Caller().Timestamp().Logger())
|
||||
}
|
||||
|
||||
return l.logger
|
||||
}
|
||||
|
||||
func (c *Log) ConsoleWriter() io.Writer {
|
||||
output := zerolog.NewConsoleWriter(func(w *zerolog.ConsoleWriter) {
|
||||
w.NoColor = false
|
||||
w.TimeFormat = time.RFC3339
|
||||
})
|
||||
|
||||
output.FormatLevel = func(i interface{}) string {
|
||||
return strings.ToUpper(fmt.Sprintf("%-6s", i))
|
||||
}
|
||||
output.FormatMessage = func(i interface{}) string {
|
||||
return fmt.Sprintf("%s", i)
|
||||
}
|
||||
output.FormatFieldName = func(i interface{}) string {
|
||||
return fmt.Sprintf("%s:", i)
|
||||
}
|
||||
output.FormatFieldValue = func(i interface{}) string {
|
||||
return strings.ToUpper(fmt.Sprintf("%s", i))
|
||||
}
|
||||
return output
|
||||
}
|
||||
```
|
@ -2,10 +2,14 @@ package config
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"122.51.31.227/go-course/go18/book/v3/models"
|
||||
"github.com/infraboard/mcube/v2/tools/pretty"
|
||||
"github.com/rs/zerolog"
|
||||
"gorm.io/driver/mysql"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
@ -24,6 +28,9 @@ func Default() *Config {
|
||||
Password: "123456",
|
||||
Debug: true,
|
||||
},
|
||||
Log: &Log{
|
||||
Level: zerolog.DebugLevel,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@ -32,6 +39,7 @@ func Default() *Config {
|
||||
type Config struct {
|
||||
Application *application `toml:"app" yaml:"app" json:"app"`
|
||||
MySQL *mySQL `toml:"mysql" yaml:"mysql" json:"mysql"`
|
||||
Log *Log `toml:"log" yaml:"log" json:"log"`
|
||||
}
|
||||
|
||||
func (c *Config) String() string {
|
||||
@ -73,6 +81,7 @@ func (m *mySQL) GetDB() *gorm.DB {
|
||||
m.Port,
|
||||
m.DB,
|
||||
)
|
||||
L().Info().Msgf("Database: %s", m.DB)
|
||||
|
||||
db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
|
||||
if err != nil {
|
||||
@ -80,7 +89,54 @@ func (m *mySQL) GetDB() *gorm.DB {
|
||||
}
|
||||
db.AutoMigrate(&models.Book{}) // 自动迁移
|
||||
m.db = db
|
||||
|
||||
}
|
||||
|
||||
return m.db
|
||||
}
|
||||
|
||||
// 如果是文件,结合该库使用"gopkg.in/natefinch/lumberjack.v2"
|
||||
// 自己的作业: 添加日志轮转配置,结合 gopkg.in/natefinch/lumberjack.v2 使用
|
||||
// 可以参考:
|
||||
type Log struct {
|
||||
Level zerolog.Level `json:"level" yaml:"level" toml:"level" env:"LOG_LEVEL"`
|
||||
|
||||
logger *zerolog.Logger
|
||||
lock sync.Mutex
|
||||
}
|
||||
|
||||
func (l *Log) SetLogger(logger zerolog.Logger) {
|
||||
l.logger = &logger
|
||||
}
|
||||
|
||||
func (l *Log) Logger() *zerolog.Logger {
|
||||
l.lock.Lock()
|
||||
defer l.lock.Unlock()
|
||||
|
||||
if l.logger == nil {
|
||||
l.SetLogger(zerolog.New(l.ConsoleWriter()).Level(l.Level).With().Caller().Timestamp().Logger())
|
||||
}
|
||||
|
||||
return l.logger
|
||||
}
|
||||
|
||||
func (c *Log) ConsoleWriter() io.Writer {
|
||||
output := zerolog.NewConsoleWriter(func(w *zerolog.ConsoleWriter) {
|
||||
w.NoColor = false
|
||||
w.TimeFormat = time.RFC3339
|
||||
})
|
||||
|
||||
output.FormatLevel = func(i interface{}) string {
|
||||
return strings.ToUpper(fmt.Sprintf("%-6s", i))
|
||||
}
|
||||
output.FormatMessage = func(i interface{}) string {
|
||||
return fmt.Sprintf("%s", i)
|
||||
}
|
||||
output.FormatFieldName = func(i interface{}) string {
|
||||
return fmt.Sprintf("%s:", i)
|
||||
}
|
||||
output.FormatFieldValue = func(i interface{}) string {
|
||||
return strings.ToUpper(fmt.Sprintf("%s", i))
|
||||
}
|
||||
return output
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ import (
|
||||
"os"
|
||||
|
||||
"github.com/caarlos0/env/v6"
|
||||
"github.com/rs/zerolog"
|
||||
"gopkg.in/yaml.v3"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
@ -29,6 +30,10 @@ func DB() *gorm.DB {
|
||||
return C().MySQL.GetDB()
|
||||
}
|
||||
|
||||
func L() *zerolog.Logger {
|
||||
return C().Log.Logger()
|
||||
}
|
||||
|
||||
// 加载配置 把外部配置读到 config全局变量里面来
|
||||
// yaml 文件yaml --> conf
|
||||
func LoadConfigFromYaml(configPath string) error {
|
||||
|
@ -1,3 +1,8 @@
|
||||
# 控制器
|
||||
|
||||
业务处理
|
||||
|
||||
|
||||
## 单元测试 (TDD)
|
||||
|
||||
|
||||
|
@ -15,14 +15,6 @@
|
||||
<mxPoint as="offset"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="15" style="edgeStyle=orthogonalEdgeStyle;html=1;exitX=0.75;exitY=1;exitDx=0;exitDy=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="3" target="12">
|
||||
<mxGeometry relative="1" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="16" value="依赖这个业务逻辑" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" vertex="1" connectable="0" parent="15">
|
||||
<mxGeometry x="0.401" y="2" relative="1" as="geometry">
|
||||
<mxPoint as="offset"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="3" value="comment handlers" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
||||
<mxGeometry x="330" y="130" width="120" height="60" as="geometry"/>
|
||||
</mxCell>
|
||||
@ -39,7 +31,7 @@
|
||||
<mxGeometry x="260" y="80" width="60" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="11" value="<h1 style="margin-top: 0px;">controllers</h1><p>controllers.Book.GetBook(id) -&gt; book</p>" style="text;html=1;whiteSpace=wrap;overflow=hidden;rounded=0;" vertex="1" parent="1">
|
||||
<mxGeometry x="270" y="230" width="180" height="120" as="geometry"/>
|
||||
<mxGeometry x="640" y="200" width="180" height="120" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="12" value="Book Controller" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
||||
<mxGeometry x="150" y="340" width="120" height="60" as="geometry"/>
|
||||
@ -47,6 +39,21 @@
|
||||
<mxCell id="14" style="edgeStyle=none;html=1;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.565;entryY=0.997;entryDx=0;entryDy=0;entryPerimeter=0;" edge="1" parent="1" source="12" target="2">
|
||||
<mxGeometry relative="1" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="19" style="edgeStyle=none;html=1;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="1" source="18" target="3">
|
||||
<mxGeometry relative="1" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="20" style="edgeStyle=none;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="18" target="12">
|
||||
<mxGeometry relative="1" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="18" value="Comment Controller" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
||||
<mxGeometry x="330" y="340" width="120" height="60" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="22" style="edgeStyle=none;html=1;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="1" source="21" target="6">
|
||||
<mxGeometry relative="1" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="21" value="Controllers" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
||||
<mxGeometry x="500" y="340" width="120" height="60" as="geometry"/>
|
||||
</mxCell>
|
||||
</root>
|
||||
</mxGraphModel>
|
||||
</diagram>
|
||||
|
@ -12,14 +12,14 @@ var Book = &BookController{}
|
||||
type BookController struct {
|
||||
}
|
||||
|
||||
func NewGetBookRequest(bookNumber string) *GetBookRequest {
|
||||
func NewGetBookRequest(bookNumber int) *GetBookRequest {
|
||||
return &GetBookRequest{
|
||||
BookNumber: bookNumber,
|
||||
}
|
||||
}
|
||||
|
||||
type GetBookRequest struct {
|
||||
BookNumber string
|
||||
BookNumber int
|
||||
// RequestId string
|
||||
// ...
|
||||
}
|
||||
@ -32,6 +32,8 @@ func (c *BookController) GetBook(ctx context.Context, in *GetBookRequest) (*mode
|
||||
// context.WithValue(ctx, "request_id", 111)
|
||||
// ctx.Value("request_id")
|
||||
|
||||
config.L().Debug().Msgf("get book: %d", in.BookNumber)
|
||||
|
||||
bookInstance := &models.Book{}
|
||||
// 需要从数据库中获取一个对象
|
||||
if err := config.DB().Where("id = ?", in.BookNumber).Take(bookInstance).Error; err != nil {
|
||||
@ -40,3 +42,23 @@ func (c *BookController) GetBook(ctx context.Context, in *GetBookRequest) (*mode
|
||||
|
||||
return bookInstance, nil
|
||||
}
|
||||
|
||||
func (c *BookController) CreateBook(ctx context.Context, in *models.BookSpec) (*models.Book, error) {
|
||||
// 有没有能够检查某个字段是否是必须填
|
||||
// Gin 集成 validator这个库, 通过 struct tag validate 来表示这个字段是否允许为空
|
||||
// validate:"required"
|
||||
// 在数据Bind的时候,这个逻辑会自动运行
|
||||
// if bookSpecInstance.Author == "" {
|
||||
// ctx.JSON(400, gin.H{"code": 400, "message": err.Error()})
|
||||
// return
|
||||
// }
|
||||
|
||||
bookInstance := &models.Book{BookSpec: *in}
|
||||
|
||||
// 数据入库(Grom), 补充自增Id的值
|
||||
if err := config.DB().Save(bookInstance).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return bookInstance, nil
|
||||
}
|
||||
|
40
book/v3/controllers/book_test.go
Normal file
40
book/v3/controllers/book_test.go
Normal file
@ -0,0 +1,40 @@
|
||||
package controllers_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"122.51.31.227/go-course/go18/book/v3/config"
|
||||
"122.51.31.227/go-course/go18/book/v3/controllers"
|
||||
"122.51.31.227/go-course/go18/book/v3/models"
|
||||
)
|
||||
|
||||
func TestGetBook(t *testing.T) {
|
||||
book, err := controllers.Book.GetBook(context.Background(), controllers.NewGetBookRequest(3))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
t.Log(book)
|
||||
}
|
||||
|
||||
func TestCreateBook(t *testing.T) {
|
||||
book, err := controllers.Book.CreateBook(context.Background(), &models.BookSpec{
|
||||
Title: "unit test for go controller obj",
|
||||
Author: "will",
|
||||
Price: 99.99,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
t.Log(book)
|
||||
}
|
||||
|
||||
func init() {
|
||||
// 执行配置的加载
|
||||
err := config.LoadConfigFromYaml(fmt.Sprintf("%s/book/v3/application.yaml", os.Getenv("workspaceFolder")))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
@ -13,7 +13,7 @@ type CommentController struct {
|
||||
}
|
||||
|
||||
type AddCommentRequest struct {
|
||||
BookNumber string
|
||||
BookNumber int
|
||||
}
|
||||
|
||||
func (c *CommentController) AddComment(ctx context.Context, in *AddCommentRequest) (*models.Comment, error) {
|
||||
|
@ -114,29 +114,24 @@ func (h *BookApiHandler) createBook(ctx *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
// 有没有能够检查某个字段是否是必须填
|
||||
// Gin 集成 validator这个库, 通过 struct tag validate 来表示这个字段是否允许为空
|
||||
// validate:"required"
|
||||
// 在数据Bind的时候,这个逻辑会自动运行
|
||||
// if bookSpecInstance.Author == "" {
|
||||
// ctx.JSON(400, gin.H{"code": 400, "message": err.Error()})
|
||||
// return
|
||||
// }
|
||||
|
||||
bookInstance := &models.Book{BookSpec: *bookSpecInstance}
|
||||
|
||||
// 数据入库(Grom), 补充自增Id的值
|
||||
if err := config.DB().Save(bookInstance).Error; err != nil {
|
||||
ctx.JSON(400, gin.H{"code": 500, "message": err.Error()})
|
||||
book, err := controllers.Book.CreateBook(ctx.Request.Context(), bookSpecInstance)
|
||||
if err != nil {
|
||||
ctx.JSON(400, gin.H{"code": 400, "message": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
// 返回响应
|
||||
ctx.JSON(http.StatusCreated, bookInstance)
|
||||
ctx.JSON(http.StatusCreated, book)
|
||||
}
|
||||
|
||||
func (h *BookApiHandler) getBook(ctx *gin.Context) {
|
||||
book, err := controllers.Book.GetBook(ctx, controllers.NewGetBookRequest(ctx.Param("bn")))
|
||||
bnInt, err := strconv.ParseInt(ctx.Param("bn"), 10, 64)
|
||||
if err != nil {
|
||||
ctx.JSON(400, gin.H{"code": 400, "message": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
book, err := controllers.Book.GetBook(ctx, controllers.NewGetBookRequest(int(bnInt)))
|
||||
if err != nil {
|
||||
ctx.JSON(400, gin.H{"code": 400, "message": err.Error()})
|
||||
return
|
||||
|
@ -10,6 +10,13 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
// 加载配置
|
||||
path := os.Getenv("CONFIG_PATH")
|
||||
if path == "" {
|
||||
path = "application.yaml"
|
||||
}
|
||||
config.LoadConfigFromYaml(path)
|
||||
|
||||
server := gin.Default()
|
||||
|
||||
handlers.Book.Registry(server)
|
||||
|
@ -1,5 +1,7 @@
|
||||
package models
|
||||
|
||||
import "github.com/infraboard/mcube/v2/tools/pretty"
|
||||
|
||||
type BookSet struct {
|
||||
// 总共多少个
|
||||
Total int64 `json:"total"`
|
||||
@ -14,6 +16,10 @@ type Book struct {
|
||||
BookSpec
|
||||
}
|
||||
|
||||
func (b *Book) String() string {
|
||||
return pretty.ToJSON(b)
|
||||
}
|
||||
|
||||
type BookSpec struct {
|
||||
// type 用于要使用gorm 来自动创建和更新表的时候 才需要定义
|
||||
Title string `json:"title" gorm:"column:title;type:varchar(200)" validate:"required"`
|
||||
|
2
go.mod
2
go.mod
@ -6,6 +6,7 @@ require (
|
||||
github.com/caarlos0/env/v6 v6.10.1
|
||||
github.com/gin-gonic/gin v1.10.0
|
||||
github.com/infraboard/mcube/v2 v2.0.59
|
||||
github.com/rs/zerolog v1.34.0
|
||||
github.com/stretchr/testify v1.10.0
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
gorm.io/driver/mysql v1.5.7
|
||||
@ -29,6 +30,7 @@ require (
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.2.10 // indirect
|
||||
github.com/leodido/go-urn v1.4.0 // indirect
|
||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
|
12
go.sum
12
go.sum
@ -8,6 +8,7 @@ github.com/caarlos0/env/v6 v6.10.1/go.mod h1:hvp/ryKXKipEkcuYjs9mI4bBCg+UI0Yhgm5
|
||||
github.com/cloudwego/base64x v0.1.5 h1:XPciSp1xaq2VCSt6lF0phncD4koWyULpl5bUxbfCyP4=
|
||||
github.com/cloudwego/base64x v0.1.5/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w=
|
||||
github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY=
|
||||
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
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=
|
||||
@ -29,6 +30,7 @@ github.com/go-sql-driver/mysql v1.7.0 h1:ueSltNNllEqE3qcWBTD0iQd3IpL/6U+mJxLkazJ
|
||||
github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
|
||||
github.com/goccy/go-json v0.10.5 h1:Fq85nIqj+gXn/S5ahsiTlK3TmC85qgirsdTP/+DeaC4=
|
||||
github.com/goccy/go-json v0.10.5/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
|
||||
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
||||
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
@ -46,6 +48,10 @@ github.com/klauspost/cpuid/v2 v2.2.10/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQe
|
||||
github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M=
|
||||
github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
|
||||
github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
|
||||
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
||||
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
||||
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
@ -55,8 +61,12 @@ github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9G
|
||||
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||
github.com/pelletier/go-toml/v2 v2.2.3 h1:YmeHyLY8mFWbdkNWwpr+qIL2bEqT0o95WSdkNHvL12M=
|
||||
github.com/pelletier/go-toml/v2 v2.2.3/go.mod h1:MfCQTFTvCcUyyvvwm1+G6H/jORL20Xlb6rzQu9GuUkc=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/rs/xid v1.6.0/go.mod h1:7XoLgs4eV+QndskICGsho+ADou8ySMSjJKDIan90Nz0=
|
||||
github.com/rs/zerolog v1.34.0 h1:k43nTLIwcTVQAncfCw4KZ2VY6ukYoZaBPNOE8txlOeY=
|
||||
github.com/rs/zerolog v1.34.0/go.mod h1:bJsvje4Z08ROH4Nhs5iH600c3IkWhwp44iRc54W6wYQ=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
@ -79,7 +89,9 @@ golang.org/x/crypto v0.38.0 h1:jt+WWG8IZlBnVbomuhg2Mdq0+BBQaHbtqHEFEigjUV8=
|
||||
golang.org/x/crypto v0.38.0/go.mod h1:MvrbAqul58NNYPKnOra203SB9vpuZW0e+RRZV+Ggqjw=
|
||||
golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8=
|
||||
golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8=
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw=
|
||||
golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
||||
golang.org/x/text v0.25.0 h1:qVyWApTSYLk/drJRO5mDlNYskwQznZmkpV2c8q9zls4=
|
||||
|
Loading…
x
Reference in New Issue
Block a user