genassets.go 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. // Copyright (C) 2014 The Syncthing Authors.
  2. //
  3. // This Source Code Form is subject to the terms of the Mozilla Public
  4. // License, v. 2.0. If a copy of the MPL was not distributed with this file,
  5. // You can obtain one at https://mozilla.org/MPL/2.0/.
  6. // +build ignore
  7. package main
  8. import (
  9. "bytes"
  10. "compress/gzip"
  11. "flag"
  12. "fmt"
  13. "go/format"
  14. "io"
  15. "os"
  16. "path/filepath"
  17. "strconv"
  18. "strings"
  19. "text/template"
  20. "time"
  21. )
  22. var tpl = template.Must(template.New("assets").Parse(`// Code generated by genassets.go - DO NOT EDIT.
  23. package auto
  24. const Generated int64 = {{.Generated}}
  25. func Assets() map[string][]byte {
  26. var assets = make(map[string][]byte, {{.Assets | len}})
  27. {{range $asset := .Assets}}
  28. assets["{{$asset.Name}}"] = {{$asset.Data}}{{end}}
  29. return assets
  30. }
  31. `))
  32. type asset struct {
  33. Name string
  34. Data string
  35. }
  36. var assets []asset
  37. func walkerFor(basePath string) filepath.WalkFunc {
  38. return func(name string, info os.FileInfo, err error) error {
  39. if err != nil {
  40. return err
  41. }
  42. if strings.HasPrefix(filepath.Base(name), ".") {
  43. // Skip dotfiles
  44. return nil
  45. }
  46. if info.Mode().IsRegular() {
  47. fd, err := os.Open(name)
  48. if err != nil {
  49. return err
  50. }
  51. var buf bytes.Buffer
  52. gw := gzip.NewWriter(&buf)
  53. io.Copy(gw, fd)
  54. fd.Close()
  55. gw.Flush()
  56. gw.Close()
  57. name, _ = filepath.Rel(basePath, name)
  58. assets = append(assets, asset{
  59. Name: filepath.ToSlash(name),
  60. Data: fmt.Sprintf("[]byte(%q)", buf.String()),
  61. })
  62. }
  63. return nil
  64. }
  65. }
  66. type templateVars struct {
  67. Assets []asset
  68. Generated int64
  69. }
  70. func main() {
  71. outfile := flag.String("o", "", "Name of output file (default stdout)")
  72. flag.Parse()
  73. filepath.Walk(flag.Arg(0), walkerFor(flag.Arg(0)))
  74. var buf bytes.Buffer
  75. // Generated time is now, except if the SOURCE_DATE_EPOCH environment
  76. // variable is set (for reproducible builds).
  77. generated := time.Now().Unix()
  78. if s, _ := strconv.ParseInt(os.Getenv("SOURCE_DATE_EPOCH"), 10, 64); s > 0 {
  79. generated = s
  80. }
  81. tpl.Execute(&buf, templateVars{
  82. Assets: assets,
  83. Generated: generated,
  84. })
  85. bs, err := format.Source(buf.Bytes())
  86. if err != nil {
  87. fmt.Fprintln(os.Stderr, err)
  88. os.Exit(1)
  89. }
  90. out := io.Writer(os.Stdout)
  91. if *outfile != "" {
  92. out, err = os.Create(*outfile)
  93. if err != nil {
  94. fmt.Fprintln(os.Stderr, err)
  95. os.Exit(1)
  96. }
  97. }
  98. out.Write(bs)
  99. }