diff --git a/.codecov.yml b/.codecov.yml index 9d4cf21a..babd2c0d 100644 --- a/.codecov.yml +++ b/.codecov.yml @@ -15,4 +15,4 @@ ignore: - /example/cmd/excited - /example/gen/proto/go/foo - /example/gen/proto/go/sub - - /internal/x/cmd/testdata/grpc/gen/grpcpb + - /internal/cmd/testdata/grpc/gen/grpcpb diff --git a/Makefile b/Makefile index 8db84fbd..2a53d9cc 100644 --- a/Makefile +++ b/Makefile @@ -33,10 +33,10 @@ license: .PHONY: golden golden: install - for file in $(shell find internal/x/cmd/testdata/format -name '*.proto.golden'); do \ + for file in $(shell find internal/cmd/testdata/format -name '*.proto.golden'); do \ rm -f $${file}; \ done - for file in $(shell find internal/x/cmd/testdata/format -name '*.proto'); do \ + for file in $(shell find internal/cmd/testdata/format -name '*.proto'); do \ prototool format $${file} > $${file}.golden || true; \ done @@ -57,7 +57,7 @@ example: install .PHONY: internalgen internalgen: install - prototool gen internal/x/cmd/testdata/grpc + prototool gen internal/cmd/testdata/grpc rm -f etc/config/example/prototool.yaml prototool init etc/config/example --uncomment diff --git a/cmd/prototool/main.go b/cmd/prototool/main.go index 7a0183a8..1adbc08e 100644 --- a/cmd/prototool/main.go +++ b/cmd/prototool/main.go @@ -23,7 +23,7 @@ package main import ( "os" - "github.com/uber/prototool/internal/x/cmd" + "github.com/uber/prototool/internal/cmd" ) func main() { diff --git a/internal/x/cmd/cmd.go b/internal/cmd/cmd.go similarity index 81% rename from internal/x/cmd/cmd.go rename to internal/cmd/cmd.go index c9d3740d..c6922e26 100644 --- a/internal/x/cmd/cmd.go +++ b/internal/cmd/cmd.go @@ -18,6 +18,14 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. +// Package cmd contains the logic to setup Prototool with github.com/spf13/cobra. +// +// The packages cmd/prototool, internal/gen/gen-prototool-bash-completion, +// internal/gen/gen-prototool-manpages and internal/gen/gen-prototool-zsh-completion +// are main packages that call into this package, and this package calls into +// internal/exec to execute the logic. +// +// This package also contains integration testing for Prototool. package cmd import ( @@ -29,7 +37,6 @@ import ( "github.com/spf13/cobra" "github.com/spf13/cobra/doc" - "github.com/spf13/pflag" "github.com/uber/prototool/internal/x/exec" "go.uber.org/zap" "go.uber.org/zap/zapcore" @@ -88,24 +95,56 @@ func runRootCommand(args []string, stdin io.Reader, stdout io.Writer, stderr io. func getRootCommand(exitCodeAddr *int, args []string, stdin io.Reader, stdout io.Writer, stderr io.Writer) *cobra.Command { flags := &flags{} - versionCmd := &cobra.Command{ - Use: "version", - Short: "Print the version.", + allCmd := &cobra.Command{ + Use: "all dirOrProtoFiles...", + Short: "Compile, then format and overwrite, then re-compile and generate, then lint, stopping if any step fails.", + Run: func(cmd *cobra.Command, args []string) { + checkCmd(exitCodeAddr, stdin, stdout, stderr, flags, func(runner exec.Runner) error { + return runner.All(args, flags.disableFormat, flags.disableLint) + }) + }, + } + flags.bindDirMode(allCmd.PersistentFlags()) + flags.bindDisableFormat(allCmd.PersistentFlags()) + flags.bindDisableLint(allCmd.PersistentFlags()) + + binaryToJSONCmd := &cobra.Command{ + Use: "binary-to-json dirOrProtoFiles... messagePath data", + Short: "Convert the data from json to binary for the message path and data.", + Args: cobra.MinimumNArgs(3), + Run: func(cmd *cobra.Command, args []string) { + checkCmd(exitCodeAddr, stdin, stdout, stderr, flags, func(runner exec.Runner) error { return runner.BinaryToJSON(args) }) + }, + } + flags.bindDirMode(binaryToJSONCmd.PersistentFlags()) + + cleanCmd := &cobra.Command{ + Use: "clean", + Short: "Delete the cache.", Args: cobra.NoArgs, Run: func(cmd *cobra.Command, args []string) { - checkCmd(exitCodeAddr, stdin, stdout, stderr, flags, exec.Runner.Version) + checkCmd(exitCodeAddr, stdin, stdout, stderr, flags, exec.Runner.Clean) }, } - initCmd := &cobra.Command{ - Use: "init [dirPath]", - Short: "Generate an initial config file in the current or given directory.", - Args: cobra.MaximumNArgs(1), + compileCmd := &cobra.Command{ + Use: "compile dirOrProtoFiles...", + Short: "Compile with protoc to check for failures.", Run: func(cmd *cobra.Command, args []string) { - checkCmd(exitCodeAddr, stdin, stdout, stderr, flags, func(runner exec.Runner) error { return runner.Init(args, flags.uncomment) }) + checkCmd(exitCodeAddr, stdin, stdout, stderr, flags, func(runner exec.Runner) error { return runner.Compile(args) }) }, } - flags.bindUncomment(initCmd.PersistentFlags()) + flags.bindDirMode(compileCmd.PersistentFlags()) + + descriptorProtoCmd := &cobra.Command{ + Use: "descriptor-proto dirOrProtoFiles... messagePath", + Short: "Get the descriptor proto for the message path.", + Args: cobra.MinimumNArgs(1), + Run: func(cmd *cobra.Command, args []string) { + checkCmd(exitCodeAddr, stdin, stdout, stderr, flags, func(runner exec.Runner) error { return runner.DescriptorProto(args) }) + }, + } + flags.bindDirMode(descriptorProtoCmd.PersistentFlags()) downloadCmd := &cobra.Command{ Use: "download", @@ -116,14 +155,15 @@ func getRootCommand(exitCodeAddr *int, args []string, stdin io.Reader, stdout io }, } - cleanCmd := &cobra.Command{ - Use: "clean", - Short: "Delete the cache.", - Args: cobra.NoArgs, + fieldDescriptorProtoCmd := &cobra.Command{ + Use: "field-descriptor-proto dirOrProtoFiles... fieldPath", + Short: "Get the field descriptor proto for the field path.", + Args: cobra.MinimumNArgs(1), Run: func(cmd *cobra.Command, args []string) { - checkCmd(exitCodeAddr, stdin, stdout, stderr, flags, exec.Runner.Clean) + checkCmd(exitCodeAddr, stdin, stdout, stderr, flags, func(runner exec.Runner) error { return runner.FieldDescriptorProto(args) }) }, } + flags.bindDirMode(fieldDescriptorProtoCmd.PersistentFlags()) filesCmd := &cobra.Command{ Use: "files dirOrProtoFiles...", @@ -133,14 +173,18 @@ func getRootCommand(exitCodeAddr *int, args []string, stdin io.Reader, stdout io }, } - compileCmd := &cobra.Command{ - Use: "compile dirOrProtoFiles...", - Short: "Compile with protoc to check for failures.", + formatCmd := &cobra.Command{ + Use: "format dirOrProtoFiles...", + Short: "Format a proto file and compile with protoc to check for failures.", Run: func(cmd *cobra.Command, args []string) { - checkCmd(exitCodeAddr, stdin, stdout, stderr, flags, func(runner exec.Runner) error { return runner.Compile(args) }) + checkCmd(exitCodeAddr, stdin, stdout, stderr, flags, func(runner exec.Runner) error { + return runner.Format(args, flags.overwrite, flags.diffMode, flags.lintMode) + }) }, } - flags.bindDirMode(compileCmd.PersistentFlags()) + flags.bindDiffMode(formatCmd.PersistentFlags()) + flags.bindLintMode(formatCmd.PersistentFlags()) + flags.bindOverwrite(formatCmd.PersistentFlags()) genCmd := &cobra.Command{ Use: "gen dirOrProtoFiles...", @@ -151,45 +195,40 @@ func getRootCommand(exitCodeAddr *int, args []string, stdin io.Reader, stdout io } flags.bindDirMode(genCmd.PersistentFlags()) - descriptorProtoCmd := &cobra.Command{ - Use: "descriptor-proto dirOrProtoFiles... messagePath", - Short: "Get the descriptor proto for the message path.", - Args: cobra.MinimumNArgs(1), - Run: func(cmd *cobra.Command, args []string) { - checkCmd(exitCodeAddr, stdin, stdout, stderr, flags, func(runner exec.Runner) error { return runner.DescriptorProto(args) }) - }, - } - flags.bindDirMode(descriptorProtoCmd.PersistentFlags()) - - fieldDescriptorProtoCmd := &cobra.Command{ - Use: "field-descriptor-proto dirOrProtoFiles... fieldPath", - Short: "Get the field descriptor proto for the field path.", - Args: cobra.MinimumNArgs(1), + grpcCmd := &cobra.Command{ + Use: "grpc dirOrProtoFiles... serverAddress package.service/Method requestData", + Short: "Call a gRPC endpoint.", Run: func(cmd *cobra.Command, args []string) { - checkCmd(exitCodeAddr, stdin, stdout, stderr, flags, func(runner exec.Runner) error { return runner.FieldDescriptorProto(args) }) + checkCmd(exitCodeAddr, stdin, stdout, stderr, flags, func(runner exec.Runner) error { + return runner.GRPC(args, flags.headers, flags.callTimeout, flags.connectTimeout, flags.keepaliveTime) + }) }, } - flags.bindDirMode(fieldDescriptorProtoCmd.PersistentFlags()) + flags.bindCallTimeout(grpcCmd.PersistentFlags()) + flags.bindConnectTimeout(grpcCmd.PersistentFlags()) + flags.bindDirMode(grpcCmd.PersistentFlags()) + flags.bindHeaders(grpcCmd.PersistentFlags()) + flags.bindKeepaliveTime(grpcCmd.PersistentFlags()) - serviceDescriptorProtoCmd := &cobra.Command{ - Use: "service-descriptor-proto dirOrProtoFiles... servicePath", - Short: "Get the service descriptor proto for the service path.", - Args: cobra.MinimumNArgs(1), + initCmd := &cobra.Command{ + Use: "init [dirPath]", + Short: "Generate an initial config file in the current or given directory.", + Args: cobra.MaximumNArgs(1), Run: func(cmd *cobra.Command, args []string) { - checkCmd(exitCodeAddr, stdin, stdout, stderr, flags, func(runner exec.Runner) error { return runner.ServiceDescriptorProto(args) }) + checkCmd(exitCodeAddr, stdin, stdout, stderr, flags, func(runner exec.Runner) error { return runner.Init(args, flags.uncomment) }) }, } - flags.bindDirMode(serviceDescriptorProtoCmd.PersistentFlags()) + flags.bindUncomment(initCmd.PersistentFlags()) - protocCommandsCmd := &cobra.Command{ - Use: "protoc-commands dirOrProtoFiles...", - Short: "Print the commands that would be run on compile or gen.", + jsonToBinaryCmd := &cobra.Command{ + Use: "json-to-binary dirOrProtoFiles... messagePath data", + Short: "Convert the data from json to binary for the message path and data.", + Args: cobra.MinimumNArgs(2), Run: func(cmd *cobra.Command, args []string) { - checkCmd(exitCodeAddr, stdin, stdout, stderr, flags, func(runner exec.Runner) error { return runner.ProtocCommands(args, flags.gen) }) + checkCmd(exitCodeAddr, stdin, stdout, stderr, flags, func(runner exec.Runner) error { return runner.JSONToBinary(args) }) }, } - flags.bindGen(protocCommandsCmd.PersistentFlags()) - flags.bindDirMode(protocCommandsCmd.PersistentFlags()) + flags.bindDirMode(jsonToBinaryCmd.PersistentFlags()) lintCmd := &cobra.Command{ Use: "lint dirOrProtoFiles...", @@ -200,15 +239,6 @@ func getRootCommand(exitCodeAddr *int, args []string, stdin io.Reader, stdout io } flags.bindDirMode(lintCmd.PersistentFlags()) - listLintersCmd := &cobra.Command{ - Use: "list-linters", - Short: "List the configurerd linters.", - Args: cobra.NoArgs, - Run: func(cmd *cobra.Command, args []string) { - checkCmd(exitCodeAddr, stdin, stdout, stderr, flags, exec.Runner.ListLinters) - }, - } - listAllLintersCmd := &cobra.Command{ Use: "list-all-linters", Short: "List all available linters.", @@ -218,15 +248,6 @@ func getRootCommand(exitCodeAddr *int, args []string, stdin io.Reader, stdout io }, } - listLintGroupCmd := &cobra.Command{ - Use: "list-lint-group group", - Short: "List the linters in the given lint group.", - Args: cobra.ExactArgs(1), - Run: func(cmd *cobra.Command, args []string) { - checkCmd(exitCodeAddr, stdin, stdout, stderr, flags, func(runner exec.Runner) error { return runner.ListLintGroup(args[0]) }) - }, - } - listAllLintGroupsCmd := &cobra.Command{ Use: "list-all-lint-groups", Short: "List all the available lint groups.", @@ -236,95 +257,82 @@ func getRootCommand(exitCodeAddr *int, args []string, stdin io.Reader, stdout io }, } - formatCmd := &cobra.Command{ - Use: "format dirOrProtoFiles...", - Short: "Format a proto file and compile with protoc to check for failures.", + listLintersCmd := &cobra.Command{ + Use: "list-linters", + Short: "List the configurerd linters.", + Args: cobra.NoArgs, Run: func(cmd *cobra.Command, args []string) { - checkCmd(exitCodeAddr, stdin, stdout, stderr, flags, func(runner exec.Runner) error { - return runner.Format(args, flags.overwrite, flags.diffMode, flags.lintMode) - }) + checkCmd(exitCodeAddr, stdin, stdout, stderr, flags, exec.Runner.ListLinters) }, } - flags.bindOverwrite(formatCmd.PersistentFlags()) - flags.bindDiffMode(formatCmd.PersistentFlags()) - flags.bindLintMode(formatCmd.PersistentFlags()) - binaryToJSONCmd := &cobra.Command{ - Use: "binary-to-json dirOrProtoFiles... messagePath data", - Short: "Convert the data from json to binary for the message path and data.", - Args: cobra.MinimumNArgs(3), + listLintGroupCmd := &cobra.Command{ + Use: "list-lint-group group", + Short: "List the linters in the given lint group.", + Args: cobra.ExactArgs(1), Run: func(cmd *cobra.Command, args []string) { - checkCmd(exitCodeAddr, stdin, stdout, stderr, flags, func(runner exec.Runner) error { return runner.BinaryToJSON(args) }) + checkCmd(exitCodeAddr, stdin, stdout, stderr, flags, func(runner exec.Runner) error { return runner.ListLintGroup(args[0]) }) }, } - flags.bindDirMode(binaryToJSONCmd.PersistentFlags()) - jsonToBinaryCmd := &cobra.Command{ - Use: "json-to-binary dirOrProtoFiles... messagePath data", - Short: "Convert the data from json to binary for the message path and data.", - Args: cobra.MinimumNArgs(2), + protocCommandsCmd := &cobra.Command{ + Use: "protoc-commands dirOrProtoFiles...", + Short: "Print the commands that would be run on compile or gen.", Run: func(cmd *cobra.Command, args []string) { - checkCmd(exitCodeAddr, stdin, stdout, stderr, flags, func(runner exec.Runner) error { return runner.JSONToBinary(args) }) + checkCmd(exitCodeAddr, stdin, stdout, stderr, flags, func(runner exec.Runner) error { return runner.ProtocCommands(args, flags.gen) }) }, } - flags.bindDirMode(jsonToBinaryCmd.PersistentFlags()) + flags.bindDirMode(protocCommandsCmd.PersistentFlags()) + flags.bindGen(protocCommandsCmd.PersistentFlags()) - allCmd := &cobra.Command{ - Use: "all dirOrProtoFiles...", - Short: "Compile, then format and overwrite, then re-compile and generate, then lint, stopping if any step fails.", + serviceDescriptorProtoCmd := &cobra.Command{ + Use: "service-descriptor-proto dirOrProtoFiles... servicePath", + Short: "Get the service descriptor proto for the service path.", + Args: cobra.MinimumNArgs(1), Run: func(cmd *cobra.Command, args []string) { - checkCmd(exitCodeAddr, stdin, stdout, stderr, flags, func(runner exec.Runner) error { - return runner.All(args, flags.disableFormat, flags.disableLint) - }) + checkCmd(exitCodeAddr, stdin, stdout, stderr, flags, func(runner exec.Runner) error { return runner.ServiceDescriptorProto(args) }) }, } - flags.bindDisableFormat(allCmd.PersistentFlags()) - flags.bindDisableLint(allCmd.PersistentFlags()) - flags.bindDirMode(allCmd.PersistentFlags()) + flags.bindDirMode(serviceDescriptorProtoCmd.PersistentFlags()) - grpcCmd := &cobra.Command{ - Use: "grpc dirOrProtoFiles... serverAddress package.service/Method requestData", - Short: "Call a gRPC endpoint.", + versionCmd := &cobra.Command{ + Use: "version", + Short: "Print the version.", + Args: cobra.NoArgs, Run: func(cmd *cobra.Command, args []string) { - checkCmd(exitCodeAddr, stdin, stdout, stderr, flags, func(runner exec.Runner) error { - return runner.GRPC(args, flags.headers, flags.callTimeout, flags.connectTimeout, flags.keepaliveTime) - }) + checkCmd(exitCodeAddr, stdin, stdout, stderr, flags, exec.Runner.Version) }, } - flags.bindHeaders(grpcCmd.PersistentFlags()) - flags.bindCallTimeout(grpcCmd.PersistentFlags()) - flags.bindConnectTimeout(grpcCmd.PersistentFlags()) - flags.bindKeepaliveTime(grpcCmd.PersistentFlags()) - flags.bindDirMode(grpcCmd.PersistentFlags()) rootCmd := &cobra.Command{Use: "prototool"} - rootCmd.AddCommand(versionCmd) - rootCmd.AddCommand(initCmd) - rootCmd.AddCommand(downloadCmd) + rootCmd.AddCommand(allCmd) + rootCmd.AddCommand(binaryToJSONCmd) rootCmd.AddCommand(cleanCmd) - rootCmd.AddCommand(filesCmd) rootCmd.AddCommand(compileCmd) - rootCmd.AddCommand(genCmd) rootCmd.AddCommand(descriptorProtoCmd) + rootCmd.AddCommand(downloadCmd) rootCmd.AddCommand(fieldDescriptorProtoCmd) - rootCmd.AddCommand(serviceDescriptorProtoCmd) - rootCmd.AddCommand(protocCommandsCmd) + rootCmd.AddCommand(filesCmd) + rootCmd.AddCommand(formatCmd) + rootCmd.AddCommand(genCmd) + rootCmd.AddCommand(grpcCmd) + rootCmd.AddCommand(initCmd) + rootCmd.AddCommand(jsonToBinaryCmd) rootCmd.AddCommand(lintCmd) - rootCmd.AddCommand(listLintersCmd) rootCmd.AddCommand(listAllLintersCmd) - rootCmd.AddCommand(listLintGroupCmd) rootCmd.AddCommand(listAllLintGroupsCmd) - rootCmd.AddCommand(formatCmd) - rootCmd.AddCommand(binaryToJSONCmd) - rootCmd.AddCommand(jsonToBinaryCmd) - rootCmd.AddCommand(allCmd) - rootCmd.AddCommand(grpcCmd) + rootCmd.AddCommand(listLintersCmd) + rootCmd.AddCommand(listLintGroupCmd) + rootCmd.AddCommand(protocCommandsCmd) + rootCmd.AddCommand(serviceDescriptorProtoCmd) + rootCmd.AddCommand(versionCmd) - flags.bindDebug(rootCmd.PersistentFlags()) + // flags bound to rootCmd are global flags flags.bindCachePath(rootCmd.PersistentFlags()) - flags.bindProtocURL(rootCmd.PersistentFlags()) - flags.bindPrintFields(rootCmd.PersistentFlags()) + flags.bindDebug(rootCmd.PersistentFlags()) flags.bindHarbormaster(rootCmd.PersistentFlags()) + flags.bindPrintFields(rootCmd.PersistentFlags()) + flags.bindProtocURL(rootCmd.PersistentFlags()) rootCmd.SetArgs(args) rootCmd.SetOutput(stdout) @@ -366,28 +374,28 @@ func getRunner(stdin io.Reader, stdout io.Writer, stderr io.Writer, flags *flags exec.RunnerWithCachePath(flags.cachePath), ) } - if flags.protocURL != "" { + if flags.dirMode { runnerOptions = append( runnerOptions, - exec.RunnerWithProtocURL(flags.protocURL), + exec.RunnerWithDirMode(), ) } - if flags.printFields != "" { + if flags.harbormaster { runnerOptions = append( runnerOptions, - exec.RunnerWithPrintFields(flags.printFields), + exec.RunnerWithHarbormaster(), ) } - if flags.dirMode { + if flags.printFields != "" { runnerOptions = append( runnerOptions, - exec.RunnerWithDirMode(), + exec.RunnerWithPrintFields(flags.printFields), ) } - if flags.harbormaster { + if flags.protocURL != "" { runnerOptions = append( runnerOptions, - exec.RunnerWithHarbormaster(), + exec.RunnerWithProtocURL(flags.protocURL), ) } workDirPath, err := os.Getwd() @@ -422,91 +430,3 @@ func printAndGetErrorExitCode(err error, stdout io.Writer) int { } return 1 } - -type flags struct { - debug bool - cachePath string - protocURL string - printFields string - dirMode bool - overwrite bool - diffMode bool - lintMode bool - disableFormat bool - disableLint bool - gen bool - headers []string - callTimeout string - connectTimeout string - keepaliveTime string - uncomment bool - harbormaster bool -} - -func (f *flags) bindDebug(flagSet *pflag.FlagSet) { - flagSet.BoolVar(&f.debug, "debug", false, "Run in debug mode, which will print out debug logging.") -} - -func (f *flags) bindCachePath(flagSet *pflag.FlagSet) { - flagSet.StringVar(&f.cachePath, "cache-path", "", "The path to use for the cache, otherwise uses the default behavior.") -} - -func (f *flags) bindProtocURL(flagSet *pflag.FlagSet) { - flagSet.StringVar(&f.protocURL, "protoc-url", "", "The url to use to download the protoc zip file, otherwise uses GitHub Releases. Setting this option will ignore the config protoc_version setting.") -} - -func (f *flags) bindPrintFields(flagSet *pflag.FlagSet) { - flagSet.StringVar(&f.printFields, "print-fields", "filename:line:column:message", "The colon-separated fields to print out on error.") -} - -func (f *flags) bindDirMode(flagSet *pflag.FlagSet) { - flagSet.BoolVar(&f.dirMode, "dir-mode", false, "Run as if the directory the file was given, but only print the errors from the file. Useful for integration with editors.") -} - -func (f *flags) bindOverwrite(flagSet *pflag.FlagSet) { - flagSet.BoolVarP(&f.overwrite, "overwrite", "w", false, "Overwrite the existing file instead of writing the formatted file to stdout.") -} - -func (f *flags) bindDiffMode(flagSet *pflag.FlagSet) { - flagSet.BoolVarP(&f.diffMode, "diff", "d", false, "Write a diff instead of writing the formatted file to stdout.") -} - -func (f *flags) bindLintMode(flagSet *pflag.FlagSet) { - flagSet.BoolVarP(&f.lintMode, "lint", "l", false, "Write a lint error saying that the file is not formatted instead of writing the formatted file to stdout.") -} - -func (f *flags) bindDisableFormat(flagSet *pflag.FlagSet) { - flagSet.BoolVar(&f.disableFormat, "disable-format", false, "Do not run formatting.") -} - -func (f *flags) bindDisableLint(flagSet *pflag.FlagSet) { - flagSet.BoolVar(&f.disableLint, "disable-lint", false, "Do not run linting.") -} - -func (f *flags) bindGen(flagSet *pflag.FlagSet) { - flagSet.BoolVar(&f.gen, "gen", false, "Print the commands that would be run on gen instead of compile.") -} - -func (f *flags) bindHeaders(flagSet *pflag.FlagSet) { - flagSet.StringSliceVarP(&f.headers, "header", "H", []string{}, "Additional request headers in 'name:value' format.") -} - -func (f *flags) bindCallTimeout(flagSet *pflag.FlagSet) { - flagSet.StringVar(&f.callTimeout, "call-timeout", "60s", "The maximum time to for all calls to be completed.") -} - -func (f *flags) bindConnectTimeout(flagSet *pflag.FlagSet) { - flagSet.StringVar(&f.connectTimeout, "connect-timeout", "10s", "The maximum time to wait for the connection to be established.") -} - -func (f *flags) bindKeepaliveTime(flagSet *pflag.FlagSet) { - flagSet.StringVar(&f.keepaliveTime, "keepalive-time", "", "The maximum idle time after which a keepalive probe is sent.") -} - -func (f *flags) bindUncomment(flagSet *pflag.FlagSet) { - flagSet.BoolVar(&f.uncomment, "uncomment", false, "Uncomment the example config settings.") -} - -func (f *flags) bindHarbormaster(flagSet *pflag.FlagSet) { - flagSet.BoolVar(&f.harbormaster, "harbormaster", false, "Print failures in JSON compatible with the Harbormaster API.") -} diff --git a/internal/x/cmd/cmd_test.go b/internal/cmd/cmd_test.go similarity index 99% rename from internal/x/cmd/cmd_test.go rename to internal/cmd/cmd_test.go index 5abbb885..b28b7d98 100644 --- a/internal/x/cmd/cmd_test.go +++ b/internal/cmd/cmd_test.go @@ -35,7 +35,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/uber/prototool/internal/x/cmd/testdata/grpc/gen/grpcpb" + "github.com/uber/prototool/internal/cmd/testdata/grpc/gen/grpcpb" "github.com/uber/prototool/internal/x/settings" "google.golang.org/grpc" ) diff --git a/internal/cmd/flags.go b/internal/cmd/flags.go new file mode 100644 index 00000000..74918ac3 --- /dev/null +++ b/internal/cmd/flags.go @@ -0,0 +1,113 @@ +// Copyright (c) 2018 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +package cmd + +import ( + "github.com/spf13/pflag" +) + +type flags struct { + cachePath string + callTimeout string + connectTimeout string + debug bool + diffMode bool + dirMode bool + disableFormat bool + disableLint bool + gen bool + harbormaster bool + headers []string + keepaliveTime string + lintMode bool + overwrite bool + printFields string + protocURL string + uncomment bool +} + +func (f *flags) bindCachePath(flagSet *pflag.FlagSet) { + flagSet.StringVar(&f.cachePath, "cache-path", "", "The path to use for the cache, otherwise uses the default behavior.") +} + +func (f *flags) bindCallTimeout(flagSet *pflag.FlagSet) { + flagSet.StringVar(&f.callTimeout, "call-timeout", "60s", "The maximum time to for all calls to be completed.") +} + +func (f *flags) bindConnectTimeout(flagSet *pflag.FlagSet) { + flagSet.StringVar(&f.connectTimeout, "connect-timeout", "10s", "The maximum time to wait for the connection to be established.") +} + +func (f *flags) bindDebug(flagSet *pflag.FlagSet) { + flagSet.BoolVar(&f.debug, "debug", false, "Run in debug mode, which will print out debug logging.") +} + +func (f *flags) bindDiffMode(flagSet *pflag.FlagSet) { + flagSet.BoolVarP(&f.diffMode, "diff", "d", false, "Write a diff instead of writing the formatted file to stdout.") +} + +func (f *flags) bindDirMode(flagSet *pflag.FlagSet) { + flagSet.BoolVar(&f.dirMode, "dir-mode", false, "Run as if the directory the file was given, but only print the errors from the file. Useful for integration with editors.") +} + +func (f *flags) bindDisableFormat(flagSet *pflag.FlagSet) { + flagSet.BoolVar(&f.disableFormat, "disable-format", false, "Do not run formatting.") +} + +func (f *flags) bindDisableLint(flagSet *pflag.FlagSet) { + flagSet.BoolVar(&f.disableLint, "disable-lint", false, "Do not run linting.") +} + +func (f *flags) bindGen(flagSet *pflag.FlagSet) { + flagSet.BoolVar(&f.gen, "gen", false, "Print the commands that would be run on gen instead of compile.") +} + +func (f *flags) bindHarbormaster(flagSet *pflag.FlagSet) { + flagSet.BoolVar(&f.harbormaster, "harbormaster", false, "Print failures in JSON compatible with the Harbormaster API.") +} + +func (f *flags) bindHeaders(flagSet *pflag.FlagSet) { + flagSet.StringSliceVarP(&f.headers, "header", "H", []string{}, "Additional request headers in 'name:value' format.") +} + +func (f *flags) bindKeepaliveTime(flagSet *pflag.FlagSet) { + flagSet.StringVar(&f.keepaliveTime, "keepalive-time", "", "The maximum idle time after which a keepalive probe is sent.") +} + +func (f *flags) bindLintMode(flagSet *pflag.FlagSet) { + flagSet.BoolVarP(&f.lintMode, "lint", "l", false, "Write a lint error saying that the file is not formatted instead of writing the formatted file to stdout.") +} + +func (f *flags) bindOverwrite(flagSet *pflag.FlagSet) { + flagSet.BoolVarP(&f.overwrite, "overwrite", "w", false, "Overwrite the existing file instead of writing the formatted file to stdout.") +} + +func (f *flags) bindPrintFields(flagSet *pflag.FlagSet) { + flagSet.StringVar(&f.printFields, "print-fields", "filename:line:column:message", "The colon-separated fields to print out on error.") +} + +func (f *flags) bindProtocURL(flagSet *pflag.FlagSet) { + flagSet.StringVar(&f.protocURL, "protoc-url", "", "The url to use to download the protoc zip file, otherwise uses GitHub Releases. Setting this option will ignore the config protoc_version setting.") +} + +func (f *flags) bindUncomment(flagSet *pflag.FlagSet) { + flagSet.BoolVar(&f.uncomment, "uncomment", false, "Uncomment the example config settings.") +} diff --git a/internal/x/cmd/testdata/bar/dep.proto b/internal/cmd/testdata/bar/dep.proto similarity index 100% rename from internal/x/cmd/testdata/bar/dep.proto rename to internal/cmd/testdata/bar/dep.proto diff --git a/internal/x/cmd/testdata/compile/dep.proto b/internal/cmd/testdata/compile/dep.proto similarity index 100% rename from internal/x/cmd/testdata/compile/dep.proto rename to internal/cmd/testdata/compile/dep.proto diff --git a/internal/x/cmd/testdata/compile/dep_errors.proto b/internal/cmd/testdata/compile/dep_errors.proto similarity index 100% rename from internal/x/cmd/testdata/compile/dep_errors.proto rename to internal/cmd/testdata/compile/dep_errors.proto diff --git a/internal/x/cmd/testdata/compile/errors_on_import.proto b/internal/cmd/testdata/compile/errors_on_import.proto similarity index 100% rename from internal/x/cmd/testdata/compile/errors_on_import.proto rename to internal/cmd/testdata/compile/errors_on_import.proto diff --git a/internal/x/cmd/testdata/compile/extra_import.proto b/internal/cmd/testdata/compile/extra_import.proto similarity index 100% rename from internal/x/cmd/testdata/compile/extra_import.proto rename to internal/cmd/testdata/compile/extra_import.proto diff --git a/internal/x/cmd/testdata/compile/json_camel_case_conflict.proto b/internal/cmd/testdata/compile/json_camel_case_conflict.proto similarity index 100% rename from internal/x/cmd/testdata/compile/json_camel_case_conflict.proto rename to internal/cmd/testdata/compile/json_camel_case_conflict.proto diff --git a/internal/x/cmd/testdata/compile/missing_package_semicolon.proto b/internal/cmd/testdata/compile/missing_package_semicolon.proto similarity index 100% rename from internal/x/cmd/testdata/compile/missing_package_semicolon.proto rename to internal/cmd/testdata/compile/missing_package_semicolon.proto diff --git a/internal/x/cmd/testdata/compile/missing_syntax.proto b/internal/cmd/testdata/compile/missing_syntax.proto similarity index 100% rename from internal/x/cmd/testdata/compile/missing_syntax.proto rename to internal/cmd/testdata/compile/missing_syntax.proto diff --git a/internal/x/cmd/testdata/compile/not_imported.proto b/internal/cmd/testdata/compile/not_imported.proto similarity index 100% rename from internal/x/cmd/testdata/compile/not_imported.proto rename to internal/cmd/testdata/compile/not_imported.proto diff --git a/internal/x/cmd/testdata/compile/prototool.yaml b/internal/cmd/testdata/compile/prototool.yaml similarity index 100% rename from internal/x/cmd/testdata/compile/prototool.yaml rename to internal/cmd/testdata/compile/prototool.yaml diff --git a/internal/x/cmd/testdata/compile/syntax_proto2.proto b/internal/cmd/testdata/compile/syntax_proto2.proto similarity index 100% rename from internal/x/cmd/testdata/compile/syntax_proto2.proto rename to internal/cmd/testdata/compile/syntax_proto2.proto diff --git a/internal/x/cmd/testdata/foo/success.proto b/internal/cmd/testdata/foo/success.proto similarity index 100% rename from internal/x/cmd/testdata/foo/success.proto rename to internal/cmd/testdata/foo/success.proto diff --git a/internal/x/cmd/testdata/format/bar/bar.proto b/internal/cmd/testdata/format/bar/bar.proto similarity index 100% rename from internal/x/cmd/testdata/format/bar/bar.proto rename to internal/cmd/testdata/format/bar/bar.proto diff --git a/internal/x/cmd/testdata/format/bar/bar.proto.golden b/internal/cmd/testdata/format/bar/bar.proto.golden similarity index 100% rename from internal/x/cmd/testdata/format/bar/bar.proto.golden rename to internal/cmd/testdata/format/bar/bar.proto.golden diff --git a/internal/x/cmd/testdata/format/bar/bar_proto2.proto b/internal/cmd/testdata/format/bar/bar_proto2.proto similarity index 100% rename from internal/x/cmd/testdata/format/bar/bar_proto2.proto rename to internal/cmd/testdata/format/bar/bar_proto2.proto diff --git a/internal/x/cmd/testdata/format/bar/bar_proto2.proto.golden b/internal/cmd/testdata/format/bar/bar_proto2.proto.golden similarity index 100% rename from internal/x/cmd/testdata/format/bar/bar_proto2.proto.golden rename to internal/cmd/testdata/format/bar/bar_proto2.proto.golden diff --git a/internal/x/cmd/testdata/format/foo/foo.proto b/internal/cmd/testdata/format/foo/foo.proto similarity index 100% rename from internal/x/cmd/testdata/format/foo/foo.proto rename to internal/cmd/testdata/format/foo/foo.proto diff --git a/internal/x/cmd/testdata/format/foo/foo.proto.golden b/internal/cmd/testdata/format/foo/foo.proto.golden similarity index 100% rename from internal/x/cmd/testdata/format/foo/foo.proto.golden rename to internal/cmd/testdata/format/foo/foo.proto.golden diff --git a/internal/x/cmd/testdata/format/foo/foo_proto2.proto b/internal/cmd/testdata/format/foo/foo_proto2.proto similarity index 100% rename from internal/x/cmd/testdata/format/foo/foo_proto2.proto rename to internal/cmd/testdata/format/foo/foo_proto2.proto diff --git a/internal/x/cmd/testdata/format/foo/foo_proto2.proto.golden b/internal/cmd/testdata/format/foo/foo_proto2.proto.golden similarity index 100% rename from internal/x/cmd/testdata/format/foo/foo_proto2.proto.golden rename to internal/cmd/testdata/format/foo/foo_proto2.proto.golden diff --git a/internal/x/cmd/testdata/format/prototool.yaml b/internal/cmd/testdata/format/prototool.yaml similarity index 100% rename from internal/x/cmd/testdata/format/prototool.yaml rename to internal/cmd/testdata/format/prototool.yaml diff --git a/internal/x/cmd/testdata/grpc/gen/grpcpb/.nocover b/internal/cmd/testdata/grpc/gen/grpcpb/.nocover similarity index 100% rename from internal/x/cmd/testdata/grpc/gen/grpcpb/.nocover rename to internal/cmd/testdata/grpc/gen/grpcpb/.nocover diff --git a/internal/x/cmd/testdata/grpc/gen/grpcpb/grpc.pb.go b/internal/cmd/testdata/grpc/gen/grpcpb/grpc.pb.go similarity index 100% rename from internal/x/cmd/testdata/grpc/gen/grpcpb/grpc.pb.go rename to internal/cmd/testdata/grpc/gen/grpcpb/grpc.pb.go diff --git a/internal/x/cmd/testdata/grpc/grpc.proto b/internal/cmd/testdata/grpc/grpc.proto similarity index 100% rename from internal/x/cmd/testdata/grpc/grpc.proto rename to internal/cmd/testdata/grpc/grpc.proto diff --git a/internal/x/cmd/testdata/grpc/prototool.yaml b/internal/cmd/testdata/grpc/prototool.yaml similarity index 73% rename from internal/x/cmd/testdata/grpc/prototool.yaml rename to internal/cmd/testdata/grpc/prototool.yaml index 30a6df39..544c3a40 100644 --- a/internal/x/cmd/testdata/grpc/prototool.yaml +++ b/internal/cmd/testdata/grpc/prototool.yaml @@ -4,7 +4,7 @@ lint: - REQUEST_RESPONSE_TYPES_UNIQUE gen: go_options: - import_path: github.com/uber/prototool/internal/x/cmd/testdata/grpc + import_path: github.com/uber/prototool/internal/cmd/testdata/grpc plugins: - name: gogoslick type: gogo diff --git a/internal/x/cmd/testdata/lint/base_file.proto b/internal/cmd/testdata/lint/base_file.proto similarity index 100% rename from internal/x/cmd/testdata/lint/base_file.proto rename to internal/cmd/testdata/lint/base_file.proto diff --git a/internal/x/cmd/testdata/lint/file_options_incorrect.proto b/internal/cmd/testdata/lint/file_options_incorrect.proto similarity index 100% rename from internal/x/cmd/testdata/lint/file_options_incorrect.proto rename to internal/cmd/testdata/lint/file_options_incorrect.proto diff --git a/internal/x/cmd/testdata/lint/file_options_required.proto b/internal/cmd/testdata/lint/file_options_required.proto similarity index 100% rename from internal/x/cmd/testdata/lint/file_options_required.proto rename to internal/cmd/testdata/lint/file_options_required.proto diff --git a/internal/x/cmd/testdata/lint/lots.proto b/internal/cmd/testdata/lint/lots.proto similarity index 100% rename from internal/x/cmd/testdata/lint/lots.proto rename to internal/cmd/testdata/lint/lots.proto diff --git a/internal/x/cmd/testdata/lint/message_name_not_capitalized.proto b/internal/cmd/testdata/lint/message_name_not_capitalized.proto similarity index 100% rename from internal/x/cmd/testdata/lint/message_name_not_capitalized.proto rename to internal/cmd/testdata/lint/message_name_not_capitalized.proto diff --git a/internal/x/cmd/testdata/lint/samedir/bar1.proto b/internal/cmd/testdata/lint/samedir/bar1.proto similarity index 100% rename from internal/x/cmd/testdata/lint/samedir/bar1.proto rename to internal/cmd/testdata/lint/samedir/bar1.proto diff --git a/internal/x/cmd/testdata/lint/samedir/foo1.proto b/internal/cmd/testdata/lint/samedir/foo1.proto similarity index 100% rename from internal/x/cmd/testdata/lint/samedir/foo1.proto rename to internal/cmd/testdata/lint/samedir/foo1.proto diff --git a/internal/x/cmd/testdata/lint/samedir/foo2.proto b/internal/cmd/testdata/lint/samedir/foo2.proto similarity index 100% rename from internal/x/cmd/testdata/lint/samedir/foo2.proto rename to internal/cmd/testdata/lint/samedir/foo2.proto diff --git a/internal/x/cmd/testdata/lint/samedir/prototool.yaml b/internal/cmd/testdata/lint/samedir/prototool.yaml similarity index 100% rename from internal/x/cmd/testdata/lint/samedir/prototool.yaml rename to internal/cmd/testdata/lint/samedir/prototool.yaml diff --git a/internal/x/cmd/testdata/lint/samedirgopkg/bar1.proto b/internal/cmd/testdata/lint/samedirgopkg/bar1.proto similarity index 100% rename from internal/x/cmd/testdata/lint/samedirgopkg/bar1.proto rename to internal/cmd/testdata/lint/samedirgopkg/bar1.proto diff --git a/internal/x/cmd/testdata/lint/samedirgopkg/foo1.proto b/internal/cmd/testdata/lint/samedirgopkg/foo1.proto similarity index 100% rename from internal/x/cmd/testdata/lint/samedirgopkg/foo1.proto rename to internal/cmd/testdata/lint/samedirgopkg/foo1.proto diff --git a/internal/x/cmd/testdata/lint/samedirgopkg/foo2.proto b/internal/cmd/testdata/lint/samedirgopkg/foo2.proto similarity index 100% rename from internal/x/cmd/testdata/lint/samedirgopkg/foo2.proto rename to internal/cmd/testdata/lint/samedirgopkg/foo2.proto diff --git a/internal/x/cmd/testdata/lint/samedirgopkg/prototool.yaml b/internal/cmd/testdata/lint/samedirgopkg/prototool.yaml similarity index 100% rename from internal/x/cmd/testdata/lint/samedirgopkg/prototool.yaml rename to internal/cmd/testdata/lint/samedirgopkg/prototool.yaml diff --git a/internal/x/cmd/testdata/lint/samedirjavapkg/bar1.proto b/internal/cmd/testdata/lint/samedirjavapkg/bar1.proto similarity index 100% rename from internal/x/cmd/testdata/lint/samedirjavapkg/bar1.proto rename to internal/cmd/testdata/lint/samedirjavapkg/bar1.proto diff --git a/internal/x/cmd/testdata/lint/samedirjavapkg/foo1.proto b/internal/cmd/testdata/lint/samedirjavapkg/foo1.proto similarity index 100% rename from internal/x/cmd/testdata/lint/samedirjavapkg/foo1.proto rename to internal/cmd/testdata/lint/samedirjavapkg/foo1.proto diff --git a/internal/x/cmd/testdata/lint/samedirjavapkg/foo2.proto b/internal/cmd/testdata/lint/samedirjavapkg/foo2.proto similarity index 100% rename from internal/x/cmd/testdata/lint/samedirjavapkg/foo2.proto rename to internal/cmd/testdata/lint/samedirjavapkg/foo2.proto diff --git a/internal/x/cmd/testdata/lint/samedirjavapkg/prototool.yaml b/internal/cmd/testdata/lint/samedirjavapkg/prototool.yaml similarity index 100% rename from internal/x/cmd/testdata/lint/samedirjavapkg/prototool.yaml rename to internal/cmd/testdata/lint/samedirjavapkg/prototool.yaml diff --git a/internal/x/cmd/testdata/lint/syntax_proto2.proto b/internal/cmd/testdata/lint/syntax_proto2.proto similarity index 100% rename from internal/x/cmd/testdata/lint/syntax_proto2.proto rename to internal/cmd/testdata/lint/syntax_proto2.proto diff --git a/internal/x/cmd/testdata/prototool.yaml b/internal/cmd/testdata/prototool.yaml similarity index 100% rename from internal/x/cmd/testdata/prototool.yaml rename to internal/cmd/testdata/prototool.yaml diff --git a/internal/x/gen/gen-prototool-bash-completion/main.go b/internal/x/gen/gen-prototool-bash-completion/main.go index 43a2cc1a..1b5a81c4 100644 --- a/internal/x/gen/gen-prototool-bash-completion/main.go +++ b/internal/x/gen/gen-prototool-bash-completion/main.go @@ -23,7 +23,7 @@ package main import ( "os" - "github.com/uber/prototool/internal/x/cmd" + "github.com/uber/prototool/internal/cmd" ) func main() { diff --git a/internal/x/gen/gen-prototool-manpages/main.go b/internal/x/gen/gen-prototool-manpages/main.go index 53c2d637..6c070cef 100644 --- a/internal/x/gen/gen-prototool-manpages/main.go +++ b/internal/x/gen/gen-prototool-manpages/main.go @@ -23,7 +23,7 @@ package main import ( "os" - "github.com/uber/prototool/internal/x/cmd" + "github.com/uber/prototool/internal/cmd" ) func main() { diff --git a/internal/x/gen/gen-prototool-zsh-completion/main.go b/internal/x/gen/gen-prototool-zsh-completion/main.go index 0170744d..fa46e62d 100644 --- a/internal/x/gen/gen-prototool-zsh-completion/main.go +++ b/internal/x/gen/gen-prototool-zsh-completion/main.go @@ -23,7 +23,7 @@ package main import ( "os" - "github.com/uber/prototool/internal/x/cmd" + "github.com/uber/prototool/internal/cmd" ) func main() {