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

Commit

Permalink
Add protoc-bin-path and protoc-wkt-path flags (#231)
Browse files Browse the repository at this point in the history
  • Loading branch information
amckinney authored Sep 14, 2018
1 parent 3f348ae commit 76bb33b
Show file tree
Hide file tree
Showing 9 changed files with 286 additions and 15 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
- Accept `prototool.json` files for configuation in addition to
`prototool.yaml` files.
- Add `--config-data` flag.
- Add `protoc-bin-path` and `protoc-wkt-path` flags to manually
set the paths for where `protoc` is run and where the
well-known types are included from.


## [1.2.0] - 2018-08-29
Expand Down
10 changes: 10 additions & 0 deletions internal/cmd/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ type flags struct {
overwrite bool
pkg string
printFields string
protocBinPath string
protocWKTPath string
protocURL string
stdin bool
uncomment bool
Expand Down Expand Up @@ -140,6 +142,14 @@ 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) bindProtocBinPath(flagSet *pflag.FlagSet) {
flagSet.StringVar(&f.protocBinPath, "protoc-bin-path", "", "The path to the protoc binary. Setting this option will ignore the config protoc.version setting. This flag must be used with protoc-wkt-path and must not be used with the protoc-url flag.")
}

func (f *flags) bindProtocWKTPath(flagSet *pflag.FlagSet) {
flagSet.StringVar(&f.protocWKTPath, "protoc-wkt-path", "", "The path to the well-known types. Setting this option will ignore the config protoc.version setting. This flag must be used with protoc-bin-path and must not be used with the protoc-url flag.")
}

func (f *flags) bindStdin(flagSet *pflag.FlagSet) {
flagSet.BoolVar(&f.stdin, "stdin", false, "Read the GRPC request data from stdin in JSON format. Either this or --data is required.")
}
Expand Down
24 changes: 24 additions & 0 deletions internal/cmd/templates.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ var (
flags.bindJSON(flagSet)
flags.bindFix(flagSet)
flags.bindProtocURL(flagSet)
flags.bindProtocBinPath(flagSet)
flags.bindProtocWKTPath(flagSet)
},
}

Expand Down Expand Up @@ -88,6 +90,8 @@ var (
flags.bindDryRun(flagSet)
flags.bindJSON(flagSet)
flags.bindProtocURL(flagSet)
flags.bindProtocBinPath(flagSet)
flags.bindProtocWKTPath(flagSet)
},
}

Expand Down Expand Up @@ -225,6 +229,8 @@ If Vim integration is set up, files will be generated when you open a new Protob
flags.bindOverwrite(flagSet)
flags.bindFix(flagSet)
flags.bindProtocURL(flagSet)
flags.bindProtocBinPath(flagSet)
flags.bindProtocWKTPath(flagSet)
},
}

Expand All @@ -240,6 +246,8 @@ If Vim integration is set up, files will be generated when you open a new Protob
flags.bindDryRun(flagSet)
flags.bindJSON(flagSet)
flags.bindProtocURL(flagSet)
flags.bindProtocBinPath(flagSet)
flags.bindProtocWKTPath(flagSet)
},
}

Expand Down Expand Up @@ -329,6 +337,8 @@ $ cat input.json | prototool grpc example \
flags.bindMethod(flagSet)
flags.bindStdin(flagSet)
flags.bindProtocURL(flagSet)
flags.bindProtocBinPath(flagSet)
flags.bindProtocWKTPath(flagSet)
},
}

Expand Down Expand Up @@ -371,6 +381,8 @@ $ cat input.json | prototool grpc example \
flags.bindListAllLinters(flagSet)
flags.bindListLinters(flagSet)
flags.bindProtocURL(flagSet)
flags.bindProtocBinPath(flagSet)
flags.bindProtocWKTPath(flagSet)
},
}

