github.com/chainreactors/fingers@v1.2.1/scripts/add_plusbuild.go (about)

     1  // add_plusbuild walks a directory tree and adds // +build lines to .go files
     2  // that only have //go:build constraints. This makes them parseable by Go < 1.17.
     3  //
     4  // Usage: go run scripts/add_plusbuild.go <dir>
     5  package main
     6  
     7  import (
     8  	"bytes"
     9  	"fmt"
    10  	"go/build/constraint"
    11  	"os"
    12  	"path/filepath"
    13  	"strings"
    14  )
    15  
    16  func main() {
    17  	root := os.Args[1]
    18  	var fixed int
    19  	filepath.Walk(root, func(path string, info os.FileInfo, err error) error {
    20  		if err != nil || info.IsDir() || !strings.HasSuffix(path, ".go") {
    21  			return nil
    22  		}
    23  		data, err := os.ReadFile(path)
    24  		if err != nil {
    25  			return nil
    26  		}
    27  		if !bytes.Contains(data, []byte("//go:build ")) {
    28  			return nil
    29  		}
    30  		if bytes.Contains(data, []byte("// +build ")) {
    31  			return nil
    32  		}
    33  		lines := bytes.SplitN(data, []byte("\n"), 40)
    34  		for i, line := range lines {
    35  			s := strings.TrimSpace(string(line))
    36  			if !strings.HasPrefix(s, "//go:build ") {
    37  				continue
    38  			}
    39  			expr, err := constraint.Parse(s)
    40  			if err != nil {
    41  				break
    42  			}
    43  			plusBuild := "// +build " + toLegacy(expr)
    44  			insert := string(line) + "\n" + plusBuild
    45  			lines[i] = []byte(insert)
    46  			os.WriteFile(path, bytes.Join(lines, []byte("\n")), info.Mode())
    47  			fixed++
    48  			break
    49  		}
    50  		return nil
    51  	})
    52  	fmt.Printf("added // +build to %d files\n", fixed)
    53  }
    54  
    55  func toLegacy(expr constraint.Expr) string {
    56  	switch e := expr.(type) {
    57  	case *constraint.TagExpr:
    58  		return e.Tag
    59  	case *constraint.NotExpr:
    60  		return "!" + toLegacy(e.X)
    61  	case *constraint.AndExpr:
    62  		return toLegacy(e.X) + "," + toLegacy(e.Y)
    63  	case *constraint.OrExpr:
    64  		return toLegacy(e.X) + " " + toLegacy(e.Y)
    65  	default:
    66  		return ""
    67  	}
    68  }