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  }