Source file src/internal/goexperiment/mkconsts.go

     1  // Copyright 2021 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  //go:build ignore
     6  
     7  // mkconsts generates const definition files for each GOEXPERIMENT.
     8  package main
     9  
    10  import (
    11  	"bytes"
    12  	"fmt"
    13  	"internal/goexperiment"
    14  	"log"
    15  	"os"
    16  	"reflect"
    17  	"strings"
    18  )
    19  
    20  func main() {
    21  	// Delete existing experiment constant files.
    22  	ents, err := os.ReadDir(".")
    23  	if err != nil {
    24  		log.Fatal(err)
    25  	}
    26  	for _, ent := range ents {
    27  		name := ent.Name()
    28  		if !strings.HasPrefix(name, "exp_") {
    29  			continue
    30  		}
    31  		// Check that this is definitely a generated file.
    32  		data, err := os.ReadFile(name)
    33  		if err != nil {
    34  			log.Fatalf("reading %s: %v", name, err)
    35  		}
    36  		if !bytes.Contains(data, []byte("Code generated by mkconsts")) {
    37  			log.Fatalf("%s: expected generated file", name)
    38  		}
    39  		if err := os.Remove(name); err != nil {
    40  			log.Fatal(err)
    41  		}
    42  	}
    43  
    44  	// Generate new experiment constant files.
    45  	rt := reflect.TypeOf(&goexperiment.Flags{}).Elem()
    46  	for i := 0; i < rt.NumField(); i++ {
    47  		f := rt.Field(i).Name
    48  		buildTag := "goexperiment." + strings.ToLower(f)
    49  		for _, val := range []bool{false, true} {
    50  			name := fmt.Sprintf("exp_%s_%s.go", strings.ToLower(f), pick(val, "off", "on"))
    51  			data := fmt.Sprintf(`// Code generated by mkconsts.go. DO NOT EDIT.
    52  
    53  //go:build %s%s
    54  
    55  package goexperiment
    56  
    57  const %s = %v
    58  const %sInt = %s
    59  `, pick(val, "!", ""), buildTag, f, val, f, pick(val, "0", "1"))
    60  			if err := os.WriteFile(name, []byte(data), 0666); err != nil {
    61  				log.Fatalf("writing %s: %v", name, err)
    62  			}
    63  		}
    64  	}
    65  }
    66  
    67  func pick(v bool, f, t string) string {
    68  	if v {
    69  		return t
    70  	}
    71  	return f
    72  }
    73  

View as plain text