| 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...) Expand all 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...) Expand all 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 |