cmd/gotext: fix misbehaviors
The existing implementation has misbehaviors described in golang/go#56842:
- `gotext extract` ignores `lang` flag
- `gotext generate` ignores `out` flag
- Misbehavior of `gotext generate` when no flag specified
This commit fixes these bugs:
- Update `Command.UsageLine` for `cmdGenerate`
- Fix flag misbehaviors by encapsuling flag definition statements into individual `Command.Init()` functions of commands
- Fix `gotext generate` misbehavior by executing `pipeline.State.Merge()` before `pipeline.State.Generate()`
Fixes golang/go#56842
Change-Id: Id5e324b573b2b389bec22181482a97445230d0cc
Reviewed-on: https://go-review.googlesource.com/c/text/+/452115
Auto-Submit: Dmitri Shuralyov <dmitshur@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Heschi Kreinick <heschi@google.com>
Reviewed-by: Marcel van Lohuizen <mpvl@golang.org>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
Run-TryBot: Dmitri Shuralyov <dmitshur@golang.org>
diff --git a/cmd/gotext/doc.go b/cmd/gotext/doc.go
index d363ae2..fcf3605 100644
--- a/cmd/gotext/doc.go
+++ b/cmd/gotext/doc.go
@@ -46,5 +46,5 @@
//
// Usage:
//
-// gotext generate <package>
+// gotext generate <package> [-out <gofile>]
package main
diff --git a/cmd/gotext/extract.go b/cmd/gotext/extract.go
index 103d7e6..80a3a72 100644
--- a/cmd/gotext/extract.go
+++ b/cmd/gotext/extract.go
@@ -14,16 +14,17 @@
// - handle features (gender, plural)
// - message rewriting
-func init() {
- lang = cmdExtract.Flag.String("lang", "en-US", "comma-separated list of languages to process")
-}
-
var cmdExtract = &Command{
+ Init: initExtract,
Run: runExtract,
UsageLine: "extract <package>*",
Short: "extracts strings to be translated from code",
}
+func initExtract(cmd *Command) {
+ lang = cmd.Flag.String("lang", "en-US", "comma-separated list of languages to process")
+}
+
func runExtract(cmd *Command, config *pipeline.Config, args []string) error {
config.Packages = args
state, err := pipeline.Extract(config)
diff --git a/cmd/gotext/generate.go b/cmd/gotext/generate.go
index 36820df..77b3c81 100644
--- a/cmd/gotext/generate.go
+++ b/cmd/gotext/generate.go
@@ -8,14 +8,15 @@
"golang.org/x/text/message/pipeline"
)
-func init() {
- out = cmdGenerate.Flag.String("out", "", "output file to write to")
+var cmdGenerate = &Command{
+ Init: initGenerate,
+ Run: runGenerate,
+ UsageLine: "generate <package> [-out <gofile>]",
+ Short: "generates code to insert translated messages",
}
-var cmdGenerate = &Command{
- Run: runGenerate,
- UsageLine: "generate <package>",
- Short: "generates code to insert translated messages",
+func initGenerate(cmd *Command) {
+ out = cmd.Flag.String("out", "", "output file to write to")
}
func runGenerate(cmd *Command, config *pipeline.Config, args []string) error {
@@ -27,5 +28,8 @@
if err := s.Import(); err != nil {
return wrap(err, "import failed")
}
+ if err := s.Merge(); err != nil {
+ return wrap(err, "merge failed")
+ }
return wrap(s.Generate(), "generation failed")
}
diff --git a/cmd/gotext/main.go b/cmd/gotext/main.go
index aad1d4a..f69ea93 100644
--- a/cmd/gotext/main.go
+++ b/cmd/gotext/main.go
@@ -35,6 +35,10 @@
}
var (
+ lang *string
+ out *string
+ overwrite *bool
+
srcLang = flag.String("srclang", "en-US", "the source-code language")
dir = flag.String("dir", "locales", "default subdirectory to store translation files")
)
@@ -57,6 +61,9 @@
// A Command is an implementation of a go command
// like go build or go fix.
type Command struct {
+ // Init initializes the flag set of the command.
+ Init func(cmd *Command)
+
// Run runs the command.
// The args are the arguments after the command name.
Run func(cmd *Command, c *pipeline.Config, args []string) error
@@ -139,6 +146,7 @@
for _, cmd := range commands {
if cmd.Name() == args[0] && cmd.Runnable() {
+ cmd.Init(cmd)
cmd.Flag.Usage = func() { cmd.Usage() }
cmd.Flag.Parse(args[1:])
args = cmd.Flag.Args()
@@ -331,6 +339,9 @@
}
func getLangs() (tags []language.Tag) {
+ if lang == nil {
+ return []language.Tag{language.AmericanEnglish}
+ }
for _, t := range strings.Split(*lang, ",") {
if t == "" {
continue
diff --git a/cmd/gotext/rewrite.go b/cmd/gotext/rewrite.go
index 9702ca7..5a6fd3a 100644
--- a/cmd/gotext/rewrite.go
+++ b/cmd/gotext/rewrite.go
@@ -19,15 +19,8 @@
// - handle features (gender, plural)
// - message rewriting
-func init() {
- overwrite = cmdRewrite.Flag.Bool("w", false, "write files in place")
-}
-
-var (
- overwrite *bool
-)
-
var cmdRewrite = &Command{
+ Init: initRewrite,
Run: runRewrite,
UsageLine: "rewrite <package>",
Short: "rewrites fmt functions to use a message Printer",
@@ -39,6 +32,10 @@
`,
}
+func initRewrite(cmd *Command) {
+ overwrite = cmd.Flag.Bool("w", false, "write files in place")
+}
+
func runRewrite(cmd *Command, _ *pipeline.Config, args []string) error {
var w io.Writer
if !*overwrite {
diff --git a/cmd/gotext/update.go b/cmd/gotext/update.go
index 1260750..50f1c2d 100644
--- a/cmd/gotext/update.go
+++ b/cmd/gotext/update.go
@@ -14,22 +14,18 @@
// - handle features (gender, plural)
// - message rewriting
-var (
- lang *string
- out *string
-)
-
-func init() {
- lang = cmdUpdate.Flag.String("lang", "en-US", "comma-separated list of languages to process")
- out = cmdUpdate.Flag.String("out", "", "output file to write to")
-}
-
var cmdUpdate = &Command{
+ Init: initUpdate,
Run: runUpdate,
UsageLine: "update <package>* [-out <gofile>]",
Short: "merge translations and generate catalog",
}
+func initUpdate(cmd *Command) {
+ lang = cmd.Flag.String("lang", "en-US", "comma-separated list of languages to process")
+ out = cmd.Flag.String("out", "", "output file to write to")
+}
+
func runUpdate(cmd *Command, config *pipeline.Config, args []string) error {
config.Packages = args
state, err := pipeline.Extract(config)
diff --git a/message/pipeline/generate.go b/message/pipeline/generate.go
index bb1f85b..f747c37 100644
--- a/message/pipeline/generate.go
+++ b/message/pipeline/generate.go
@@ -8,6 +8,7 @@
"fmt"
"go/build"
"io"
+ "os"
"path/filepath"
"regexp"
"sort"
@@ -52,6 +53,10 @@
gopath := filepath.SplitList(build.Default.GOPATH)[0]
path = filepath.Join(gopath, "src", filepath.FromSlash(pkgs[0].Pkg.Path()))
}
+ if len(s.Config.GenFile) == 0 {
+ cw.WriteGo(os.Stdout, pkg, "")
+ return nil
+ }
if filepath.IsAbs(s.Config.GenFile) {
path = s.Config.GenFile
} else {