Skip to content
This repository has been archived by the owner on Mar 4, 2022. It is now read-only.

Commit

Permalink
Add --config-data flag (#224)
Browse files Browse the repository at this point in the history
  • Loading branch information
bufdev authored and amckinney committed Sep 14, 2018
1 parent c591abf commit 3f348ae
Show file tree
Hide file tree
Showing 10 changed files with 200 additions and 29 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
### Added
- Accept `prototool.json` files for configuation in addition to
`prototool.yaml` files.
- Add `--config-data` flag.


## [1.2.0] - 2018-08-29
Expand Down
47 changes: 45 additions & 2 deletions internal/cmd/cmd_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,49 @@ func TestLint(t *testing.T) {
)
}

func TestLintConfigDataOverride(t *testing.T) {
cwd, err := os.Getwd()
require.NoError(t, err)
require.NoError(t, os.Chdir("testdata/lint/gopackagelongform"))
defer func() {
require.NoError(t, os.Chdir(cwd))
}()
assertDoLintFile(
t,
false,
`5:1:FILE_OPTIONS_GO_PACKAGE_NOT_LONG_FORM`,
"gopackagelongform.proto",
"--config-data",
`{"lint":{"rules":{"remove":["FILE_OPTIONS_EQUAL_GO_PACKAGE_PB_SUFFIX"]}}}`,
)
assertDoLintFile(
t,
false,
`5:1:FILE_OPTIONS_EQUAL_GO_PACKAGE_PB_SUFFIX`,
"gopackagelongform.proto",
"--config-data",
`{"lint":{"rules":{"remove":["FILE_OPTIONS_GO_PACKAGE_NOT_LONG_FORM"]}}}`,
)
assertDoLintFile(
t,
false,
`5:1:FILE_OPTIONS_EQUAL_GO_PACKAGE_PB_SUFFIX
5:1:FILE_OPTIONS_GO_PACKAGE_NOT_LONG_FORM`,
"gopackagelongform.proto",
"--config-data",
`{}`,
)
assertExact(
t,
1,
`json: unknown field "unknown_key"`,
"lint",
"gopackagelongform.proto",
"--config-data",
`{"unknown_key":"foo"}`,
)
}

func TestGoldenFormat(t *testing.T) {
t.Parallel()
assertGoldenFormat(t, false, false, "testdata/format/proto3/foo/bar/bar.proto")
Expand Down Expand Up @@ -709,7 +752,7 @@ func assertDoCreateFile(t *testing.T, expectSuccess bool, remove bool, filePath
}
}

