github.com/insionng/yougam@v0.0.0-20170714101924-2bc18d833463/libraries/golang/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 "github.com/insionng/yougam/libraries/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 rangetable = generate("unicode/rangetable") 82 cases = generate("cases", norm, language, rangetable) 83 width = generate("width") 84 bidi = generate("unicode/bidi", norm, rangetable) 85 _ = generate("secure/precis", norm, rangetable, cases, width, bidi) 86 _ = generate("encoding/htmlindex", language) 87 _ = generate("currency", cldr, language, internal) 88 _ = generate("internal/number", cldr, language, internal) 89 _ = generate("language/display", cldr, language) 90 _ = generate("collate", norm, cldr, language, rangetable) 91 _ = generate("search", norm, cldr, language, rangetable) 92 ) 93 all.Wait() 94 95 if hasErrors { 96 fmt.Println("FAIL") 97 os.Exit(1) 98 } 99 vprintf("SUCCESS\n") 100 } 101 102 var ( 103 all sync.WaitGroup 104 hasErrors bool 105 ) 106 107 type dependency struct { 108 sync.WaitGroup 109 hasErrors bool 110 } 111 112 func generate(pkg string, deps ...*dependency) *dependency { 113 var wg dependency 114 if exclude(pkg) { 115 return &wg 116 } 117 wg.Add(1) 118 all.Add(1) 119 go func() { 120 defer wg.Done() 121 defer all.Done() 122 // Wait for dependencies to finish. 123 for _, d := range deps { 124 d.Wait() 125 if d.hasErrors && !*force { 126 fmt.Printf("--- ABORT: %s\n", pkg) 127 wg.hasErrors = true 128 return 129 } 130 } 131 vprintf("=== GENERATE %s\n", pkg) 132 args := []string{"generate"} 133 if *verbose { 134 args = append(args, "-v") 135 } 136 args = append(args, "./"+pkg) 137 cmd := exec.Command(filepath.Join(runtime.GOROOT(), "bin", "go"), args...) 138 w := &bytes.Buffer{} 139 cmd.Stderr = w 140 cmd.Stdout = w 141 if err := cmd.Run(); err != nil { 142 fmt.Printf("--- FAIL: %s:\n\t%v\n\tError: %v\n", pkg, indent(w), err) 143 hasErrors = true 144 wg.hasErrors = true 145 return 146 } 147 148 vprintf("=== TEST %s\n", pkg) 149 args[0] = "test" 150 cmd = exec.Command(filepath.Join(runtime.GOROOT(), "bin", "go"), args...) 151 wt := &bytes.Buffer{} 152 cmd.Stderr = wt 153 cmd.Stdout = wt 154 if err := cmd.Run(); err != nil { 155 fmt.Printf("--- FAIL: %s:\n\t%v\n\tError: %v\n", pkg, indent(wt), err) 156 hasErrors = true 157 wg.hasErrors = true 158 return 159 } 160 vprintf("--- SUCCESS: %s\n\t%v\n", pkg, indent(w)) 161 fmt.Print(wt.String()) 162 }() 163 return &wg 164 } 165 166 func contains(a []string, s string) bool { 167 for _, e := range a { 168 if s == e { 169 return true 170 } 171 } 172 return false 173 } 174 175 func indent(b *bytes.Buffer) string { 176 return strings.Replace(strings.TrimSpace(b.String()), "\n", "\n\t", -1) 177 }