Skip to content

Instantly share code, notes, and snippets.

@bryanjhv
Created April 7, 2022 03:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bryanjhv/dd0c7ee048d5c646a9ec94e2807e32a7 to your computer and use it in GitHub Desktop.
Save bryanjhv/dd0c7ee048d5c646a9ec94e2807e32a7 to your computer and use it in GitHub Desktop.
// Log custom tags used by running go root, and the files where they
// are used, so you can quickly see which tags can be used for
// specific behavior or just see, for example, which modules are CGo.
package main
import (
"fmt"
"go/scanner"
"go/token"
"io/fs"
"os"
"path/filepath"
"regexp"
"runtime"
"sort"
"strings"
)
type Token struct {
pos token.Position
tok token.Token
lit string
}
func main() {
root := runtime.GOROOT() + "/src"
grouped := make(map[string][]string)
isTag := regexp.MustCompile("[a-z0-9._]+")
known := make(map[string]bool)
for _, tkn := range scan(root+"/go/build/syslist.go", token.STRING) {
for _, tag := range strings.Fields(strings.TrimSpace(strings.Trim(tkn.lit, `"`))) {
known[tag] = true
}
}
if len(known) == 0 {
panic("parser: unable to find known tags")
}
var filenames []string
err := filepath.WalkDir(root, func(path string, d fs.DirEntry, err error) error {
if err == nil && !d.IsDir() && filepath.Ext(path) == ".go" {
if !strings.Contains(path, "/vendor/") && !strings.Contains(path, "/testdata/") {
filenames = append(filenames, path)
}
}
return err
})
if err != nil {
panic(err)
}
for _, filename := range filenames {
for _, tkn := range scan(filename, token.COMMENT) {
lit := tkn.lit
var build string
if strings.HasPrefix(lit, "//go:build") {
build = lit[11:]
}
if strings.HasPrefix(lit, "// +build") {
build = lit[10:]
}
if build == "" {
continue
}
for _, tag := range isTag.FindAllString(build, -1) {
if !known[tag] {
grouped[tag] = append(grouped[tag], tkn.pos.String())
}
}
}
}
tags := make([]string, 0, len(grouped))
for tag, _ := range grouped {
tags = append(tags, tag)
}
sort.Strings(tags)
for _, tag := range tags {
fmt.Println(tag + ":")
for _, filename := range grouped[tag] {
fmt.Println(filename)
}
fmt.Println()
}
}
func scan(filename string, what token.Token) (tokens []Token) {
src, err := os.ReadFile(filename)
if err != nil {
return
}
var s scanner.Scanner
fset := token.NewFileSet()
file := fset.AddFile(filename, fset.Base(), len(src))
s.Init(file, src, nil, scanner.ScanComments)
for {
pos, tok, lit := s.Scan()
if tok == token.EOF {
break
}
if tok == what {
tokens = append(tokens, Token{fset.Position(pos), tok, lit})
}
}
return
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment