//go:build ignore //go:generate go run gen_icons.go // gen_icons reads SVG files and generates icons/embedded.go with go:embed directives. // Run: go generate ./icons // To regenerate: cd icons && go run gen_icons.go package main import ( "bytes" "fmt" "go/format" "io/fs" "os" "path/filepath" "sort" "strings" "text/template" ) const output = "icons.go" var iconTemplate = template.Must(template.New("").Parse(`// Code generated by gen_icons.go; DO NOT EDIT. package icons import ( "embed" ) //go:embed {{.Embeds}} var svgFS embed.FS {{range $name, $files := .Icons}} // {{$name}}SVG contains the {{$name}} icon SVG source. var {{$name}}SVG = ` + "`" + `{{.}}` + "`" + ` {{end}} `)) type iconData struct { Embeds string Icons map[string]string } func main() { icons := make(map[string]string) var embeds []string err := filepath.WalkDir(".", func(path string, d fs.DirEntry, err error) error { if err != nil { return err } if d.IsDir() { return nil } if !strings.HasSuffix(path, ".svg") { return nil } data, err := os.ReadFile(path) if err != nil { return err } name := strings.TrimSuffix(filepath.Base(path), ".svg") icons[name] = string(data) embeds = append(embeds, filepath.Base(path)) return nil }) if err != nil { fmt.Fprintf(os.Stderr, "error: %v\n", err) os.Exit(1) } // Sort embeds for deterministic output sort.Strings(embeds) data := iconData{ Embeds: strings.Join(embeds, " "), Icons: icons, } var buf bytes.Buffer if err := iconTemplate.Execute(&buf, data); err != nil { fmt.Fprintf(os.Stderr, "template error: %v\n", err) os.Exit(1) } src, err := format.Source(buf.Bytes()) if err != nil { fmt.Fprintf(os.Stderr, "format error: %v\n", err) os.Exit(1) } if err := os.WriteFile(output, src, 0644); err != nil { fmt.Fprintf(os.Stderr, "write error: %v\n", err) os.Exit(1) } fmt.Println("generated icons.go") }