github.com/graybobo/golang.org-package-offline-cache@v0.0.0-20200626051047-6608995c132f/x/text/gen.go (about) 1 // Copyright 2015 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 5 // +build ignore 6 7 // gen runs go generate on Unicode- and CLDR-related package in the text 8 // repositories, taking into account dependencies and versions. 9 package main 10 11 import ( 12 "bytes" 13 "flag" 14 "fmt" 15 "os" 16 "os/exec" 17 "path/filepath" 18 "runtime" 19 "strings" 20 "sync" 21 "unicode" 22 23 "golang.org/x/text/internal/gen" 24 ) 25 26 var ( 27 verbose = flag.Bool("v", false, "verbose output") 28 force = flag.Bool("force", false, "ignore failing dependencies") 29 excludeList = flag.String("exclude", "", 30 "comma-separated list of packages to exclude") 31 32 // The user can specify a selection of packages to build on the command line. 33 args []string 34 ) 35 36 func exclude(pkg string) bool { 37 if len(args) > 0 { 38 return !contains(args, pkg) 39 } 40 return contains(strings.Split(*excludeList, ","), pkg) 41 } 42 43 // TODO: 44 // - Better version handling. 45 // - Generate tables for the core unicode package? 46 // - Add generation for encodings. This requires some retooling here and there. 47 // - Running repo-wide "long" tests. 48 49 var vprintf = fmt.Printf 50 51 func main() { 52 gen.Init() 53 args = flag.Args() 54 if !*verbose { 55 // Set vprintf to a no-op. 56 vprintf = func(string, ...interface{}) (int, error) { return 0, nil } 57 } 58 59 // TODO: create temporary cache directory to load files and create and set 60 // a "cache" option if the user did not specify the UNICODE_DIR environment 61 // variable. This will prevent duplicate downloads and also will enable long 62 // tests, which really need to be run after each generated package. 63 64 if gen.UnicodeVersion() != unicode.Version { 65 fmt.Printf("Requested Unicode version %s; core unicode version is %s.\n", 66 gen.UnicodeVersion, 67 unicode.Version) 68 // TODO: use collate to compare. Simple comparison will work, though, 69 // until Unicode reaches version 10. To avoid circular dependencies, we 70 // could use the NumericWeighter without using package collate using a 71 // trivial Weighter implementation. 72 if gen.UnicodeVersion() < unicode.Version && !*force { 73 os.Exit(2) 74 } 75 } 76 var ( 77 cldr = generate("unicode/cldr") 78 language = generate("language", cldr) 79 internal = generate("internal", language) 80 norm = generate("unicode/norm") 81 _ = generate("unicode/rangetable") 82 _ = generate("unicode/bidi", norm) 83 _ = generate("encoding/htmlindex", language) 84 _ = generate("width") 85 _ = generate("currency", cldr, language, internal) 86 _ = generate("language/display", cldr, language) 87 _ = generate("cases", norm, language) 88 _ = generate("collate", norm, cldr, language) 89 _ = generate("search", norm, cldr, language) 90 ) 91 all.Wait() 92 93 if hasErrors { 94 fmt.Println("FAIL") 95 os.Exit(1) 96 } 97 vprintf("SUCCESS\n") 98 } 99 100 var ( 101 all sync.WaitGroup 102 hasErrors bool 103 ) 104 105 type dependency struct { 106 sync.WaitGroup 107 hasErrors bool 108 } 109 110 func generate(pkg string, deps ...*dependency) *dependency { 111 var wg dependency 112 if exclude(pkg) { 113 return &wg 114 } 115 wg.Add(1) 116 all.Add(1) 117 go func() { 118 defer wg.Done() 119 defer all.Done() 120 // Wait for dependencies to finish. 121 for _, d := range deps { 122 d.Wait() 123 if d.hasErrors && !*force { 124 fmt.Printf("--- ABORT: %s\n", pkg) 125 wg.hasErrors = true 126 return 127 } 128 } 129 vprintf("=== GENERATE %s\n", pkg) 130 args := []string{"generate"} 131 if *verbose { 132 args = append(args, "-v") 133 } 134 args = append(args, "./"+pkg) 135 cmd := exec.Command(filepath.Join(runtime.GOROOT(), "bin", "go"), args...) 136 w := &bytes.Buffer{} 137 cmd.Stderr = w 138 cmd.Stdout = w 139 if err := cmd.Run(); err != nil { 140 fmt.Printf("--- FAIL: %s:\n\t%v\n\tError: %v\n", pkg, indent(w), err) 141 hasErrors = true 142 wg.hasErrors = true 143 return 144 } 145 146 vprintf("=== TEST %s\n", pkg) 147 args[0] = "test" 148 cmd = exec.Command(filepath.Join(runtime.GOROOT(), "bin", "go"), args...) 149 wt := &bytes.Buffer{} 150 cmd.Stderr = wt 151 cmd.Stdout = wt 152 if err := cmd.Run(); err != nil { 153 fmt.Printf("--- FAIL: %s:\n\t%v\n\tError: %v\n", pkg, indent(wt), err) 154 hasErrors = true 155 wg.hasErrors = true 156 return 157 } 158 vprintf("--- SUCCESS: %s\n\t%v\n", pkg, indent(w)) 159 fmt.Print(wt.String()) 160 }() 161 return &wg 162 } 163 164 func contains(a []string, s string) bool { 165 for _, e := range a { 166 if s == e { 167 return true 168 } 169 } 170 return false 171 } 172 173 func indent(b *bytes.Buffer) string { 174 return strings.Replace(strings.TrimSpace(b.String()), "\n", "\n\t", -1) 175 }