diff --git a/.circleci/config.yml b/.circleci/config.yml index f8426c8..b574df9 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1,12 +1,10 @@ version: 2 jobs: test: - working_directory: /go/src/github.com/segmentio/data-digger docker: - - image: circleci/golang:1.14 + - image: cimg/go:1.24.4 environment: GO111MODULE: "on" - ECR_ENABLED: True DIGGER_TEST_KAFKA_ADDR: "kafka:9092" DIGGER_TEST_S3_ADDR: "http://localstack:4572" @@ -38,9 +36,6 @@ jobs: - setup_remote_docker: reusable: true docker_layer_caching: true - - restore_cache: - keys: - - go-modules-{{ checksum "go.sum" }} - run: name: Run tests command: make test @@ -49,36 +44,6 @@ jobs: environment: SNYK_LEVEL: 'FLHI' command: curl -sL https://raw.githubusercontent.com/segmentio/snyk_helpers/master/initialization/snyk.sh | sh - - save_cache: - key: go-modules-{{ checksum "go.sum" }} - paths: - - "/go/pkg/mod" - - publish-ecr: - working_directory: /go/src/github.com/segmentio/data-digger - docker: - - image: circleci/golang:1.14 - - steps: - - checkout - - setup_remote_docker: - reusable: true - docker_layer_caching: true - - run: - name: ECR Login - command: | - curl -O https://bootstrap.pypa.io/get-pip.py && python get-pip.py - pip install awscli==1.16.292 - $(aws ecr get-login --no-include-email --region ${AWS_REGION} --registry-ids ${AWS_ACCOUNT_ID}) - - run: - name: Build and push image - command: | - export SHORT_GIT_SHA=$(echo ${CIRCLE_SHA1} | cut -c -7) - docker build \ - -t ${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com/data-digger:${SHORT_GIT_SHA} \ - --build-arg VERSION=${SHORT_GIT_SHA} \ - . - docker push ${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com/data-digger:${SHORT_GIT_SHA} workflows: version: 2 @@ -89,9 +54,3 @@ workflows: filters: tags: only: /.*/ - - publish-ecr: - context: segmentio-org-global - requires: [test] - filters: - tags: - only: /.*/ diff --git a/Dockerfile b/Dockerfile index 90c5ff1..72ff254 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,5 @@ -FROM golang:1.14 as builder -ENV SRC github.com/segmentio/data-digger +FROM golang:1.24.4 AS builder +ENV SRC=github.com/segmentio/data-digger ENV CGO_ENABLED=0 COPY . /go/src/${SRC} diff --git a/Makefile b/Makefile index c0ca682..5984d32 100644 --- a/Makefile +++ b/Makefile @@ -1,23 +1,17 @@ -ifndef VERSION - VERSION := $(shell git describe --tags --always --dirty="-dev") -endif - PKG := ./cmd/digger BIN := build/digger -LDFLAGS := -ldflags='-X "main.version=$(VERSION)"' - .PHONY: digger digger: - go build -o $(BIN) $(LDFLAGS) $(PKG) + go build -o $(BIN) $(PKG) .PHONY: digger-linux digger-linux: - $QGOOS=linux GOARCH=amd64 go build -o build/digger-linux $(LDFLAGS) ./cmd/digger + $QGOOS=linux GOARCH=amd64 go build -o build/digger-linux ./cmd/digger .PHONY: install install: - go install $(LDFLAGS) $(PKG) + go install $(PKG) .PHONY: vet vet: @@ -33,4 +27,4 @@ test: vet .PHONY: clean clean: - rm -Rf build + rm -Rf build vendor test_inputs diff --git a/NOTICE b/NOTICE index 11f0aba..cec6e64 100644 --- a/NOTICE +++ b/NOTICE @@ -1,3 +1,41 @@ topicctl Copyright 2020 Segment.io, Inc. Released under the MIT License. See LICENSE for license terms and conditions. + +This project includes the following open source code: + +AWS SDK for go Copyright © Amazon.com, Inc. +License: Apache 2.0 (http://www.apache.org/licenses/LICENSE‐2.0.html) + +cli Copyright © Segment.io, Inc. +License: MIT (https://opensource.org/licenses/MIT) + +encoding Copyright © Segment.io, Inc. +License: MIT (https://opensource.org/licenses/MIT) + +gjson Copyright © Josh Baker +License: MIT (https://opensource.org/licenses/MIT) + +gogo Copyright © The GoGo Authors +License: 3-Clause BSD (https://opensource.org/licenses/BSD-3-Clause) + +kafka-go Copyright © Segment.io, Inc. +License: MIT (https://opensource.org/licenses/MIT) + +logrus Copyright © Simon Eskildsen +License: MIT (https://opensource.org/licenses/MIT) + +logrus-prefixed-formatter Copyright © Denis Parchenko +License: MIT (https://opensource.org/licenses/MIT) + +spinner Copyright © Brian Downs +License: Apache 2.0 (http://www.apache.org/licenses/LICENSE‐2.0.html) + +tablewriter Copyright © Oleku Konko +License: MIT (https://opensource.org/licenses/MIT) + +testify Copyright © Mat Ryer, Tyler Bunnell and contributors +License: MIT (https://opensource.org/licenses/MIT) + +uilive Copyright © Greg Osuri +License: MIT (https://opensource.org/licenses/MIT) diff --git a/README.md b/README.md index 60d1c88..74be515 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,5 @@ [![Circle CI](https://circleci.com/gh/segmentio/data-digger.svg?style=svg&circle-token=567fa1e91d2191b3158e7e0d2145cb3cda9d6f83)](https://circleci.com/gh/segmentio/data-digger) +[![Go Report Card](https://goreportcard.com/badge/github.com/segmentio/data-digger)](https://goreportcard.com/report/github.com/segmentio/data-digger) # data-digger The data-digger is a simple tool for "digging" through JSON or protobuf-formatted @@ -141,9 +142,9 @@ The `kafka` subcommand exposes a number of options to configure the underlying K -a, --address string kafka address -o, --offset int64 kafka offset (default: -1) -p, --partitions string comma-separated list of partitions - --since duration time to start at relative to now + --since string time to start at; can be either RFC3339 timestamp or duration relative to now -t, --topic string kafka topic - --until duration time to end at relative to now + --until string time to end at; can be either RFC3339 timestamp or duration relative to now ``` The `address` and `topic` options are required; the others are optional and will default to diff --git a/cmd/digger/main.go b/cmd/digger/main.go index b644b1c..f469091 100644 --- a/cmd/digger/main.go +++ b/cmd/digger/main.go @@ -4,29 +4,14 @@ import ( "context" "os" "os/signal" - "plugin" - "strings" "syscall" "github.com/segmentio/cli" - dig "github.com/segmentio/data-digger/pkg/digger" + "github.com/segmentio/data-digger/cmd/digger/subcmd" log "github.com/sirupsen/logrus" prefixed "github.com/x-cray/logrus-prefixed-formatter" ) -type commonConfig struct { - Debug bool `flag:"--debug" help:"turn on debug logging" default:"false"` - Filter string `flag:"-f,--filter" help:"filter regexp to apply before generating stats" default:"-"` - K int `flag:"-k,--num-categories" help:"number of top values to show" default:"25"` - Numeric bool `flag:"--numeric" help:"treat values as numbers instead of strings" default:"false"` - PathsStr string `flag:"--paths" help:"comma-separated list of paths to generate stats for" default:"-"` - Plugins string `flag:"--plugins" help:"comma-separated list of golang plugins to load at start" default:"-"` - PrintMissing bool `flag:"--print-missing" help:"print out messages that missing all paths" default:"false"` - Raw bool `flag:"--raw" help:"show raw messages that pass filters" default:"false"` - RawExtended bool `flag:"--raw-extended" help:"show extended info about messages that pass filters" default:"false"` - SortByName bool `flag:"--sort-by-name" help:"sort top k values by their category/key names" default:"false"` -} - func init() { log.SetFormatter(&prefixed.TextFormatter{ TimestampFormat: "2006-01-02 15:04:05", @@ -38,7 +23,7 @@ func main() { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - sigChan := make(chan os.Signal) + sigChan := make(chan os.Signal, 1) signal.Notify(sigChan, os.Interrupt, syscall.SIGTERM) go func() { @@ -49,47 +34,10 @@ func main() { cli.Exec( cli.CommandSet{ - "file": fileCmd(ctx), - "kafka": kafkaCmd(ctx), - "s3": s3Cmd(ctx), - "version": versionCmd(ctx), - }, - ) -} - -func makeProcessors(config commonConfig, protoTypes []string) ([]dig.Processor, error) { - liveStats, err := dig.NewLiveStats( - dig.LiveStatsConfig{ - K: config.K, - Filter: config.Filter, - Numeric: config.Numeric, - PrintMissing: config.PrintMissing, - ProtoTypes: protoTypes, - PathsStr: config.PathsStr, - Raw: config.Raw, - RawExtended: config.RawExtended, - SortByName: config.SortByName, + "file": subcmd.FileCmd(ctx), + "kafka": subcmd.KafkaCmd(ctx), + "s3": subcmd.S3Cmd(ctx), + "version": subcmd.VersionCmd(ctx), }, ) - if err != nil { - return nil, err - } - - return []dig.Processor{liveStats}, nil -} - -func loadPlugins(pathsStr string) error { - if pathsStr == "" { - return nil - } - - paths := strings.Split(pathsStr, ",") - for _, path := range paths { - _, err := plugin.Open(path) - if err != nil { - return err - } - } - - return nil } diff --git a/cmd/digger/subcmd/common.go b/cmd/digger/subcmd/common.go new file mode 100644 index 0000000..52c1eae --- /dev/null +++ b/cmd/digger/subcmd/common.go @@ -0,0 +1,60 @@ +package subcmd + +import ( + "plugin" + "strings" + + dig "github.com/segmentio/data-digger/pkg/digger" + log "github.com/sirupsen/logrus" +) + +type commonConfig struct { + Debug bool `flag:"--debug" help:"turn on debug logging" default:"false"` + Filter string `flag:"-f,--filter" help:"filter regexp to apply before generating stats" default:"-"` + K int `flag:"-k,--num-categories" help:"number of top values to show" default:"25"` + Numeric bool `flag:"--numeric" help:"treat values as numbers instead of strings" default:"false"` + PathsStr string `flag:"--paths" help:"comma-separated list of paths to generate stats for" default:"-"` + Plugins string `flag:"--plugins" help:"comma-separated list of golang plugins to load at start" default:"-"` + PrintMissing bool `flag:"--print-missing" help:"print out messages that missing all paths" default:"false"` + Raw bool `flag:"--raw" help:"show raw messages that pass filters" default:"false"` + RawExtended bool `flag:"--raw-extended" help:"show extended info about messages that pass filters" default:"false"` + SortByName bool `flag:"--sort-by-name" help:"sort top k values by their category/key names" default:"false"` +} + +func makeProcessors(config commonConfig, protoTypes []string) ([]dig.Processor, error) { + liveStats, err := dig.NewLiveStats( + dig.LiveStatsConfig{ + K: config.K, + Filter: config.Filter, + Numeric: config.Numeric, + PrintMissing: config.PrintMissing, + ProtoTypes: protoTypes, + PathsStr: config.PathsStr, + Raw: config.Raw, + RawExtended: config.RawExtended, + SortByName: config.SortByName, + }, + ) + if err != nil { + return nil, err + } + + return []dig.Processor{liveStats}, nil +} + +func loadPlugins(pathsStr string) error { + if pathsStr == "" { + return nil + } + + paths := strings.Split(pathsStr, ",") + for _, path := range paths { + log.Debugf("Loading plugin at path %s", path) + _, err := plugin.Open(path) + if err != nil { + return err + } + } + + return nil +} diff --git a/cmd/digger/file.go b/cmd/digger/subcmd/file.go similarity index 84% rename from cmd/digger/file.go rename to cmd/digger/subcmd/file.go index b31b8a8..1aee2a8 100644 --- a/cmd/digger/file.go +++ b/cmd/digger/subcmd/file.go @@ -1,4 +1,4 @@ -package main +package subcmd import ( "context" @@ -16,7 +16,8 @@ type fileConfig struct { Recursive bool `flag:"--recursive" help:"scan subdirectories recursively" default:"false"` } -func fileCmd(ctx context.Context) cli.Function { +// FileCmd defines a CLI function for digging through local files. +func FileCmd(ctx context.Context) cli.Function { return cli.Command( func(config fileConfig) { if config.Debug { @@ -24,7 +25,10 @@ func fileCmd(ctx context.Context) cli.Function { } else { log.SetLevel(log.InfoLevel) } - loadPlugins(config.Plugins) + err := loadPlugins(config.Plugins) + if err != nil { + log.Fatalf("Could not load plugins: %+v", err) + } processors, err := makeProcessors(config.commonConfig, []string{}) if err != nil { diff --git a/cmd/digger/kafka.go b/cmd/digger/subcmd/kafka.go similarity index 62% rename from cmd/digger/kafka.go rename to cmd/digger/subcmd/kafka.go index d37e783..667da56 100644 --- a/cmd/digger/kafka.go +++ b/cmd/digger/subcmd/kafka.go @@ -1,12 +1,10 @@ -package main +package subcmd import ( "context" - "errors" "strings" "time" - "github.com/hashicorp/go-multierror" "github.com/segmentio/cli" dig "github.com/segmentio/data-digger/pkg/digger" "github.com/segmentio/data-digger/pkg/util" @@ -17,16 +15,17 @@ import ( type kafkaConfig struct { commonConfig - Address string `flag:"-a,--address" help:"kafka address"` - Offset int64 `flag:"-o,--offset" help:"kafka offset" default:"-1"` - Partitions string `flag:"-p,--partitions" help:"comma-separated list of partitions" default:"-"` - ProtoTypes string `flag:"--proto-types" help:"comma-separated list of registered proto types" default:"-"` - Since time.Duration `flag:"--since" help:"time to start at (relative to now)" default:"-"` - Topic string `flag:"-t,--topic" help:"kafka topic"` - Until time.Duration `flag:"--until" help:"time to end at (relative to now)" default:"-"` + Address string `flag:"-a,--address" help:"kafka address"` + Offset int64 `flag:"-o,--offset" help:"kafka offset" default:"-1"` + Partitions string `flag:"-p,--partitions" help:"comma-separated list of partitions" default:"-"` + ProtoTypes string `flag:"--proto-types" help:"comma-separated list of registered proto types" default:"-"` + SinceStr string `flag:"--since" help:"time to start at; can be either RFC3339 timestamp or duration relative to now" default:"-"` + Topic string `flag:"-t,--topic" help:"kafka topic"` + UntilStr string `flag:"--until" help:"time to end at; can be either RFC3339 timestamp or duration relative to now" default:"-"` } -func kafkaCmd(ctx context.Context) cli.Function { +// KafkaCmd defines a CLI function for digging through Kafka messages. +func KafkaCmd(ctx context.Context) cli.Function { return cli.Command( func(config kafkaConfig) { if config.Debug { @@ -34,10 +33,26 @@ func kafkaCmd(ctx context.Context) cli.Function { } else { log.SetLevel(log.InfoLevel) } - loadPlugins(config.Plugins) + err := loadPlugins(config.Plugins) + if err != nil { + log.Fatalf("Could not load plugins: %+v", err) + } + + now := time.Now().UTC() + since, err := util.ParseTimeOrDuration(config.SinceStr, now) + if err != nil { + log.Fatalf("Error parsing since flag: %+v", err) + } + until, err := util.ParseTimeOrDuration(config.UntilStr, now) + if err != nil { + log.Fatalf("Error parsing until flag: %+v", err) + } - if err := validateKafkaConfig(config); err != nil { - log.Fatalf("Config not valid: %+v", err) + if !since.IsZero() && since.After(now) { + log.Fatalf("Since must be in past") + } + if !since.IsZero() && !until.IsZero() && since.After(until) { + log.Fatalf("Until must be after since") } partitions, total, err := readKafkaPartitions( @@ -74,8 +89,8 @@ func kafkaCmd(ctx context.Context) cli.Function { Address: config.Address, Topic: config.Topic, Offset: config.Offset, - Since: config.Since, - Until: config.Until, + Since: since, + Until: until, Partitions: partitions, MinBytes: 10e3, MaxBytes: 10e6, @@ -102,25 +117,6 @@ func kafkaCmd(ctx context.Context) cli.Function { ) } -func validateKafkaConfig(config kafkaConfig) error { - var err error - - if config.Since > 0 { - err = multierror.Append( - err, - errors.New("since must be in past"), - ) - } - if config.Since > config.Until { - err = multierror.Append( - err, - errors.New("since must be before until"), - ) - } - - return err -} - func readKafkaPartitions( address, topic, partitions string, ) ([]kafka.Partition, int, error) { diff --git a/cmd/digger/s3.go b/cmd/digger/subcmd/s3.go similarity index 86% rename from cmd/digger/s3.go rename to cmd/digger/subcmd/s3.go index 14305a7..7a803f1 100644 --- a/cmd/digger/s3.go +++ b/cmd/digger/subcmd/s3.go @@ -1,4 +1,4 @@ -package main +package subcmd import ( "context" @@ -19,7 +19,8 @@ type s3Config struct { Prefixes string `flag:"-p,--prefixes" help:"comma-separated list of prefixes"` } -func s3Cmd(ctx context.Context) cli.Function { +// S3Cmd defines a CLI function for digging through S3 objects. +func S3Cmd(ctx context.Context) cli.Function { return cli.Command( func(config s3Config) { if config.Debug { @@ -27,7 +28,10 @@ func s3Cmd(ctx context.Context) cli.Function { } else { log.SetLevel(log.InfoLevel) } - loadPlugins(config.Plugins) + err := loadPlugins(config.Plugins) + if err != nil { + log.Fatalf("Could not load plugins: %+v", err) + } processors, err := makeProcessors(config.commonConfig, []string{}) if err != nil { diff --git a/cmd/digger/version.go b/cmd/digger/subcmd/version.go similarity index 64% rename from cmd/digger/version.go rename to cmd/digger/subcmd/version.go index 42abba1..eb9a39a 100644 --- a/cmd/digger/version.go +++ b/cmd/digger/subcmd/version.go @@ -1,4 +1,4 @@ -package main +package subcmd import ( "context" @@ -10,7 +10,8 @@ import ( type versionConfig struct{} -func versionCmd(ctx context.Context) cli.Function { +// VersionCmd defines a CLI function for returning the digger version. +func VersionCmd(ctx context.Context) cli.Function { return cli.Command( func(config versionConfig) { fmt.Printf("digger version v%s\n", version.Version) diff --git a/go.mod b/go.mod index 2afc726..b526c39 100644 --- a/go.mod +++ b/go.mod @@ -1,35 +1,42 @@ module github.com/segmentio/data-digger -go 1.14 +go 1.24.4 require ( - github.com/aws/aws-sdk-go v1.35.2 - github.com/briandowns/spinner v1.11.1 - github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect - github.com/frankban/quicktest v1.5.0 // indirect - github.com/fsnotify/fsnotify v1.4.9 // indirect - github.com/gogo/protobuf v1.3.1 + github.com/aws/aws-sdk-go v1.55.7 + github.com/briandowns/spinner v1.23.2 + github.com/gogo/protobuf v1.3.2 github.com/gosuri/uilive v0.0.4 - github.com/hashicorp/go-multierror v1.1.0 - github.com/klauspost/compress v1.10.5 // indirect - github.com/konsorten/go-windows-terminal-sequences v1.0.2 // indirect - github.com/mattn/go-isatty v0.0.12 // indirect - github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d // indirect github.com/olekukonko/tablewriter v0.0.4 + github.com/segmentio/cli v0.8.1 + github.com/segmentio/encoding v0.4.1 + github.com/segmentio/kafka-go v0.4.48 + github.com/sirupsen/logrus v1.9.3 + github.com/stretchr/testify v1.8.0 + github.com/tidwall/gjson v1.18.0 + github.com/x-cray/logrus-prefixed-formatter v0.5.2 +) + +require ( + github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect + github.com/fatih/color v1.18.0 // indirect + github.com/jmespath/go-jmespath v0.4.0 // indirect + github.com/klauspost/compress v1.18.0 // indirect + github.com/mattn/go-colorable v0.1.14 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect + github.com/mattn/go-runewidth v0.0.16 // indirect + github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d // indirect github.com/onsi/ginkgo v1.11.0 // indirect github.com/onsi/gomega v1.7.0 // indirect - github.com/pierrec/lz4 v2.3.0+incompatible // indirect + github.com/pierrec/lz4/v4 v4.1.22 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect - github.com/segmentio/cli v0.3.4 - github.com/segmentio/encoding v0.1.18-0.20200918055401-1c9305c300e4 - github.com/segmentio/kafka-go v0.4.3-0.20200817184048-f6834a22676c - github.com/sirupsen/logrus v1.4.2 - github.com/stretchr/testify v1.5.1 - github.com/tidwall/gjson v1.6.0 - github.com/tidwall/pretty v1.0.1 // indirect - github.com/x-cray/logrus-prefixed-formatter v0.5.2 - golang.org/x/net v0.0.0-20200707034311-ab3426394381 // indirect - golang.org/x/sys v0.0.0-20200722175500-76b94024e4b6 // indirect - golang.org/x/text v0.3.2 // indirect + github.com/rivo/uniseg v0.4.7 // indirect + github.com/segmentio/asm v1.2.0 // indirect + github.com/tidwall/match v1.1.1 // indirect + github.com/tidwall/pretty v1.2.1 // indirect + golang.org/x/crypto v0.39.0 // indirect + golang.org/x/sys v0.33.0 // indirect + golang.org/x/term v0.32.0 // indirect gopkg.in/yaml.v2 v2.3.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 3c54478..a73763a 100644 --- a/go.sum +++ b/go.sum @@ -1,65 +1,37 @@ -github.com/aws/aws-sdk-go v1.35.2 h1:qK+noh6b9KW+5CP1NmmWsQCUbnzucSGrjHEs69MEl6A= -github.com/aws/aws-sdk-go v1.35.2/go.mod h1:H7NKnBqNVzoTJpGfLrQkkD+ytBA93eiDYi/+8rV9s48= -github.com/briandowns/spinner v1.11.1 h1:OixPqDEcX3juo5AjQZAnFPbeUA0jvkp2qzB5gOZJ/L0= -github.com/briandowns/spinner v1.11.1/go.mod h1:QOuQk7x+EaDASo80FEXwlwiA+j/PPIcX3FScO+3/ZPQ= +github.com/aws/aws-sdk-go v1.55.7 h1:UJrkFq7es5CShfBwlWAC8DA077vp8PyVbQd3lqLiztE= +github.com/aws/aws-sdk-go v1.55.7/go.mod h1:eRwEWoyTWFMVYVQzKMNHWP5/RV4xIUGMQfXQHfHkpNU= +github.com/briandowns/spinner v1.23.2 h1:Zc6ecUnI+YzLmJniCfDNaMbW0Wid1d5+qcTq4L2FW8w= +github.com/briandowns/spinner v1.23.2/go.mod h1:LaZeM4wm2Ywy6vO571mvhQNRcWfRUnXOs0RcKV0wYKM= 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= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -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/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys= -github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= -github.com/frankban/quicktest v1.5.0 h1:Tb4jWdSpdjKzTUicPnY61PZxKbDoGa7ABbrReT3gQVY= -github.com/frankban/quicktest v1.5.0/go.mod h1:jaStnuzAqU1AJdCO0l53JDCJrVDKcS03DbaAcR7Ks/o= -github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= +github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM= +github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= -github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= -github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= -github.com/gogo/protobuf v1.3.1 h1:DqDEcV5aeaTmdFBePNpYsp3FlcVH/2ISVVM9Qf8PSls= -github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= -github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM= +github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= +github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4= -github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/google/go-cmp v0.3.1 h1:Xye71clBPdm5HgqGwUkwhbynsUJZhDbS20FvLhQ2izg= -github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/gosuri/uilive v0.0.4 h1:hUEBpQDj8D8jXgtCdBu7sWsy5sbW/5GhuO8KBwJ2jyY= github.com/gosuri/uilive v0.0.4/go.mod h1:V/epo5LjjlDE5RJUcqx8dbw+zc93y5Ya3yg8tfZ74VI= -github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA= -github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= -github.com/hashicorp/go-multierror v1.1.0 h1:B9UzwGQJehnUY1yNrnwREHc3fGbC2xefo8g4TbElacI= -github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA= github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8= github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= -github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= +github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/klauspost/compress v1.9.8 h1:VMAMUUOh+gaxKTMk+zqbjsSjsIcUcL/LF4o63i82QyA= -github.com/klauspost/compress v1.9.8/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= -github.com/klauspost/compress v1.10.5 h1:7q6vHIqubShURwQz8cQK6yIe/xC3IF0Vm7TGfqjewrc= -github.com/klauspost/compress v1.10.5/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= -github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk= -github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/konsorten/go-windows-terminal-sequences v1.0.2 h1:DB17ag19krx9CFsz4o3enTrPXyIXCl+2iCXH/aMAp9s= -github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= -github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/mattn/go-colorable v0.1.2 h1:/bC9yWikZXAL9uJdulbSfyVNIR3n3trXl+v8+1sx8mU= -github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= -github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= -github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= -github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= -github.com/mattn/go-runewidth v0.0.7 h1:Ei8KR0497xHyKJPAv59M1dkC+rOZCMBJ+t3fZ+twI54= +github.com/klauspost/compress v1.15.9/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU= +github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo= +github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ= +github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE= +github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8= +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/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= +github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc= +github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d h1:5PJl274Y63IEHC+7izoQE9x6ikvDFZS2mDVS3drnohI= github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE= github.com/olekukonko/tablewriter v0.0.4 h1:vHD/YYe1Wolo78koG299f7V/VAS08c6IpCLn+Ejf/w8= @@ -69,68 +41,119 @@ github.com/onsi/ginkgo v1.11.0 h1:JAKSXpt1YjtLA7YpPiqO9ss6sNXEsPfSGdwN0UHqzrw= github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/gomega v1.7.0 h1:XPnZz8VVBHjVsy1vzJmRwIcSwiUO+JFfrv/xGiigmME= github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= -github.com/pierrec/lz4 v2.0.5+incompatible h1:2xWsjqPFWcplujydGg4WmhC/6fZqK42wMM8aXeqhl0I= -github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= -github.com/pierrec/lz4 v2.3.0+incompatible h1:CZzRn4Ut9GbUkHlQ7jqBXeZQV41ZSKWFc302ZU6lUTk= -github.com/pierrec/lz4 v2.3.0+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= -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/pierrec/lz4/v4 v4.1.15/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= +github.com/pierrec/lz4/v4 v4.1.22 h1:cKFw6uJDK+/gfw5BcDL0JL5aBsAFdsIT18eRtLj7VIU= +github.com/pierrec/lz4/v4 v4.1.22/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/segmentio/cli v0.3.4 h1:fdghOrtrCL4WLVFlWHw85hrAeDqAP3r+3ahJR2YDtJ4= -github.com/segmentio/cli v0.3.4/go.mod h1:+m0rKUSZsAc4BPzL3Cw9jergrTVzySBdBerJcC/qfes= -github.com/segmentio/encoding v0.1.18-0.20200918055401-1c9305c300e4 h1:BAJMw5297gxOyT9sjssffGq8jxGCDVqOsVGr/iIAZ/g= -github.com/segmentio/encoding v0.1.18-0.20200918055401-1c9305c300e4/go.mod h1:MJjRE6bMDocliO2FyFC2Dusp+uYdBfHWh5Bw7QyExto= -github.com/segmentio/kafka-go v0.4.3-0.20200817184048-f6834a22676c h1:NjBTh0nj2PODSm34xQDnqhH9a6mkYH8l9x7EADg4q2Q= -github.com/segmentio/kafka-go v0.4.3-0.20200817184048-f6834a22676c/go.mod h1:Inh7PqOsxmfgasV8InZYKVXWsdjcCq2d9tFV75GLbuM= -github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4= -github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= +github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= +github.com/segmentio/asm v1.2.0 h1:9BQrFxC+YOHJlTlHGkTrFWf59nbL3XnCoFLTwDCI7ys= +github.com/segmentio/asm v1.2.0/go.mod h1:BqMnlJP91P8d+4ibuonYZw9mfnzI9HfxselHZr5aAcs= +github.com/segmentio/cli v0.8.1 h1:spRC4l8KbOj9ZqzVxOJQWEds2D1hMpbWXtk4mqHxirg= +github.com/segmentio/cli v0.8.1/go.mod h1:hUo4b8AmuIu555zbsZdiXLcNqVgK/soFURob8zmWquM= +github.com/segmentio/encoding v0.4.1 h1:KLGaLSW0jrmhB58Nn4+98spfvPvmo4Ci1P/WIQ9wn7w= +github.com/segmentio/encoding v0.4.1/go.mod h1:/d03Cd8PoaDeceuhUUUQWjU0KhWjrmYrWPgtJHYZSnI= +github.com/segmentio/kafka-go v0.4.48 h1:9jyu9CWK4W5W+SroCe8EffbrRZVqAOkuaLd/ApID4Vs= +github.com/segmentio/kafka-go v0.4.48/go.mod h1:HjF6XbOKh0Pjlkr5GVZxt6CsjjwnmhVOfURM5KMd8qg= +github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= +github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= -github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4= -github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= -github.com/tidwall/gjson v1.6.0 h1:9VEQWz6LLMUsUl6PueE49ir4Ka6CzLymOAZDxpFsTDc= -github.com/tidwall/gjson v1.6.0/go.mod h1:P256ACg0Mn+j1RXIDXoss50DeIABTYK1PULOJHhxOls= -github.com/tidwall/match v1.0.1 h1:PnKP62LPNxHKTwvHHZZzdOAOCtsJTjo6dZLCwpKm5xc= -github.com/tidwall/match v1.0.1/go.mod h1:LujAq0jyVjBy028G1WhWfIzbpQfMO8bBZ6Tyb0+pL9E= -github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4= -github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= -github.com/tidwall/pretty v1.0.1 h1:WE4RBSZ1x6McVVC8S/Md+Qse8YUv6HRObAx6ke00NY8= -github.com/tidwall/pretty v1.0.1/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +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/tidwall/gjson v1.18.0 h1:FIDeeyB800efLX89e5a8Y0BNH+LOngJyGrIWxG2FKQY= +github.com/tidwall/gjson v1.18.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= +github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= +github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= +github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= +github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4= +github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= github.com/x-cray/logrus-prefixed-formatter v0.5.2 h1:00txxvfBM9muc0jiLIEAkAcIMJzfthRT6usrui8uGmg= github.com/x-cray/logrus-prefixed-formatter v0.5.2/go.mod h1:2duySbKsL6M18s5GU7VPsoEPHyzalCE06qoARUCeBBE= -github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c h1:u40Z8hqBAAQyv+vATcGgV0YCnDjqSL7/q/JyPhhJSPk= -github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I= -github.com/xdg/stringprep v1.0.0 h1:d9X0esnoa3dFsV0FG35rAT0RIhYFlPq7MiP+DW89La0= -github.com/xdg/stringprep v1.0.0/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y= +github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c= +github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= +github.com/xdg-go/scram v1.1.2 h1:FHX5I5B4i4hKRVRBCFRxq1iQRej7WO3hhBuJf+UUySY= +github.com/xdg-go/scram v1.1.2/go.mod h1:RT/sEzTbU5y00aCK8UOx6R7YryM0iF1N2MOmC3kKLN4= +github.com/xdg-go/stringprep v1.0.4 h1:XLI/Ng3O1Atzq0oBs3TWm+5ZVgkq2aqdlvP9JtoZ6c8= +github.com/xdg-go/stringprep v1.0.4/go.mod h1:mPGuuIYwz7CmR2bT9j4GbQqutWS1zV24gijq1dTyGkM= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190506204251-e1dfcc566284/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= +golang.org/x/crypto v0.39.0 h1:SHs+kF4LP+f+p14esP5jAoDpHU8Gu/v9lFRK6IT5imM= +golang.org/x/crypto v0.39.0/go.mod h1:L+Xg3Wf6HoL4Bn4238Z6ft6KfEpN0tJGo53AAPC632U= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200707034311-ab3426394381 h1:VXak5I6aEWmAXeQjA+QSZzlgNrpq9mjcfDemuexIKsU= -golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f h1:wMNYb4v58l5UBM7MYRLPG6ZhfOqbKu7X5eyFl8ZhKvA= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/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-20201021035429-f5854403a974/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-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= +golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= +golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4= +golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/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-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/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-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200722175500-76b94024e4b6 h1:X9xIZ1YU8bLZA3l6gqDUHSFiD0GFI9S548h6C8nDtOY= -golang.org/x/sys v0.0.0-20200722175500-76b94024e4b6/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +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.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.13.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/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/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= +golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= +golang.org/x/term v0.32.0 h1:DR4lr0TjUs3epypdhTOkMmuF5CDFJ/8pOnbzMZPQ7bg= +golang.org/x/term v0.32.0/go.mod h1:uZG1FhGx848Sqfsq4/DlJr3xGGsYMu/L5GW4abiaEPQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= -golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.26.0 h1:P42AVeLghgTYr4+xUnTRKDMqpar+PtX7KWuNQL21L8M= +golang.org/x/text v0.26.0/go.mod h1:QK15LZJUUQVJxhz7wXgxSy/CJaTFjd0G+YLonydOVQA= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= @@ -138,9 +161,9 @@ gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMy gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 h1:tQIYjPdBoyREyB9XMu+nnTclpTYkz2zFM+lzLJFO4gQ= -gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/pkg/digger/kafka.go b/pkg/digger/kafka.go index 78cef06..7484867 100644 --- a/pkg/digger/kafka.go +++ b/pkg/digger/kafka.go @@ -20,8 +20,8 @@ type KafkaConsumer struct { Topic string Partitions []kafka.Partition Offset int64 - Since time.Duration - Until time.Duration + Since time.Time + Until time.Time MinBytes int MaxBytes int @@ -62,11 +62,6 @@ func (k *KafkaConsumer) consumePartition( } defer reader.Close() - var stopTime time.Time - if k.Until != 0 { - stopTime = time.Now().Add(k.Until) - } - for { messageObj := message{} @@ -82,7 +77,7 @@ func (k *KafkaConsumer) consumePartition( continue } - if !stopTime.IsZero() && msg.Time.After(stopTime) { + if !k.Until.IsZero() && msg.Time.After(k.Until) { log.Warnf("Partition %d has reached until duration, stopping", partition) return nil } @@ -109,8 +104,8 @@ func (k *KafkaConsumer) newReader( }, ) - if k.Since != 0 { - err := reader.SetOffsetAt(ctx, time.Now().Add(k.Since)) + if !k.Since.IsZero() { + err := reader.SetOffsetAt(ctx, k.Since) if err != nil { return nil, err } diff --git a/pkg/digger/processor.go b/pkg/digger/processor.go index 82fd39c..553189f 100644 --- a/pkg/digger/processor.go +++ b/pkg/digger/processor.go @@ -247,7 +247,7 @@ func (l *LiveStats) printProgress(outputWriter io.Writer, spinnerIndex int) { topKSummary := l.topKCounter.Summary() messageSummary := l.messageCounter.Summary() - fmt.Fprintf( + fmt.Fprint( outputWriter, strings.Join( []string{ diff --git a/pkg/digger/s3.go b/pkg/digger/s3.go index dab8f1d..f44248c 100644 --- a/pkg/digger/s3.go +++ b/pkg/digger/s3.go @@ -5,6 +5,7 @@ import ( "context" "errors" "fmt" + "strings" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/s3" @@ -130,11 +131,18 @@ func (s *S3Consumer) processKey( ) error { log.Debugf("Processing key %s", aws.StringValue(objInfo.Key)) + var contentEncoding *string + if strings.HasSuffix(aws.StringValue(objInfo.Key), ".gz") { + // Assume gzip encoding (which might not actually be set in the object in S3) + contentEncoding = aws.String("gzip") + } + obj, err := s.S3Client.GetObjectWithContext( ctx, &s3.GetObjectInput{ - Bucket: aws.String(s.Bucket), - Key: objInfo.Key, + Bucket: aws.String(s.Bucket), + Key: objInfo.Key, + ResponseContentEncoding: contentEncoding, }, ) if err != nil { diff --git a/pkg/json/gjson.go b/pkg/json/gjson.go index afccfc4..1134032 100644 --- a/pkg/json/gjson.go +++ b/pkg/json/gjson.go @@ -15,7 +15,6 @@ import ( func init() { gjson.AddModifier("base64d", base64Decode) gjson.AddModifier("trim", trimString) - gjson.AddModifier("writeKeyAuth", parseAuthWriteKey) } func base64Decode(json, arg string) string { @@ -58,25 +57,6 @@ func base64Decode(json, arg string) string { return string(result) } -// parseAuthWriteKey converts the value of the "Authorization" header -// in a request to a source write key. -func parseAuthWriteKey(json, arg string) string { - if len(json) < 12 || - !strings.HasPrefix(json, `["Basic `) || - !strings.HasSuffix(json, `"]`) { - return "" - } - - decoded, err := base64.StdEncoding.DecodeString(json[8 : len(json)-2]) - if err != nil || len(decoded) < 2 { - log.Debugf("Error base64 decoding string: %+v", err) - return "" - } - decodedStr := strings.TrimSpace(string(decoded)) - - return fmt.Sprintf(`"%s"`, string(decodedStr[0:len(decodedStr)-1])) -} - func trimString(json, arg string) string { maxLen, err := strconv.Atoi(arg) if err != nil { diff --git a/pkg/json/gjson_test.go b/pkg/json/gjson_test.go index 4b7d491..71c1718 100644 --- a/pkg/json/gjson_test.go +++ b/pkg/json/gjson_test.go @@ -34,29 +34,6 @@ func TestBase64Decode(t *testing.T) { ) } -func TestParseAuthWriteKey(t *testing.T) { - assert.Equal( - t, - "", - parseAuthWriteKey("xxx", ""), - ) - assert.Equal( - t, - "", - parseAuthWriteKey(`["Basic"]`, ""), - ) - assert.Equal( - t, - "", - parseAuthWriteKey(`["Basic notvalidbase64"]`, ""), - ) - assert.Equal( - t, - `"writeKey"`, - parseAuthWriteKey(`["Basic d3JpdGVLZXk6Cg=="]`, ""), - ) -} - func TestTrim(t *testing.T) { assert.Equal( t, diff --git a/pkg/util/time.go b/pkg/util/time.go new file mode 100644 index 0000000..eaedd8e --- /dev/null +++ b/pkg/util/time.go @@ -0,0 +1,28 @@ +package util + +import ( + "fmt" + "time" +) + +// ParseTimeOrDuration converts an input string into a time. It first tries parsing it +// as an RFC3339 timestamp and then if that fails as a duration (relative to now). +func ParseTimeOrDuration(input string, now time.Time) (time.Time, error) { + if input == "" { + return time.Time{}, nil + } + + timestamp, err := time.Parse(time.RFC3339, input) + if err == nil { + return timestamp, nil + } + + duration, err := time.ParseDuration(input) + if err != nil { + return time.Time{}, fmt.Errorf( + "Could not parse %s as either timestamp or duration", + input, + ) + } + return now.Add(duration), nil +} diff --git a/pkg/util/time_test.go b/pkg/util/time_test.go new file mode 100644 index 0000000..1164e63 --- /dev/null +++ b/pkg/util/time_test.go @@ -0,0 +1,28 @@ +package util + +import ( + "testing" + "time" + + "github.com/stretchr/testify/assert" +) + +func TestParseTimeOrDuration(t *testing.T) { + now := time.Date(2020, 10, 28, 20, 30, 5, 0, time.UTC) + + result, err := ParseTimeOrDuration("", now) + assert.NoError(t, err) + assert.True(t, result.IsZero()) + + result, err = ParseTimeOrDuration("-25m", now) + assert.NoError(t, err) + assert.Equal(t, now.Add(-25*time.Minute), result) + + result, err = ParseTimeOrDuration("2020-10-29T10:12:44Z", now) + assert.NoError(t, err) + assert.Equal(t, time.Date(2020, 10, 29, 10, 12, 44, 0, time.UTC), result) + + result, err = ParseTimeOrDuration("bad time", now) + assert.Error(t, err) + assert.True(t, result.IsZero()) +} diff --git a/pkg/version/version.go b/pkg/version/version.go index dd47286..d3f08d5 100644 --- a/pkg/version/version.go +++ b/pkg/version/version.go @@ -1,4 +1,4 @@ package version // Version is the current data-digger version. -const Version = "0.0.1" +const Version = "0.0.2"