Skip to content

Commit

Permalink
experiment with getting valid topic offsets
Browse files Browse the repository at this point in the history
  • Loading branch information
jbvmio committed Feb 6, 2023
1 parent 227020a commit 2781f40
Show file tree
Hide file tree
Showing 10 changed files with 150 additions and 32 deletions.
7 changes: 7 additions & 0 deletions cli/cmd/lag/getLag.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import (
var lagFlags kafka.LagFlags
var onlyTotal bool

var ValidOffsets bool

var CmdGetLag = &cobra.Command{
Use: "lag",
Short: "Get Lag Info",
Expand All @@ -31,6 +33,11 @@ var CmdGetLag = &cobra.Command{
totalLag = kafka.FindTotalLag()
onlyTotal = true
}
if ValidOffsets {
for i := 0; i < len(lag); i++ {
lag[i].GetValid()
}
}
switch true {
case cmd.Flags().Changed("out"):
outFmt, err := cmd.Flags().GetString("out")
Expand Down
3 changes: 3 additions & 0 deletions cli/cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (
"github.com/jbvmio/kafkactl/cli/cmd/get"
"github.com/jbvmio/kafkactl/cli/cmd/msg"
"github.com/jbvmio/kafkactl/cli/cmd/send"
"github.com/jbvmio/kafkactl/cli/cmd/test"
"github.com/jbvmio/kafkactl/cli/cmd/zk"
"github.com/jbvmio/kafkactl/cli/kafka"
"github.com/jbvmio/kafkactl/cli/x/out"
Expand Down Expand Up @@ -97,6 +98,8 @@ func init() {
rootCmd.AddCommand(zk.CmdZK)
rootCmd.AddCommand(bur.CmdBur)

rootCmd.AddCommand(test.CmdTest)

}

func initConfig() {
Expand Down
26 changes: 24 additions & 2 deletions cli/cmd/topic/descTopic.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,18 @@ import (
"github.com/spf13/cobra"
)

var validOffsets bool

var CmdDescTopic = &cobra.Command{
Use: "topic",
Aliases: []string{"topics"},
Short: "Get Topic Details",
Args: cobra.MinimumNArgs(1),
Run: func(cmd *cobra.Command, args []string) {
lag.ValidOffsets = validOffsets
var tom []kafkactl.TopicOffsetMap
switch true {
var vTom kafka.ValidOffsetTOM
switch {
case topicFlags.Lag:
lag.CmdGetLag.Run(cmd, args)
return
Expand All @@ -25,20 +29,38 @@ var CmdDescTopic = &cobra.Command{
default:
tom = kafka.SearchTOM(args...)
}
switch true {

if validOffsets {
vo := kafka.GetValidOffsets(tom)
vTom = kafka.ValidOffsetTOM{
Tom: tom,
ValidOffsets: vo,
}
}

switch {
case cmd.Flags().Changed("out"):
outFmt, err := cmd.Flags().GetString("out")
if err != nil {
out.Warnf("WARN: %v", err)
}
if validOffsets {
out.IfErrf(out.Marshal(vTom, outFmt))
return
}
out.IfErrf(out.Marshal(tom, outFmt))
default:
if validOffsets {
kafka.PrintOut(vTom)
return
}
kafka.PrintOut(tom)
}
},
}

func init() {
CmdDescTopic.Flags().BoolVar(&topicFlags.Lag, "lag", false, "Show Any Lag from Specified Topics.")
CmdDescTopic.Flags().BoolVar(&validOffsets, "valid-offsets", false, "Discover Valid Offsets from Specified Topics.")
CmdDescTopic.Flags().Int32SliceVar(&topicFlags.Leaders, "leader", []int32{}, "Filter Topic Partitions by Current Leaders")
}
2 changes: 2 additions & 0 deletions cli/cmd/topic/getTopic.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ var CmdGetTopic = &cobra.Command{
Short: "Get Topic Info",
Run: func(cmd *cobra.Command, args []string) {
var topicSummaries []kafkactl.TopicSummary
lag.ValidOffsets = validOffsets
switch {
case topicFlags.Lag:
lag.CmdGetLag.Run(cmd, args)
Expand Down Expand Up @@ -50,5 +51,6 @@ func init() {
CmdGetTopic.Flags().BoolVar(&topicFlags.Describe, "describe", false, "Shortcut/Pass to Describe Command.")
CmdGetTopic.Flags().BoolVar(&topicFlags.Group, "groups", false, "Show Active Groups Consuming from Specified Topics.")
CmdGetTopic.Flags().BoolVar(&topicFlags.Lag, "lag", false, "Show Any Lag from Specified Topics.")
CmdGetTopic.Flags().BoolVar(&validOffsets, "valid-offsets", false, "Discover Valid Offsets from Specified Topics.")
CmdGetTopic.Flags().Int32SliceVar(&topicFlags.Leaders, "leader", []int32{}, "Filter Topic Partitions by Current Leaders")
}
25 changes: 18 additions & 7 deletions cli/kafka/lag.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,15 @@ type GrpLag struct {

// PartitionLag struct def:
type PartitionLag struct {
Group string
Topic string
Partition int32
Host string
Member string
Offset int64
Lag int64
Group string
Topic string
Partition int32
Host string
Member string
Offset int64
Lag int64
ValidOffset int64
ValidLag int64
}

// TotalLag struct def:
Expand All @@ -51,6 +53,15 @@ type TotalLag struct {
TotalLag int64
}

func (PL *PartitionLag) GetValid() {
vOff, err := GetLastValidOffset(PL.Topic, PL.Partition, PL.Offset)
if err != nil {
closeFatal("error retrieving last valid offset: %v\n", err)
}
PL.ValidOffset = vOff
PL.ValidLag = PL.Offset - vOff
}

func FindPartitionLag() []PartitionLag {
grpMeta, err := client.GetGroupMeta()
handleC("Metadata Error: %v", err)
Expand Down
4 changes: 4 additions & 0 deletions cli/kafka/offsets.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ type TopicPartitionMeta struct {
TopicLeader int32
}

func GetLastValidOffset(topic string, partition int32, fromOffset int64) (int64, error) {
return client.GetLastValidOffset(topic, partition, fromOffset)
}

func getGroupTopicOffsets(group, topic string) []GroupTopicOffsetMeta {
exact = true
var GTMeta []GroupTopicOffsetMeta
Expand Down
22 changes: 19 additions & 3 deletions cli/kafka/print.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,14 @@ func PrintOut(i interface{}) {
for _, v := range i {
tbl.AddRow(v.Topic, v.Parts, v.RFactor, v.ISRs, v.OfflineReplicas)
}

case ValidOffsetTOM:
tbl = table.New("TOPIC", "PART", "BROKER.OFFSET", "VALID.OFFSET", "LEADER", "REPLICAS", "ISRs", "OFFLINE")
for _, v := range i.Tom {
for _, p := range v.TopicMeta {
tbl.AddRow(p.Topic, p.Partition, v.PartitionOffsets[p.Partition], i.ValidOffsets[p.Topic][p.Partition], p.Leader, p.Replicas, p.ISRs, p.OfflineReplicas)
}
}
case []kafkactl.TopicOffsetMap:
tbl = table.New("TOPIC", "PART", "OFFSET", "LEADER", "REPLICAS", "ISRs", "OFFLINE")
for _, v := range i {
Expand All @@ -65,9 +73,17 @@ func PrintOut(i interface{}) {
}
}
case []PartitionLag:
tbl = table.New("GROUP", "TOPIC", "PART", "MEMBER", "OFFSET", "LAG", "HOST")
for _, v := range i {
tbl.AddRow(v.Group, v.Topic, v.Partition, v.Member, v.Offset, v.Lag, v.Host)
switch {
case i[0].ValidOffset != 0:
tbl = table.New("GROUP", "TOPIC", "PART", "MEMBER", "OFFSET", "LAG", "VALID.LAG", "HOST")
for _, v := range i {
tbl.AddRow(v.Group, v.Topic, v.Partition, v.Member, v.Offset, v.Lag, v.ValidLag, v.Host)
}
default:
tbl = table.New("GROUP", "TOPIC", "PART", "MEMBER", "BROKER.OFFSET", "LAG", "HOST")
for _, v := range i {
tbl.AddRow(v.Group, v.Topic, v.Partition, v.Member, v.Offset, v.Lag, v.Host)
}
}
case []TotalLag:
tbl = table.New("GROUP", "TOPIC", "TOTALLAG")
Expand Down
53 changes: 53 additions & 0 deletions cli/kafka/topics.go
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,59 @@ func FilterTOMByLeader(tom []kafkactl.TopicOffsetMap, leaders []int32) []kafkact
return TOM
}

// FilterTOMByPartitions needs testing ...
func FilterTOMByPartitions(tom []kafkactl.TopicOffsetMap, partitions []int32) []kafkactl.TopicOffsetMap {
var TOM []kafkactl.TopicOffsetMap
done := make(map[string]struct{})
for _, t := range tom {
var topicMeta []kafkactl.TopicMeta
partOffsets := make(map[int32]int64)
leaderOffsets := make(map[int32]int32)
if _, there := done[t.Topic]; !there {
done[t.Topic] = struct{}{}
for _, tm := range t.TopicMeta {
for _, part := range partitions {
if _, ok := t.PartitionOffsets[part]; ok {
topicMeta = append(topicMeta, tm)
partOffsets[tm.Partition] = t.PartitionOffsets[tm.Partition]
leaderOffsets[part] = t.PartitionLeaders[part]
}
}
}
}
tom := kafkactl.TopicOffsetMap{
Topic: t.Topic,
TopicMeta: topicMeta,
PartitionOffsets: partOffsets,
PartitionLeaders: leaderOffsets,
}
TOM = append(TOM, tom)
}
return TOM
}

type ValidOffsetTOM struct {
Tom []kafkactl.TopicOffsetMap
ValidOffsets map[string]map[int32]int64
}

func GetValidOffsets(tom []kafkactl.TopicOffsetMap) map[string]map[int32]int64 {
validOffsets := make(map[string]map[int32]int64)
for _, topic := range tom {
for part, offset := range topic.PartitionOffsets {
vOff, err := GetLastValidOffset(topic.Topic, part, offset)
if err != nil {
closeFatal("error retrieving last valid offset: %v\n", err)
}
if validOffsets[topic.Topic] == nil {
validOffsets[topic.Topic] = make(map[int32]int64)
}
validOffsets[topic.Topic][part] = vOff
}
}
return validOffsets
}

func validateLeaders(leaders []int32) {
pMap := make(map[int32]bool, len(leaders))
for _, p := range leaders {
Expand Down
12 changes: 6 additions & 6 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ go 1.19
replace github.com/jbvmio/kafka => ../kafka

require (
github.com/Shopify/sarama v1.37.2
github.com/Shopify/sarama v1.38.1
github.com/fatih/color v1.7.0
github.com/gizak/termui v2.2.1-0.20180111180145-a433c24293cf+incompatible
github.com/jbvmio/burrow v0.0.0-20190204223802-646e7559142e
Expand All @@ -26,7 +26,7 @@ require (
github.com/BurntSushi/toml v1.2.1 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/eapache/go-resiliency v1.3.0 // indirect
github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21 // indirect
github.com/eapache/go-xerial-snappy v0.0.0-20230111030713-bf00bc1b83b6 // indirect
github.com/eapache/queue v1.1.0 // indirect
github.com/fsnotify/fsnotify v1.4.7 // indirect
github.com/golang/snappy v0.0.4 // indirect
Expand All @@ -40,7 +40,7 @@ require (
github.com/jcmturner/gofork v1.7.6 // indirect
github.com/jcmturner/gokrb5/v8 v8.4.3 // indirect
github.com/jcmturner/rpc/v2 v2.0.3 // indirect
github.com/klauspost/compress v1.15.12 // indirect
github.com/klauspost/compress v1.15.14 // indirect
github.com/magiconair/properties v1.8.0 // indirect
github.com/maruel/panicparse v1.1.1 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
Expand All @@ -58,7 +58,7 @@ require (
github.com/spf13/pflag v1.0.4-0.20181223182923-24fa6976df40 // indirect
github.com/tidwall/match v1.1.1 // indirect
golang.org/x/crypto v0.1.0 // indirect
golang.org/x/net v0.1.0 // indirect
golang.org/x/sys v0.2.0 // indirect
golang.org/x/text v0.4.0 // indirect
golang.org/x/net v0.5.0 // indirect
golang.org/x/sys v0.4.0 // indirect
golang.org/x/text v0.6.0 // indirect
)
28 changes: 14 additions & 14 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
github.com/BurntSushi/toml v1.2.1 h1:9F2/+DoOYIOksmaJFPw1tGFy1eDnIJXg+UHjuD8lTak=
github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
github.com/Shopify/sarama v1.37.2 h1:LoBbU0yJPte0cE5TZCGdlzZRmMgMtZU/XgnUKZg9Cv4=
github.com/Shopify/sarama v1.37.2/go.mod h1:Nxye/E+YPru//Bpaorfhc3JsSGYwCaDDj+R4bK52U5o=
github.com/Shopify/sarama v1.38.1 h1:lqqPUPQZ7zPqYlWpTh+LQ9bhYNu2xJL6k1SJN4WVe2A=
github.com/Shopify/sarama v1.38.1/go.mod h1:iwv9a67Ha8VNa+TifujYoWGxWnu2kNVAQdSdZ4X2o5g=
github.com/Shopify/toxiproxy/v2 v2.5.0 h1:i4LPT+qrSlKNtQf5QliVjdP08GyAH8+BUIc9gT0eahc=
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
Expand All @@ -12,8 +12,8 @@ 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/eapache/go-resiliency v1.3.0 h1:RRL0nge+cWGlxXbUzJ7yMcq6w2XBEr19dCN6HECGaT0=
github.com/eapache/go-resiliency v1.3.0/go.mod h1:5yPzW0MIvSe0JDsv0v+DvcjEv2FyD6iZYSs1ZI+iQho=
github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21 h1:YEetp8/yCZMuEPMUDHG0CW/brkkEp8mzqk2+ODEitlw=
github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU=
github.com/eapache/go-xerial-snappy v0.0.0-20230111030713-bf00bc1b83b6 h1:8yY/I9ndfrgrXUbOGObLHKBR4Fl3nZXwM2c7OYTT8hM=
github.com/eapache/go-xerial-snappy v0.0.0-20230111030713-bf00bc1b83b6/go.mod h1:YvSRo5mw33fLEx1+DlK6L2VV43tJt5Eyel9n9XBcR+0=
github.com/eapache/queue v1.1.0 h1:YOEu7KNc61ntiQlcEeUIoDTJ2o8mQznoNvUhiigpIqc=
github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=
github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys=
Expand Down Expand Up @@ -57,8 +57,8 @@ github.com/jcmturner/gokrb5/v8 v8.4.3 h1:iTonLeSJOn7MVUtyMT+arAn5AKAPrkilzhGw8wE
github.com/jcmturner/gokrb5/v8 v8.4.3/go.mod h1:dqRwJGXznQrzw6cWmyo6kH+E7jksEQG/CyVWsJEsJO0=
github.com/jcmturner/rpc/v2 v2.0.3 h1:7FXXj8Ti1IaVFpSAziCZWNzbNuZmnvw/i6CqLNdWfZY=
github.com/jcmturner/rpc/v2 v2.0.3/go.mod h1:VUJYCIDm3PVOEHw8sgt091/20OJjskO/YJki3ELg/Hc=
github.com/klauspost/compress v1.15.12 h1:YClS/PImqYbn+UILDnqxQCZ3RehC9N318SU3kElDUEM=
github.com/klauspost/compress v1.15.12/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM=
github.com/klauspost/compress v1.15.14 h1:i7WCKDToww0wA+9qrUZ1xOjp218vfFo3nTU6UHp+gOc=
github.com/klauspost/compress v1.15.14/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM=
github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/magiconair/properties v1.8.0 h1:LLgXmsheXeRoUOBOjtwPQCWIYqM/LU1ayDtDePerRcY=
Expand Down Expand Up @@ -115,8 +115,8 @@ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
github.com/tidwall/gjson v1.12.1 h1:ikuZsLdhr8Ws0IdROXUS1Gi4v9Z4pGqpX/CvJkxvfpo=
github.com/tidwall/gjson v1.12.1/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
Expand All @@ -133,9 +133,9 @@ golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw
golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220725212005-46097bf591d3/go.mod h1:AaygXjzTFtRAg2ttMY5RMuhpJ3cNnI0XpyFJD1iQRSM=
golang.org/x/net v0.1.0 h1:hZ/3BUoy5aId7sCpA/Tc5lt8DkFgdVS2onTpJsZ/fl0=
golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco=
golang.org/x/sync v0.0.0-20220923202941-7f9b1623fab7 h1:ZrnxWX62AgTKOSagEqxvb3ffipvEDX2pl7E1TdqLqIc=
golang.org/x/net v0.5.0 h1:GyT4nK/YDHSqa1c4753ouYCDajOYKTja9Xb/OHtgvSw=
golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws=
golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
Expand All @@ -144,15 +144,15 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.2.0 h1:ljd4t30dBnAvMZaQCevtY0xLLD0A+bRZXbgLMLU1F/A=
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.4.0 h1:Zr2JFtRQNX3BCZ8YtxRE9hNJYC8J6I1MVbMg6owUp18=
golang.org/x/sys v0.4.0/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-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.4.0 h1:BrVqGRd7+k1DiOgtnFvAkoQEWQvBc25ouMJM6429SFg=
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.6.0 h1:3XmdazWV+ubf7QgHSTWeykHOci5oeekaGJBLkrkaw4k=
golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
Expand Down

0 comments on commit 2781f40

Please sign in to comment.