summaryrefslogtreecommitdiff
path: root/vendor/golang.org/x/text/gen.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/golang.org/x/text/gen.go')
-rw-r--r--vendor/golang.org/x/text/gen.go319
1 files changed, 319 insertions, 0 deletions
diff --git a/vendor/golang.org/x/text/gen.go b/vendor/golang.org/x/text/gen.go
new file mode 100644
index 0000000..757fefb
--- /dev/null
+++ b/vendor/golang.org/x/text/gen.go
@@ -0,0 +1,319 @@
+// Copyright 2015 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build ignore
+
+// gen runs go generate on Unicode- and CLDR-related package in the text
+// repositories, taking into account dependencies and versions.
+package main
+
+import (
+ "bytes"
+ "flag"
+ "fmt"
+ "go/build"
+ "go/format"
+ "io/ioutil"
+ "os"
+ "os/exec"
+ "path"
+ "path/filepath"
+ "regexp"
+ "runtime"
+ "strings"
+ "sync"
+ "unicode"
+
+ "golang.org/x/text/collate"
+ "golang.org/x/text/internal/gen"
+ "golang.org/x/text/language"
+)
+
+var (
+ verbose = flag.Bool("v", false, "verbose output")
+ force = flag.Bool("force", false, "ignore failing dependencies")
+ doCore = flag.Bool("core", false, "force an update to core")
+ excludeList = flag.String("exclude", "",
+ "comma-separated list of packages to exclude")
+
+ // The user can specify a selection of packages to build on the command line.
+ args []string
+)
+
+func exclude(pkg string) bool {
+ if len(args) > 0 {
+ return !contains(args, pkg)
+ }
+ return contains(strings.Split(*excludeList, ","), pkg)
+}
+
+// TODO:
+// - Better version handling.
+// - Generate tables for the core unicode package?
+// - Add generation for encodings. This requires some retooling here and there.
+// - Running repo-wide "long" tests.
+
+var vprintf = fmt.Printf
+
+func main() {
+ gen.Init()
+ args = flag.Args()
+ if !*verbose {
+ // Set vprintf to a no-op.
+ vprintf = func(string, ...interface{}) (int, error) { return 0, nil }
+ }
+
+ // TODO: create temporary cache directory to load files and create and set
+ // a "cache" option if the user did not specify the UNICODE_DIR environment
+ // variable. This will prevent duplicate downloads and also will enable long
+ // tests, which really need to be run after each generated package.
+
+ updateCore := *doCore
+ if gen.UnicodeVersion() != unicode.Version {
+ fmt.Printf("Requested Unicode version %s; core unicode version is %s.\n",
+ gen.UnicodeVersion(),
+ unicode.Version)
+ c := collate.New(language.Und, collate.Numeric)
+ if c.CompareString(gen.UnicodeVersion(), unicode.Version) < 0 && !*force {
+ os.Exit(2)
+ }
+ updateCore = true
+ goroot := os.Getenv("GOROOT")
+ appendToFile(
+ filepath.Join(goroot, "api", "except.txt"),
+ fmt.Sprintf("pkg unicode, const Version = %q\n", unicode.Version),
+ )
+ const lines = `pkg unicode, const Version = %q
+// TODO: add a new line of the following form for each new script and property.
+pkg unicode, var <new script or property> *RangeTable
+`
+ appendToFile(
+ filepath.Join(goroot, "api", "next.txt"),
+ fmt.Sprintf(lines, gen.UnicodeVersion()),
+ )
+ }
+
+ var unicode = &dependency{}
+ if updateCore {
+ fmt.Printf("Updating core to version %s...\n", gen.UnicodeVersion())
+ unicode = generate("unicode")
+
+ // Test some users of the unicode packages, especially the ones that
+ // keep a mirrored table. These may need to be corrected by hand.
+ generate("regexp", unicode)
+ generate("strconv", unicode) // mimics Unicode table
+ generate("strings", unicode)
+ generate("testing", unicode) // mimics Unicode table
+ }
+
+ var (
+ cldr = generate("./unicode/cldr", unicode)
+ language = generate("./language", cldr)
+ internal = generate("./internal", unicode, language)
+ norm = generate("./unicode/norm", unicode)
+ rangetable = generate("./unicode/rangetable", unicode)
+ cases = generate("./cases", unicode, norm, language, rangetable)
+ width = generate("./width", unicode)
+ bidi = generate("./unicode/bidi", unicode, norm, rangetable)
+ mib = generate("./encoding/internal/identifier", unicode)
+ number = generate("./internal/number", unicode, cldr, language, internal)
+ _ = generate("./encoding/htmlindex", unicode, language, mib)
+ _ = generate("./encoding/ianaindex", unicode, language, mib)
+ _ = generate("./secure/precis", unicode, norm, rangetable, cases, width, bidi)
+ _ = generate("./internal/cldrtree", language)
+ _ = generate("./currency", unicode, cldr, language, internal, number)
+ _ = generate("./feature/plural", unicode, cldr, language, internal, number)
+ _ = generate("./internal/export/idna", unicode, bidi, norm)
+ _ = generate("./language/display", unicode, cldr, language, internal, number)
+ _ = generate("./collate", unicode, norm, cldr, language, rangetable)
+ _ = generate("./search", unicode, norm, cldr, language, rangetable)
+ )
+ all.Wait()
+
+ // Copy exported packages to the destination golang.org repo.
+ copyExported("golang.org/x/net/idna")
+
+ if updateCore {
+ copyVendored()
+ }
+
+ if hasErrors {
+ fmt.Println("FAIL")
+ os.Exit(1)
+ }
+ vprintf("SUCCESS\n")
+}
+
+func appendToFile(file, text string) {
+ fmt.Println("Augmenting", file)
+ w, err := os.OpenFile(file, os.O_APPEND|os.O_WRONLY, 0600)
+ if err != nil {
+ fmt.Println("Failed to open file:", err)
+ os.Exit(1)
+ }
+ defer w.Close()
+ if _, err := w.WriteString(text); err != nil {
+ fmt.Println("Failed to write to file:", err)
+ os.Exit(1)
+ }
+}
+
+var (
+ all sync.WaitGroup
+ hasErrors bool
+)
+
+type dependency struct {
+ sync.WaitGroup
+ hasErrors bool
+}
+
+func generate(pkg string, deps ...*dependency) *dependency {
+ var wg dependency
+ if exclude(pkg) {
+ return &wg
+ }
+ wg.Add(1)
+ all.Add(1)
+ go func() {
+ defer wg.Done()
+ defer all.Done()
+ // Wait for dependencies to finish.
+ for _, d := range deps {
+ d.Wait()
+ if d.hasErrors && !*force {
+ fmt.Printf("--- ABORT: %s\n", pkg)
+ wg.hasErrors = true
+ return
+ }
+ }
+ vprintf("=== GENERATE %s\n", pkg)
+ args := []string{"generate"}
+ if *verbose {
+ args = append(args, "-v")
+ }
+ args = append(args, pkg)
+ cmd := exec.Command(filepath.Join(runtime.GOROOT(), "bin", "go"), args...)
+ w := &bytes.Buffer{}
+ cmd.Stderr = w
+ cmd.Stdout = w
+ if err := cmd.Run(); err != nil {
+ fmt.Printf("--- FAIL: %s:\n\t%v\n\tError: %v\n", pkg, indent(w), err)
+ hasErrors = true
+ wg.hasErrors = true
+ return
+ }
+
+ vprintf("=== TEST %s\n", pkg)
+ args[0] = "test"
+ cmd = exec.Command(filepath.Join(runtime.GOROOT(), "bin", "go"), args...)
+ wt := &bytes.Buffer{}
+ cmd.Stderr = wt
+ cmd.Stdout = wt
+ if err := cmd.Run(); err != nil {
+ fmt.Printf("--- FAIL: %s:\n\t%v\n\tError: %v\n", pkg, indent(wt), err)
+ hasErrors = true
+ wg.hasErrors = true
+ return
+ }
+ vprintf("--- SUCCESS: %s\n\t%v\n", pkg, indent(w))
+ fmt.Print(wt.String())
+ }()
+ return &wg
+}
+
+// copyExported copies a package in x/text/internal/export to the
+// destination repository.
+func copyExported(p string) {
+ copyPackage(
+ filepath.Join("internal", "export", path.Base(p)),
+ filepath.Join("..", filepath.FromSlash(p[len("golang.org/x"):])),
+ "golang.org/x/text/internal/export/"+path.Base(p),
+ p)
+}
+
+// copyVendored copies packages used by Go core into the vendored directory.
+func copyVendored() {
+ root := filepath.Join(build.Default.GOROOT, filepath.FromSlash("src/vendor/golang_org/x"))
+
+ err := filepath.Walk(root, func(dir string, info os.FileInfo, err error) error {
+ if err != nil || !info.IsDir() || root == dir {
+ return err
+ }
+ src := dir[len(root)+1:]
+ const slash = string(filepath.Separator)
+ if c := strings.Split(src, slash); c[0] == "text" {
+ // Copy a text repo package from its normal location.
+ src = strings.Join(c[1:], slash)
+ } else {
+ // Copy the vendored package if it exists in the export directory.
+ src = filepath.Join("internal", "export", filepath.Base(src))
+ }
+ copyPackage(src, dir, "golang.org", "golang_org")
+ return nil
+ })
+ if err != nil {
+ fmt.Printf("Seeding directory %s has failed %v:", root, err)
+ os.Exit(1)
+ }
+}
+
+// goGenRE is used to remove go:generate lines.
+var goGenRE = regexp.MustCompile("//go:generate[^\n]*\n")
+
+// copyPackage copies relevant files from a directory in x/text to the
+// destination package directory. The destination package is assumed to have
+// the same name. For each copied file go:generate lines are removed and
+// and package comments are rewritten to the new path.
+func copyPackage(dirSrc, dirDst, search, replace string) {
+ err := filepath.Walk(dirSrc, func(file string, info os.FileInfo, err error) error {
+ base := filepath.Base(file)
+ if err != nil || info.IsDir() ||
+ !strings.HasSuffix(base, ".go") ||
+ strings.HasSuffix(base, "_test.go") ||
+ // Don't process subdirectories.
+ filepath.Dir(file) != dirSrc {
+ return nil
+ }
+ b, err := ioutil.ReadFile(file)
+ if err != nil || bytes.Contains(b, []byte("\n// +build ignore")) {
+ return err
+ }
+ // Fix paths.
+ b = bytes.Replace(b, []byte(search), []byte(replace), -1)
+ // Remove go:generate lines.
+ b = goGenRE.ReplaceAllLiteral(b, nil)
+ comment := "// Code generated by running \"go generate\" in golang.org/x/text. DO NOT EDIT.\n\n"
+ if *doCore {
+ comment = "// Code generated by running \"go run gen.go -core\" in golang.org/x/text. DO NOT EDIT.\n\n"
+ }
+ if !bytes.HasPrefix(b, []byte(comment)) {
+ b = append([]byte(comment), b...)
+ }
+ if b, err = format.Source(b); err != nil {
+ fmt.Println("Failed to format file:", err)
+ os.Exit(1)
+ }
+ file = filepath.Join(dirDst, base)
+ vprintf("=== COPY %s\n", file)
+ return ioutil.WriteFile(file, b, 0666)
+ })
+ if err != nil {
+ fmt.Println("Copying exported files failed:", err)
+ os.Exit(1)
+ }
+}
+
+func contains(a []string, s string) bool {
+ for _, e := range a {
+ if s == e {
+ return true
+ }
+ }
+ return false
+}
+
+func indent(b *bytes.Buffer) string {
+ return strings.Replace(strings.TrimSpace(b.String()), "\n", "\n\t", -1)
+}