1// Copyright 2017 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package main
6
7import (
8	"encoding/json"
9	"fmt"
10	"io/ioutil"
11	"os"
12	"path/filepath"
13	"regexp"
14	"strings"
15
16	"golang.org/x/text/message/pipeline"
17	"golang.org/x/tools/go/loader"
18)
19
20func init() {
21	out = cmdGenerate.Flag.String("out", "", "output file to write to")
22}
23
24var (
25	out *string
26)
27
28var cmdGenerate = &Command{
29	Run:       runGenerate,
30	UsageLine: "generate <package>",
31	Short:     "generates code to insert translated messages",
32}
33
34var transRe = regexp.MustCompile(`messages\.(.*)\.json`)
35
36func runGenerate(cmd *Command, args []string) error {
37
38	prog, err := loadPackages(&loader.Config{}, args)
39	if err != nil {
40		return wrap(err, "could not load package")
41	}
42
43	pkgs := prog.InitialPackages()
44	if len(pkgs) != 1 {
45		return fmt.Errorf("more than one package selected: %v", pkgs)
46	}
47	pkg := pkgs[0].Pkg.Name()
48
49	// TODO: add in external input. Right now we assume that all files are
50	// manually created and stored in the textdata directory.
51
52	// Build up index of translations and original messages.
53	extracted := pipeline.Locale{}
54	translations := []*pipeline.Locale{}
55
56	err = filepath.Walk(*dir, func(path string, f os.FileInfo, err error) error {
57		if err != nil {
58			return wrap(err, "loading data")
59		}
60		if f.IsDir() {
61			return nil
62		}
63		if f.Name() == extractFile {
64			b, err := ioutil.ReadFile(path)
65			if err != nil {
66				return wrap(err, "read file failed")
67			}
68			if err := json.Unmarshal(b, &extracted); err != nil {
69				return wrap(err, "unmarshal source failed")
70			}
71			return nil
72		}
73		if f.Name() == outFile {
74			return nil
75		}
76		if !strings.HasSuffix(path, gotextSuffix) {
77			return nil
78		}
79		b, err := ioutil.ReadFile(path)
80		if err != nil {
81			return wrap(err, "read file failed")
82		}
83		var locale pipeline.Locale
84		if err := json.Unmarshal(b, &locale); err != nil {
85			return wrap(err, "parsing translation file failed")
86		}
87		translations = append(translations, &locale)
88		return nil
89	})
90	if err != nil {
91		return err
92	}
93
94	w := os.Stdout
95	if *out != "" {
96		w, err = os.Create(*out)
97		if err != nil {
98			return wrap(err, "create file failed")
99		}
100	}
101
102	_, err = pipeline.Generate(w, pkg, &extracted, translations...)
103	return err
104}
105