From 5e8421705f39856cf50b67e0f4f38e0d9d419d25 Mon Sep 17 00:00:00 2001 From: Varun Gandhi Date: Fri, 10 Jun 2022 18:21:01 +0300 Subject: [PATCH] cli: Replace docopt with urfave/cli. (#48) * cli: Replace docopt with urfave/cli. Fixes issue 25. * docs: Add subheadings to Readme. * nit: Rearrange imports. * nit: Compress if. --- Readme.md | 104 ++++++++++++++++++++++++++++++++++++++++++++++- cmd/Readme.md | 66 ------------------------------ cmd/convert.go | 34 ++++++++++++++-- cmd/main.go | 86 +++++++++++++++++++-------------------- cmd/main_test.go | 56 +++++++++++++------------ cmd/snapshot.go | 38 +++++++++++++++-- cmd/stats.go | 26 ++++++++++-- go.mod | 6 +-- go.sum | 8 ++-- 9 files changed, 274 insertions(+), 150 deletions(-) mode change 120000 => 100644 Readme.md delete mode 100644 cmd/Readme.md diff --git a/Readme.md b/Readme.md deleted file mode 120000 index c03729aa..00000000 --- a/Readme.md +++ /dev/null @@ -1 +0,0 @@ -cmd/Readme.md \ No newline at end of file diff --git a/Readme.md b/Readme.md new file mode 100644 index 00000000..8f256d19 --- /dev/null +++ b/Readme.md @@ -0,0 +1,103 @@ +# SCIP Code Intelligence Protocol + +SCIP (pronounciation: "skip") is a language-agnostic protocol +for indexing source code, +which can be used to power code navigation functionality +such as Go to definition, Find references, and Find implementations. + +This repository includes: + +- A [protobuf schema for SCIP](./scip.proto). +- Rich Go bindings for SCIP: This includes many utility functions + to help build tooling on top of SCIP. +- Auto-generated bindings for TypeScript, Rust and Haskell. +- The [`scip` CLI](#scip-cli-reference) makes SCIP indexes + a breeze to work with. + +If you're interested in better understanding the motivation behind SCIP, +check out the [announcement blog post](https://about.sourcegraph.com/blog/announcing-scip). + +If you're interested in writing a new indexer that emits SCIP, +check out our documentation on +[how to write an indexer](https://docs.sourcegraph.com/code_intelligence/explanations/writing_an_indexer). + +## Contributing + +We welcome questions, suggestions as well as code and docs contributions. + +For submitting contributions, check out [Development.md](./Development.md) +to better understand project structure and common workflows. + +Contributors should abide by the [Sourcegraph Code of Conduct](https://handbook.sourcegraph.com/company-info-and-process/communication/code_of_conduct/). + +## SCIP CLI reference + +``` +NAME: + scip - SCIP Code Intelligence Protocol CLI + +USAGE: + scip [global options] command [command options] [arguments...] + +DESCRIPTION: + For more details, see the project README at: + + https://github.com/sourcegraph/scip + +COMMANDS: + convert Convert a SCIP index to an LSIF index + snapshot Generate snapshot files for golden testing + stats Output useful statistics about a SCIP index + help, h Shows a list of commands or help for one command + +GLOBAL OPTIONS: + --help, -h show help (default: false) + --version, -v Print the current version and exit. (default: false) +``` + +### `scip convert` + +``` +NAME: + scip convert - Convert a SCIP index to an LSIF index + +USAGE: + scip convert [command options] [arguments...] + +OPTIONS: + --from value Path to SCIP index file (default: index.scip) + --to value Output path for LSIF index (default: dump.lsif) +``` + +### `scip snapshot` + +``` +NAME: + scip snapshot - Generate snapshot files for golden testing + +USAGE: + scip snapshot [command options] [arguments...] + +DESCRIPTION: + The snapshot subcommand generates snapshot files which + can be use for inspecting the output of an index in a + visual way. Occurrences are marked with caret signs (^) + and symbol information. + +OPTIONS: + --from value Path to SCIP index file (default: index.scip) + --to value Path to output directory for snapshot files (default: scip-snapshot) +``` + +### `scip stats` + +``` +NAME: + scip stats - Output useful statistics about a SCIP index + +USAGE: + scip stats [command options] [arguments...] + +OPTIONS: + --from value Path to SCIP index file (default: index.scip) +``` diff --git a/cmd/Readme.md b/cmd/Readme.md deleted file mode 100644 index a7cb092d..00000000 --- a/cmd/Readme.md +++ /dev/null @@ -1,66 +0,0 @@ -# SCIP Code Intelligence Protocol - -SCIP (pronounciation: "skip") is a language-agnostic protocol -for indexing source code, -which can be used to power code navigation functionality -such as Go to definition, Find references, and Find implementations. - -This repository includes: - -- A [protobuf schema for SCIP](./scip.proto). -- Rich Go bindings for SCIP: This includes many utility functions - to help build tooling on top of SCIP. -- Auto-generated bindings for TypeScript, Rust and Haskell. -- The [`scip` CLI](#scip-cli-reference) makes SCIP indexes - a breeze to work with. - -If you're interested in better understanding the motivation behind SCIP, -check out the [announcement blog post](https://about.sourcegraph.com/blog/announcing-scip). - -If you're interested in writing a new indexer that emits SCIP, -check out our documentation on -[how to write an indexer](https://docs.sourcegraph.com/code_intelligence/explanations/writing_an_indexer). - - - -## SCIP CLI reference - - - -``` -Usage: - scip convert [--from=] [--to=] - scip stats [--from=] - scip snapshot [--from=] [--output=] - scip --version - scip -h | --help - -Options: - --from= Input file for conversion [default: index.scip]. - --to= Output file for conversion [default: dump.lsif]. - --output= Output directory [default: scip-snapshot]. - --version Show version. - -h --help Show help text. - -A single dash path ('-') for --from (--to) is interpreted as stdin (stdout). - -The 'convert' subcommand currently only supports conversion from SCIP to LSIF. -``` - - - -## Contributing - -We welcome questions, suggestions as well as code and docs contributions. - -For submitting contributions, check out [Development.md](./Development.md) -to better understand project structure and common workflows. - -Contributors should abide by the [Sourcegraph Code of Conduct](https://handbook.sourcegraph.com/company-info-and-process/communication/code_of_conduct/). diff --git a/cmd/convert.go b/cmd/convert.go index 2069570c..43c46522 100644 --- a/cmd/convert.go +++ b/cmd/convert.go @@ -5,20 +5,48 @@ import ( "os" "strings" + "github.com/urfave/cli/v2" + "github.com/sourcegraph/sourcegraph/lib/codeintel/lsif/protocol/reader" "github.com/sourcegraph/sourcegraph/lib/errors" "github.com/sourcegraph/scip/bindings/go/scip" ) -func convertMain(parsedArgs map[string]interface{}) error { - scipIndex, err := readFromOption(parsedArgs["--from"].(string)) +type convertFlags struct { + from string + to string +} + +func convertCommand() cli.Command { + var convertFlags convertFlags + convert := cli.Command{ + Name: "convert", + Usage: "Convert a SCIP index to an LSIF index", + Flags: []cli.Flag{ + fromFlag(&convertFlags.from), + &cli.StringFlag{ + Name: "to", + Usage: "Output path for LSIF index", + Destination: &convertFlags.to, + DefaultText: "dump.lsif", + }, + }, + Action: func(c *cli.Context) error { + return convertMain(convertFlags) + }, + } + return convert +} + +func convertMain(flags convertFlags) error { + scipIndex, err := readFromOption(flags.from) if err != nil { return err } var lsifWriter io.Writer - toPath := parsedArgs["--to"].(string) + toPath := flags.to if toPath == "-" { lsifWriter = os.Stdout } else if !strings.HasSuffix(toPath, ".lsif") { diff --git a/cmd/main.go b/cmd/main.go index da97f18c..c1e9868e 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -1,59 +1,59 @@ package main import ( - _ "embed" "fmt" + "log" "os" - "regexp" - "github.com/docopt/docopt-go" + "github.com/urfave/cli/v2" ) -//go:embed Readme.md -var readme string - -func helpText() string { - usageRegexp := regexp.MustCompile("(?s)\n\n```\n(.*)\n```\n\n") - usageText := usageRegexp.FindStringSubmatch(readme)[1] - return fmt.Sprintf(helpTextTemplate, usageText) +func main() { + app := scipApp() + if err := app.Run(os.Args); err != nil { + log.Fatal(err) + } } -const helpTextTemplate string = `Semantic Code Intelligence Protocol CLI. - -%s - -For more details, see the project README: https://github.com/sourcegraph/scip -` +func commands() []*cli.Command { + convert := convertCommand() + snapshot := snapshotCommand() + stats := statsCommand() + return []*cli.Command{&convert, &snapshot, &stats} +} -func bailIfError(err error) { - if err != nil { - os.Stderr.WriteString(err.Error()) - os.Exit(1) +func scipApp() cli.App { + var versionFlag bool + app := cli.App{ + Name: "scip", + Usage: "SCIP Code Intelligence Protocol CLI", + Description: "For more details, see the project README at:\n\n\thttps://github.com/sourcegraph/scip", + Flags: []cli.Flag{ + &cli.BoolFlag{ + Name: "version", + Usage: "Print the current version and exit.", + Destination: &versionFlag, + Aliases: []string{"v"}, + }, + }, + Action: func(c *cli.Context) error { + if versionFlag { + fmt.Println("0.1.0") + os.Exit(0) + } + // FIXME: What is the right way to print help text and error here? + return nil + }, + Commands: commands(), } + return app } -func main() { - parsedArgs, err := docopt.ParseDoc(helpText()) - bailIfError(err) - // --help is handled by docopt - if parsedArgs["--version"].(bool) { - fmt.Println("0.1.0") - os.Exit(0) - } - if parsedArgs["convert"].(bool) { - bailIfError(convertMain(parsedArgs)) - os.Exit(0) - } - if parsedArgs["stats"].(bool) { - bailIfError(statsMain(parsedArgs)) - os.Exit(0) - } - if parsedArgs["snapshot"].(bool) { - bailIfError(snapshotMain(parsedArgs)) - os.Exit(0) +func fromFlag(storage *string) *cli.StringFlag { + return &cli.StringFlag{ + Name: "from", + Usage: "Path to SCIP index file", + Destination: storage, + DefaultText: "index.scip", } - // Normally, this should be impossible as docopt should properly handle - // incorrect arguments, but might as well exit nicely. 🤷🏽 - os.Stderr.WriteString(helpText()) - os.Exit(1) } diff --git a/cmd/main_test.go b/cmd/main_test.go index 567c5b43..4cb06dbf 100644 --- a/cmd/main_test.go +++ b/cmd/main_test.go @@ -2,11 +2,12 @@ package main import ( "bytes" + "fmt" "os" "path/filepath" + "strings" "testing" - docopt "github.com/docopt/docopt-go" "github.com/stretchr/testify/require" "github.com/sourcegraph/sourcegraph/lib/codeintel/lsif/protocol/reader" @@ -16,31 +17,36 @@ import ( "github.com/sourcegraph/scip/cmd/tests/reprolang/bindings/go/repro" ) -func TestArgumentParsing(t *testing.T) { - type argMap = map[string]any - testCases := []struct { - argv []string - keys argMap - }{ - {[]string{"-h"}, argMap{"--help": true}}, - {[]string{"--help"}, argMap{"--help": true}}, - {[]string{"convert"}, argMap{"--from": "index.scip", "--to": "dump.lsif"}}, - {[]string{"convert", "--from", "tmp.scip"}, argMap{"--from": "tmp.scip"}}, - {[]string{"convert", "--from=tmp.scip"}, argMap{"--from": "tmp.scip"}}, - {[]string{"convert", "--to=tmp.lsif"}, argMap{"--to": "tmp.lsif"}}, - {[]string{"convert", "--from=tmp.scip", "--to=tmp.lsif"}, argMap{"--from": "tmp.scip", "--to": "tmp.lsif"}}, - {[]string{"convert", "--to=tmp.lsif", "--from=tmp.scip"}, argMap{"--from": "tmp.scip", "--to": "tmp.lsif"}}, +func TestReadmeInSync(t *testing.T) { + app := scipApp() + readmeBytes, err := os.ReadFile(filepath.Join("..", "Readme.md")) + require.Nil(t, err) + readme := string(readmeBytes) + + check := func(args []string, commandName string) { + r, w, err := os.Pipe() + require.Nil(t, err) + origStdout := os.Stdout + os.Stdout = w + defer func() { os.Stdout = origStdout }() + + require.Nil(t, app.Run(args)) + _, err = w.Write([]byte{0}) // needed for Read below to terminate + require.Nil(t, err) + helpBytes := make([]byte, 1024*1024) + n, err := r.Read(helpBytes) + helpBytes = helpBytes[:n-1] // ignore NULL at end + require.Nil(t, err) + help := strings.TrimSpace(string(helpBytes)) + require.Truef(t, strings.Contains(readme, help), + "Readme.md missing help text %s for %s.\nRun `%s` and paste the output in the Readme.", + help, commandName, strings.Join(append([]string{"scip"}, args...), " ")) } - parser := docopt.Parser{SkipHelpFlags: true} - for _, testCase := range testCases { - parsedArgs, err := parser.ParseArgs(helpText(), testCase.argv, "") - if testCase.keys == nil { - require.Error(t, err) - continue - } - for k, v := range testCase.keys { - require.Equal(t, v, parsedArgs[k]) - } + + check([]string{"--help"}, "scip") + + for _, command := range commands() { + check([]string{command.Name, "--help"}, fmt.Sprintf("subcommand %s", command.Name)) } } diff --git a/cmd/snapshot.go b/cmd/snapshot.go index ddb9966d..8e0a4cec 100644 --- a/cmd/snapshot.go +++ b/cmd/snapshot.go @@ -5,17 +5,49 @@ import ( "os" "path/filepath" + "github.com/urfave/cli/v2" + "github.com/sourcegraph/scip/bindings/go/scip" "github.com/sourcegraph/scip/bindings/go/scip/testutil" ) -func snapshotMain(parsedArgs map[string]interface{}) error { - from := parsedArgs["--from"].(string) +type snapshotFlags struct { + from string + output string +} + +func snapshotCommand() cli.Command { + var snapshotFlags snapshotFlags + snapshot := cli.Command{ + Name: "snapshot", + Usage: "Generate snapshot files for golden testing", + Description: `The snapshot subcommand generates snapshot files which +can be use for inspecting the output of an index in a +visual way. Occurrences are marked with caret signs (^) +and symbol information.`, + Flags: []cli.Flag{ + fromFlag(&snapshotFlags.from), + &cli.StringFlag{ + Name: "to", + Usage: "Path to output directory for snapshot files", + Destination: &snapshotFlags.output, + DefaultText: "scip-snapshot", + }, + }, + Action: func(c *cli.Context) error { + return snapshotMain(snapshotFlags) + }, + } + return snapshot +} + +func snapshotMain(flags snapshotFlags) error { + from := flags.from index, err := readFromOption(from) if err != nil { return err } - output := parsedArgs["--output"].(string) + output := flags.output err = os.RemoveAll(output) if err != nil { return err diff --git a/cmd/stats.go b/cmd/stats.go index 17dbe590..32f46a4a 100644 --- a/cmd/stats.go +++ b/cmd/stats.go @@ -8,12 +8,32 @@ import ( "path/filepath" "github.com/hhatto/gocloc" - "github.com/sourcegraph/scip/bindings/go/scip" + "github.com/urfave/cli/v2" + "github.com/sourcegraph/sourcegraph/lib/errors" + + "github.com/sourcegraph/scip/bindings/go/scip" ) -func statsMain(parsedArgs map[string]interface{}) error { - from := parsedArgs["--from"].(string) +type statsFlags struct { + from string +} + +func statsCommand() cli.Command { + var statsFlags statsFlags + stats := cli.Command{ + Name: "stats", + Usage: "Output useful statistics about a SCIP index", + Flags: []cli.Flag{fromFlag(&statsFlags.from)}, + Action: func(c *cli.Context) error { + return statsMain(statsFlags) + }, + } + return stats +} + +func statsMain(flags statsFlags) error { + from := flags.from index, err := readFromOption(from) if err != nil { return err diff --git a/go.mod b/go.mod index e7103758..0afdb1d4 100644 --- a/go.mod +++ b/go.mod @@ -4,13 +4,14 @@ go 1.18 require ( github.com/bufbuild/buf v1.4.0 - github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815 github.com/google/go-cmp v0.5.7 github.com/hexops/gotextdiff v1.0.3 + github.com/hhatto/gocloc v0.4.2 github.com/pseudomuto/protoc-gen-doc v1.5.1 github.com/smacker/go-tree-sitter v0.0.0-20220209044044-0d3022e933c3 github.com/sourcegraph/sourcegraph/lib v0.0.0-20220511160847-5a43d3ea24eb github.com/stretchr/testify v1.7.1 + github.com/urfave/cli/v2 v2.8.1 golang.org/x/tools v0.1.10 google.golang.org/protobuf v1.28.0 ) @@ -34,12 +35,10 @@ require ( github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/protobuf v1.5.2 // indirect github.com/google/uuid v1.3.0 // indirect - github.com/hhatto/gocloc v0.4.2 // indirect github.com/huandu/xstrings v1.0.0 // indirect github.com/imdario/mergo v0.3.4 // indirect github.com/inconshreveable/mousetrap v1.0.0 // indirect github.com/jdxcode/netrc v0.0.0-20210204082910-926c7f70242a // indirect - github.com/jessevdk/go-flags v1.4.0 // indirect github.com/jhump/protocompile v0.0.0-20220216033700-d705409f108f // indirect github.com/jhump/protoreflect v1.12.1-0.20220417024638-438db461d753 // indirect github.com/json-iterator/go v1.1.12 // indirect @@ -59,6 +58,7 @@ require ( github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/spf13/cobra v1.4.0 // indirect github.com/spf13/pflag v1.0.5 // indirect + github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect go.opencensus.io v0.23.0 // indirect go.uber.org/atomic v1.9.0 // indirect go.uber.org/multierr v1.8.0 // indirect diff --git a/go.sum b/go.sum index 2373152e..1bbacd61 100644 --- a/go.sum +++ b/go.sum @@ -58,8 +58,6 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/dgraph-io/badger v1.6.0/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6psNgSztDR4= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= -github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815 h1:bWDMxwH3px2JBh6AyO7hdCn/PkvCZXii8TGj7sbtEbQ= -github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385/go.mod h1:0vRUJqYpeSZifjYj7uP3BG/gKcuzL9xWVV/Y+cK33KM= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= @@ -169,7 +167,6 @@ github.com/iris-contrib/pongo2 v0.0.1/go.mod h1:Ssh+00+3GAZqSQb30AvBRNxBx7rf0Gqw github.com/iris-contrib/schema v0.0.1/go.mod h1:urYA3uvUNG1TIIjOSCzHr9/LmbQo8LrOcOqfqxa4hXw= github.com/jdxcode/netrc v0.0.0-20210204082910-926c7f70242a h1:d4+I1YEKVmWZrgkt6jpXBnLgV2ZjO0YxEtLDdfIZfH4= github.com/jdxcode/netrc v0.0.0-20210204082910-926c7f70242a/go.mod h1:Zi/ZFkEqFHTm7qkjyNJjaWH4LQA9LQhGJyF0lTYGpxw= -github.com/jessevdk/go-flags v1.4.0 h1:4IU2WS7AumrZ/40jfhf4QVDMsQwqA7VEHozFRrGARJA= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jhump/gopoet v0.0.0-20190322174617-17282ff210b3/go.mod h1:me9yfT6IJSlOL3FCfrg+L6yzUEZ+5jW6WHt4Sk+UPUI= github.com/jhump/gopoet v0.1.0/go.mod h1:me9yfT6IJSlOL3FCfrg+L6yzUEZ+5jW6WHt4Sk+UPUI= @@ -297,6 +294,7 @@ github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9 github.com/sourcegraph/sourcegraph/lib v0.0.0-20220511160847-5a43d3ea24eb h1:D8ciD0FEcPNnVm6BC8vg7gWJ9VxoJe6k/4j+Qxparj0= github.com/sourcegraph/sourcegraph/lib v0.0.0-20220511160847-5a43d3ea24eb/go.mod h1:iFiGPqnhOvQziDZkpWasU+Uo1BaEt/Au9kNK4VpqyOw= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= +github.com/spf13/afero v1.2.2 h1:5jhuqJyZCZf2JRofRvN/nIFgIWNzPa3/Vz8mYylgbWc= github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= @@ -320,6 +318,8 @@ github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGr github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= +github.com/urfave/cli/v2 v2.8.1 h1:CGuYNZF9IKZY/rfBe3lJpccSoIY1ytfvmgQT90cNOl4= +github.com/urfave/cli/v2 v2.8.1/go.mod h1:Z41J9TPoffeoqP0Iza0YbAhGvymRdZAd2uPmZ5JxRdY= github.com/urfave/negroni v1.0.0/go.mod h1:Meg73S6kFm/4PpbYdq35yYWoCZ9mS/YSx+lKnmiohz4= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/fasthttp v1.6.0/go.mod h1:FstJa9V+Pj9vQ7OJie2qMHdwemEDaDiSdBnvPM1Su9w= @@ -330,6 +330,8 @@ github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2 github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= +github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU= +github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8= github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0/go.mod h1:/LWChgwKmvncFJFHJ7Gvn9wZArjbV5/FppcK2fKk/tI= github.com/yudai/gojsondiff v1.0.0/go.mod h1:AY32+k2cwILAkW1fbgxQ5mUmMiZFgLIV+FBNExI05xg= github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM=