package main // import "4d63.com/embedfiles" import ( "bytes" "flag" "fmt" "go/format" "io/ioutil" "os" "path/filepath" "text/template" ) const tmpl = ` // Generated by 4d63.com/embedfiles. package {{.Package}} var {{.FileNamesVar}} = []string{ {{range $name, $bytes := .Files}}"{{$name}}",{{end}} } var {{.FilesVar}} = map[string][]byte{ {{range $name, $bytes := .Files}} "{{$name}}": []byte{ {{range $bytes}}{{.}},{{end}} }, {{end}} } ` type tmplData struct { Package string Files map[string][]byte FileNamesVar string FilesVar string } func main() { out := flag.String("out", "files.go", "output go `file`") pkg := flag.String("pkg", "main", "`package` name of the go file") filesVar := flag.String("files-var", "files", "name of the generated files slice") fileNamesVar := flag.String("file-names-var", "fileNames", "name of the generated file names slice") verbose := flag.Bool("verbose", false, "") flag.Usage = func() { fmt.Fprintf(os.Stderr, "Embedfiles embeds files in the paths into a map in a go file.\n\n") fmt.Fprintf(os.Stderr, "Usage:\n\n") fmt.Fprintf(os.Stderr, " embedfiles -out=files.go -pkg=main \n\n") fmt.Fprintf(os.Stderr, "Flags:\n\n") flag.PrintDefaults() } flag.Parse() inputPaths := flag.Args() if len(inputPaths) == 0 { flag.Usage() return } f, err := os.Create(*out) if err != nil { printErr("creating file", err) return } files := map[string][]byte{} for _, inputPath := range inputPaths { err = filepath.Walk(inputPath, func(path string, info os.FileInfo, err error) error { if err != nil { return fmt.Errorf("walking: %s", err) } if info.IsDir() { return nil } if *verbose { fmt.Printf("%s ", path) } contents, err := ioutil.ReadFile(path) if err != nil { return fmt.Errorf("reading file: %s", err) } if *verbose { fmt.Printf("(%d bytes)\n", len(contents)) } path = filepath.ToSlash(path) files[path] = contents return nil }) if err != nil { printErr("walking", err) return } } t, err := template.New("").Parse(tmpl) if err != nil { printErr("parsing template", err) return } buf := bytes.Buffer{} err = t.Execute(&buf, &tmplData{Package: *pkg, Files: files, FilesVar: *filesVar, FileNamesVar: *fileNamesVar}) if err != nil { printErr("generating code", err) return } formatted, err := format.Source(buf.Bytes()) if err != nil { printErr("formatting code", err) return } f.Write(formatted) err = f.Close() if err != nil { printErr("finalizing file", err) return } } func printErr(doing string, err error) { fmt.Fprintf(os.Stderr, "Error %s: %s\n", doing, err) }