package main import ( "flag" "fmt" "go/format" "io/fs" "os" "path/filepath" "strings" ) func main() { src := flag.String("src", "./src", "BotanJS source root") out := flag.String("out", "internal/generated/externs_gen.go", "generated Go output") pkg := flag.String("pkg", "generated", "generated package name") flag.Parse() if err := os.MkdirAll(filepath.Dir(*out), 0o755); err != nil { fatal(err) } code, err := render(*pkg, *src) if err != nil { fatal(err) } fmted, err := format.Source([]byte(code)) if err != nil { _, _ = os.Stderr.WriteString(code) fatal(err) } if err := os.WriteFile(*out, fmted, 0o644); err != nil { fatal(err) } } func render(pkg string, root string) (string, error) { var b strings.Builder root = filepath.Clean(root) b.WriteString("// Code generated by externs-gen; DO NOT EDIT.\n") b.WriteString("package " + pkg + "\n\n") b.WriteString("var Externs = []string{\n") err := filepath.WalkDir(root, func(path string, d fs.DirEntry, err error) error { if err != nil { return err } if d.IsDir() { return nil } if filepath.Ext(path) != ".js" { return nil } if filepath.Base(filepath.Dir(path)) != "externs" { return nil } rel, err := filepath.Rel(root, path) if err != nil { return err } // Generated data should be slash-normalized even on Windows. rel = filepath.ToSlash(rel) fmt.Fprintf(&b, "\t%q,\n", rel) return nil }) if err != nil { return "", err } b.WriteString("}\n") return b.String(), nil } func fatal(err error) { fmt.Fprintln(os.Stderr, "externs-gen:", err) os.Exit(1) }