Expand Down Expand Up @@ -508,6 +520,18 @@ func getRunner(stdin io.Reader, stdout io.Writer, stderr io.Writer, flags *flags
exec.RunnerWithJSON(),
)
}
if flags.protocBinPath != "" {
runnerOptions = append(
runnerOptions,
exec.RunnerWithProtocBinPath(flags.protocBinPath),
)
}
if flags.protocWKTPath != "" {
runnerOptions = append(
runnerOptions,
exec.RunnerWithProtocWKTPath(flags.protocWKTPath),
)
}
if flags.printFields != "" {
runnerOptions = append(
runnerOptions,
Expand Down
14 changes: 14 additions & 0 deletions internal/exec/exec.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,20 @@ func RunnerWithPrintFields(printFields string) RunnerOption {
}
}

// RunnerWithProtocBinPath returns a RunnerOption that uses the given protoc binary path.
func RunnerWithProtocBinPath(protocBinPath string) RunnerOption {
return func(runner *runner) {
runner.protocBinPath = protocBinPath
}
}

// RunnerWithProtocWKTPath returns a RunnerOption that uses the given path to include the well-known types.
func RunnerWithProtocWKTPath(protocWKTPath string) RunnerOption {
return func(runner *runner) {
runner.protocWKTPath = protocWKTPath
}
}

// RunnerWithProtocURL returns a RunnerOption that uses the given protoc zip file URL.
func RunnerWithProtocURL(protocURL string) RunnerOption {
return func(runner *runner) {
Expand Down
52 changes: 43 additions & 9 deletions internal/exec/runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,12 +65,14 @@ type runner struct {
input io.Reader
output io.Writer

logger *zap.Logger
cachePath string
configData string
protocURL string
printFields string
json bool
logger *zap.Logger
cachePath string
configData string
protocBinPath string
protocWKTPath string
protocURL string
printFields string
json bool
}

func newRunner(workDirPath string, input io.Reader, output io.Writer, options ...RunnerOption) *runner {
Expand Down Expand Up @@ -185,7 +187,11 @@ func (r *runner) Download() error {
if err != nil {
return err
}
path, err := r.newDownloader(config).Download()
d, err := r.newDownloader(config)
if err != nil {
return err
}
path, err := d.Download()
if err != nil {
return err
}
Expand All @@ -197,7 +203,11 @@ func (r *runner) Clean() error {
if err != nil {
return err
}
return r.newDownloader(config).Delete()
d, err := r.newDownloader(config)
if err != nil {
return err
}
return d.Delete()
}

func (r *runner) Files(args []string) error {
Expand Down Expand Up @@ -649,7 +659,7 @@ func (r *runner) GRPC(args, headers []string, address, method, data, callTimeout
).Invoke(fileDescriptorSets, address, method, reader, r.output)
}

func (r *runner) newDownloader(config settings.Config) protoc.Downloader {
func (r *runner) newDownloader(config settings.Config) (protoc.Downloader, error) {
downloaderOptions := []protoc.DownloaderOption{
protoc.DownloaderWithLogger(r.logger),
}
Expand All @@ -659,6 +669,18 @@ func (r *runner) newDownloader(config settings.Config) protoc.Downloader {
protoc.DownloaderWithCachePath(r.cachePath),
)
}
if r.protocBinPath != "" {
downloaderOptions = append(
downloaderOptions,
protoc.DownloaderWithProtocBinPath(r.protocBinPath),
)
}
if r.protocWKTPath != "" {
downloaderOptions = append(
downloaderOptions,
protoc.DownloaderWithProtocWKTPath(r.protocWKTPath),
)
}
if r.protocURL != "" {
downloaderOptions = append(
downloaderOptions,
Expand All @@ -678,6 +700,18 @@ func (r *runner) newCompiler(doGen bool, doFileDescriptorSet bool) protoc.Compil
protoc.CompilerWithCachePath(r.cachePath),
)
}
if r.protocBinPath != "" {
compilerOptions = append(
compilerOptions,
protoc.CompilerWithProtocBinPath(r.protocBinPath),
)
}
if r.protocWKTPath != "" {
compilerOptions = append(
compilerOptions,
protoc.CompilerWithProtocWKTPath(r.protocWKTPath),
)
}
if r.protocURL != "" {
compilerOptions = append(
compilerOptions,
Expand Down
21 changes: 19 additions & 2 deletions internal/protoc/compiler.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ var (
type compiler struct {
logger *zap.Logger
cachePath string
protocBinPath string
protocWKTPath string
protocURL string
doGen bool
doFileDescriptorSet bool
Expand Down Expand Up @@ -268,7 +270,10 @@ func (c *compiler) getCmdMetas(protoSet *file.ProtoSet) (cmdMetas []*cmdMeta, re
}()
// you need a new downloader for every ProtoSet as each configuration file could
// have a different protoc.version value
downloader := c.newDownloader(protoSet.Config)
downloader, err := c.newDownloader(protoSet.Config)
if err != nil {
return nil, err
}
if _, err := downloader.Download(); err != nil {
return cmdMetas, err
}
Expand Down Expand Up @@ -354,7 +359,7 @@ func (c *compiler) getCmdMetas(protoSet *file.ProtoSet) (cmdMetas []*cmdMeta, re
return cmdMetas, nil
}

func (c *compiler) newDownloader(config settings.Config) Downloader {
func (c *compiler) newDownloader(config settings.Config) (Downloader, error) {
downloaderOptions := []DownloaderOption{
DownloaderWithLogger(c.logger),
}
Expand All @@ -364,6 +369,18 @@ func (c *compiler) newDownloader(config settings.Config) Downloader {
DownloaderWithCachePath(c.cachePath),
)
}
if c.protocBinPath != "" {
downloaderOptions = append(
downloaderOptions,
DownloaderWithProtocBinPath(c.protocBinPath),
)
}
if c.protocWKTPath != "" {
downloaderOptions = append(
downloaderOptions,
DownloaderWithProtocWKTPath(c.protocWKTPath),
)
}
if c.protocURL != "" {
downloaderOptions = append(
downloaderOptions,
Expand Down
49 changes: 46 additions & 3 deletions internal/protoc/downloader.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,17 +43,24 @@ import (
)

type downloader struct {
lock sync.RWMutex

logger *zap.Logger
cachePath string
protocURL string
config settings.Config

lock sync.RWMutex
// the looked-up and verified to exist base path
cachedBasePath string

// If set, Prototool will invoke protoc and include
// the well-known-types, from the configured binPath
// and wktPath.
protocBinPath string
protocWKTPath string
}

func newDownloader(config settings.Config, options ...DownloaderOption) *downloader {
func newDownloader(config settings.Config, options ...DownloaderOption) (*downloader, error) {
downloader := &downloader{
config: config,
logger: zap.NewNop(),
Expand All @@ -64,7 +71,33 @@ func newDownloader(config settings.Config, options ...DownloaderOption) *downloa
if downloader.config.Compile.ProtobufVersion == "" {
downloader.config.Compile.ProtobufVersion = vars.DefaultProtocVersion
}
return downloader
if downloader.protocBinPath != "" || downloader.protocWKTPath != "" {
if downloader.protocURL != "" {
return nil, fmt.Errorf("cannot use protoc-url in combination with either protoc-bin-path or protoc-wkt-path")
}
if downloader.protocBinPath == "" || downloader.protocWKTPath == "" {
return nil, fmt.Errorf("both protoc-bin-path and protoc-wkt-path must be set")
}
cleanBinPath := filepath.Clean(downloader.protocBinPath)
if _, err := os.Stat(cleanBinPath); os.IsNotExist(err) {
return nil, err
}
cleanWKTPath := filepath.Clean(downloader.protocWKTPath)
if _, err := os.Stat(cleanWKTPath); os.IsNotExist(err) {
return nil, err
}
protobufPath := filepath.Join(cleanWKTPath, "google", "protobuf")
info, err := os.Stat(protobufPath)
if os.IsNotExist(err) {
return nil, err
}
if !info.IsDir() {
return nil, fmt.Errorf("%q is not a valid well-known types directory", protobufPath)
}
downloader.protocBinPath = cleanBinPath
downloader.protocWKTPath = cleanWKTPath
}
return downloader, nil
}

func (d *downloader) Download() (string, error) {
Expand All @@ -78,6 +111,9 @@ func (d *downloader) Download() (string, error) {
}

func (d *downloader) ProtocPath() (string, error) {
if d.protocBinPath != "" {
return d.protocBinPath, nil
}
basePath, err := d.Download()
if err != nil {
return "", err
Expand All @@ -86,6 +122,9 @@ func (d *downloader) ProtocPath() (string, error) {
}

func (d *downloader) WellKnownTypesIncludePath() (string, error) {
if d.protocWKTPath != "" {
return d.protocWKTPath, nil
}
basePath, err := d.Download()
if err != nil {
return "", err
Expand All @@ -104,6 +143,10 @@ func (d *downloader) Delete() error {
}

func (d *downloader) cache() (string, error) {
if d.protocBinPath != "" {
return d.protocBinPath, nil
}

d.lock.Lock()
defer d.lock.Unlock()

Expand Down
Loading

0 comments on commit 76bb33b

Please sign in to comment.