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  }