func assertDoLintFile(t *testing.T, expectSuccess bool, expectedLinePrefixesWithoutFile string, filePath string) {
func assertDoLintFile(t *testing.T, expectSuccess bool, expectedLinePrefixesWithoutFile string, filePath string, args ...string) {
lines := getCleanLines(expectedLinePrefixesWithoutFile)
for i, line := range lines {
lines[i] = filePath + ":" + line
Expand All @@ -718,7 +761,7 @@ func assertDoLintFile(t *testing.T, expectSuccess bool, expectedLinePrefixesWith
if !expectSuccess {
expectedExitCode = 255
}
assertDo(t, expectedExitCode, strings.Join(lines, "\n"), "lint", filePath)
assertDo(t, expectedExitCode, strings.Join(lines, "\n"), append([]string{"lint", filePath}, args...)...)
}

func assertDoLintFiles(t *testing.T, expectSuccess bool, expectedLinePrefixes string, filePaths ...string) {
Expand Down
5 changes: 5 additions & 0 deletions internal/cmd/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ type flags struct {
address string
cachePath string
callTimeout string
configData string
connectTimeout string
data string
debug bool
Expand Down Expand Up @@ -63,6 +64,10 @@ 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) bindConfigData(flagSet *pflag.FlagSet) {
flagSet.StringVar(&f.configData, "config-data", "", "The configuration data to use instead of reading prototool.yaml or prototool.json files.\nThis will act as if there is a configuration file with the given data in the current directory, and no other configuration files recursively.\nThis is an advanced feature and is not recommended to be generally used.")
}

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.")
}
Expand Down
34 changes: 34 additions & 0 deletions internal/cmd/templates.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ var (
return runner.All(args, flags.disableFormat, flags.disableLint, flags.fix)
},
BindFlags: func(flagSet *pflag.FlagSet, flags *flags) {
flags.bindConfigData(flagSet)
flags.bindDisableFormat(flagSet)
flags.bindDisableLint(flagSet)
flags.bindJSON(flagSet)
Expand All @@ -60,6 +61,9 @@ var (
Run: func(runner exec.Runner, args []string, flags *flags) error {
return runner.BinaryToJSON(args)
},
BindFlags: func(flagSet *pflag.FlagSet, flags *flags) {
flags.bindConfigData(flagSet)
},
}

cleanCmdTemplate = &cmdTemplate{
Expand All @@ -80,6 +84,7 @@ var (
return runner.Compile(args, flags.dryRun)
},
BindFlags: func(flagSet *pflag.FlagSet, flags *flags) {
flags.bindConfigData(flagSet)
flags.bindDryRun(flagSet)
flags.bindJSON(flagSet)
flags.bindProtocURL(flagSet)
Expand Down Expand Up @@ -152,6 +157,7 @@ If Vim integration is set up, files will be generated when you open a new Protob
return runner.Create(args, flags.pkg)
},
BindFlags: func(flagSet *pflag.FlagSet, flags *flags) {
flags.bindConfigData(flagSet)
flags.bindPackage(flagSet)
},
}
Expand All @@ -163,6 +169,9 @@ If Vim integration is set up, files will be generated when you open a new Protob
Run: func(runner exec.Runner, args []string, flags *flags) error {
return runner.DescriptorProto(args)
},
BindFlags: func(flagSet *pflag.FlagSet, flags *flags) {
flags.bindConfigData(flagSet)
},
}

downloadCmdTemplate = &cmdTemplate{
Expand All @@ -172,6 +181,9 @@ If Vim integration is set up, files will be generated when you open a new Protob
Run: func(runner exec.Runner, args []string, flags *flags) error {
return runner.Download()
},
BindFlags: func(flagSet *pflag.FlagSet, flags *flags) {
flags.bindConfigData(flagSet)
},
}

fieldDescriptorProtoCmdTemplate = &cmdTemplate{
Expand All @@ -181,6 +193,9 @@ If Vim integration is set up, files will be generated when you open a new Protob
Run: func(runner exec.Runner, args []string, flags *flags) error {
return runner.FieldDescriptorProto(args)
},
BindFlags: func(flagSet *pflag.FlagSet, flags *flags) {
flags.bindConfigData(flagSet)
},
}

filesCmdTemplate = &cmdTemplate{
Expand All @@ -190,6 +205,9 @@ If Vim integration is set up, files will be generated when you open a new Protob
Run: func(runner exec.Runner, args []string, flags *flags) error {
return runner.Files(args)
},
BindFlags: func(flagSet *pflag.FlagSet, flags *flags) {
flags.bindConfigData(flagSet)
},
}

formatCmdTemplate = &cmdTemplate{
Expand All @@ -200,6 +218,7 @@ If Vim integration is set up, files will be generated when you open a new Protob
return runner.Format(args, flags.overwrite, flags.diffMode, flags.lintMode, flags.fix)
},
BindFlags: func(flagSet *pflag.FlagSet, flags *flags) {
flags.bindConfigData(flagSet)
flags.bindDiffMode(flagSet)
flags.bindJSON(flagSet)
flags.bindLintMode(flagSet)
Expand All @@ -217,6 +236,7 @@ If Vim integration is set up, files will be generated when you open a new Protob
return runner.Gen(args, flags.dryRun)
},
BindFlags: func(flagSet *pflag.FlagSet, flags *flags) {
flags.bindConfigData(flagSet)
flags.bindDryRun(flagSet)
flags.bindJSON(flagSet)
flags.bindProtocURL(flagSet)
Expand Down Expand Up @@ -299,6 +319,7 @@ $ cat input.json | prototool grpc example \
return runner.GRPC(args, flags.headers, flags.address, flags.method, flags.data, flags.callTimeout, flags.connectTimeout, flags.keepaliveTime, flags.stdin)
},
BindFlags: func(flagSet *pflag.FlagSet, flags *flags) {
flags.bindConfigData(flagSet)
flags.bindAddress(flagSet)
flags.bindCallTimeout(flagSet)
flags.bindConnectTimeout(flagSet)
Expand Down Expand Up @@ -331,6 +352,9 @@ $ cat input.json | prototool grpc example \
Run: func(runner exec.Runner, args []string, flags *flags) error {
return runner.JSONToBinary(args)
},
BindFlags: func(flagSet *pflag.FlagSet, flags *flags) {
flags.bindConfigData(flagSet)
},
}

lintCmdTemplate = &cmdTemplate{
Expand All @@ -342,6 +366,7 @@ $ cat input.json | prototool grpc example \
return runner.Lint(args, flags.listAllLinters, flags.listLinters)
},
BindFlags: func(flagSet *pflag.FlagSet, flags *flags) {
flags.bindConfigData(flagSet)
flags.bindJSON(flagSet)
flags.bindListAllLinters(flagSet)
flags.bindListLinters(flagSet)
Expand Down Expand Up @@ -374,6 +399,9 @@ $ cat input.json | prototool grpc example \
Run: func(runner exec.Runner, args []string, flags *flags) error {
return runner.ServiceDescriptorProto(args)
},
BindFlags: func(flagSet *pflag.FlagSet, flags *flags) {
flags.bindConfigData(flagSet)
},
}

versionCmdTemplate = &cmdTemplate{
Expand Down Expand Up @@ -468,6 +496,12 @@ func getRunner(stdin io.Reader, stdout io.Writer, stderr io.Writer, flags *flags
exec.RunnerWithCachePath(flags.cachePath),
)
}
if flags.configData != "" {
runnerOptions = append(
runnerOptions,
exec.RunnerWithConfigData(flags.configData),
)
}
if flags.json {
runnerOptions = append(
runnerOptions,
Expand Down
7 changes: 7 additions & 0 deletions internal/exec/exec.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,13 @@ func RunnerWithCachePath(cachePath string) RunnerOption {
}
}

// RunnerWithConfigData returns a RunnerOption that uses the given config path.
func RunnerWithConfigData(configData string) RunnerOption {
return func(runner *runner) {
runner.configData = configData
}
}

// RunnerWithJSON returns a RunnerOption that will print failures as JSON.
func RunnerWithJSON() RunnerOption {
return func(runner *runner) {
Expand Down
15 changes: 13 additions & 2 deletions internal/exec/runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ type runner struct {

logger *zap.Logger
cachePath string
configData string
protocURL string
printFields string
json bool
Expand All @@ -84,9 +85,16 @@ func newRunner(workDirPath string, input io.Reader, output io.Writer, options ..
runner.configProvider = settings.NewConfigProvider(
settings.ConfigProviderWithLogger(runner.logger),
)
runner.protoSetProvider = file.NewProtoSetProvider(
protoSetProviderOptions := []file.ProtoSetProviderOption{
file.ProtoSetProviderWithLogger(runner.logger),
)
}
if runner.configData != "" {
protoSetProviderOptions = append(
protoSetProviderOptions,
file.ProtoSetProviderWithConfigData(runner.configData),
)
}
runner.protoSetProvider = file.NewProtoSetProvider(protoSetProviderOptions...)
return runner
}

Expand Down Expand Up @@ -750,6 +758,9 @@ func (r *runner) newGRPCHandler(
}

func (r *runner) getConfig(dirPath string) (settings.Config, error) {
if r.configData != "" {
return r.configProvider.GetForData(dirPath, r.configData)
}
return r.configProvider.GetForDir(dirPath)
}

Expand Down
9 changes: 9 additions & 0 deletions internal/file/file.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,15 @@ func ProtoSetProviderWithLogger(logger *zap.Logger) ProtoSetProviderOption {
}
}

// ProtoSetProviderWithConfigData returns a ProtoSetProviderOption that uses the given configuration
// data instead of using configuration files that are found. This acts as if there is only one
// configuration file at the current working directory. All found configuration files are ignored.
func ProtoSetProviderWithConfigData(configData string) ProtoSetProviderOption {
return func(protoSetProvider *protoSetProvider) {
protoSetProvider.configData = configData
}
}

// ProtoSetProviderWithWalkTimeout returns a ProtoSetProviderOption will timeout after walking
// a directory structure when searching for Protobuf files after the given amount of time.
//
Expand Down
Loading

0 comments on commit 3f348ae

Please sign in to comment.