OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 package main | 5 package main |
6 | 6 |
7 import ( | 7 import ( |
8 "bufio" | 8 "bufio" |
9 "flag" | 9 "flag" |
10 "fmt" | 10 "fmt" |
11 "io" | 11 "io" |
12 "os" | 12 "os" |
13 "sort" | 13 "sort" |
14 "strings" | 14 "strings" |
15 "text/template" | 15 "text/template" |
16 | 16 |
17 "github.com/luci/luci-go/common/errors" | 17 "github.com/luci/luci-go/common/errors" |
18 "github.com/luci/luci-go/common/flag/stringsetflag" | 18 "github.com/luci/luci-go/common/flag/stringsetflag" |
19 ) | 19 ) |
20 | 20 |
21 type app struct { | 21 type app struct { |
22 out io.Writer | 22 out io.Writer |
23 | 23 |
24 packageName string | 24 packageName string |
25 typeNames stringsetflag.Flag | 25 typeNames stringsetflag.Flag |
26 outFile string | 26 outFile string |
| 27 header string |
27 } | 28 } |
28 | 29 |
29 const help = `Usage of %s: | 30 const help = `Usage of %s: |
30 | 31 |
31 %s is a go-generator program that generates PropertyConverter implementations | 32 %s is a go-generator program that generates PropertyConverter implementations |
32 for types produced by protoc. It can be used in a go generation file like: | 33 for types produced by protoc. It can be used in a go generation file like: |
33 | 34 |
34 //go:generate <protoc command> | 35 //go:generate <protoc command> |
35 //go:generate proto-gae -type MessageType -type OtherMessageType | 36 //go:generate proto-gae -type MessageType -type OtherMessageType |
36 | 37 |
37 This will produce a new file which implements the ToProperty and FromProperty | 38 This will produce a new file which implements the ToProperty and FromProperty |
38 methods for the named types. | 39 methods for the named types. |
39 | 40 |
40 Options: | 41 Options: |
41 ` | 42 ` |
42 | 43 |
| 44 const copyright = `// Copyright 2016 The Chromium Authors. All rights reserved. |
| 45 // Use of this source code is governed by a BSD-style license that can be |
| 46 // found in the LICENSE file. |
| 47 ` |
| 48 |
43 func (a *app) parseArgs(fs *flag.FlagSet, args []string) error { | 49 func (a *app) parseArgs(fs *flag.FlagSet, args []string) error { |
44 fs.SetOutput(a.out) | 50 fs.SetOutput(a.out) |
45 fs.Usage = func() { | 51 fs.Usage = func() { |
46 fmt.Fprintf(a.out, help, args[0], args[0]) | 52 fmt.Fprintf(a.out, help, args[0], args[0]) |
47 fs.PrintDefaults() | 53 fs.PrintDefaults() |
48 } | 54 } |
49 | 55 |
50 fs.Var(&a.typeNames, "type", | 56 fs.Var(&a.typeNames, "type", |
51 "A generated proto.Message type to generate stubs for (required,
repeatable)") | 57 "A generated proto.Message type to generate stubs for (required,
repeatable)") |
52 fs.StringVar(&a.outFile, "out", "proto_gae.gen.go", | 58 fs.StringVar(&a.outFile, "out", "proto_gae.gen.go", |
53 "The name of the output file") | 59 "The name of the output file") |
| 60 fs.StringVar(&a.header, "header", copyright, "Header text to put at the
top of "+ |
| 61 "the generated file. Defaults to the Chromium Authors copyright.
") |
54 | 62 |
55 if err := fs.Parse(args[1:]); err != nil { | 63 if err := fs.Parse(args[1:]); err != nil { |
56 return err | 64 return err |
57 } | 65 } |
58 fail := errors.MultiError(nil) | 66 fail := errors.MultiError(nil) |
59 if a.typeNames.Data == nil || a.typeNames.Data.Len() == 0 { | 67 if a.typeNames.Data == nil || a.typeNames.Data.Len() == 0 { |
60 fail = append(fail, errors.New("must specify one or more -type")
) | 68 fail = append(fail, errors.New("must specify one or more -type")
) |
61 } | 69 } |
62 if !strings.HasSuffix(a.outFile, ".go") { | 70 if !strings.HasSuffix(a.outFile, ".go") { |
63 fail = append(fail, errors.New("-output must end with '.go'")) | 71 fail = append(fail, errors.New("-output must end with '.go'")) |
64 } | 72 } |
65 if len(fail) > 0 { | 73 if len(fail) > 0 { |
66 for _, e := range fail { | 74 for _, e := range fail { |
67 fmt.Fprintln(a.out, "error:", e) | 75 fmt.Fprintln(a.out, "error:", e) |
68 } | 76 } |
69 fmt.Fprintln(a.out) | 77 fmt.Fprintln(a.out) |
70 fs.Usage() | 78 fs.Usage() |
71 return fail | 79 return fail |
72 } | 80 } |
73 return nil | 81 return nil |
74 } | 82 } |
75 | 83 |
76 var tmpl = template.Must( | 84 var tmpl = template.Must( |
77 » template.New("main").Parse(`// AUTOGENERATED: Do not edit | 85 » template.New("main").Parse(`{{if index . "header"}}{{index . "header"}} |
| 86 {{end}}// AUTOGENERATED: Do not edit |
78 | 87 |
79 package {{index . "package"}} | 88 package {{index . "package"}} |
80 | 89 |
81 import ( | 90 import ( |
82 "github.com/golang/protobuf/proto" | 91 "github.com/golang/protobuf/proto" |
83 | 92 |
84 "github.com/luci/gae/service/datastore" | 93 "github.com/luci/gae/service/datastore" |
85 ){{range index . "types"}} | 94 ){{range index . "types"}} |
86 | 95 |
87 var _ datastore.PropertyConverter = (*{{.}})(nil) | 96 var _ datastore.PropertyConverter = (*{{.}})(nil) |
(...skipping 20 matching lines...) Loading... |
108 }{{end}} | 117 }{{end}} |
109 `)) | 118 `)) |
110 | 119 |
111 func (a *app) writeTo(w io.Writer) error { | 120 func (a *app) writeTo(w io.Writer) error { |
112 typeNames := a.typeNames.Data.ToSlice() | 121 typeNames := a.typeNames.Data.ToSlice() |
113 sort.Strings(typeNames) | 122 sort.Strings(typeNames) |
114 | 123 |
115 return tmpl.Execute(w, map[string]interface{}{ | 124 return tmpl.Execute(w, map[string]interface{}{ |
116 "package": a.packageName, | 125 "package": a.packageName, |
117 "types": typeNames, | 126 "types": typeNames, |
| 127 "header": a.header, |
118 }) | 128 }) |
119 } | 129 } |
120 | 130 |
121 func (a *app) main() { | 131 func (a *app) main() { |
122 if err := a.parseArgs(flag.NewFlagSet(os.Args[0], flag.ContinueOnError),
os.Args); err != nil { | 132 if err := a.parseArgs(flag.NewFlagSet(os.Args[0], flag.ContinueOnError),
os.Args); err != nil { |
123 os.Exit(1) | 133 os.Exit(1) |
124 } | 134 } |
125 ofile, err := os.Create(a.outFile) | 135 ofile, err := os.Create(a.outFile) |
126 if err != nil { | 136 if err != nil { |
127 fmt.Fprintf(a.out, "error: %s", err) | 137 fmt.Fprintf(a.out, "error: %s", err) |
(...skipping 23 matching lines...) Loading... |
151 if err := buf.Flush(); err != nil { | 161 if err := buf.Flush(); err != nil { |
152 fmt.Fprintf(a.out, "error while writing: %s", err) | 162 fmt.Fprintf(a.out, "error while writing: %s", err) |
153 closeFn(true) | 163 closeFn(true) |
154 os.Exit(4) | 164 os.Exit(4) |
155 } | 165 } |
156 } | 166 } |
157 | 167 |
158 func main() { | 168 func main() { |
159 (&app{out: os.Stderr, packageName: os.Getenv("GOPACKAGE")}).main() | 169 (&app{out: os.Stderr, packageName: os.Getenv("GOPACKAGE")}).main() |
160 } | 170 } |
OLD | NEW |