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

View as plain text