From c491c45a35b0f6bd2eb4cf478b9289099a044cbf Mon Sep 17 00:00:00 2001 From: "jan.hajek@zerops.io" Date: Sun, 11 Feb 2024 13:50:47 +0100 Subject: [PATCH] update --- .golangci.yaml | 81 +++ cmd/main.go | 3 +- go.mod | 54 +- go.sum | 568 +++--------------- .../handler_findFilesByRules_test.go | 9 +- src/archiveClient/handler_findGitFiles.go | 5 +- src/archiveClient/handler_tarFiles_test.go | 16 +- src/cmd/bucket.go | 30 - src/cmd/bucketS3.go | 51 -- src/cmd/bucketS3Create.go | 82 --- src/cmd/bucketS3Delete.go | 79 --- src/cmd/bucketZerops.go | 14 - src/cmd/bucketZeropsCreate.go | 66 -- src/cmd/bucketZeropsDelete.go | 62 -- src/cmd/login.go | 6 +- src/cmd/project.go | 1 + src/cmd/projectDelete.go | 3 +- src/cmd/projectImport.go | 44 +- src/cmd/projectList.go | 1 + src/cmd/projectServiceImport.go | 1 + src/cmd/projectStart.go | 1 + src/cmd/projectStop.go | 1 + src/cmd/root.go | 1 - src/cmd/scope.go | 1 + src/cmd/scopeProject.go | 3 +- src/cmd/scopeReset.go | 3 +- src/cmd/service.go | 1 + src/cmd/serviceDelete.go | 3 +- src/cmd/serviceDeploy.go | 69 +-- src/cmd/serviceList.go | 1 + src/cmd/serviceLog.go | 2 +- src/cmd/servicePush.go | 125 +--- src/cmd/servicePushDeployShared.go | 150 +++++ src/cmd/serviceStart.go | 1 + src/cmd/serviceStop.go | 1 + src/cmd/status.go | 1 + src/cmd/statusInfo.go | 1 + src/cmd/statusShowDebugLogs.go | 16 +- src/cmd/version.go | 1 + src/cmdBuilder/cmd.go | 12 + src/cmdBuilder/cmdBuilderBuildCobraCmd.go | 6 +- src/cmdBuilder/cmdBuilderCreateRunFunc.go | 22 +- src/cmdBuilder/cmdBuilderExecuteRootCmd.go | 6 +- src/cmdRunner/run.go | 24 +- src/cmdRunner/run_test.go | 16 +- src/constants/zerops.go | 3 +- src/entity/repository/appVersion.go | 1 - src/entity/repository/container.go | 1 - src/httpClient/handler.go | 24 +- src/i18n/en.go | 186 +++--- src/i18n/i18n.go | 154 +++-- src/logger/handler.go | 2 - src/params/handler.go | 38 +- src/region/region.go | 5 +- src/serviceLogs/handler_checkInputValues.go | 7 +- src/serviceLogs/handler_formatByRfc.go | 9 +- src/serviceLogs/handler_formatByTemplate.go | 5 +- src/serviceLogs/handler_formatLogs.go | 9 +- src/serviceLogs/handler_getServiceLogUrl.go | 4 +- src/serviceLogs/handler_ws.go | 12 +- src/storage/handler_test.go | 19 +- src/uxBlock/blocks.go | 5 +- src/uxBlock/prompt.go | 5 +- src/uxBlock/select.go | 63 +- src/uxBlock/showcase/main.go | 37 +- src/uxBlock/spinner.go | 8 +- src/uxBlock/table.go | 14 + src/{cmd/uxHelpers.go => uxHelpers/prompt.go} | 8 +- .../handler_get_service_stacks_by_project.go | 1 - tools/gomodrun.go | 5 +- tools/install.sh | 26 - 71 files changed, 795 insertions(+), 1500 deletions(-) delete mode 100644 src/cmd/bucket.go delete mode 100644 src/cmd/bucketS3.go delete mode 100644 src/cmd/bucketS3Create.go delete mode 100644 src/cmd/bucketS3Delete.go delete mode 100644 src/cmd/bucketZerops.go delete mode 100644 src/cmd/bucketZeropsCreate.go delete mode 100644 src/cmd/bucketZeropsDelete.go create mode 100644 src/cmd/servicePushDeployShared.go rename src/{cmd/uxHelpers.go => uxHelpers/prompt.go} (56%) diff --git a/.golangci.yaml b/.golangci.yaml index 72a83ff9..8e2a1795 100644 --- a/.golangci.yaml +++ b/.golangci.yaml @@ -29,6 +29,87 @@ linters: - godox - rowserrcheck - prealloc + - asasalint + - asciicheck + - bidichk + - bodyclose + - containedctx + - contextcheck + - deadcode + - decorder + - dogsled + - dupword + - durationcheck + - errcheck + - errchkjson + - errname + - errorlint + - execinquery + - exhaustive + - exportloopref + - forcetypeassert + - ginkgolinter + - gocheckcompilerdirectives + - gochecksumtype + - gocritic + - gocyclo + - godox + - gofmt + - goheader + - goimports + - gomoddirectives + - gomodguard + - goprintffuncname + - gosec + - gosimple + - gosmopolitan + - govet + - grouper + - ifshort + - importas + - ineffassign + - interfacebloat + - interfacer + - loggercheck + - maintidx + - makezero + - mirror + - misspell + - musttag + - nakedret + - nestif + - nilerr + - noctx + - nolintlint + - nosprintfhostport + - perfsprint + - prealloc + - predeclared + - promlinter + - protogetter + - reassign + - rowserrcheck + - scopelint + - sloglint + - sqlclosecheck + - staticcheck + - structcheck + - tagalign + - tagliatelle + - tenv + - testableexamples + - testifylint + - thelper + - tparallel + - typecheck + - unconvert + - unparam + - unused + - usestdlibvars + - varcheck + - wastedassign + - whitespace + - zerologlint disable-all: true fast: false diff --git a/cmd/main.go b/cmd/main.go index 8c03e3be..9879f005 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -7,8 +7,7 @@ import ( ) func main() { - err := cmd.ExecuteCmd() - if err != nil { + if cmd.ExecuteCmd() != nil { os.Exit(1) } } diff --git a/go.mod b/go.mod index 895c7e70..da70b39a 100644 --- a/go.mod +++ b/go.mod @@ -5,19 +5,19 @@ go 1.21 require github.com/zeropsio/zerops-go v1.0.4 require ( - github.com/aws/aws-sdk-go v1.44.77 - github.com/charmbracelet/bubbles v0.16.1 - github.com/charmbracelet/bubbletea v0.24.2 + github.com/charmbracelet/bubbles v0.18.0 + github.com/charmbracelet/bubbletea v0.25.0 github.com/charmbracelet/lipgloss v0.9.1 - github.com/google/uuid v1.4.0 - github.com/gorilla/websocket v1.5.0 + github.com/golang/mock v1.6.0 + github.com/google/uuid v1.6.0 + github.com/gorilla/websocket v1.5.1 github.com/mattn/go-isatty v0.0.20 - github.com/onsi/gomega v1.10.1 github.com/pkg/errors v0.9.1 - github.com/sirupsen/logrus v1.9.0 - github.com/spf13/cobra v1.5.0 - github.com/spf13/viper v1.13.0 - github.com/stretchr/testify v1.8.0 + github.com/sirupsen/logrus v1.9.3 + github.com/spf13/cobra v1.8.0 + github.com/spf13/viper v1.18.2 + github.com/stretchr/testify v1.8.4 + golang.org/x/crypto v0.16.0 golang.org/x/text v0.14.0 gopkg.in/yaml.v3 v3.0.1 ) @@ -25,14 +25,12 @@ require ( require ( github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81 // indirect - github.com/davecgh/go-spew v1.1.1 // indirect - github.com/fsnotify/fsnotify v1.5.4 // indirect - github.com/golang/mock v1.4.4 // indirect + github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect + github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/hashicorp/hcl v1.0.0 // indirect - github.com/inconshreveable/mousetrap v1.0.1 // indirect - github.com/jmespath/go-jmespath v0.4.0 // indirect + github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/lucasb-eyer/go-colorful v1.2.0 // indirect - github.com/magiconair/properties v1.8.6 // indirect + github.com/magiconair/properties v1.8.7 // indirect github.com/mattn/go-localereader v0.0.1 // indirect github.com/mattn/go-runewidth v0.0.15 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect @@ -40,22 +38,24 @@ require ( github.com/muesli/cancelreader v0.2.2 // indirect github.com/muesli/reflow v0.3.0 // indirect github.com/muesli/termenv v0.15.2 // indirect - github.com/pelletier/go-toml v1.9.5 // indirect - github.com/pelletier/go-toml/v2 v2.0.5 // indirect - github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/rivo/uniseg v0.4.2 // indirect + github.com/pelletier/go-toml/v2 v2.1.0 // indirect + github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect + github.com/rivo/uniseg v0.4.6 // indirect + github.com/sagikazarmark/locafero v0.4.0 // indirect + github.com/sagikazarmark/slog-shim v0.1.0 // indirect github.com/shopspring/decimal v1.3.1 // indirect - github.com/spf13/afero v1.9.2 // indirect - github.com/spf13/cast v1.5.0 // indirect - github.com/spf13/jwalterweatherman v1.1.0 // indirect + github.com/sourcegraph/conc v0.3.0 // indirect + github.com/spf13/afero v1.11.0 // indirect + github.com/spf13/cast v1.6.0 // indirect github.com/spf13/pflag v1.0.5 // indirect - github.com/subosito/gotenv v1.4.1 // indirect + github.com/subosito/gotenv v1.6.0 // indirect + go.uber.org/atomic v1.9.0 // indirect + go.uber.org/multierr v1.9.0 // indirect + golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect golang.org/x/net v0.19.0 // indirect - golang.org/x/sync v0.1.0 // indirect + golang.org/x/sync v0.5.0 // indirect golang.org/x/sys v0.15.0 // indirect golang.org/x/term v0.15.0 // indirect - golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df // indirect gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect gopkg.in/ini.v1 v1.67.0 // indirect - gopkg.in/yaml.v2 v2.4.0 // indirect ) diff --git a/go.sum b/go.sum index a13aa168..9aa81e4e 100644 --- a/go.sum +++ b/go.sum @@ -1,172 +1,45 @@ -cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= -cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= -cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= -cloud.google.com/go v0.44.3/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= -cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= -cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= -cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= -cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= -cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= -cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= -cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= -cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= -cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= -cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= -cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= -cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= -cloud.google.com/go v0.75.0/go.mod h1:VGuuCn7PG0dwsd5XPVm2Mm3wlh3EL55/79EKB6hlPTY= -cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= -cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= -cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= -cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= -cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= -cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= -cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= -cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= -cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= -cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= -cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= -cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= -cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= -cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= -cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= -cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= -cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= -cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo= -dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= -github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= -github.com/aws/aws-sdk-go v1.44.77 h1:m5rTfdv04/swD+vTuS2zn4NEwKX3yEJPMhiVCFDL/mU= -github.com/aws/aws-sdk-go v1.44.77/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k= github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8= -github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/charmbracelet/bubbles v0.16.1 h1:6uzpAAaT9ZqKssntbvZMlksWHruQLNxg49H5WdeuYSY= -github.com/charmbracelet/bubbles v0.16.1/go.mod h1:2QCp9LFlEsBQMvIYERr7Ww2H2bA7xen1idUDIzm/+Xc= -github.com/charmbracelet/bubbletea v0.24.2 h1:uaQIKx9Ai6Gdh5zpTbGiWpytMU+CfsPp06RaW2cx/SY= -github.com/charmbracelet/bubbletea v0.24.2/go.mod h1:XdrNrV4J8GiyshTtx3DNuYkR1FDaJmO3l2nejekbsgg= +github.com/charmbracelet/bubbles v0.18.0 h1:PYv1A036luoBGroX6VWjQIE9Syf2Wby2oOl/39KLfy0= +github.com/charmbracelet/bubbles v0.18.0/go.mod h1:08qhZhtIwzgrtBjAcJnij1t1H0ZRjwHyGsy6AL11PSw= +github.com/charmbracelet/bubbletea v0.25.0 h1:bAfwk7jRz7FKFl9RzlIULPkStffg5k6pNt5dywy4TcM= +github.com/charmbracelet/bubbletea v0.25.0/go.mod h1:EN3QDR1T5ZdWmdfDzYcqOCAps45+QIJbLOBxmVNWNNg= github.com/charmbracelet/lipgloss v0.9.1 h1:PNyd3jvaJbg4jRHKWXnCj1akQm4rh8dbEzN1p/u1KWg= github.com/charmbracelet/lipgloss v0.9.1/go.mod h1:1mPmG4cxScwUQALAAnacHaigiiHB9Pmr+v1VEawJl6I= -github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= -github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= -github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= -github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= -github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= -github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81 h1:q2hJAaP1k2wIvVRd/hEHD7lacgqrCPS+k8g1MndzfWY= github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81/go.mod h1:YynlIjWYF8myEu6sdkwKIvGQq+cOckRm6So2avqoYAk= -github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= 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/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= -github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= -github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= -github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= -github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= -github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE= -github.com/frankban/quicktest v1.14.3/go.mod h1:mgiwOwqx65TmIk1wJ6Q7wvnVMocbUorkibMOrVTHZps= -github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/fsnotify/fsnotify v1.5.4 h1:jRbGcIw6P2Meqdwuo0H1p6JVLbL5DHKAKlYndzMwVZI= -github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU= -github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= -github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= -github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= -github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= -github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.4 h1:l75CXGRSwbaYNpl/Z2X1XIIAMSCquvXgpVZDhwEIJsc= -github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= -github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= -github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= -github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= -github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= -github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= -github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= -github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= -github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= -github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= -github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= -github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= -github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= -github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= -github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= -github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= -github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.4.0 h1:MtMxsa51/r9yyhkyLsVeVt0B+BGQZzpQiTQ4eHZ8bc4= -github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= -github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= -github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= -github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= -github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -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/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/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= +github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= +github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= +github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= +github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= +github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= +github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY= +github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= -github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= -github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= -github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= -github.com/inconshreveable/mousetrap v1.0.1 h1:U3uMjPSQEBMNp1lFxmllqCPM6P5u/Xq7Pgzkat/bFNc= -github.com/inconshreveable/mousetrap v1.0.1/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= -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/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= -github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= -github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= -github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= +github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= -github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= -github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY= github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= -github.com/magiconair/properties v1.8.6 h1:5ibWZ6iY0NctNGWo87LalDlEZ6R41TqbbDamhfG/Qzo= -github.com/magiconair/properties v1.8.6/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= +github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= +github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= 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-localereader v0.0.1 h1:ygSAOl7ZXTx4RdPYinUpg6W99U8jWvWi9Ye2JC/oIi4= @@ -184,399 +57,102 @@ github.com/muesli/reflow v0.3.0 h1:IFsN6K9NfGtjeggFP+68I4chLZV2yIKsXJFNZ+eWh6s= github.com/muesli/reflow v0.3.0/go.mod h1:pbwTDkVPibjO2kyvBQRBxTWEEGDGq0FlB1BIKtnHY/8= github.com/muesli/termenv v0.15.2 h1:GohcuySI0QmI3wN8Ok9PtKGkgkFIk7y6Vpb5PvrY+Wo= github.com/muesli/termenv v0.15.2/go.mod h1:Epx+iuz8sNs7mNKhxzH4fWXGNpZwUaJKRS1noLXviQ8= -github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78= -github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= -github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.12.1 h1:mFwc4LvZ0xpSvDZ3E+k8Yte0hLOMxXUlP+yXtJqkYfQ= -github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= -github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= -github.com/onsi/gomega v1.10.1 h1:o0+MgICZLuZ7xjH7Vx6zS/zcu93/BEp1VwkIW1mEXCE= -github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= -github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8= -github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= -github.com/pelletier/go-toml/v2 v2.0.5 h1:ipoSadvV8oGUjnUbMub59IDPPwfxF694nG/jwbMiyQg= -github.com/pelletier/go-toml/v2 v2.0.5/go.mod h1:OMHamSCAODeSsVrwwvcJOaoN0LIUIaFVNZzmWyNfXas= +github.com/pelletier/go-toml/v2 v2.1.0 h1:FnwAJ4oYMvbT/34k9zzHuZNrhlz48GB3/s6at6/MHO4= +github.com/pelletier/go-toml/v2 v2.1.0/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg= -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/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +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/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= -github.com/rivo/uniseg v0.4.2 h1:YwD0ulJSJytLpiaWua0sBDusfsCZohxjxzVTYjwxfV8= -github.com/rivo/uniseg v0.4.2/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= -github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/rogpeppe/go-internal v1.6.1 h1:/FiVV8dS/e+YqF2JvO3yXRFbBLTIuSDkuC7aBOAvL+k= -github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= +github.com/rivo/uniseg v0.4.6 h1:Sovz9sDSwbOz9tgUy8JpT+KgCkPYJEN/oYzlJiYTNLg= +github.com/rivo/uniseg v0.4.6/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= +github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= +github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/sagikazarmark/locafero v0.4.0 h1:HApY1R9zGo4DBgr7dqsTH/JJxLTTsOt7u6keLGt6kNQ= +github.com/sagikazarmark/locafero v0.4.0/go.mod h1:Pe1W6UlPYUk/+wc/6KFhbORCfqzgYEpgQ3O5fPuL3H4= +github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE= +github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ= github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8= github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= -github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= -github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= -github.com/spf13/afero v1.9.2 h1:j49Hj62F0n+DaZ1dDCvhABaPNSGNkt32oRFxI33IEMw= -github.com/spf13/afero v1.9.2/go.mod h1:iUV7ddyEEZPO5gA3zD4fJt6iStLlL+Lg4m2cihcDf8Y= -github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w= -github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155UU= -github.com/spf13/cobra v1.5.0 h1:X+jTBEBqF0bHN+9cSMgmfuvv2VHJ9ezmFNf9Y/XstYU= -github.com/spf13/cobra v1.5.0/go.mod h1:dWXEIy2H428czQCjInthrTRUg7yKbok+2Qi/yBIJoUM= -github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk= -github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= +github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= +github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo= +github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0= +github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8= +github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY= +github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0= +github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= +github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0= +github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/spf13/viper v1.13.0 h1:BWSJ/M+f+3nmdz9bxB+bWX28kkALN2ok11D0rSo8EJU= -github.com/spf13/viper v1.13.0/go.mod h1:Icm2xNL3/8uyh/wFuB1jI7TiTNKp8632Nwegu+zgdYw= +github.com/spf13/viper v1.18.2 h1:LUXCnvUvSM6FXAsj6nnfc8Q2tp1dIgUfY9Kc8GsSOiQ= +github.com/spf13/viper v1.18.2/go.mod h1:EKmWIqdnk5lOcmR72yw6hS+8OPYcwD0jteitLMVB+yk= 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/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= -github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= 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/subosito/gotenv v1.4.1 h1:jyEFiXpy21Wm81FBN71l9VoMMV8H8jG+qIK3GCpY6Qs= -github.com/subosito/gotenv v1.4.1/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0= -github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= +github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= +github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/zeropsio/zerops-go v1.0.4 h1:FQM1M+/c9GwKezzc6TOvgPl2q3wjem+9JlpWpPQxLgM= github.com/zeropsio/zerops-go v1.0.4/go.mod h1:Nuqf1xWt53IRLyVoXgR4hF4ICc9jlfOfQgnN3ZhJR3E= -go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= -go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= -go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= +go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE= +go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= +go.uber.org/multierr v1.9.0 h1:7fIwc/ZtS0q++VgcfqFDxSBZVv/Xo49/SYnDFupUwlI= +go.uber.org/multierr v1.9.0/go.mod h1:X2jQV1h+kxSjClGpnseKVIxpmcjrj7MNnI0bnlfKTVQ= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= 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-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= -golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= -golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= -golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= -golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= -golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= -golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= -golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= -golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= -golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= -golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= -golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= -golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= -golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= -golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= -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.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.8.0 h1:LUYupSeNrTNCGzR/hVBk2NHZO4hXcVaW1k4Qx7rjPx8= -golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/crypto v0.16.0 h1:mMMrFzRSCF0GvB7Ne27XVtVAaXLrPmgPC7/v0tkwHaY= +golang.org/x/crypto v0.16.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= +golang.org/x/exp v0.0.0-20230905200255-921286631fa9 h1:GoHiUyI/Tp2nVkLI2mCxVkOjsbSXD66ic0XW0js0R9g= +golang.org/x/exp v0.0.0-20230905200255-921286631fa9/go.mod h1:S2oDrQGGwySpoQPVqRShND87VCbxmc6bL1Yd2oYrm6k= +golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c= golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U= -golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= -golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE= +golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/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-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/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-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= 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.15.0 h1:y/Oo/a/q3IXu26lQgl04j/gjuBDOBlx7X6Om1j2CPW4= golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0= -golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -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.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= -golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= -golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= -golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= -golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= -golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= -golang.org/x/tools v0.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM= -golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= +golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= 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= -golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df h1:5Pf6pFKu98ODmgnpvkJ3kFUOQGGLIzLIkbzUHp47618= -golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= -google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= -google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= -google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= -google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= -google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= -google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= -google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= -google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= -google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= -google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= -google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= -google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= -google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= -google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= -google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= -google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= -google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= -google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= -google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= -google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= -google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= -google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= -google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= -google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= -google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= -google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= -google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= -google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= -google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= -google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= -google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= -google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= -gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -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.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.4/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/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= -gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= 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= -honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= -honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= -rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= -rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= diff --git a/src/archiveClient/handler_findFilesByRules_test.go b/src/archiveClient/handler_findFilesByRules_test.go index d56d5bd0..c19e63c7 100644 --- a/src/archiveClient/handler_findFilesByRules_test.go +++ b/src/archiveClient/handler_findFilesByRules_test.go @@ -4,7 +4,7 @@ import ( "testing" "github.com/golang/mock/gomock" - . "github.com/onsi/gomega" + "github.com/stretchr/testify/require" "github.com/zeropsio/zcli/src/uxBlock/mocks" ) @@ -228,13 +228,10 @@ func TestValidation(t *testing.T) { for _, test := range testErrorResponseDataProvider { test := test // scope lint t.Run(test.name+" in "+test.workingDir, func(t *testing.T) { - - RegisterTestingT(t) - archiver := New(Config{}) files, err := archiver.FindFilesByRules(uxBlocks, test.workingDir, test.input) - Expect(err).ShouldNot(HaveOccurred()) + require.NoError(t, err) output := func() (res []string) { for _, f := range files { @@ -243,7 +240,7 @@ func TestValidation(t *testing.T) { return }() - Expect(output).To(Equal(test.output)) + require.Equal(t, test.output, output) }) } } diff --git a/src/archiveClient/handler_findGitFiles.go b/src/archiveClient/handler_findGitFiles.go index e18dc0c0..c208449b 100644 --- a/src/archiveClient/handler_findGitFiles.go +++ b/src/archiveClient/handler_findGitFiles.go @@ -9,6 +9,7 @@ import ( "path/filepath" "strings" + "github.com/pkg/errors" "github.com/zeropsio/zcli/src/cmdRunner" ) @@ -98,7 +99,7 @@ func (h *Handler) FindGitFiles(workingDir string) (res []File, _ error) { } } - return + return res, nil } func (h *Handler) listFiles(cmd *exec.Cmd, fn func(path string) error) error { @@ -112,7 +113,7 @@ func (h *Handler) listFiles(cmd *exec.Cmd, fn func(path string) error) error { lineB, _, err := rd.ReadLine() line := string(lineB) - if err == io.EOF { + if errors.Is(err, io.EOF) { if line != "" { if err := fn(line); err != nil { return err diff --git a/src/archiveClient/handler_tarFiles_test.go b/src/archiveClient/handler_tarFiles_test.go index 3a6de581..86a2b17e 100644 --- a/src/archiveClient/handler_tarFiles_test.go +++ b/src/archiveClient/handler_tarFiles_test.go @@ -8,12 +8,10 @@ import ( "io" "testing" - . "github.com/onsi/gomega" + "github.com/stretchr/testify/require" ) func TestSymlink(t *testing.T) { - RegisterTestingT(t) - archiver := New(Config{}) errChan := make(chan error) reader, writer := io.Pipe() @@ -30,26 +28,26 @@ func TestSymlink(t *testing.T) { ) gz, err := gzip.NewReader(reader) - Expect(err).ShouldNot(HaveOccurred()) + require.NoError(t, err) b, err := io.ReadAll(gz) - Expect(err).ShouldNot(HaveOccurred()) + require.NoError(t, err) r := tar.NewReader(bytes.NewReader(b)) - Expect(err).ShouldNot(HaveOccurred()) + require.NoError(t, err) for { header, err := r.Next() if errors.Is(err, io.EOF) { break } - Expect(err).ShouldNot(HaveOccurred()) + require.NoError(t, err) switch header.Typeflag { case tar.TypeSymlink: - Expect(header.Linkname).To(Equal("../file2.1.txt")) + require.Equal(t, "../file2.1.txt", header.Linkname) default: - Expect(errors.New("unknown type")).ShouldNot(HaveOccurred()) + t.Fatal("unknown type") } } } diff --git a/src/cmd/bucket.go b/src/cmd/bucket.go deleted file mode 100644 index 5c6f944b..00000000 --- a/src/cmd/bucket.go +++ /dev/null @@ -1,30 +0,0 @@ -package cmd - -import ( - "errors" - - "github.com/zeropsio/zcli/src/cmdBuilder" - "github.com/zeropsio/zcli/src/i18n" -) - -func bucketCmd() *cmdBuilder.Cmd { - return cmdBuilder.NewCmd(). - Use("bucket"). - Short(i18n.T(i18n.CmdBucket)). - AddChildrenCmd(bucketZeropsCmd()). - AddChildrenCmd(bucketS3Cmd()) -} - -// TODO - janhajek better place? -const ( - xAmzAclName = "x-amz-acl" -) - -func checkXAmzAcl(xAmzAcl string) error { - switch xAmzAcl { - case "", "private", "public-read", "public-read-write", "authenticated-read": - return nil - } - - return errors.New(i18n.T(i18n.BucketGenericXAmzAclInvalid)) -} diff --git a/src/cmd/bucketS3.go b/src/cmd/bucketS3.go deleted file mode 100644 index 08a76aa1..00000000 --- a/src/cmd/bucketS3.go +++ /dev/null @@ -1,51 +0,0 @@ -package cmd - -import ( - "errors" - "os" - - "github.com/zeropsio/zcli/src/cmdBuilder" - "github.com/zeropsio/zcli/src/i18n" -) - -func bucketS3Cmd() *cmdBuilder.Cmd { - return cmdBuilder.NewCmd(). - Use("s3"). - Short(i18n.T(i18n.CmdBucketS3)). - AddChildrenCmd(bucketS3CreateCmd()). - AddChildrenCmd(bucketS3DeleteCmd()) -} - -// TODO - janhajek better place? -const ( - s3ServerRegion = "us-east-1" - accessKeyIdName = "accessKeyId" - secretAccessKeyName = "secretAccessKey" -) - -func getAccessKeys(accessKeyId string, secretAccessKey string, serviceName string) (string, string, error) { - // only one of the flags is set - if (accessKeyId == "" && secretAccessKey != "") || (accessKeyId != "" && secretAccessKey == "") { - return "", "", errors.New(i18n.T(i18n.BucketS3FlagBothMandatory)) - } - - if accessKeyId == "" && secretAccessKey == "" { - if val, ok := os.LookupEnv(serviceName + "_" + accessKeyIdName); ok { - accessKeyId = val - } - if val, ok := os.LookupEnv(serviceName + "_" + secretAccessKeyName); ok { - secretAccessKey = val - } - - // only one of the env variables was set - if (accessKeyId == "" && secretAccessKey != "") || (accessKeyId != "" && secretAccessKey == "") { - return "", "", errors.New(i18n.T(i18n.BucketS3EnvBothMandatory)) - } - } - - if accessKeyId == "" || secretAccessKey == "" { - return "", "", errors.New(i18n.T(i18n.BucketS3FlagBothMandatory)) - } - - return accessKeyId, secretAccessKey, nil -} diff --git a/src/cmd/bucketS3Create.go b/src/cmd/bucketS3Create.go deleted file mode 100644 index b8abc0ec..00000000 --- a/src/cmd/bucketS3Create.go +++ /dev/null @@ -1,82 +0,0 @@ -package cmd - -import ( - "context" - "fmt" - "strings" - - "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/aws/credentials" - "github.com/aws/aws-sdk-go/aws/session" - "github.com/aws/aws-sdk-go/service/s3" - "github.com/pkg/errors" - "github.com/zeropsio/zcli/src/cmdBuilder" - "github.com/zeropsio/zcli/src/i18n" -) - -func bucketS3CreateCmd() *cmdBuilder.Cmd { - return cmdBuilder.NewCmd(). - Use("create"). - Short(i18n.T(i18n.CmdBucketCreate)). - Long(i18n.T(i18n.CmdBucketCreate)). - ScopeLevel(cmdBuilder.Service). - Arg("bucketName"). - StringFlag(xAmzAclName, "", i18n.T(i18n.BucketGenericXAmzAcl)). - StringFlag(accessKeyIdName, "", i18n.T(i18n.BucketS3AccessKeyId)). - StringFlag(secretAccessKeyName, "", i18n.T(i18n.BucketS3SecretAccessKey)). - LoggedUserRunFunc(func(ctx context.Context, cmdData *cmdBuilder.LoggedUserCmdData) error { - uxBlocks := cmdData.UxBlocks - - xAmzAcl := cmdData.Params.GetString(xAmzAclName) - err := checkXAmzAcl(xAmzAcl) - if err != nil { - return err - } - - accessKeyId, secretAccessKey, err := getAccessKeys( - cmdData.Params.GetString(accessKeyIdName), - cmdData.Params.GetString(secretAccessKeyName), - cmdData.Service.Name.String(), - ) - if err != nil { - return err - } - - bucketName := fmt.Sprintf("%s.%s", strings.ToLower(accessKeyId), cmdData.Args["bucketName"][0]) - - uxBlocks.PrintLine(i18n.T(i18n.BucketCreateCreatingDirect, bucketName)) - uxBlocks.PrintLine(i18n.T(i18n.BucketGenericBucketNamePrefixed)) - - awsConf := aws.NewConfig(). - WithEndpoint(cmdData.CliStorage.Data().RegionData.S3StorageAddress). - WithRegion(s3ServerRegion). - WithS3ForcePathStyle(true). - WithCredentials( - credentials.NewStaticCredentials(accessKeyId, secretAccessKey, ""), - ) - - sess, err := session.NewSession(awsConf) - if err != nil { - return err - } - - bucketInput := (&s3.CreateBucketInput{}). - SetACL(xAmzAclName). - SetBucket(bucketName) - - if _, err := s3.New(sess).CreateBucketWithContext(ctx, bucketInput); err != nil { - var s3Err s3.RequestFailure - if errors.As(err, &s3Err) { - if s3Err.Code() == s3.ErrCodeBucketAlreadyExists { - return errors.New(i18n.T(i18n.BucketS3BucketAlreadyExists)) - } - return errors.Errorf(i18n.T(i18n.BucketS3RequestFailed), s3Err) - } - return err - } - - uxBlocks.PrintSuccessLine(i18n.T(i18n.BucketCreated)) - - return nil - }) -} diff --git a/src/cmd/bucketS3Delete.go b/src/cmd/bucketS3Delete.go deleted file mode 100644 index eb62da3b..00000000 --- a/src/cmd/bucketS3Delete.go +++ /dev/null @@ -1,79 +0,0 @@ -package cmd - -import ( - "context" - "fmt" - "strings" - - "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/aws/credentials" - "github.com/aws/aws-sdk-go/aws/session" - "github.com/aws/aws-sdk-go/service/s3" - "github.com/pkg/errors" - "github.com/zeropsio/zcli/src/cmdBuilder" - "github.com/zeropsio/zcli/src/i18n" -) - -func bucketS3DeleteCmd() *cmdBuilder.Cmd { - return cmdBuilder.NewCmd(). - Use("delete"). - Short(i18n.T(i18n.CmdBucketDelete)). - ScopeLevel(cmdBuilder.Service). - Arg("bucketName"). - StringFlag(accessKeyIdName, "", i18n.T(i18n.BucketS3AccessKeyId)). - StringFlag(secretAccessKeyName, "", i18n.T(i18n.BucketS3SecretAccessKey)). - BoolFlag("confirm", false, i18n.T(i18n.ConfirmFlag)). - LoggedUserRunFunc(func(ctx context.Context, cmdData *cmdBuilder.LoggedUserCmdData) error { - uxBlocks := cmdData.UxBlocks - - accessKeyId, secretAccessKey, err := getAccessKeys( - cmdData.Params.GetString(accessKeyIdName), - cmdData.Params.GetString(secretAccessKeyName), - cmdData.Service.Name.String(), - ) - if err != nil { - return err - } - - bucketName := fmt.Sprintf("%s.%s", strings.ToLower(accessKeyId), cmdData.Args["bucketName"][0]) - - if !cmdData.Params.GetBool("confirm") { - err = YesNoPromptDestructive(ctx, cmdData, i18n.T(i18n.BucketDeleteConfirm, bucketName)) - if err != nil { - return err - } - } - - uxBlocks.PrintLine(i18n.T(i18n.BucketDeleteDeletingDirect, bucketName)) - uxBlocks.PrintLine(i18n.T(i18n.BucketGenericBucketNamePrefixed)) - - awsConf := aws.NewConfig(). - WithEndpoint(cmdData.CliStorage.Data().RegionData.S3StorageAddress). - WithRegion(s3ServerRegion). - WithS3ForcePathStyle(true). - WithCredentials( - credentials.NewStaticCredentials(accessKeyId, secretAccessKey, ""), - ) - - sess, err := session.NewSession(awsConf) - if err != nil { - return err - } - - bucketInput := (&s3.DeleteBucketInput{}). - SetBucket(bucketName). - SetExpectedBucketOwner(accessKeyId) - - if _, err := s3.New(sess).DeleteBucketWithContext(ctx, bucketInput); err != nil { - var s3Err s3.RequestFailure - if errors.As(err, &s3Err) { - return errors.Errorf(i18n.T(i18n.BucketS3RequestFailed), s3Err) - } - return err - } - - uxBlocks.PrintSuccessLine(i18n.T(i18n.BucketDeleted)) - - return nil - }) -} diff --git a/src/cmd/bucketZerops.go b/src/cmd/bucketZerops.go deleted file mode 100644 index de49f9e0..00000000 --- a/src/cmd/bucketZerops.go +++ /dev/null @@ -1,14 +0,0 @@ -package cmd - -import ( - "github.com/zeropsio/zcli/src/cmdBuilder" - "github.com/zeropsio/zcli/src/i18n" -) - -func bucketZeropsCmd() *cmdBuilder.Cmd { - return cmdBuilder.NewCmd(). - Use("zerops"). - Short(i18n.T(i18n.CmdBucketZerops)). - AddChildrenCmd(bucketZeropsCreateCmd()). - AddChildrenCmd(bucketZeropsDeleteCmd()) -} diff --git a/src/cmd/bucketZeropsCreate.go b/src/cmd/bucketZeropsCreate.go deleted file mode 100644 index 7c79c31c..00000000 --- a/src/cmd/bucketZeropsCreate.go +++ /dev/null @@ -1,66 +0,0 @@ -package cmd - -import ( - "context" - "fmt" - "strings" - - "github.com/pkg/errors" - "github.com/zeropsio/zcli/src/cmdBuilder" - "github.com/zeropsio/zcli/src/i18n" - "github.com/zeropsio/zerops-go/dto/input/body" - "github.com/zeropsio/zerops-go/dto/input/path" - "github.com/zeropsio/zerops-go/types" - "github.com/zeropsio/zerops-go/types/enum" -) - -func bucketZeropsCreateCmd() *cmdBuilder.Cmd { - return cmdBuilder.NewCmd(). - Use("create"). - Short(i18n.T(i18n.CmdBucketCreate)). - ScopeLevel(cmdBuilder.Service). - Arg("bucketName"). - StringFlag(xAmzAclName, "", i18n.T(i18n.BucketGenericXAmzAcl)). - LoggedUserRunFunc(func(ctx context.Context, cmdData *cmdBuilder.LoggedUserCmdData) error { - uxBlocks := cmdData.UxBlocks - - xAmzAcl := cmdData.Params.GetString(xAmzAclName) - err := checkXAmzAcl(xAmzAcl) - if err != nil { - return err - } - - if cmdData.Service.ServiceTypeCategory != enum.ServiceStackTypeCategoryEnumObjectStorage { - return errors.New(i18n.T(i18n.BucketGenericOnlyForObjectStorage)) - } - - serviceId := cmdData.Service.ID - bucketName := fmt.Sprintf("%s.%s", strings.ToLower(serviceId.Native()), cmdData.Args["bucketName"][0]) - - uxBlocks.PrintLine(i18n.T(i18n.BucketCreateCreatingZeropsApi, bucketName)) - uxBlocks.PrintLine(i18n.T(i18n.BucketGenericBucketNamePrefixed)) - - bucketBody := body.PostS3Bucket{ - Name: types.NewString(bucketName), - } - if xAmzAcl != "" { - bucketBody.XAmzAcl = types.NewStringNull(xAmzAcl) - } - - resp, err := cmdData.RestApiClient.PostS3Bucket( - ctx, - path.ServiceStackIdNamed{ServiceStackId: serviceId}, - bucketBody, - ) - if err != nil { - return err - } - if _, err := resp.Output(); err != nil { - return err - } - - uxBlocks.PrintSuccessLine(i18n.T(i18n.BucketCreated)) - - return nil - }) -} diff --git a/src/cmd/bucketZeropsDelete.go b/src/cmd/bucketZeropsDelete.go deleted file mode 100644 index 50c7a6fc..00000000 --- a/src/cmd/bucketZeropsDelete.go +++ /dev/null @@ -1,62 +0,0 @@ -package cmd - -import ( - "context" - "fmt" - "strings" - - "github.com/pkg/errors" - "github.com/zeropsio/zcli/src/cmdBuilder" - "github.com/zeropsio/zcli/src/i18n" - "github.com/zeropsio/zerops-go/dto/input/path" - "github.com/zeropsio/zerops-go/types" - "github.com/zeropsio/zerops-go/types/enum" -) - -func bucketZeropsDeleteCmd() *cmdBuilder.Cmd { - return cmdBuilder.NewCmd(). - Use("delete"). - Short(i18n.T(i18n.CmdBucketDelete)). - ScopeLevel(cmdBuilder.Service). - Arg("bucketName"). - BoolFlag("confirm", false, i18n.T(i18n.ConfirmFlag)). - LoggedUserRunFunc(func(ctx context.Context, cmdData *cmdBuilder.LoggedUserCmdData) error { - uxBlocks := cmdData.UxBlocks - - if cmdData.Service.ServiceTypeCategory != enum.ServiceStackTypeCategoryEnumObjectStorage { - return errors.New(i18n.T(i18n.BucketGenericOnlyForObjectStorage)) - } - - serviceId := cmdData.Service.ID - // TODO - janhajek duplicate - bucketName := fmt.Sprintf("%s.%s", strings.ToLower(serviceId.Native()), cmdData.Args["bucketName"][0]) - - if !cmdData.Params.GetBool("confirm") { - err := YesNoPromptDestructive(ctx, cmdData, i18n.T(i18n.BucketDeleteConfirm, bucketName)) - if err != nil { - return err - } - } - - uxBlocks.PrintLine(i18n.T(i18n.BucketDeleteDeletingZeropsApi, bucketName)) - uxBlocks.PrintLine(i18n.T(i18n.BucketGenericBucketNamePrefixed)) - - resp, err := cmdData.RestApiClient.DeleteS3( - ctx, - path.S3Bucket{ - ServiceStackId: serviceId, - Name: types.NewString(bucketName), - }, - ) - if err != nil { - return err - } - if _, err := resp.Output(); err != nil { - return err - } - - uxBlocks.PrintSuccessLine(i18n.T(i18n.BucketDeleted)) - - return nil - }) -} diff --git a/src/cmd/login.go b/src/cmd/login.go index a6027278..0fd65cc7 100644 --- a/src/cmd/login.go +++ b/src/cmd/login.go @@ -21,13 +21,14 @@ func loginCmd() *cmdBuilder.Cmd { Short(i18n.T(i18n.CmdLogin)). StringFlag("regionUrl", constants.DefaultRegionUrl, i18n.T(i18n.RegionUrlFlag), cmdBuilder.HiddenFlag()). StringFlag("region", "", i18n.T(i18n.RegionFlag), cmdBuilder.HiddenFlag()). + HelpFlag(i18n.T(i18n.LoginHelp)). Arg("token"). GuestRunFunc(func(ctx context.Context, cmdData *cmdBuilder.GuestCmdData) error { uxBlocks := cmdData.UxBlocks regionRetriever := region.New(httpClient.New(ctx, httpClient.Config{HttpTimeout: time.Minute * 5})) - regions, err := regionRetriever.RetrieveAllFromURL(cmdData.Params.GetString("regionUrl")) + regions, err := regionRetriever.RetrieveAllFromURL(ctx, cmdData.Params.GetString("regionUrl")) if err != nil { return err } @@ -85,8 +86,7 @@ func getLoginRegion( } } - // TODO - janhajek translation - header := (&uxBlock.TableRow{}).AddStringCells("Name") + header := (&uxBlock.TableRow{}).AddStringCells(i18n.T(i18n.RegionTableColumnName)) tableBody := &uxBlock.TableBody{} for _, reg := range regions { diff --git a/src/cmd/project.go b/src/cmd/project.go index 99f1e262..477c8da6 100644 --- a/src/cmd/project.go +++ b/src/cmd/project.go @@ -9,6 +9,7 @@ func projectCmd() *cmdBuilder.Cmd { return cmdBuilder.NewCmd(). Use("project"). Short(i18n.T(i18n.CmdProject)). + HelpFlag(i18n.T(i18n.ProjectHelp)). AddChildrenCmd(projectListCmd()). AddChildrenCmd(projectStartCmd()). AddChildrenCmd(projectStopCmd()). diff --git a/src/cmd/projectDelete.go b/src/cmd/projectDelete.go index 8e41089d..87c68134 100644 --- a/src/cmd/projectDelete.go +++ b/src/cmd/projectDelete.go @@ -17,9 +17,10 @@ func projectDeleteCmd() *cmdBuilder.Cmd { ScopeLevel(cmdBuilder.Project). Arg(cmdBuilder.ProjectArgName, cmdBuilder.OptionalArg()). BoolFlag("confirm", false, i18n.T(i18n.ConfirmFlag)). + HelpFlag(i18n.T(i18n.ProjectDeleteHelp)). LoggedUserRunFunc(func(ctx context.Context, cmdData *cmdBuilder.LoggedUserCmdData) error { if !cmdData.Params.GetBool("confirm") { - err := YesNoPromptDestructive(ctx, cmdData, i18n.T(i18n.ProjectDeleteConfirm, cmdData.Project.Name)) + err := uxHelpers.YesNoPromptDestructive(ctx, cmdData.UxBlocks, i18n.T(i18n.ProjectDeleteConfirm, cmdData.Project.Name)) if err != nil { return err } diff --git a/src/cmd/projectImport.go b/src/cmd/projectImport.go index f5f59690..0428bf37 100644 --- a/src/cmd/projectImport.go +++ b/src/cmd/projectImport.go @@ -23,26 +23,13 @@ func projectImportCmd() *cmdBuilder.Cmd { Arg(projectImportArgName). StringFlag("orgId", "", i18n.T(i18n.OrgIdFlag)). StringFlag("workingDie", "./", i18n.T(i18n.BuildWorkingDir)). + HelpFlag(i18n.T(i18n.ProjectImportHelp)). LoggedUserRunFunc(func(ctx context.Context, cmdData *cmdBuilder.LoggedUserCmdData) error { uxBlocks := cmdData.UxBlocks - orgId := uuid.ClientId(cmdData.Params.GetString("orgId")) - if orgId == "" { - orgs, err := repository.GetAllOrgs(ctx, cmdData.RestApiClient) - if err != nil { - return err - } - - if len(orgs) == 1 { - orgId = orgs[0].ID - } else { - selectedOrg, err := uxHelpers.PrintOrgSelector(ctx, uxBlocks, cmdData.RestApiClient) - if err != nil { - return err - } - - orgId = selectedOrg.ID - } + orgId, err := getOrgId(ctx, cmdData) + if err != nil { + return err } yamlContent, err := yamlReader.ReadContent( @@ -96,3 +83,26 @@ func projectImportCmd() *cmdBuilder.Cmd { return nil }) } + +func getOrgId(ctx context.Context, cmdData *cmdBuilder.LoggedUserCmdData) (uuid.ClientId, error) { + orgId := uuid.ClientId(cmdData.Params.GetString("orgId")) + if orgId != "" { + return orgId, nil + } + + orgs, err := repository.GetAllOrgs(ctx, cmdData.RestApiClient) + if err != nil { + return "", err + } + + if len(orgs) == 1 { + return orgs[0].ID, nil + } + + selectedOrg, err := uxHelpers.PrintOrgSelector(ctx, cmdData.UxBlocks, cmdData.RestApiClient) + if err != nil { + return "", err + } + + return selectedOrg.ID, nil +} diff --git a/src/cmd/projectList.go b/src/cmd/projectList.go index 260c02e2..e98c7688 100644 --- a/src/cmd/projectList.go +++ b/src/cmd/projectList.go @@ -12,6 +12,7 @@ func projectListCmd() *cmdBuilder.Cmd { return cmdBuilder.NewCmd(). Use("list"). Short(i18n.T(i18n.CmdProjectList)). + HelpFlag(i18n.T(i18n.ProjectListHelp)). LoggedUserRunFunc(func(ctx context.Context, cmdData *cmdBuilder.LoggedUserCmdData) error { err := uxHelpers.PrintProjectList(ctx, cmdData.UxBlocks, cmdData.RestApiClient) if err != nil { diff --git a/src/cmd/projectServiceImport.go b/src/cmd/projectServiceImport.go index a916d25f..6e984ec7 100644 --- a/src/cmd/projectServiceImport.go +++ b/src/cmd/projectServiceImport.go @@ -19,6 +19,7 @@ func projectServiceImportCmd() *cmdBuilder.Cmd { Short(i18n.T(i18n.CmdServiceImport)). ScopeLevel(cmdBuilder.Project). Arg(serviceImportArgName). + HelpFlag(i18n.T(i18n.ProjectServiceImportHelp)). LoggedUserRunFunc(func(ctx context.Context, cmdData *cmdBuilder.LoggedUserCmdData) error { uxBlocks := cmdData.UxBlocks diff --git a/src/cmd/projectStart.go b/src/cmd/projectStart.go index 1fb196dc..8292d849 100644 --- a/src/cmd/projectStart.go +++ b/src/cmd/projectStart.go @@ -15,6 +15,7 @@ func projectStartCmd() *cmdBuilder.Cmd { Short(i18n.T(i18n.CmdProjectStart)). ScopeLevel(cmdBuilder.Project). Arg(cmdBuilder.ProjectArgName, cmdBuilder.OptionalArg()). + HelpFlag(i18n.T(i18n.ProjectStartHelp)). LoggedUserRunFunc(func(ctx context.Context, cmdData *cmdBuilder.LoggedUserCmdData) error { startProjectResponse, err := cmdData.RestApiClient.PutProjectStart( ctx, diff --git a/src/cmd/projectStop.go b/src/cmd/projectStop.go index 8aeb7ef2..d84460da 100644 --- a/src/cmd/projectStop.go +++ b/src/cmd/projectStop.go @@ -16,6 +16,7 @@ func projectStopCmd() *cmdBuilder.Cmd { Short(i18n.T(i18n.CmdProjectStop)). ScopeLevel(cmdBuilder.Project). Arg(cmdBuilder.ProjectArgName, cmdBuilder.OptionalArg()). + HelpFlag(i18n.T(i18n.ProjectStopHelp)). LoggedUserRunFunc(func(ctx context.Context, cmdData *cmdBuilder.LoggedUserCmdData) error { stopProjectResponse, err := cmdData.RestApiClient.PutProjectStop( ctx, diff --git a/src/cmd/root.go b/src/cmd/root.go index 5024c6de..2e6c18cf 100644 --- a/src/cmd/root.go +++ b/src/cmd/root.go @@ -13,7 +13,6 @@ func ExecuteCmd() error { cmdBuilder.AddCommand(projectCmd()) cmdBuilder.AddCommand(serviceCmd()) cmdBuilder.AddCommand(statusCmd()) - cmdBuilder.AddCommand(bucketCmd()) return cmdBuilder.CreateAndExecuteRootCobraCmd() } diff --git a/src/cmd/scope.go b/src/cmd/scope.go index feeb75be..e2a9b8d2 100644 --- a/src/cmd/scope.go +++ b/src/cmd/scope.go @@ -9,6 +9,7 @@ func scopeCmd() *cmdBuilder.Cmd { return cmdBuilder.NewCmd(). Use("scope"). Short(i18n.T(i18n.CmdScope)). + HelpFlag(i18n.T(i18n.ScopeHelp)). AddChildrenCmd(scopeProjectCmd()). AddChildrenCmd(scopeResetCmd()) } diff --git a/src/cmd/scopeProject.go b/src/cmd/scopeProject.go index 4b99d20e..0a7f8007 100644 --- a/src/cmd/scopeProject.go +++ b/src/cmd/scopeProject.go @@ -28,8 +28,7 @@ func scopeProjectCmd() *cmdBuilder.Cmd { } cmdData.UxBlocks.PrintWarningLine(i18n.T(i18n.ScopedProjectNotFound)) } else { - // TODO - janhajek message - cmdData.UxBlocks.PrintInfoLine("previously scoped project: " + project.Name.String()) + cmdData.UxBlocks.PrintInfoLine(i18n.T(i18n.PreviouslyScopedProject, project.Name.String())) } } diff --git a/src/cmd/scopeReset.go b/src/cmd/scopeReset.go index c92dc602..bfb23dcc 100644 --- a/src/cmd/scopeReset.go +++ b/src/cmd/scopeReset.go @@ -22,8 +22,7 @@ func scopeResetCmd() *cmdBuilder.Cmd { return err } - // TODO - janhajek message - cmdData.UxBlocks.PrintInfoLine("scope reset") + cmdData.UxBlocks.PrintInfoLine(i18n.T(i18n.ScopeReset)) return nil }) diff --git a/src/cmd/service.go b/src/cmd/service.go index 6eb65471..88bca53a 100644 --- a/src/cmd/service.go +++ b/src/cmd/service.go @@ -9,6 +9,7 @@ func serviceCmd() *cmdBuilder.Cmd { return cmdBuilder.NewCmd(). Use("service"). Short(i18n.T(i18n.CmdService)). + Short(i18n.T(i18n.ServiceHelp)). AddChildrenCmd(serviceDeleteCmd()). AddChildrenCmd(serviceListCmd()). AddChildrenCmd(serviceLogCmd()). diff --git a/src/cmd/serviceDelete.go b/src/cmd/serviceDelete.go index a09e45b7..ef2db851 100644 --- a/src/cmd/serviceDelete.go +++ b/src/cmd/serviceDelete.go @@ -16,9 +16,10 @@ func serviceDeleteCmd() *cmdBuilder.Cmd { ScopeLevel(cmdBuilder.Service). Arg(cmdBuilder.ServiceArgName, cmdBuilder.OptionalArg()). BoolFlag("confirm", false, i18n.T(i18n.ConfirmFlag)). + Short(i18n.T(i18n.ServiceDeleteHelp)). LoggedUserRunFunc(func(ctx context.Context, cmdData *cmdBuilder.LoggedUserCmdData) error { if !cmdData.Params.GetBool("confirm") { - err := YesNoPromptDestructive(ctx, cmdData, i18n.T(i18n.ServiceDeleteConfirm, cmdData.Service.Name)) + err := uxHelpers.YesNoPromptDestructive(ctx, cmdData.UxBlocks, i18n.T(i18n.ServiceDeleteConfirm, cmdData.Service.Name)) if err != nil { return err } diff --git a/src/cmd/serviceDeploy.go b/src/cmd/serviceDeploy.go index 1e470713..8cc8e3ca 100644 --- a/src/cmd/serviceDeploy.go +++ b/src/cmd/serviceDeploy.go @@ -4,19 +4,13 @@ import ( "context" "encoding/base64" "io" - "os" - "path/filepath" "time" - "github.com/pkg/errors" "github.com/zeropsio/zcli/src/archiveClient" "github.com/zeropsio/zcli/src/cmdBuilder" - "github.com/zeropsio/zcli/src/entity" "github.com/zeropsio/zcli/src/httpClient" "github.com/zeropsio/zcli/src/i18n" - "github.com/zeropsio/zcli/src/uxBlock" "github.com/zeropsio/zcli/src/uxHelpers" - "github.com/zeropsio/zcli/src/zeropsRestApiClient" "github.com/zeropsio/zerops-go/dto/input/body" "github.com/zeropsio/zerops-go/dto/input/path" "github.com/zeropsio/zerops-go/types" @@ -32,8 +26,9 @@ func serviceDeployCmd() *cmdBuilder.Cmd { StringFlag("workingDir", "./", i18n.T(i18n.BuildWorkingDir)). StringFlag("archiveFilePath", "", i18n.T(i18n.BuildArchiveFilePath)). StringFlag("versionName", "", i18n.T(i18n.BuildVersionName)). - StringFlag("zeropsYamlPath", "", i18n.T(i18n.SourceName)). + StringFlag("zeropsYamlPath", "", i18n.T(i18n.ZeropsYamlLocation)). BoolFlag("deployGitFolder", false, i18n.T(i18n.ZeropsYamlLocation)). + Short(i18n.T(i18n.ServiceDeployHelp)). LoggedUserRunFunc(func(ctx context.Context, cmdData *cmdBuilder.LoggedUserCmdData) error { uxBlocks := cmdData.UxBlocks @@ -106,7 +101,7 @@ func serviceDeployCmd() *cmdBuilder.Cmd { cmdData.UxBlocks, []uxHelpers.Process{{ F: func(ctx context.Context) error { - if err := packageUpload(httpClient, appVersion.UploadUrl.String(), reader); err != nil { + if err := packageUpload(ctx, httpClient, appVersion.UploadUrl.String(), reader); err != nil { // if an error occurred while packing the app, return that error select { case err := <-tarErrChan: @@ -170,61 +165,3 @@ func serviceDeployCmd() *cmdBuilder.Cmd { return nil }) } - -func getValidConfigContent(uxBlocks uxBlock.UxBlocks, workingDir string, zeropsYamlPath string) ([]byte, error) { - workingDir, err := filepath.Abs(workingDir) - if err != nil { - return nil, err - } - - if zeropsYamlPath != "" { - workingDir = filepath.Join(workingDir, zeropsYamlPath) - } - - zeropsYamlPath = filepath.Join(workingDir, ZeropsYamlFileName) - - zeropsYamlStat, err := os.Stat(zeropsYamlPath) - if err != nil { - if os.IsNotExist(err) { - return nil, errors.New(i18n.T(i18n.BuildDeployZeropsYamlNotFound, zeropsYamlPath)) - } - return nil, err - } - - uxBlocks.PrintLine(i18n.T(i18n.BuildDeployZeropsYamlFound, zeropsYamlPath)) - - if zeropsYamlStat.Size() == 0 { - return nil, errors.New(i18n.T(i18n.BuildDeployZeropsYamlEmpty)) - } - if zeropsYamlStat.Size() > 10*1024 { - return nil, errors.New(i18n.T(i18n.BuildDeployZeropsYamlTooLarge)) - } - - yamlContent, err := os.ReadFile(zeropsYamlPath) - if err != nil { - return nil, err - } - - return yamlContent, nil -} - -func validateZeropsYamlContent( - ctx context.Context, - restApiClient *zeropsRestApiClient.Handler, - service *entity.Service, - yamlContent []byte, -) error { - resp, err := restApiClient.PostServiceStackZeropsYamlValidation(ctx, body.ZeropsYamlValidation{ - Name: service.Name, - ServiceStackTypeId: service.ServiceTypeId, - ZeropsYaml: types.NewText(string(yamlContent)), - }) - if err != nil { - return err - } - if _, err = resp.Output(); err != nil { - return err - } - - return nil -} diff --git a/src/cmd/serviceList.go b/src/cmd/serviceList.go index fc24ad76..96c2f6f2 100644 --- a/src/cmd/serviceList.go +++ b/src/cmd/serviceList.go @@ -14,6 +14,7 @@ func serviceListCmd() *cmdBuilder.Cmd { Short(i18n.T(i18n.CmdProjectList)). ScopeLevel(cmdBuilder.Project). Arg(cmdBuilder.ProjectArgName, cmdBuilder.OptionalArg()). + Short(i18n.T(i18n.ServiceListHelp)). LoggedUserRunFunc(func(ctx context.Context, cmdData *cmdBuilder.LoggedUserCmdData) error { err := uxHelpers.PrintServiceList(ctx, cmdData.UxBlocks, cmdData.RestApiClient, *cmdData.Project) if err != nil { diff --git a/src/cmd/serviceLog.go b/src/cmd/serviceLog.go index a0b1f354..2c72556a 100644 --- a/src/cmd/serviceLog.go +++ b/src/cmd/serviceLog.go @@ -18,7 +18,6 @@ func serviceLogCmd() *cmdBuilder.Cmd { Short(i18n.T(i18n.CmdServiceLog)). Long(i18n.T(i18n.CmdServiceLogLong)+i18n.T(i18n.ServiceLogAdditional)). ScopeLevel(cmdBuilder.Service). - StringFlag("x-amz-acl", "", i18n.T(i18n.BucketGenericXAmzAcl)). IntFlag("limit", 100, i18n.T(i18n.LogLimitFlag)). StringFlag("minimumSeverity", "", i18n.T(i18n.LogMinSeverityFlag)). StringFlag("messageType", "APPLICATION", i18n.T(i18n.LogMsgTypeFlag)). @@ -26,6 +25,7 @@ func serviceLogCmd() *cmdBuilder.Cmd { StringFlag("formatTemplate", "", i18n.T(i18n.LogFormatTemplateFlag)). BoolFlag("follow", false, i18n.T(i18n.LogFollowFlag)). BoolFlag("showBuildLogs", false, i18n.T(i18n.LogShowBuildFlag)). + Short(i18n.T(i18n.ServiceLogHelp)). LoggedUserRunFunc(func(ctx context.Context, cmdData *cmdBuilder.LoggedUserCmdData) error { handler := serviceLogs.New( serviceLogs.Config{}, diff --git a/src/cmd/servicePush.go b/src/cmd/servicePush.go index 26ef3803..55670695 100644 --- a/src/cmd/servicePush.go +++ b/src/cmd/servicePush.go @@ -4,28 +4,18 @@ import ( "context" "encoding/base64" "io" - "net/http" - "os" - "path/filepath" "time" - "github.com/pkg/errors" "github.com/zeropsio/zcli/src/archiveClient" "github.com/zeropsio/zcli/src/cmdBuilder" - "github.com/zeropsio/zcli/src/entity" "github.com/zeropsio/zcli/src/httpClient" "github.com/zeropsio/zcli/src/i18n" "github.com/zeropsio/zcli/src/uxHelpers" - "github.com/zeropsio/zcli/src/zeropsRestApiClient" "github.com/zeropsio/zerops-go/dto/input/body" "github.com/zeropsio/zerops-go/dto/input/path" - "github.com/zeropsio/zerops-go/dto/output" "github.com/zeropsio/zerops-go/types" ) -// TODO - janhajek shared -const ZeropsYamlFileName = "zerops.yaml" - func servicePushCmd() *cmdBuilder.Cmd { return cmdBuilder.NewCmd(). Use("push"). @@ -36,7 +26,9 @@ func servicePushCmd() *cmdBuilder.Cmd { StringFlag("archiveFilePath", "", i18n.T(i18n.BuildArchiveFilePath)). StringFlag("versionName", "", i18n.T(i18n.BuildVersionName)). StringFlag("source", "", i18n.T(i18n.SourceName)). + StringFlag("zeropsYamlPath", "", i18n.T(i18n.ZeropsYamlLocation)). BoolFlag("deployGitFolder", false, i18n.T(i18n.UploadGitFolder)). + Short(i18n.T(i18n.ServicePushHelp)). LoggedUserRunFunc(func(ctx context.Context, cmdData *cmdBuilder.LoggedUserCmdData) error { uxBlocks := cmdData.UxBlocks @@ -46,12 +38,21 @@ func servicePushCmd() *cmdBuilder.Cmd { uxBlocks.PrintInfoLine(i18n.T(i18n.BuildDeployCreatingPackageStart)) - files, err := arch.FindGitFiles(cmdData.Params.GetString("workingDir")) + configContent, err := getValidConfigContent( + uxBlocks, + cmdData.Params.GetString("workingDir"), + cmdData.Params.GetString("zeropsYamlPath"), + ) if err != nil { return err } - configContent, err := buildConfigContent(files) + err = validateZeropsYamlContent(ctx, cmdData.RestApiClient, cmdData.Service, configContent) + if err != nil { + return err + } + + files, err := arch.FindGitFiles(cmdData.Params.GetString("workingDir")) if err != nil { return err } @@ -96,7 +97,7 @@ func servicePushCmd() *cmdBuilder.Cmd { cmdData.UxBlocks, []uxHelpers.Process{{ F: func(ctx context.Context) error { - if err := packageUpload(httpClient, appVersion.UploadUrl.String(), reader); err != nil { + if err := packageUpload(ctx, httpClient, appVersion.UploadUrl.String(), reader); err != nil { // if an error occurred while packing the app, return that error select { case err := <-tarErrChan: @@ -170,101 +171,3 @@ func servicePushCmd() *cmdBuilder.Cmd { return nil }) } - -func createAppVersion( - ctx context.Context, - restApiClient *zeropsRestApiClient.Handler, - service *entity.Service, - versionName string, -) (output.PostAppVersion, error) { - appVersionResponse, err := restApiClient.PostAppVersion( - ctx, - body.PostAppVersion{ - ServiceStackId: service.ID, - Name: func() types.StringNull { - if versionName != "" { - return types.NewStringNull(versionName) - } - return types.StringNull{} - }(), - }, - ) - if err != nil { - return output.PostAppVersion{}, err - } - appVersion, err := appVersionResponse.Output() - if err != nil { - return output.PostAppVersion{}, err - } - - return appVersion, nil -} - -func openPackageFile(archiveFilePath string, workingDir string) (*os.File, error) { - workingDir, err := filepath.Abs(workingDir) - if err != nil { - return nil, err - } - - archiveFilePath = filepath.Join(workingDir, archiveFilePath) - - filePath, err := filepath.Abs(archiveFilePath) - if err != nil { - return nil, err - } - - // check if the target file exists - _, err = os.Stat(filePath) - if err != nil && !os.IsNotExist(err) { - return nil, err - } - if err == nil { - return nil, errors.Errorf(i18n.T(i18n.ArchClientFileAlreadyExists), archiveFilePath) - } - - file, err := os.OpenFile(filePath, os.O_RDWR|os.O_CREATE, 0660) - if err != nil { - return nil, err - } - - return file, nil -} - -func packageUpload(client *httpClient.Handler, uploadUrl string, reader io.Reader) error { - cephResponse, err := client.PutStream(uploadUrl, reader, httpClient.ContentType("application/gzip")) - if err != nil { - return err - } - if cephResponse.StatusCode != http.StatusCreated { - return errors.New(i18n.T(i18n.BuildDeployUploadPackageFailed)) - } - - return nil -} - -func buildConfigContent(files []archiveClient.File) ([]byte, error) { - for _, file := range files { - if file.ArchivePath == ZeropsYamlFileName { - stat, err := os.Stat(file.SourcePath) - if err != nil { - return nil, err - } - - if stat.Size() == 0 { - return nil, errors.New(i18n.T(i18n.BuildDeployZeropsYamlEmpty)) - } - if stat.Size() > 10*1024 { - return nil, errors.New(i18n.T(i18n.BuildDeployZeropsYamlTooLarge)) - } - - buildConfigContent, err := os.ReadFile(file.SourcePath) - if err != nil { - return nil, err - } - - return buildConfigContent, nil - } - } - - return nil, errors.New(i18n.T(i18n.BuildDeployZeropsYamlNotFound)) -} diff --git a/src/cmd/servicePushDeployShared.go b/src/cmd/servicePushDeployShared.go new file mode 100644 index 00000000..4cb37dcf --- /dev/null +++ b/src/cmd/servicePushDeployShared.go @@ -0,0 +1,150 @@ +package cmd + +import ( + "context" + "io" + "net/http" + "os" + "path/filepath" + + "github.com/pkg/errors" + "github.com/zeropsio/zcli/src/entity" + "github.com/zeropsio/zcli/src/httpClient" + "github.com/zeropsio/zcli/src/i18n" + "github.com/zeropsio/zcli/src/uxBlock" + "github.com/zeropsio/zcli/src/zeropsRestApiClient" + "github.com/zeropsio/zerops-go/dto/input/body" + "github.com/zeropsio/zerops-go/dto/output" + "github.com/zeropsio/zerops-go/types" +) + +const ZeropsYamlFileName = "zerops.yml" + +func createAppVersion( + ctx context.Context, + restApiClient *zeropsRestApiClient.Handler, + service *entity.Service, + versionName string, +) (output.PostAppVersion, error) { + appVersionResponse, err := restApiClient.PostAppVersion( + ctx, + body.PostAppVersion{ + ServiceStackId: service.ID, + Name: func() types.StringNull { + if versionName != "" { + return types.NewStringNull(versionName) + } + return types.StringNull{} + }(), + }, + ) + if err != nil { + return output.PostAppVersion{}, err + } + appVersion, err := appVersionResponse.Output() + if err != nil { + return output.PostAppVersion{}, err + } + + return appVersion, nil +} + +func openPackageFile(archiveFilePath string, workingDir string) (*os.File, error) { + workingDir, err := filepath.Abs(workingDir) + if err != nil { + return nil, err + } + + archiveFilePath = filepath.Join(workingDir, archiveFilePath) + + filePath, err := filepath.Abs(archiveFilePath) + if err != nil { + return nil, err + } + + // check if the target file exists + _, err = os.Stat(filePath) + if err != nil && !os.IsNotExist(err) { + return nil, err + } + if err == nil { + return nil, errors.Errorf(i18n.T(i18n.ArchClientFileAlreadyExists), archiveFilePath) + } + + file, err := os.OpenFile(filePath, os.O_RDWR|os.O_CREATE, 0660) + if err != nil { + return nil, err + } + + return file, nil +} + +func packageUpload(ctx context.Context, client *httpClient.Handler, uploadUrl string, reader io.Reader) error { + cephResponse, err := client.PutStream(ctx, uploadUrl, reader, httpClient.ContentType("application/gzip")) + if err != nil { + return err + } + if cephResponse.StatusCode != http.StatusCreated { + return errors.New(i18n.T(i18n.BuildDeployUploadPackageFailed)) + } + + return nil +} + +func getValidConfigContent(uxBlocks uxBlock.UxBlocks, workingDir string, zeropsYamlPath string) ([]byte, error) { + workingDir, err := filepath.Abs(workingDir) + if err != nil { + return nil, err + } + + if zeropsYamlPath != "" { + workingDir = filepath.Join(workingDir, zeropsYamlPath) + } + + zeropsYamlPath = filepath.Join(workingDir, ZeropsYamlFileName) + + zeropsYamlStat, err := os.Stat(zeropsYamlPath) + if err != nil { + if os.IsNotExist(err) { + return nil, errors.New(i18n.T(i18n.BuildDeployZeropsYamlNotFound, zeropsYamlPath)) + } + return nil, err + } + + uxBlocks.PrintLine(i18n.T(i18n.BuildDeployZeropsYamlFound, zeropsYamlPath)) + + if zeropsYamlStat.Size() == 0 { + return nil, errors.New(i18n.T(i18n.BuildDeployZeropsYamlEmpty)) + } + if zeropsYamlStat.Size() > 10*1024 { + return nil, errors.New(i18n.T(i18n.BuildDeployZeropsYamlTooLarge)) + } + + yamlContent, err := os.ReadFile(zeropsYamlPath) + if err != nil { + return nil, err + } + + return yamlContent, nil +} + +func validateZeropsYamlContent( + ctx context.Context, + restApiClient *zeropsRestApiClient.Handler, + service *entity.Service, + yamlContent []byte, +) error { + resp, err := restApiClient.PostServiceStackZeropsYamlValidation(ctx, body.ZeropsYamlValidation{ + Name: service.Name, + ServiceStackTypeId: service.ServiceTypeId, + ZeropsYaml: types.NewText(string(yamlContent)), + }) + if err != nil { + return err + } + if _, err = resp.Output(); err != nil { + return err + } + + return nil +} diff --git a/src/cmd/serviceStart.go b/src/cmd/serviceStart.go index bbf79b9c..da00e65c 100644 --- a/src/cmd/serviceStart.go +++ b/src/cmd/serviceStart.go @@ -15,6 +15,7 @@ func serviceStartCmd() *cmdBuilder.Cmd { Short(i18n.T(i18n.CmdServiceStart)). ScopeLevel(cmdBuilder.Service). Arg(cmdBuilder.ServiceArgName, cmdBuilder.OptionalArg(), cmdBuilder.OptionalArgLabel("{serviceName | serviceId}")). + Short(i18n.T(i18n.ServiceStartHelp)). LoggedUserRunFunc(func(ctx context.Context, cmdData *cmdBuilder.LoggedUserCmdData) error { startServiceResponse, err := cmdData.RestApiClient.PutServiceStackStart( ctx, diff --git a/src/cmd/serviceStop.go b/src/cmd/serviceStop.go index f7d65e2e..6e50fe17 100644 --- a/src/cmd/serviceStop.go +++ b/src/cmd/serviceStop.go @@ -16,6 +16,7 @@ func serviceStopCmd() *cmdBuilder.Cmd { Short(i18n.T(i18n.CmdServiceStop)). ScopeLevel(cmdBuilder.Service). Arg(cmdBuilder.ServiceArgName, cmdBuilder.OptionalArg()). + Short(i18n.T(i18n.ServiceStopHelp)). LoggedUserRunFunc(func(ctx context.Context, cmdData *cmdBuilder.LoggedUserCmdData) error { stopServiceResponse, err := cmdData.RestApiClient.PutServiceStackStop( ctx, diff --git a/src/cmd/status.go b/src/cmd/status.go index 0a66f8a4..ff547c8e 100644 --- a/src/cmd/status.go +++ b/src/cmd/status.go @@ -9,6 +9,7 @@ func statusCmd() *cmdBuilder.Cmd { return cmdBuilder.NewCmd(). Use("status"). Short(i18n.T(i18n.CmdStatus)). + Short(i18n.T(i18n.StatusHelp)). AddChildrenCmd(statusShowDebugLogsCmd()). AddChildrenCmd(statusInfoCmd()) } diff --git a/src/cmd/statusInfo.go b/src/cmd/statusInfo.go index b76e0d41..3d010fdc 100644 --- a/src/cmd/statusInfo.go +++ b/src/cmd/statusInfo.go @@ -16,6 +16,7 @@ func statusInfoCmd() *cmdBuilder.Cmd { return cmdBuilder.NewCmd(). Use("info"). Short(i18n.T(i18n.CmdStatusInfo)). + Short(i18n.T(i18n.StatusInfoHelp)). LoggedUserRunFunc(func(ctx context.Context, cmdData *cmdBuilder.LoggedUserCmdData) error { body := &uxBlock.TableBody{} diff --git a/src/cmd/statusShowDebugLogs.go b/src/cmd/statusShowDebugLogs.go index e083ff3b..5bfdb6e9 100644 --- a/src/cmd/statusShowDebugLogs.go +++ b/src/cmd/statusShowDebugLogs.go @@ -15,6 +15,7 @@ func statusShowDebugLogsCmd() *cmdBuilder.Cmd { return cmdBuilder.NewCmd(). Use("show-debug-logs"). Short(i18n.T(i18n.CmdStatusShowDebugLogs)). + Short(i18n.T(i18n.StatusShowDebugLogsHelp)). GuestRunFunc(func(ctx context.Context, cmdData *cmdBuilder.GuestCmdData) error { logFilePath, err := constants.LogFilePath() if err != nil { @@ -32,18 +33,23 @@ func statusShowDebugLogsCmd() *cmdBuilder.Cmd { filesize := stat.Size() if filesize == 0 { - // TODO - janhajek translate - fmt.Println("No logs found") + cmdData.UxBlocks.PrintLine(i18n.T(i18n.DebugLogsNotFound)) return nil } lines := []string{} for { cursor -= 1 - f.Seek(cursor, io.SeekEnd) + _, err = f.Seek(cursor, io.SeekEnd) + if err != nil { + return err + } char := make([]byte, 1) - f.Read(char) + _, err = f.Read(char) + if err != nil { + return err + } if cursor != -1 && (char[0] == 10 || char[0] == 13) { // stop if we find a line if len(lines) > 10 { @@ -55,7 +61,7 @@ func statusShowDebugLogsCmd() *cmdBuilder.Cmd { line = fmt.Sprintf("%s%s", string(char), line) - if cursor == -filesize { // stop if we are at the begining + if cursor == -filesize { // stop if we are at the beginning lines = append([]string{line}, lines...) break } diff --git a/src/cmd/version.go b/src/cmd/version.go index 7242ec13..cc65075b 100644 --- a/src/cmd/version.go +++ b/src/cmd/version.go @@ -15,6 +15,7 @@ func versionCmd() *cmdBuilder.Cmd { return cmdBuilder.NewCmd(). Use("version"). Short(i18n.T(i18n.CmdVersion)). + Short(i18n.T(i18n.VersionHelp)). LoggedUserRunFunc(func(ctx context.Context, cmdData *cmdBuilder.LoggedUserCmdData) error { fmt.Printf("zcli version %s (%s) %s/%s\n", Version, runtime.Version(), runtime.GOOS, runtime.GOARCH) diff --git a/src/cmdBuilder/cmd.go b/src/cmdBuilder/cmd.go index 0cbc3723..b9f5ad99 100644 --- a/src/cmdBuilder/cmd.go +++ b/src/cmdBuilder/cmd.go @@ -34,6 +34,7 @@ type cmdFlag struct { defaultValue interface{} description string hidden bool + shorthand string } func NewCmd() *Cmd { @@ -122,6 +123,12 @@ func HiddenFlag() FlagOption { } } +func ShortHand(shorthand string) FlagOption { + return func(cfg *cmdFlag) { + cfg.shorthand = shorthand + } +} + func (cmd *Cmd) StringFlag(name string, defaultValue string, description string, auxOptions ...FlagOption) *Cmd { return cmd.addFlag(name, defaultValue, description, auxOptions...) } @@ -134,6 +141,11 @@ func (cmd *Cmd) BoolFlag(name string, defaultValue bool, description string, aux return cmd.addFlag(name, defaultValue, description, auxOptions...) } +func (cmd *Cmd) HelpFlag(description string, auxOptions ...FlagOption) *Cmd { + auxOptions = append(auxOptions, ShortHand("h")) + return cmd.addFlag("help", false, description, auxOptions...) +} + func (cmd *Cmd) addFlag(name string, defaultValue interface{}, description string, auxOptions ...FlagOption) *Cmd { cfg := cmdFlag{ name: name, diff --git a/src/cmdBuilder/cmdBuilderBuildCobraCmd.go b/src/cmdBuilder/cmdBuilderBuildCobraCmd.go index 7d2f79f3..b16e5ed8 100644 --- a/src/cmdBuilder/cmdBuilderBuildCobraCmd.go +++ b/src/cmdBuilder/cmdBuilderBuildCobraCmd.go @@ -34,11 +34,11 @@ func (b *CmdBuilder) buildCobraCmd(cmd *Cmd, params *params.Handler) (*cobra.Com for _, flag := range cmd.flags { switch defaultValue := flag.defaultValue.(type) { case string: - params.RegisterString(cobraCmd, flag.name, defaultValue, flag.description) + params.RegisterString(cobraCmd, flag.name, flag.shorthand, defaultValue, flag.description) case int: - params.RegisterInt(cobraCmd, flag.name, defaultValue, flag.description) + params.RegisterInt(cobraCmd, flag.name, flag.shorthand, defaultValue, flag.description) case bool: - params.RegisterBool(cobraCmd, flag.name, defaultValue, flag.description) + params.RegisterBool(cobraCmd, flag.name, flag.shorthand, defaultValue, flag.description) default: panic(fmt.Sprintf("unexpected type %T", flag.defaultValue)) } diff --git a/src/cmdBuilder/cmdBuilderCreateRunFunc.go b/src/cmdBuilder/cmdBuilderCreateRunFunc.go index bfa57258..ff70cc62 100644 --- a/src/cmdBuilder/cmdBuilderCreateRunFunc.go +++ b/src/cmdBuilder/cmdBuilderCreateRunFunc.go @@ -22,6 +22,7 @@ import ( "github.com/zeropsio/zcli/src/uxBlock" "github.com/zeropsio/zcli/src/zeropsRestApiClient" "github.com/zeropsio/zerops-go/apiError" + "golang.org/x/term" "gopkg.in/yaml.v3" ) @@ -87,16 +88,21 @@ func (b *CmdBuilder) createCmdRunFunc(cmd *Cmd, params *params.Handler) func(*co return err } + width, _, err := term.GetSize(0) + if err != nil { + width = 100 + } + outputLogger, debugFileLogger := createLoggers(isTerminal, loggerFilePath) - uxBlocks := uxBlock.NewBlock(outputLogger, debugFileLogger, isTerminal, cancel) + uxBlocks := uxBlock.NewBlock(outputLogger, debugFileLogger, isTerminal, width, cancel) uxBlocks.PrintDebugLine(fmt.Sprintf("Command: %s", cobraCmd.CommandPath())) defer func() { if err != nil { printError(err, uxBlocks) - err = skipErr + err = errSkipErrorReporting } }() @@ -131,7 +137,6 @@ func (b *CmdBuilder) createCmdRunFunc(cmd *Cmd, params *params.Handler) func(*co } cmdData := &LoggedUserCmdData{ - GuestCmdData: guestCmdData, } @@ -144,7 +149,6 @@ func (b *CmdBuilder) createCmdRunFunc(cmd *Cmd, params *params.Handler) func(*co } } return cmd.loggedUserRunFunc(ctx, cmdData) - } return cmd.guestRunFunc(ctx, guestCmdData) @@ -156,10 +160,10 @@ func convertArgs(cmd *Cmd, args []string) (map[string][]string, error) { var isArray bool for i, arg := range cmd.args { if arg.optional && i != len(cmd.args)-1 { - return nil, errors.Errorf("optional arg %s can be only the last one", arg.name) + return nil, errors.Errorf(i18n.T(i18n.ArgsOnlyOneOptionalAllowed), arg.name) } if arg.isArray && i != len(cmd.args)-1 { - return nil, errors.Errorf("array arg %s can be only the last one", arg.name) + return nil, errors.Errorf(i18n.T(i18n.ArgsOnlyOneArrayAllowed), arg.name) } if !arg.optional { requiredArgsCount++ @@ -168,14 +172,12 @@ func convertArgs(cmd *Cmd, args []string) (map[string][]string, error) { } if len(args) < requiredArgsCount { - // TODO - janhajek message - return nil, errors.Errorf("expected at least %d arg(s), got %d", requiredArgsCount, len(args)) + return nil, errors.Errorf(i18n.T(i18n.ArgsNotEnoughRequiredArgs), requiredArgsCount, len(args)) } // the last arg is not an array, max number of given args can't be greater than the number of registered args if !isArray && len(args) > len(cmd.args) { - // TODO - janhajek message - return nil, errors.Errorf("expected no more than %d arg(s), got %d", len(cmd.args), len(args)) + return nil, errors.Errorf(i18n.T(i18n.ArgsTooManyArgs), len(cmd.args), len(args)) } argsMap := make(map[string][]string) diff --git a/src/cmdBuilder/cmdBuilderExecuteRootCmd.go b/src/cmdBuilder/cmdBuilderExecuteRootCmd.go index 94718841..c7e59bf6 100644 --- a/src/cmdBuilder/cmdBuilderExecuteRootCmd.go +++ b/src/cmdBuilder/cmdBuilderExecuteRootCmd.go @@ -29,7 +29,7 @@ var TerminalFlag string // This error needs to be handled here. Simple fmt.Println(err.Error()) is enough. // But with this line, other errors are logged twice. Once here, once in the root command. // So, I added a special error to skip the logging after the root command. -var skipErr = errors.New("skip") +var errSkipErrorReporting = errors.New("skipErrorReporting") func (b *CmdBuilder) CreateAndExecuteRootCobraCmd() error { rootCmd := createRootCommand() @@ -46,7 +46,7 @@ func (b *CmdBuilder) CreateAndExecuteRootCobraCmd() error { err := rootCmd.Execute() if err != nil { - if !errors.Is(err, skipErr) { + if !errors.Is(err, errSkipErrorReporting) { fmt.Println(err.Error()) } } @@ -61,8 +61,6 @@ func createRootCommand() *cobra.Command { SilenceErrors: true, } - // TODO - janhajek add a dynamic help for subcommands - rootCmd.Flags().BoolP("help", "h", false, i18n.T(i18n.DisplayHelp)+i18n.T(i18n.GroupHelp)) rootCmd.PersistentFlags().StringVar(&TerminalFlag, "terminal", "auto", i18n.T(i18n.TerminalFlag)) return rootCmd diff --git a/src/cmdRunner/run.go b/src/cmdRunner/run.go index 7a2644f9..e88dcd8f 100644 --- a/src/cmdRunner/run.go +++ b/src/cmdRunner/run.go @@ -8,34 +8,34 @@ import ( "strings" ) -var IpAlreadySetErr = errors.New("RTNETLINK answers: File exists") -var CannotFindDeviceErr = errors.New(`Cannot find device "wg0"`) -var OperationNotPermitted = errors.New(`Operation not permitted`) +var ErrIpAlreadySet = errors.New("RTNETLINK answers: File exists") +var ErrCannotFindDevice = errors.New(`Cannot find device "wg0"`) +var ErrOperationNotPermitted = errors.New(`Operation not permitted`) type ExecErrInterface interface { error ExitCode() int } -type execErr struct { +type execError struct { cmd *exec.Cmd prev error exitCode int } -func (e execErr) Error() string { +func (e execError) Error() string { return e.cmd.String() + ": " + e.prev.Error() } -func (e execErr) ExitCode() int { +func (e execError) ExitCode() int { return e.exitCode } -func (e execErr) Unwrap() error { +func (e execError) Unwrap() error { return e.prev } -func (e execErr) Is(target error) bool { +func (e execError) Is(target error) bool { return errors.Is(e.prev, target) } @@ -53,7 +53,7 @@ func Run(cmd *exec.Cmd) ([]byte, ExecErrInterface) { exitCode = exitError.ExitCode() } - execError := &execErr{ + execError := &execError{ cmd: cmd, exitCode: exitCode, prev: err, @@ -65,12 +65,12 @@ func Run(cmd *exec.Cmd) ([]byte, ExecErrInterface) { errOutputString := string(errOutput.Bytes()[0 : errOutput.Len()-1]) - if strings.Contains(errOutputString, OperationNotPermitted.Error()) { - execError.prev = OperationNotPermitted + if strings.Contains(errOutputString, ErrOperationNotPermitted.Error()) { + execError.prev = ErrOperationNotPermitted return nil, execError } - for _, e := range []error{IpAlreadySetErr, CannotFindDeviceErr} { + for _, e := range []error{ErrIpAlreadySet, ErrCannotFindDevice} { if errOutputString == e.Error() { execError.prev = e return nil, execError diff --git a/src/cmdRunner/run_test.go b/src/cmdRunner/run_test.go index 167c64e8..4826974a 100644 --- a/src/cmdRunner/run_test.go +++ b/src/cmdRunner/run_test.go @@ -1,22 +1,18 @@ package cmdRunner import ( - "errors" "testing" - . "github.com/onsi/gomega" + "github.com/stretchr/testify/require" ) func TestWrap(t *testing.T) { - RegisterTestingT(t) - - err := &execErr{ - prev: OperationNotPermitted, + err := &execError{ + prev: ErrOperationNotPermitted, exitCode: 1, } - Expect(errors.Is(err, OperationNotPermitted)).To(BeTrue()) - Expect(errors.Is(err, CannotFindDeviceErr)).To(BeFalse()) - Expect(err.ExitCode()).To(Equal(1)) - + require.ErrorIs(t, err, ErrOperationNotPermitted) + require.NotErrorIs(t, err, ErrCannotFindDevice) + require.Equal(t, 1, err.ExitCode()) } diff --git a/src/constants/zerops.go b/src/constants/zerops.go index 990c11a9..cebbf10e 100644 --- a/src/constants/zerops.go +++ b/src/constants/zerops.go @@ -58,8 +58,7 @@ func findFirstWritablePath(paths []pathReceiver) (string, error) { func checkPath(filePath string) error { dir := path.Dir(filePath) - err := os.MkdirAll(dir, 0775) - if err != nil { + if err := os.MkdirAll(dir, 0775); err != nil { return err } diff --git a/src/entity/repository/appVersion.go b/src/entity/repository/appVersion.go index 3b17191e..36e98565 100644 --- a/src/entity/repository/appVersion.go +++ b/src/entity/repository/appVersion.go @@ -15,7 +15,6 @@ func GetAllAppVersionByService( restApiClient *zeropsRestApiClient.Handler, service entity.Service, ) ([]entity.AppVersion, error) { - var searchData []body.EsSearchItem searchData = append(searchData, body.EsSearchItem{ Name: "clientId", diff --git a/src/entity/repository/container.go b/src/entity/repository/container.go index 2f8e5bdc..aa957456 100644 --- a/src/entity/repository/container.go +++ b/src/entity/repository/container.go @@ -46,7 +46,6 @@ func GetAllContainers( } func containerFromEsSearch(esContainer output.EsContainer) entity.Container { - return entity.Container{ ID: esContainer.Id, ClientId: esContainer.ClientId, diff --git a/src/httpClient/handler.go b/src/httpClient/handler.go index 51b9cc14..4003c488 100644 --- a/src/httpClient/handler.go +++ b/src/httpClient/handler.go @@ -49,27 +49,19 @@ type optionConfig struct { headers map[string]string } -func (h *Handler) PutStream(url string, body io.Reader, options ...Option) (Response, error) { - return h.doStream("PUT", url, body, options...) +func (h *Handler) PutStream(ctx context.Context, url string, body io.Reader, options ...Option) (Response, error) { + return h.doStream(ctx, "PUT", url, body, options...) } -func (h *Handler) Put(url string, data []byte, options ...Option) (Response, error) { - return h.do("PUT", url, data, options...) +func (h *Handler) Get(ctx context.Context, url string, options ...Option) (Response, error) { + return h.do(ctx, "GET", url, nil) } -func (h *Handler) Post(url string, data []byte, options ...Option) (Response, error) { - return h.do("POST", url, data, options...) +func (h *Handler) do(ctx context.Context, method string, url string, data []byte, options ...Option) (Response, error) { + return h.doStream(ctx, method, url, bytes.NewReader(data), options...) } -func (h *Handler) Get(url string, options ...Option) (Response, error) { - return h.do("GET", url, nil) -} - -func (h *Handler) do(method string, url string, data []byte, options ...Option) (Response, error) { - return h.doStream(method, url, bytes.NewReader(data), options...) -} - -func (h *Handler) doStream(method string, url string, body io.Reader, options ...Option) (Response, error) { +func (h *Handler) doStream(ctx context.Context, method string, url string, body io.Reader, options ...Option) (Response, error) { cfg := &optionConfig{ headers: map[string]string{ "Content-Type": "application/json", @@ -81,7 +73,7 @@ func (h *Handler) doStream(method string, url string, body io.Reader, options .. } client := &http.Client{Timeout: h.config.HttpTimeout} - req, err := http.NewRequest(method, url, body) + req, err := http.NewRequestWithContext(ctx, method, url, body) if err != nil { return Response{}, err } diff --git a/src/i18n/en.go b/src/i18n/en.go index 3b96d7c2..9ca8d603 100644 --- a/src/i18n/en.go +++ b/src/i18n/en.go @@ -2,31 +2,39 @@ package i18n var en = map[string]string{ // help - DisplayHelp: "Displays help for ", - GroupHelp: "any command.", - DeployHelp: "the deploy command.", - LogShowHelp: "the log show command.", - LoginHelp: "the login command.", - ProjectHelp: "the project command.", - ProjectStartHelp: "the project start command.", - ProjectStopHelp: "the project stop command.", - ProjectListHelp: "the project list command.", - ScopeHelp: "the scope command.", - ScopeProjectHelp: "the scope project command.", - ScopeServiceHelp: "the scope project command.", - ScopeResetHelp: "the scope reset command.", - ProjectDeleteHelp: "the project delete command.", - ProjectImportHelp: "the project import command.", - PushHelp: "the push command.", - RegionListHelp: "the region list command.", - ServiceStartHelp: "the service start command.", - ServiceStopHelp: "the service stop command.", - ServiceImportHelp: "the service import command.", - ServiceDeleteHelp: "the service delete command.", - ServiceLogHelp: "the service log command.", - VersionHelp: "the version command.", - BucketCreateHelp: "the bucket create command.", - BucketDeleteHelp: "the bucket delete command.", + DisplayHelp: "Displays help for ", + GroupHelp: "any command.", + DeployHelp: "the deploy command.", + LogShowHelp: "the log show command.", + LoginHelp: "the login command.", + ProjectHelp: "the project command.", + ProjectStartHelp: "the project start command.", + ProjectStopHelp: "the project stop command.", + ProjectListHelp: "the project list command.", + ScopeHelp: "the scope command.", + ScopeProjectHelp: "the scope project command.", + ScopeServiceHelp: "the scope project command.", + ScopeResetHelp: "the scope reset command.", + ProjectDeleteHelp: "the project delete command.", + ProjectImportHelp: "the project import command.", + ProjectServiceImportHelp: "the project service import command.", + ServiceHelp: "the service command.", + PushHelp: "the push command.", + RegionListHelp: "the region list command.", + ServiceStartHelp: "the service start command.", + ServiceStopHelp: "the service stop command.", + ServiceImportHelp: "the service import command.", + ServiceDeleteHelp: "the service delete command.", + ServiceLogHelp: "the service log command.", + ServiceDeployHelp: "the service deploy command.", + ServiceListHelp: "the service list command.", + ServicePushHelp: "the service push command.", + StatusHelp: "the status command.", + StatusInfoHelp: "the status info command.", + StatusShowDebugLogsHelp: "the status show debug logs command.", + VersionHelp: "the version command.", + BucketCreateHelp: "the bucket create command.", + BucketDeleteHelp: "the bucket delete command.", // cmd short CmdDeployDesc: "Deploys your application to Zerops.", @@ -84,24 +92,14 @@ var en = map[string]string{ LogFollowFlag: "If set, zCLI will continuously poll for new log messages. By default, the command will exit\nonce there are no more logs to display. To exit from this mode, use Control-C.", LogFormatFlag: "The format of returned log messages. Following formats are supported: \nFULL: This is the default format. Messages will be returned in the complete Syslog format. \nSHORT: Returns only timestamp and log message.\nJSON: Messages will be returned as one JSON object.\nJSONSTREAM: Messages will be returned as stream of JSON objects.", LogFormatTemplateFlag: "Set a custom log format. Can be used only with --format=FULL.\nExample: --formatTemplate=\"{{.timestamp}} {{.severity}} {{.facility}} {{.message}}\".\nSupports standard GoLang template format and functions.", - QuietModeFlag: "In terminal mode some operations need to be confirmed. 0 = Everything needs to be confirmed, 1 = Non-destructive operations need to be confirmed, 2 = Quiet mode, nothing needs to be confirmed. Default value is 0.", TerminalFlag: "If enabled provides a rich UI to communicate with a user. Possible values: auto, enabled, disabled. Default value is auto.", LogFilePathFlag: "Path to a log file. Default value: %s.", ConfirmFlag: "If set, zCLI will not ask for confirmation of destructive operations.", ServiceIdFlag: "If you have access to more than one service, you must specify the service ID for which the\ncommand is to be executed.", ProjectIdFlag: "If you have access to more than one project, you must specify the project ID for which the\ncommand is to be executed.", - // prompt - PromptEnterZeropsServiceName: "Enter hostname of zerops service", - PromptName: "name", - PromptInvalidInput: "Invalid input.", - PromptInvalidHostname: "Name contains invalid characters.", - // process - ProcessInvalidState: "last command has finished with error, identifier for communication with our support: %s", - ProcessInvalidStateProcess: "process finished with error, identifier for communication with our support:", - ProcessStart: "process started", - ProcessEnd: "process finished", + ProcessInvalidState: "last command has finished with error, identifier for communication with our support: %s", // archiveClient ArchClientWorkingDirectory: "working directory: %s", @@ -111,57 +109,45 @@ var en = map[string]string{ ArchClientFileAlreadyExists: "file [%s] already exists", // login - LoginSuccess: "You are logged as %s <%s>", - LoginIncorrectToken: "Incorrect token, login failed", - RegionUrl: "zerops region file url", + LoginSuccess: "You are logged as %s <%s>", // region - RegionNotFound: "Selected region %s not found", - - // client ID - MultipleClientIds: "you have assigned multiple client IDs, please use the --clientId flag", - AvailableClientIds: "your client IDs are: ", - MissingClientId: "no client ID found four your account", + RegionNotFound: "Selected region %s not found", + RegionTableColumnName: "Name", // import - YamlCheck: "yaml file check started", - ImportYamlOk: "Yaml file was checked", - ImportYamlEmpty: "Config file import yaml is empty", - ImportYamlTooLarge: "Max. size of import yaml is 100 KB", - ImportYamlFound: "Import yaml found", - ImportYamlNotFound: "Import yaml not found", - ImportYamlCorrupted: "Import yaml corrupted", - ServiceCount: "Number of services to be added: %d", - QueuedProcesses: "Queued processes: %d", - CoreServices: "Core services activation started", - ReadyToImportServices: "Ready to import services", + ImportYamlOk: "Yaml file was checked", + ImportYamlEmpty: "Config file import yaml is empty", + ImportYamlTooLarge: "Max. size of import yaml is 100 KB", + ImportYamlFound: "Import yaml found", + ImportYamlNotFound: "Import yaml not found", + ImportYamlCorrupted: "Import yaml corrupted", + ServiceCount: "Number of services to be added: %d", + QueuedProcesses: "Queued processes: %d", + CoreServices: "Core services activation started", // delete cmd DeleteCanceledByUser: "delete command canceled by user", // project + service - ProjectWrongId: "Please, provide correct project ID.", - ProjectsWithSameName: "found multiple projects with the same name", - AvailableProjectIds: "available project IDs are: ", - ProjectNameOrIdEmpty: "project name or ID must be filled", - ProjectDeleteConfirm: "Project %s will be deleted? \n Are you sure?", - ServiceNameIsEmpty: "Service name must be filled", - ServiceDeleteConfirm: "Service %s will be deleted? \n Are you sure?", - ProcessInit: " command initialized", - ProjectStarting: "Project is being started", - ProjectStarted: "Project was started", - ProjectStopping: "Project is begin stopped", - ProjectStopped: "Project was stopped", - ProjectDeleting: "Project is being deleted", - ProjectDeleted: "Project was deleted", - ServiceStarting: "Service is being started", - ServiceStarted: "Service was started", - ServiceStopping: "Service is being stopped", - ServiceStopped: "Service was stopped", - ServiceDeleting: "Service is being deleted", - ServiceDeleted: "Service was deleted", - ProjectImported: "project imported", - ServiceImported: "service(s) imported", + ProjectDeleteConfirm: "Project %s will be deleted? \n Are you sure?", + ServiceDeleteConfirm: "Service %s will be deleted? \n Are you sure?", + ProjectStarting: "Project is being started", + ProjectStarted: "Project was started", + ProjectStopping: "Project is begin stopped", + ProjectStopped: "Project was stopped", + ProjectDeleting: "Project is being deleted", + ProjectDeleted: "Project was deleted", + ServiceStarting: "Service is being started", + ServiceStarted: "Service was started", + ServiceStopping: "Service is being stopped", + ServiceStopped: "Service was stopped", + ServiceDeleting: "Service is being deleted", + ServiceDeleted: "Service was deleted", + ProjectImported: "project imported", + ServiceImported: "service(s) imported", + + // service logs LogLimitInvalid: "Invalid --limit value. Allowed interval is <1;1000>", LogMinSeverityInvalid: "Invalid --minimumSeverity value.", LogMinSeverityStringLimitErr: "Allowed values are EMERGENCY, ALERT, CRITICAL, ERROR, WARNING, NOTICE, INFORMATIONAL, DEBUG.", @@ -188,7 +174,6 @@ var en = map[string]string{ // deploy DeployHintPush: "To build your application in Zerops, use the zcli push command instead.", - BuildDeployServiceStatus: "service status: %s", BuildDeployCreatingPackageStart: "creating package", BuildDeployCreatingPackageDone: "package created", BuildDeployPackageSavedInto: "package file saved into: %s", @@ -201,7 +186,7 @@ var en = map[string]string{ BuildDeployZeropsYamlFound: "File zerops.yml found. Path: %s.", BuildDeployZeropsYamlNotFound: "File zerops.yml not found. Expected path: %s.", - // S3 + // s3 BucketGenericXAmzAcl: "Defines one of predefined grants, known as canned ACLs.\nValid values are: private, public-read, public-read-write, authenticated-read.", BucketGenericXAmzAclInvalid: "Invalid --x-amz-acl value. Allowed values are: private, public-read, public-read-write, authenticated-read.", BucketGenericOnlyForObjectStorage: "This command can be used on object storage services only.", @@ -223,21 +208,27 @@ var en = map[string]string{ BucketS3RequestFailed: "S3 API request failed: %s", BucketS3BucketAlreadyExists: "The bucket name already exists under a different object storage user. Set a different bucket name.", - // Status info + // status info StatusInfoCliDataFilePath: "Zerops CLI data file path", StatusInfoLogFilePath: "Zerops CLI log file path", - // Logger - LoggerUnableToOpenLogFileWarning: "Failed to open a log file, used path: %s. Try to use --log-file-path flag.\n", + // debug logs + DebugLogsNotFound: "Debug logs not found", - // generic - UnauthenticatedUser: `unauthenticated user, login before proceeding with this command -zcli login {token} -more info: https://docs.zerops.io/documentation/cli/authorization.html`, + //////////// + // global // + //////////// + + // args + ArgsOnlyOneOptionalAllowed: "optional arg %s can be only the last one", + ArgsOnlyOneArrayAllowed: "array arg %s can be only the last one", + ArgsNotEnoughRequiredArgs: "expected at least %d arg(s), got %d", + ArgsTooManyArgs: "expected no more than %d arg(s), got %d", - HintChangeRegion: "hint: try to change your region (you can list available regions using `zcli region list`)", + // logger + LoggerUnableToOpenLogFileWarning: "Failed to open a log file, used path: %s. Try to use --log-file-path flag.\n", - // UX helpers + // ux helpers ProjectSelectorListEmpty: "You don't have any projects yet. Create a new project using `zcli project import` command.", ProjectSelectorPrompt: "Please, select a project", ProjectSelectorOutOfRangeError: "We couldn't find a project with the index you entered. Please, try again or contact our support team.", @@ -250,14 +241,17 @@ more info: https://docs.zerops.io/documentation/cli/authorization.html`, SelectorAllowedOnlyInTerminal: "Interactive selection can be used only in terminal mode. Use command flags to specify missing parameters.", PromptAllowedOnlyInTerminal: "Interactive prompt can be used only in terminal mode. Use --confirm=true flag to confirm it", - // Global - SelectedProject: "Selected project: %s", - SelectedService: "Selected service: %s", - ScopedProject: "Scoped project: %s", - ScopedProjectNotFound: "Scoped project wasn't found, Select a different project using `zcli scope project` command.", + UnauthenticatedUser: `unauthenticated user, login before proceeding with this command +zcli login {token} +more info: https://docs.zerops.io/documentation/cli/authorization.html`, - ServiceIdInvalidFormat: "Invalid format of service ID. ID must have 22 characters.", - ServiceNotFound: "Service [%s] wasn't found", + // scope + SelectedProject: "Selected project: %s", + SelectedService: "Selected service: %s", + ScopedProject: "Scoped project: %s", + ScopedProjectNotFound: "Scoped project wasn't found, Select a different project using `zcli scope project` command.", + PreviouslyScopedProject: "Previously scoped project: %s", + ScopeReset: "Scope was reset", DestructiveOperationConfirmationFailed: "You have to confirm a destructive operation.", } diff --git a/src/i18n/i18n.go b/src/i18n/i18n.go index a5cc24b3..3d8f509a 100644 --- a/src/i18n/i18n.go +++ b/src/i18n/i18n.go @@ -15,31 +15,39 @@ func T(textConst string, args ...interface{}) string { const ( // help - DisplayHelp = "DisplayHelp" - GroupHelp = "GroupHelp" - DeployHelp = "DeployHelp" - LogShowHelp = "LogShowHelp" - LoginHelp = "LoginHelp" - ProjectHelp = "ProjectHelp" - ProjectStartHelp = "ProjectStartHelp" - ProjectStopHelp = "ProjectStopHelp" - ProjectListHelp = "ProjectListHelp" - ScopeHelp = "ScopeHelp" - ScopeProjectHelp = "ScopeProjectHelp" - ScopeServiceHelp = "ScopeServiceHelp" - ScopeResetHelp = "ScopeResetHelp" - ProjectDeleteHelp = "ProjectDeleteHelp" - ProjectImportHelp = "ProjectImportHelp" - PushHelp = "PushHelp" - RegionListHelp = "RegionListHelp" - ServiceStartHelp = "ServiceStartHelp" - ServiceStopHelp = "ServiceStopHelp" - ServiceImportHelp = "ServiceImportHelp" - ServiceDeleteHelp = "ServiceDeleteHelp" - ServiceLogHelp = "ServiceLogHelp" - VersionHelp = "VersionHelp" - BucketCreateHelp = "BucketCreateHelp" - BucketDeleteHelp = "BucketDeleteHelp" + DisplayHelp = "DisplayHelp" + GroupHelp = "GroupHelp" + DeployHelp = "DeployHelp" + LogShowHelp = "LogShowHelp" + LoginHelp = "LoginHelp" + ProjectHelp = "ProjectHelp" + ProjectStartHelp = "ProjectStartHelp" + ProjectStopHelp = "ProjectStopHelp" + ProjectListHelp = "ProjectListHelp" + ScopeHelp = "ScopeHelp" + ScopeProjectHelp = "ScopeProjectHelp" + ScopeServiceHelp = "ScopeServiceHelp" + ScopeResetHelp = "ScopeResetHelp" + ProjectDeleteHelp = "ProjectDeleteHelp" + ProjectImportHelp = "ProjectImportHelp" + ProjectServiceImportHelp = "ProjectServiceImportHelp" + ServiceHelp = "ServiceHelp" + PushHelp = "PushHelp" + RegionListHelp = "RegionListHelp" + ServiceStartHelp = "ServiceStartHelp" + ServiceStopHelp = "ServiceStopHelp" + ServiceImportHelp = "ServiceImportHelp" + ServiceDeleteHelp = "ServiceDeleteHelp" + ServiceLogHelp = "ServiceLogHelp" + ServiceDeployHelp = "ServiceDeployHelp" + ServiceListHelp = "ServiceListHelp" + ServicePushHelp = "ServicePushHelp" + StatusHelp = "StatusHelp" + StatusInfoHelp = "StatusInfoHelp" + StatusShowDebugLogsHelp = "StatusShowDebugLogsHelp" + VersionHelp = "VersionHelp" + BucketCreateHelp = "BucketCreateHelp" + BucketDeleteHelp = "BucketDeleteHelp" // cmd short CmdDeployDesc = "CmdDeployDesc" @@ -97,7 +105,6 @@ const ( LogShowBuildFlag = "LogShowBuildFlag" LogFormatFlag = "LogFormatFlag" LogFormatTemplateFlag = "LogFormatTemplateFlag" - QuietModeFlag = "QuietModeFlag" TerminalFlag = "TerminalFlag" LogFilePathFlag = "LogFilePathFlag" ConfirmFlag = "ConfirmFlag" @@ -129,7 +136,8 @@ const ( RegionUrl = "RegionUrl" // region - RegionNotFound = "RegionNotFound" + RegionNotFound = "RegionNotFound" + RegionTableColumnName = "RegionTableColumnName" // client ID MultipleClientIds = "MultipleClientIds" @@ -153,28 +161,30 @@ const ( DeleteCanceledByUser = "DeleteCanceledByUser" // project + service - ProjectWrongId = "ProjectWrongId" - ProjectsWithSameName = "ProjectsWithSameName" - AvailableProjectIds = "AvailableProjectIds" - ProjectNameOrIdEmpty = "ProjectNameOrIdEmpty" - ProjectDeleteConfirm = "ProjectDeleteConfirm" - ServiceNameIsEmpty = "ServiceNameIsEmpty" - ServiceDeleteConfirm = "ServiceDeleteConfirm" - ProcessInit = "ProcessInit" - ProjectStarting = "ProjectStarting" - ProjectStarted = "ProjectStarted" - ProjectStopping = "ProjectStopping" - ProjectStopped = "ProjectStopped" - ProjectDeleting = "ProjectDeleting" - ProjectDeleted = "ProjectDeleted" - ServiceStarting = "ServiceStarting" - ServiceStarted = "ServiceStarted" - ServiceStopping = "ServiceStopping" - ServiceStopped = "ServiceStopped" - ServiceDeleting = "ServiceDeleting" - ServiceDeleted = "ServiceDeleted" - ProjectImported = "ProjectImported" - ServiceImported = "ServiceImported" + ProjectWrongId = "ProjectWrongId" + ProjectsWithSameName = "ProjectsWithSameName" + AvailableProjectIds = "AvailableProjectIds" + ProjectNameOrIdEmpty = "ProjectNameOrIdEmpty" + ProjectDeleteConfirm = "ProjectDeleteConfirm" + ServiceNameIsEmpty = "ServiceNameIsEmpty" + ServiceDeleteConfirm = "ServiceDeleteConfirm" + ProcessInit = "ProcessInit" + ProjectStarting = "ProjectStarting" + ProjectStarted = "ProjectStarted" + ProjectStopping = "ProjectStopping" + ProjectStopped = "ProjectStopped" + ProjectDeleting = "ProjectDeleting" + ProjectDeleted = "ProjectDeleted" + ServiceStarting = "ServiceStarting" + ServiceStarted = "ServiceStarted" + ServiceStopping = "ServiceStopping" + ServiceStopped = "ServiceStopped" + ServiceDeleting = "ServiceDeleting" + ServiceDeleted = "ServiceDeleted" + ProjectImported = "ProjectImported" + ServiceImported = "ServiceImported" + + // service logs LogLimitInvalid = "LogLimitInvalid" LogMinSeverityInvalid = "LogMinSeverityInvalid" LogMinSeverityStringLimitErr = "LogMinSeverityStringLimitErr" @@ -214,7 +224,7 @@ const ( BuildDeployZeropsYamlFound = "BuildDeployZeropsYamlFound" BuildDeployZeropsYamlNotFound = "BuildDeployZeropsYamlNotFound" - // S3 + // s3 BucketGenericXAmzAcl = "BucketGenericXAmzAcl" BucketGenericXAmzAclInvalid = "BucketGenericXAmzAclInvalid" BucketGenericOnlyForObjectStorage = "BucketGenericOnlyForObjectStorage" @@ -236,19 +246,27 @@ const ( BucketS3RequestFailed = "RequestFailed" BucketS3BucketAlreadyExists = "BucketAlreadyExists" - // Status info + // status info StatusInfoCliDataFilePath = "StatusInfoCliDataFilePath" StatusInfoLogFilePath = "StatusInfoLogFilePath" - // Logger - LoggerUnableToOpenLogFileWarning = "LoggerUnableToOpenLogFileWarning" + // debug logs + DebugLogsNotFound = "DebugLogsNotFound" - // generic - UnauthenticatedUser = "UnauthenticatedUser" + //////////// + // global // + //////////// - HintChangeRegion = "HintChangeRegion" + // args + ArgsOnlyOneOptionalAllowed = "ArgsOnlyOneOptionalAllowed" + ArgsOnlyOneArrayAllowed = "ArgsOnlyOneArrayAllowed" + ArgsNotEnoughRequiredArgs = "ArgsNotEnoughRequiredArgs" + ArgsTooManyArgs = "ArgsTooManyArgs" - // UX helpers + // logger + LoggerUnableToOpenLogFileWarning = "LoggerUnableToOpenLogFileWarning" + + // ux helpers ProjectSelectorListEmpty = "ProjectSelectorListEmpty" ProjectSelectorPrompt = "ProjectSelectorPrompt" ProjectSelectorOutOfRangeError = "ProjectSelectorOutOfRangeError" @@ -261,18 +279,22 @@ const ( SelectorAllowedOnlyInTerminal = "SelectorAllowedOnlyInTerminal" PromptAllowedOnlyInTerminal = "PromptAllowedOnlyInTerminal" - // Global - SelectedProject = "SelectedProject" - SelectedService = "SelectedService" - ScopedProject = "ScopedProject" - ScopedProjectNotFound = "ScopedProjectNotFound" - ScopedServiceNotFound = "ScopedServiceNotFound" + UnauthenticatedUser = "UnauthenticatedUser" + + // scope + SelectedProject = "SelectedProject" + SelectedService = "SelectedService" + ScopedProject = "ScopedProject" + ScopedProjectNotFound = "ScopedProjectNotFound" + PreviouslyScopedProject = "PreviouslyScopedProject" + ScopeReset = "ScopeReset" + + DestructiveOperationConfirmationFailed = "DestructiveOperationConfirmationFailed" + HintChangeRegion = "HintChangeRegion" + ScopedServiceNotFound = "ScopedServiceNotFound" ProjectIdInvalidFormat = "ProjectIdInvalidFormat" ProjectNotFound = "ProjectNotFound" - ServiceIdInvalidFormat = "ServiceIdInvalidFormat" ServiceNotFound = "ServiceNotFound" - - DestructiveOperationConfirmationFailed = "DestructiveOperationConfirmationFailed" ) diff --git a/src/logger/handler.go b/src/logger/handler.go index 8df325c1..2ea572f1 100644 --- a/src/logger/handler.go +++ b/src/logger/handler.go @@ -36,7 +36,6 @@ func NewOutputLogger(config OutputConfig) *Handler { return &Handler{ logrus: l, } - } type DebugFileConfig struct { @@ -66,7 +65,6 @@ func NewDebugFileLogger(config DebugFileConfig) *Handler { return &Handler{ logrus: l, } - } func (h *Handler) Info(a ...interface{}) { diff --git a/src/params/handler.go b/src/params/handler.go index 0171ab7c..2679654e 100644 --- a/src/params/handler.go +++ b/src/params/handler.go @@ -26,52 +26,49 @@ func (h *Handler) getCmdId(cmd *cobra.Command, name string) string { return cmd.Use + name } -func (h *Handler) RegisterString(cmd *cobra.Command, name, defaultValue, description string) { +func (h *Handler) RegisterString(cmd *cobra.Command, name, shorthand, defaultValue, description string) { var paramValue string - cmd.Flags().StringVar(¶mValue, name, defaultValue, description) + cmd.Flags().StringVarP(¶mValue, name, shorthand, defaultValue, description) h.params[h.getCmdId(cmd, name)] = func() *string { if cmd.Flags().Lookup(name).Changed { return ¶mValue } - if h.viper.GetString(name) != "" { - v := h.viper.GetString(name) - return &v + if val := h.viper.GetString(toSnakeCase(name)); val != "" { + return &val } return ¶mValue } } -func (h *Handler) RegisterBool(cmd *cobra.Command, name string, defaultValue bool, description string) { +func (h *Handler) RegisterBool(cmd *cobra.Command, name, shorthand string, defaultValue bool, description string) { var paramValue bool - cmd.Flags().BoolVar(¶mValue, name, defaultValue, description) + cmd.Flags().BoolVarP(¶mValue, name, shorthand, defaultValue, description) h.params[h.getCmdId(cmd, name)] = func() *bool { if cmd.Flags().Lookup(name).Changed { return ¶mValue } - if h.viper.GetBool(name) != false { - v := h.viper.GetBool(name) - return &v + if val := h.viper.GetBool(toSnakeCase(name)); val { + return &val } return ¶mValue } } -func (h *Handler) RegisterInt(cmd *cobra.Command, name string, defaultValue int, description string) { +func (h *Handler) RegisterInt(cmd *cobra.Command, name, shorthand string, defaultValue int, description string) { var paramValue int - cmd.Flags().IntVar(¶mValue, name, defaultValue, description) + cmd.Flags().IntVarP(¶mValue, name, shorthand, defaultValue, description) h.params[h.getCmdId(cmd, name)] = func() *int { if cmd.Flags().Lookup(name).Changed { return ¶mValue } - if h.viper.GetInt(name) != 0 { - v := h.viper.GetInt(name) - return &v + if val := h.viper.GetInt(toSnakeCase(name)); val != 0 { + return &val } return ¶mValue } @@ -131,3 +128,14 @@ func (h *Handler) InitViper() error { return nil } + +func toSnakeCase(flagName string) string { + var result string + for i, r := range flagName { + if i > 0 && r >= 'A' && r <= 'Z' { + result += "_" + } + result += string(r) + } + return result +} diff --git a/src/region/region.go b/src/region/region.go index 65471030..70f234aa 100644 --- a/src/region/region.go +++ b/src/region/region.go @@ -1,6 +1,7 @@ package region import ( + "context" "encoding/json" "sort" @@ -27,8 +28,8 @@ func New(client *httpClient.Handler) *Handler { } } -func (h *Handler) RetrieveAllFromURL(regionURL string) ([]Data, error) { - resp, err := h.client.Get(regionURL) +func (h *Handler) RetrieveAllFromURL(ctx context.Context, regionURL string) ([]Data, error) { + resp, err := h.client.Get(ctx, regionURL) if err != nil { return nil, err } diff --git a/src/serviceLogs/handler_checkInputValues.go b/src/serviceLogs/handler_checkInputValues.go index 6e2cd282..1e7b1e48 100644 --- a/src/serviceLogs/handler_checkInputValues.go +++ b/src/serviceLogs/handler_checkInputValues.go @@ -1,7 +1,6 @@ package serviceLogs import ( - "fmt" "html/template" "strconv" "strings" @@ -79,9 +78,9 @@ func (h *Handler) getMinSeverity(config RunConfig) (intVal int, err error) { } _, err = strconv.Atoi(ms) if err != nil { - return 1, fmt.Errorf("%s %s", i18n.T(i18n.LogMinSeverityInvalid), i18n.T(i18n.LogMinSeverityStringLimitErr)) + return 1, errors.Errorf("%s %s", i18n.T(i18n.LogMinSeverityInvalid), i18n.T(i18n.LogMinSeverityStringLimitErr)) } - return 1, fmt.Errorf("%s %s", i18n.T(i18n.LogMinSeverityInvalid), i18n.T(i18n.LogMinSeverityNumLimitErr)) + return 1, errors.Errorf("%s %s", i18n.T(i18n.LogMinSeverityInvalid), i18n.T(i18n.LogMinSeverityNumLimitErr)) } // getFacility returns facility number based on msgType @@ -118,7 +117,7 @@ func (h *Handler) getFormat(config RunConfig) (string, string, error) { // e.g. --formatTemplate="{{.timestamp}} {{.priority}} {{.facility}} {{.message}}" func (h *Handler) checkFormat(ft string) (string, error) { if err := validateTemplate(ft); err != nil { - return "", fmt.Errorf("%s %s", i18n.T(i18n.LogFormatTemplateInvalid), err) + return "", errors.Errorf("%s %s", i18n.T(i18n.LogFormatTemplateInvalid), err) } return ft, nil } diff --git a/src/serviceLogs/handler_formatByRfc.go b/src/serviceLogs/handler_formatByRfc.go index 0edae025..da10ef94 100644 --- a/src/serviceLogs/handler_formatByRfc.go +++ b/src/serviceLogs/handler_formatByRfc.go @@ -19,8 +19,8 @@ import ( "time" ) -func getFullByRfc(logData []Data, RFC string) { - if RFC == RFC3164 { +func getFullByRfc(logData []Data, rfc string) { + if rfc == RFC3164 { for _, data := range logData { fmt.Printf("<%d>%s %s %s: %s\n", data.Priority, @@ -47,8 +47,7 @@ func getFullByRfc(logData []Data, RFC string) { // add missing 0 to have the same length for all timestamps func fixTimestamp(timestamp string) string { - missing := 27 - len(timestamp) - if missing == 0 { + if 27-len(timestamp) == 0 { return timestamp } splitVal := strings.Split(timestamp, ".") @@ -64,7 +63,7 @@ func rfc3164TimeFormat(timestamp string) string { layout := "2006-01-02T15:04:05.000000Z" timeStamp, err := time.Parse(layout, timestamp) if err != nil { - fmt.Println(err) + return err.Error() } return timeStamp.Format("Jan 02 15:04:05") } diff --git a/src/serviceLogs/handler_formatByTemplate.go b/src/serviceLogs/handler_formatByTemplate.go index 0536fc3c..8ccfd762 100644 --- a/src/serviceLogs/handler_formatByTemplate.go +++ b/src/serviceLogs/handler_formatByTemplate.go @@ -6,6 +6,7 @@ import ( "strings" "text/template" + "github.com/pkg/errors" "golang.org/x/text/cases" "golang.org/x/text/language" @@ -20,7 +21,7 @@ func getFullWithTemplate(logData []Data, formatTemplate string) error { for _, o := range logData { err := formatDataByTemplate(o, ft) if err != nil { - return fmt.Errorf("%s %s", i18n.T(i18n.LogFormatTemplateInvalid), err) + return errors.Errorf("%s %s", i18n.T(i18n.LogFormatTemplateInvalid), err) } } return nil @@ -46,7 +47,7 @@ func testTokens(tokens []string) error { // if any `{` characters are left, it means the items were not split by correctly rmLeft := strings.Replace(token, "{", "", 2) if strings.Contains(rmLeft, "{") { - return fmt.Errorf("%s %s", i18n.T(i18n.LogFormatTemplateInvalid), i18n.T(i18n.LogFormatTemplateNoSpace)) + return errors.Errorf("%s %s", i18n.T(i18n.LogFormatTemplateInvalid), i18n.T(i18n.LogFormatTemplateNoSpace)) } } return nil diff --git a/src/serviceLogs/handler_formatLogs.go b/src/serviceLogs/handler_formatLogs.go index f7409549..357ef51b 100644 --- a/src/serviceLogs/handler_formatLogs.go +++ b/src/serviceLogs/handler_formatLogs.go @@ -13,7 +13,8 @@ func parseResponseByFormat(jsonData Response, format, formatTemplate, mode strin logs = reverseLogs(logs) } - if format == FULL { + switch format { + case FULL: if formatTemplate != "" { if err = getFullWithTemplate(logs, formatTemplate); err != nil { return err @@ -24,11 +25,11 @@ func parseResponseByFormat(jsonData Response, format, formatTemplate, mode strin getFullByRfc(logs, RFC5424) return nil } - } else if format == SHORT { + case SHORT: for _, o := range logs { fmt.Printf("%v %s \n", o.Timestamp, o.Content) } - } else if format == JSONSTREAM { + case JSONSTREAM: for _, o := range logs { val, err := json.Marshal(o) if err != nil { @@ -36,7 +37,7 @@ func parseResponseByFormat(jsonData Response, format, formatTemplate, mode strin } fmt.Println(string(val)) } - } else { + default: val, err := json.Marshal(logs) if err != nil { return err diff --git a/src/serviceLogs/handler_getServiceLogUrl.go b/src/serviceLogs/handler_getServiceLogUrl.go index 34e5d098..b94a3a0d 100644 --- a/src/serviceLogs/handler_getServiceLogUrl.go +++ b/src/serviceLogs/handler_getServiceLogUrl.go @@ -2,9 +2,9 @@ package serviceLogs import ( "context" - "fmt" "strings" + "github.com/pkg/errors" "github.com/zeropsio/zerops-go/dto/output" "github.com/zeropsio/zcli/src/i18n" @@ -20,7 +20,7 @@ func (h *Handler) getServiceLogResData(ctx context.Context, projectId uuid.Proje resOutput, err := response.Output() if err != nil { - return "", "", fmt.Errorf("%s %v", i18n.T(i18n.LogAccessFailed), err) + return "", "", errors.Errorf("%s %v", i18n.T(i18n.LogAccessFailed), err) } method, url := getLogRequestData(resOutput) return method, url, nil diff --git a/src/serviceLogs/handler_ws.go b/src/serviceLogs/handler_ws.go index 473a40da..2bd13751 100644 --- a/src/serviceLogs/handler_ws.go +++ b/src/serviceLogs/handler_ws.go @@ -9,6 +9,7 @@ import ( "time" "github.com/gorilla/websocket" + "github.com/pkg/errors" "github.com/zeropsio/zcli/src/i18n" "github.com/zeropsio/zerops-go/types/uuid" ) @@ -28,7 +29,7 @@ func (h *Handler) getLogStream( conn, reps, err := websocket.DefaultDialer.Dial(url, nil) if err != nil { - return fmt.Errorf("%s %s\n", i18n.T(i18n.LogReadingFailed), err.Error()) + return errors.Errorf("%s %s\n", i18n.T(i18n.LogReadingFailed), err.Error()) } defer reps.Body.Close() defer conn.Close() @@ -44,7 +45,10 @@ func (h *Handler) getLogStream( case <-done: // if interrupted by user if ctx.Err() != nil { - return nil + if errors.Is(ctx.Err(), context.Canceled) { + return nil + } + return err } // otherwise try to reconnect the websocket err := h.printLogs(ctx, inputs, projectId, serviceId, containerId) @@ -90,7 +94,7 @@ func (h *Handler) receiveHandler(connection *websocket.Conn, format string, done } finishedByUser := strings.Contains(err.Error(), "use of closed network connection") if !finishedByUser { - errMsg := fmt.Errorf("%s %s\n", i18n.T(i18n.LogReadingFailed), err.Error()) + errMsg := errors.Errorf("%s %s\n", i18n.T(i18n.LogReadingFailed), err.Error()) fmt.Println(errMsg) } return @@ -104,7 +108,7 @@ func (h *Handler) printStreamLog(data []byte, format string) { jsonData, _ := parseResponse(data) // only if there is a new message coming if len(jsonData.Items) > 0 { - //update last msg ID for ws reconnection + // update last msg ID for ws reconnection h.lastMsgId = jsonData.Items[len(jsonData.Items)-1].Id err := parseResponseByFormat(jsonData, format, "", STREAM) if err != nil { diff --git a/src/storage/handler_test.go b/src/storage/handler_test.go index 04e7bd8c..cdbf17f8 100644 --- a/src/storage/handler_test.go +++ b/src/storage/handler_test.go @@ -4,12 +4,10 @@ import ( "os" "testing" - . "github.com/onsi/gomega" + "github.com/stretchr/testify/require" ) func TestStorage(t *testing.T) { - RegisterTestingT(t) - type dataObject struct { Param string } @@ -18,11 +16,11 @@ func TestStorage(t *testing.T) { storage, err := New[dataObject](Config{ FilePath: "./test", }) - Expect(err).ShouldNot(HaveOccurred()) + require.NoError(t, err) { d := storage.Data() - Expect(d.Param).To(Equal("")) + require.Equal(t, "", d.Param) } { @@ -30,8 +28,8 @@ func TestStorage(t *testing.T) { data.Param = "value" return data }) - Expect(err).ShouldNot(HaveOccurred()) - Expect(d.Param).To(Equal("value")) + require.NoError(t, err) + require.Equal(t, "value", d.Param) } } @@ -39,13 +37,12 @@ func TestStorage(t *testing.T) { storage, err := New[dataObject](Config{ FilePath: "./test", }) - Expect(err).ShouldNot(HaveOccurred()) + require.NoError(t, err) d := storage.Data() - Expect(d.Param).To(Equal("value")) + require.Equal(t, "value", d.Param) } err := os.Remove("./test") - Expect(err).ShouldNot(HaveOccurred()) - + require.NoError(t, err) } diff --git a/src/uxBlock/blocks.go b/src/uxBlock/blocks.go index b8f9111e..e2b4663d 100644 --- a/src/uxBlock/blocks.go +++ b/src/uxBlock/blocks.go @@ -28,9 +28,10 @@ type UxBlocks interface { } type uxBlocks struct { - isTerminal bool outputLogger logger.Logger debugFileLogger logger.Logger + isTerminal bool + terminalWidth int // ctxCancel is used to cancel the context of the command. // Bubbles package that we use to render graphic components steals the signal handler. @@ -44,6 +45,7 @@ func NewBlock( outputLogger logger.Logger, debugFileLogger logger.Logger, isTerminal bool, + terminalWidth int, ctxCancel context.CancelFunc, ) *uxBlocks { // safety check @@ -55,6 +57,7 @@ func NewBlock( outputLogger: outputLogger, debugFileLogger: debugFileLogger, isTerminal: isTerminal, + terminalWidth: terminalWidth, ctxCancel: ctxCancel, } } diff --git a/src/uxBlock/prompt.go b/src/uxBlock/prompt.go index c0b8fe7e..1f413468 100644 --- a/src/uxBlock/prompt.go +++ b/src/uxBlock/prompt.go @@ -37,8 +37,8 @@ func (b *uxBlocks) Prompt( choices: choices, } p := tea.NewProgram(model, tea.WithoutSignalHandler(), tea.WithContext(ctx)) - _, err := p.Run() - if err != nil { + + if _, err := p.Run(); err != nil { return 0, err } @@ -67,7 +67,6 @@ func (m *promptModel) Init() tea.Cmd { func (m *promptModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) { if msg, ok := msg.(tea.KeyMsg); ok { switch msg.String() { - case "ctrl+c": m.canceled = true return m, tea.Quit diff --git a/src/uxBlock/select.go b/src/uxBlock/select.go index 4818fd9d..d3f6d350 100644 --- a/src/uxBlock/select.go +++ b/src/uxBlock/select.go @@ -91,42 +91,41 @@ func (m *selectModel) Init() tea.Cmd { func (m *selectModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) { // Make sure these keys always quiting - if msg, ok := msg.(tea.KeyMsg); ok { - switch msg.String() { - - case "ctrl+c": - m.canceled = true - return m, tea.Quit - - case "up": - if m.cursor > 0 { - m.cursor-- - } - - case "down": - if m.cursor < len(m.tableBody.rows)-1 { - m.cursor++ - } - case "enter": - m.quiting = true + keyMsg, ok := msg.(tea.KeyMsg) + if !ok { + return m, nil + } + switch keyMsg.String() { + case "ctrl+c": + m.canceled = true + return m, tea.Quit + + case "up": + if m.cursor > 0 { + m.cursor-- + } - if !m.cfg.multiSelect { - m.selected = make(map[int]struct{}) - m.selected[m.cursor] = struct{}{} - } + case "down": + if m.cursor < len(m.tableBody.rows)-1 { + m.cursor++ + } + case "enter": + m.quiting = true - return m, tea.Quit + if !m.cfg.multiSelect { + m.selected = make(map[int]struct{}) + m.selected[m.cursor] = struct{}{} } - if m.cfg.multiSelect { - switch msg.String() { + return m, tea.Quit + } - case " ": - if _, ok := m.selected[m.cursor]; ok { - delete(m.selected, m.cursor) - } else { - m.selected[m.cursor] = struct{}{} - } + if m.cfg.multiSelect { + if keyMsg.String() == " " { + if _, ok := m.selected[m.cursor]; ok { + delete(m.selected, m.cursor) + } else { + m.selected[m.cursor] = struct{}{} } } } @@ -188,5 +187,7 @@ func (m *selectModel) View() string { s = SelectionIcon + m.cfg.label + "\n" } + t.Width(calculateTableWidth(t, m.uxBlocks.terminalWidth)) + return s + t.String() } diff --git a/src/uxBlock/showcase/main.go b/src/uxBlock/showcase/main.go index ffcdc233..71d58ae1 100644 --- a/src/uxBlock/showcase/main.go +++ b/src/uxBlock/showcase/main.go @@ -11,32 +11,23 @@ import ( "github.com/mattn/go-isatty" "github.com/zeropsio/zcli/src/logger" . "github.com/zeropsio/zcli/src/uxBlock" + "golang.org/x/term" ) func main() { ctx, cancel := context.WithCancel(context.Background()) regSignals(cancel) - blocks, err := createBlocks(cancel) - if err != nil { - fmt.Println(err) - os.Exit(1) - } + blocks := createBlocks(cancel) - err = do(ctx, blocks) - if err != nil { - fmt.Println(err) - os.Exit(1) - } + do(ctx, blocks) } -func do(ctx context.Context, blocks UxBlocks) error { +func do(ctx context.Context, blocks UxBlocks) { prompts(ctx, blocks) spinners(ctx, blocks) texts(ctx, blocks) tables(ctx, blocks) - - return nil } func spinners(ctx context.Context, blocks UxBlocks) { @@ -92,7 +83,7 @@ func prompts(ctx context.Context, blocks UxBlocks) { fmt.Println("========= prompt block end =========") } -func texts(ctx context.Context, blocks UxBlocks) { +func texts(_ context.Context, blocks UxBlocks) { fmt.Println("========= texts block =========") blocks.PrintInfoLine("info line") blocks.PrintWarningLine("warning line") @@ -106,7 +97,12 @@ func tables(ctx context.Context, blocks UxBlocks) { tableData := [][]string{ {"lorem", "ipsum", "dolor", "sit"}, - {"amet", "consectetur", "adipiscing", "elit"}, + { + "amet", + "lorem ipsum dolor sit amet consectetur adipiscing elit sed do eiusmod tempor incididunt ut labore et dolore magna aliqua lorem ipsum dolor sit amet consectetur adipiscing elit sed do eiusmod tempor incididunt ut labore et dolore magna aliqua", + "adipiscing", + "elit", + }, {"sed", "do", "eiusmod", "tempor"}, {"incididunt", "ut", "labore", "et"}, } @@ -145,18 +141,23 @@ func regSignals(contextCancel func()) { }() } -func createBlocks(contextCancelFunc func()) (UxBlocks, error) { +func createBlocks(contextCancelFunc func()) UxBlocks { isTerminal := isatty.IsTerminal(os.Stdout.Fd()) || isatty.IsCygwinTerminal(os.Stdout.Fd()) outputLogger := logger.NewOutputLogger(logger.OutputConfig{ IsTerminal: isTerminal, }) + width, _, err := term.GetSize(0) + if err != nil { + width = 100 + } + debugFileLogger := logger.NewDebugFileLogger(logger.DebugFileConfig{ FilePath: "zerops.log", }) - blocks := NewBlock(outputLogger, debugFileLogger, isTerminal, contextCancelFunc) + blocks := NewBlock(outputLogger, debugFileLogger, isTerminal, width, contextCancelFunc) - return blocks, nil + return blocks } diff --git a/src/uxBlock/spinner.go b/src/uxBlock/spinner.go index 92e7e590..be4a9b84 100644 --- a/src/uxBlock/spinner.go +++ b/src/uxBlock/spinner.go @@ -30,6 +30,7 @@ func (b *uxBlocks) RunSpinners(ctx context.Context, spinners []*Spinner, auxOpti p := tea.NewProgram(model, tea.WithoutSignalHandler(), tea.WithContext(ctx)) go func() { + //nolint:errcheck p.Run() if model.canceled { b.ctxCancel() @@ -77,9 +78,7 @@ func (m *spinnerModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) { return m, tea.Quit case tea.KeyMsg: - switch msg.String() { - case "ctrl+c": - + if msg.String() == "ctrl+c" { m.canceled = true m.quiting = true return m, tea.Quit @@ -106,14 +105,11 @@ func (m *spinnerModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) { lock.Lock() cmdList[i] = cmd lock.Unlock() - }(i) } wg.Wait() return m, XXX(cmdList...) - } - return m, nil } diff --git a/src/uxBlock/table.go b/src/uxBlock/table.go index 636da285..7f2c8008 100644 --- a/src/uxBlock/table.go +++ b/src/uxBlock/table.go @@ -134,5 +134,19 @@ func (b *uxBlocks) Table(body *TableBody, auxOptions ...TableOption) { } t = t.Rows(rows...) + t.Width(calculateTableWidth(t, b.terminalWidth)) + fmt.Println(t) } + +// calculateTableWidth calculates the width of the table. +// If the table is wider than the terminal, a table starts falling apart. +// To set a fix width could help, but in that case, even if the table is smaller, it takes the whole terminal width. +// And it doesn't look good. +func calculateTableWidth(t *table.Table, terminalWidth int) int { + tableWidth := lipgloss.Width(t.String()) + if tableWidth > terminalWidth { + return terminalWidth + } + return 0 +} diff --git a/src/cmd/uxHelpers.go b/src/uxHelpers/prompt.go similarity index 56% rename from src/cmd/uxHelpers.go rename to src/uxHelpers/prompt.go index 9b5e9888..36354d22 100644 --- a/src/cmd/uxHelpers.go +++ b/src/uxHelpers/prompt.go @@ -1,17 +1,17 @@ -package cmd +package uxHelpers import ( "context" "github.com/pkg/errors" - "github.com/zeropsio/zcli/src/cmdBuilder" "github.com/zeropsio/zcli/src/i18n" + "github.com/zeropsio/zcli/src/uxBlock" ) -func YesNoPromptDestructive(ctx context.Context, cmdData *cmdBuilder.LoggedUserCmdData, message string) error { +func YesNoPromptDestructive(ctx context.Context, uxBlocks uxBlock.UxBlocks, message string) error { // TODO - janhajek translate choices := []string{"NO", "YES"} - choice, err := cmdData.UxBlocks.Prompt(ctx, message, choices) + choice, err := uxBlocks.Prompt(ctx, message, choices) if err != nil { return err } diff --git a/src/zeropsRestApiClient/handler_get_service_stacks_by_project.go b/src/zeropsRestApiClient/handler_get_service_stacks_by_project.go index cc2b6201..96d51c64 100644 --- a/src/zeropsRestApiClient/handler_get_service_stacks_by_project.go +++ b/src/zeropsRestApiClient/handler_get_service_stacks_by_project.go @@ -102,5 +102,4 @@ type EsServiceStackInfoJsonObject struct { ServiceStackTypeName types.String `json:"serviceStackTypeName"` // serviceStackTypeName - types.String ServiceStackTypeCategory enum.ServiceStackTypeCategoryEnum `json:"serviceStackTypeCategory"` // serviceStackTypeCategory - enum.ServiceStackTypeCategoryEnum ServiceStackTypeVersionName types.String `json:"serviceStackTypeVersionName"` // serviceStackTypeVersionName - types.String - } diff --git a/tools/gomodrun.go b/tools/gomodrun.go index 98600fbe..437601d2 100644 --- a/tools/gomodrun.go +++ b/tools/gomodrun.go @@ -1,12 +1,13 @@ package main import ( - "fmt" "log" "os" "os/exec" "path" "path/filepath" + + "github.com/pkg/errors" ) func getMod(dir string) (string, error) { @@ -17,7 +18,7 @@ func getMod(dir string) (string, error) { if newDir != "" { return getMod(newDir) } - return "", fmt.Errorf("go.mod not found") + return "", errors.New("go.mod not found") } func main() { diff --git a/tools/install.sh b/tools/install.sh index e2f46a73..e0887c47 100755 --- a/tools/install.sh +++ b/tools/install.sh @@ -17,32 +17,6 @@ export PATH="${GOBIN}:${PATH}" echo "GOBIN=${GOBIN}" -go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.28.1 -go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.2.0 - -[[ -f protoc.zip ]] && rm protoc.zip -[[ -f bin/protoc ]] && rm bin/protoc -[[ -d include ]] && rm -rf include -[[ -d tmp ]] && rm -rf tmp -mkdir include -mkdir tmp -cd tmp - -if [[ "$OSTYPE" == "darwin"* ]]; then - wget -O protoc.zip https://github.com/protocolbuffers/protobuf/releases/download/v21.3/protoc-21.3-osx-x86_64.zip -else - wget -O protoc.zip https://github.com/protocolbuffers/protobuf/releases/download/v21.3/protoc-21.3-linux-x86_64.zip -fi - -ls -la protoc.zip -unzip protoc.zip - -mv bin/protoc ../bin -mv -v ./include/* ../include/google - -cd .. -chmod +x bin/protoc - rm -rf tmp # https://github.com/golangci/golangci-lint#go Please, do not installDaemon golangci-lint by go get