feat: add cli/format package
This commit is contained in:
parent
e40a8515cf
commit
4a8add1d3d
|
@ -0,0 +1,38 @@
|
||||||
|
package json
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"io"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
"gitlab.com/wpetit/goweb/cli/format"
|
||||||
|
)
|
||||||
|
|
||||||
|
const Format format.Format = "json"
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
format.Register(Format, NewWriter())
|
||||||
|
}
|
||||||
|
|
||||||
|
type Writer struct{}
|
||||||
|
|
||||||
|
// Format implements format.Writer.
|
||||||
|
func (*Writer) Write(writer io.Writer, hints format.Hints, data ...any) error {
|
||||||
|
encoder := json.NewEncoder(writer)
|
||||||
|
|
||||||
|
if hints.OutputMode == format.OutputModeWide {
|
||||||
|
encoder.SetIndent("", " ")
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := encoder.Encode(data); err != nil {
|
||||||
|
return errors.WithStack(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewWriter() *Writer {
|
||||||
|
return &Writer{}
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ format.Writer = &Writer{}
|
|
@ -0,0 +1,49 @@
|
||||||
|
package format
|
||||||
|
|
||||||
|
type PropHintName string
|
||||||
|
|
||||||
|
type PropHintFunc func() (PropHintName, any)
|
||||||
|
|
||||||
|
type Prop struct {
|
||||||
|
name string
|
||||||
|
label string
|
||||||
|
hints map[PropHintName]any
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Prop) Name() string {
|
||||||
|
return p.name
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Prop) Label() string {
|
||||||
|
return p.label
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewProp(name, label string, funcs ...PropHintFunc) Prop {
|
||||||
|
hints := make(map[PropHintName]any)
|
||||||
|
for _, fn := range funcs {
|
||||||
|
name, value := fn()
|
||||||
|
hints[name] = value
|
||||||
|
}
|
||||||
|
|
||||||
|
return Prop{name, label, hints}
|
||||||
|
}
|
||||||
|
|
||||||
|
func WithPropHint(name PropHintName, value any) PropHintFunc {
|
||||||
|
return func() (PropHintName, any) {
|
||||||
|
return name, value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func PropHint[T any](p Prop, name PropHintName, defaultValue T) T {
|
||||||
|
rawValue, exists := p.hints[name]
|
||||||
|
if !exists {
|
||||||
|
return defaultValue
|
||||||
|
}
|
||||||
|
|
||||||
|
value, ok := rawValue.(T)
|
||||||
|
if !ok {
|
||||||
|
return defaultValue
|
||||||
|
}
|
||||||
|
|
||||||
|
return value
|
||||||
|
}
|
|
@ -0,0 +1,46 @@
|
||||||
|
package format
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Format string
|
||||||
|
|
||||||
|
type Registry map[Format]Writer
|
||||||
|
|
||||||
|
var defaultRegistry = Registry{}
|
||||||
|
|
||||||
|
var ErrUnknownFormat = errors.New("unknown format")
|
||||||
|
|
||||||
|
func Write(format Format, writer io.Writer, hints Hints, data ...any) error {
|
||||||
|
formatWriter, exists := defaultRegistry[format]
|
||||||
|
if !exists {
|
||||||
|
return errors.WithStack(ErrUnknownFormat)
|
||||||
|
}
|
||||||
|
|
||||||
|
if hints.OutputMode == "" {
|
||||||
|
hints.OutputMode = OutputModeCompact
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := formatWriter.Write(writer, hints, data...); err != nil {
|
||||||
|
return errors.WithStack(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func Available() []Format {
|
||||||
|
formats := make([]Format, 0, len(defaultRegistry))
|
||||||
|
|
||||||
|
for f := range defaultRegistry {
|
||||||
|
formats = append(formats, f)
|
||||||
|
}
|
||||||
|
|
||||||
|
return formats
|
||||||
|
}
|
||||||
|
|
||||||
|
func Register(format Format, writer Writer) {
|
||||||
|
defaultRegistry[format] = writer
|
||||||
|
}
|
|
@ -0,0 +1,61 @@
|
||||||
|
package table
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"reflect"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
"gitlab.com/wpetit/goweb/cli/format"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
hintCompactModeMaxColumnWidth format.PropHintName = "compactModeMaxColumnWidth"
|
||||||
|
)
|
||||||
|
|
||||||
|
func WithCompactModeMaxColumnWidth(max int) format.PropHintFunc {
|
||||||
|
return format.WithPropHint(hintCompactModeMaxColumnWidth, max)
|
||||||
|
}
|
||||||
|
|
||||||
|
func getProps(d any) []format.Prop {
|
||||||
|
props := make([]format.Prop, 0)
|
||||||
|
|
||||||
|
v := reflect.Indirect(reflect.ValueOf(d))
|
||||||
|
typeOf := v.Type()
|
||||||
|
|
||||||
|
for i := 0; i < v.NumField(); i++ {
|
||||||
|
name := typeOf.Field(i).Name
|
||||||
|
props = append(props, format.NewProp(name, name))
|
||||||
|
}
|
||||||
|
|
||||||
|
return props
|
||||||
|
}
|
||||||
|
|
||||||
|
func getFieldValue(obj any, name string) string {
|
||||||
|
v := reflect.Indirect(reflect.ValueOf(obj))
|
||||||
|
|
||||||
|
fieldValue := v.FieldByName(name)
|
||||||
|
|
||||||
|
if !fieldValue.IsValid() {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
switch fieldValue.Kind() {
|
||||||
|
case reflect.Map:
|
||||||
|
fallthrough
|
||||||
|
case reflect.Struct:
|
||||||
|
fallthrough
|
||||||
|
case reflect.Slice:
|
||||||
|
fallthrough
|
||||||
|
case reflect.Interface:
|
||||||
|
json, err := json.Marshal(fieldValue.Interface())
|
||||||
|
if err != nil {
|
||||||
|
panic(errors.WithStack(err))
|
||||||
|
}
|
||||||
|
|
||||||
|
return string(json)
|
||||||
|
|
||||||
|
default:
|
||||||
|
return fmt.Sprintf("%v", fieldValue)
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,80 @@
|
||||||
|
package table
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io"
|
||||||
|
|
||||||
|
"github.com/jedib0t/go-pretty/v6/table"
|
||||||
|
"gitlab.com/wpetit/goweb/cli/format"
|
||||||
|
)
|
||||||
|
|
||||||
|
const Format format.Format = "table"
|
||||||
|
|
||||||
|
const DefaultCompactModeMaxColumnWidth = 30
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
format.Register(Format, NewWriter(DefaultCompactModeMaxColumnWidth))
|
||||||
|
}
|
||||||
|
|
||||||
|
type Writer struct {
|
||||||
|
compactModeMaxColumnWidth int
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write implements format.Writer.
|
||||||
|
func (w *Writer) Write(writer io.Writer, hints format.Hints, data ...any) error {
|
||||||
|
t := table.NewWriter()
|
||||||
|
|
||||||
|
t.SetOutputMirror(writer)
|
||||||
|
|
||||||
|
var props []format.Prop
|
||||||
|
|
||||||
|
if hints.Props != nil {
|
||||||
|
props = hints.Props
|
||||||
|
} else {
|
||||||
|
if len(data) > 0 {
|
||||||
|
props = getProps(data[0])
|
||||||
|
} else {
|
||||||
|
props = make([]format.Prop, 0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
labels := table.Row{}
|
||||||
|
|
||||||
|
for _, p := range props {
|
||||||
|
labels = append(labels, p.Label())
|
||||||
|
}
|
||||||
|
|
||||||
|
t.AppendHeader(labels)
|
||||||
|
|
||||||
|
isCompactMode := hints.OutputMode == format.OutputModeCompact
|
||||||
|
|
||||||
|
for _, d := range data {
|
||||||
|
row := table.Row{}
|
||||||
|
|
||||||
|
for _, p := range props {
|
||||||
|
value := getFieldValue(d, p.Name())
|
||||||
|
|
||||||
|
compactModeMaxColumnWidth := format.PropHint(p,
|
||||||
|
hintCompactModeMaxColumnWidth,
|
||||||
|
w.compactModeMaxColumnWidth,
|
||||||
|
)
|
||||||
|
|
||||||
|
if isCompactMode && len(value) > compactModeMaxColumnWidth {
|
||||||
|
value = value[:compactModeMaxColumnWidth] + "..."
|
||||||
|
}
|
||||||
|
|
||||||
|
row = append(row, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
t.AppendRow(row)
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Render()
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewWriter(compactModeMaxColumnWidth int) *Writer {
|
||||||
|
return &Writer{compactModeMaxColumnWidth}
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ format.Writer = &Writer{}
|
|
@ -0,0 +1,86 @@
|
||||||
|
package table
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
"gitlab.com/wpetit/goweb/cli/format"
|
||||||
|
)
|
||||||
|
|
||||||
|
type dummyItem struct {
|
||||||
|
MyString string
|
||||||
|
MyInt int
|
||||||
|
MySub subItem
|
||||||
|
}
|
||||||
|
|
||||||
|
type subItem struct {
|
||||||
|
MyBool bool
|
||||||
|
}
|
||||||
|
|
||||||
|
var dummyItems = []any{
|
||||||
|
dummyItem{
|
||||||
|
MyString: "Foo",
|
||||||
|
MyInt: 1,
|
||||||
|
MySub: subItem{
|
||||||
|
MyBool: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
dummyItem{
|
||||||
|
MyString: "Bar",
|
||||||
|
MyInt: 0,
|
||||||
|
MySub: subItem{
|
||||||
|
MyBool: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWriterNoHints(t *testing.T) {
|
||||||
|
var buf bytes.Buffer
|
||||||
|
|
||||||
|
writer := NewWriter(DefaultCompactModeMaxColumnWidth)
|
||||||
|
|
||||||
|
if err := writer.Write(&buf, format.Hints{}, dummyItems...); err != nil {
|
||||||
|
t.Fatalf("%+v", errors.WithStack(err))
|
||||||
|
}
|
||||||
|
|
||||||
|
expected := `+----------+-------+------------------+
|
||||||
|
| MYSTRING | MYINT | MYSUB |
|
||||||
|
+----------+-------+------------------+
|
||||||
|
| Foo | 1 | {"MyBool":false} |
|
||||||
|
| Bar | 0 | {"MyBool":true} |
|
||||||
|
+----------+-------+------------------+`
|
||||||
|
|
||||||
|
if e, g := strings.TrimSpace(expected), strings.TrimSpace(buf.String()); e != g {
|
||||||
|
t.Errorf("buf.String(): expected \n%v\ngot\n%v", e, g)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWriterWithPropHints(t *testing.T) {
|
||||||
|
var buf bytes.Buffer
|
||||||
|
|
||||||
|
writer := NewWriter(DefaultCompactModeMaxColumnWidth)
|
||||||
|
|
||||||
|
hints := format.Hints{
|
||||||
|
Props: []format.Prop{
|
||||||
|
format.NewProp("MyString", "MyString"),
|
||||||
|
format.NewProp("MyInt", "MyInt"),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := writer.Write(&buf, hints, dummyItems...); err != nil {
|
||||||
|
t.Fatalf("%+v", errors.WithStack(err))
|
||||||
|
}
|
||||||
|
|
||||||
|
expected := `+----------+-------+
|
||||||
|
| MYSTRING | MYINT |
|
||||||
|
+----------+-------+
|
||||||
|
| Foo | 1 |
|
||||||
|
| Bar | 0 |
|
||||||
|
+----------+-------+`
|
||||||
|
|
||||||
|
if e, g := strings.TrimSpace(expected), strings.TrimSpace(buf.String()); e != g {
|
||||||
|
t.Errorf("buf.String(): expected \n%v\ngot\n%v", e, g)
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
package format
|
||||||
|
|
||||||
|
import "io"
|
||||||
|
|
||||||
|
type OutputMode string
|
||||||
|
|
||||||
|
const (
|
||||||
|
OutputModeWide OutputMode = "wide"
|
||||||
|
OutputModeCompact OutputMode = "compact"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Hints struct {
|
||||||
|
Props []Prop
|
||||||
|
OutputMode OutputMode
|
||||||
|
}
|
||||||
|
|
||||||
|
type Writer interface {
|
||||||
|
Write(writer io.Writer, hints Hints, data ...any) error
|
||||||
|
}
|
1
go.mod
1
go.mod
|
@ -28,6 +28,7 @@ require (
|
||||||
github.com/golang/groupcache v0.0.0-20191027212112-611e8accdfc9 // indirect
|
github.com/golang/groupcache v0.0.0-20191027212112-611e8accdfc9 // indirect
|
||||||
github.com/golang/protobuf v1.5.3 // indirect
|
github.com/golang/protobuf v1.5.3 // indirect
|
||||||
github.com/google/go-cmp v0.6.0 // indirect
|
github.com/google/go-cmp v0.6.0 // indirect
|
||||||
|
github.com/jedib0t/go-pretty/v6 v6.4.9
|
||||||
github.com/leodido/go-urn v1.2.1 // indirect
|
github.com/leodido/go-urn v1.2.1 // indirect
|
||||||
github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
|
github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
|
||||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||||
|
|
6
go.sum
6
go.sum
|
@ -102,6 +102,8 @@ github.com/gorilla/sessions v1.2.0/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/z
|
||||||
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||||
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||||
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
||||||
|
github.com/jedib0t/go-pretty/v6 v6.4.9 h1:vZ6bjGg2eBSrJn365qlxGcaWu09Id+LHtrfDWlB2Usc=
|
||||||
|
github.com/jedib0t/go-pretty/v6 v6.4.9/go.mod h1:Ndk3ase2CkQbXLLNf5QDHoYb6J9WtVfmHZu9n8rk2xs=
|
||||||
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
|
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
|
||||||
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/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||||
|
@ -125,6 +127,7 @@ github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/
|
||||||
github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA=
|
github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA=
|
||||||
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||||
github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk=
|
github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk=
|
||||||
|
github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
|
||||||
github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U=
|
github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U=
|
||||||
github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
|
github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
|
||||||
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||||
|
@ -139,6 +142,7 @@ github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE
|
||||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
|
github.com/pkg/profile v1.6.0/go.mod h1:qBsxPvzyUincmltOk6iyRVxHYg4adc0OFOv72ZdLa18=
|
||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
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/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||||
|
@ -157,6 +161,7 @@ github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UV
|
||||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
|
github.com/stretchr/testify v1.7.4/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||||
github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8=
|
github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8=
|
||||||
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||||
|
@ -231,6 +236,7 @@ golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20191210023423-ac6580df4449/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20191210023423-ac6580df4449/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ=
|
golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ=
|
||||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA=
|
golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA=
|
||||||
|
|
Loading…
Reference in New Issue