OSDN Git Service

new repo
[bytom/vapor.git] / vendor / google.golang.org / genproto / regen.go
1 // Copyright 2016 Google Inc.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 // +build ignore
16
17 // Regen.go regenerates the genproto repository.
18 //
19 // Regen.go recursively walks through each directory named by given arguments,
20 // looking for all .proto files. (Symlinks are not followed.)
21 // If the pkg_prefix flag is not an empty string,
22 // any proto file without `go_package` option
23 // or whose option does not begin with the prefix is ignored.
24 // Protoc is executed on remaining files,
25 // one invocation per set of files declaring the same Go package.
26 package main
27
28 import (
29         "flag"
30         "fmt"
31         "io/ioutil"
32         "log"
33         "os"
34         "os/exec"
35         "path/filepath"
36         "regexp"
37         "strconv"
38         "strings"
39 )
40
41 var goPkgOptRe = regexp.MustCompile(`(?m)^option go_package = (.*);`)
42
43 func usage() {
44         fmt.Fprintln(os.Stderr, `usage: go run regen.go -go_out=path/to/output [-pkg_prefix=pkg/prefix] roots...
45
46 Most users will not need to run this file directly.
47 To regenerate this repository, run regen.sh instead.`)
48         flag.PrintDefaults()
49 }
50
51 func main() {
52         goOutDir := flag.String("go_out", "", "go_out argument to pass to protoc-gen-go")
53         pkgPrefix := flag.String("pkg_prefix", "", "only include proto files with go_package starting with this prefix")
54         flag.Usage = usage
55         flag.Parse()
56
57         if *goOutDir == "" {
58                 log.Fatal("need go_out flag")
59         }
60
61         pkgFiles := make(map[string][]string)
62         walkFn := func(path string, info os.FileInfo, err error) error {
63                 if err != nil {
64                         return err
65                 }
66                 if !info.Mode().IsRegular() || !strings.HasSuffix(path, ".proto") {
67                         return nil
68                 }
69                 pkg, err := goPkg(path)
70                 if err != nil {
71                         return err
72                 }
73                 pkgFiles[pkg] = append(pkgFiles[pkg], path)
74                 return nil
75         }
76         for _, root := range flag.Args() {
77                 if err := filepath.Walk(root, walkFn); err != nil {
78                         log.Fatal(err)
79                 }
80         }
81         for pkg, fnames := range pkgFiles {
82                 if !strings.HasPrefix(pkg, *pkgPrefix) {
83                         continue
84                 }
85                 if out, err := protoc(*goOutDir, flag.Args(), fnames); err != nil {
86                         log.Fatalf("error executing protoc: %s\n%s", err, out)
87                 }
88         }
89 }
90
91 // goPkg reports the import path declared in the given file's
92 // `go_package` option. If the option is missing, goPkg returns empty string.
93 func goPkg(fname string) (string, error) {
94         content, err := ioutil.ReadFile(fname)
95         if err != nil {
96                 return "", err
97         }
98
99         var pkgName string
100         if match := goPkgOptRe.FindSubmatch(content); len(match) > 0 {
101                 pn, err := strconv.Unquote(string(match[1]))
102                 if err != nil {
103                         return "", err
104                 }
105                 pkgName = pn
106         }
107         if p := strings.IndexRune(pkgName, ';'); p > 0 {
108                 pkgName = pkgName[:p]
109         }
110         return pkgName, nil
111 }
112
113 // protoc executes the "protoc" command on files named in fnames,
114 // passing go_out and include flags specified in goOut and includes respectively.
115 // protoc returns combined output from stdout and stderr.
116 func protoc(goOut string, includes, fnames []string) ([]byte, error) {
117         args := []string{"--go_out=plugins=grpc:" + goOut}
118         for _, inc := range includes {
119                 args = append(args, "-I", inc)
120         }
121         args = append(args, fnames...)
122         return exec.Command("protoc", args...).CombinedOutput()
123 }