golang101-embed.go 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. //go:build go1.16
  2. // +build go1.16
  3. package main
  4. import (
  5. "embed"
  6. //"errors"
  7. "fmt"
  8. "html/template"
  9. "io/fs"
  10. "log"
  11. "net/http"
  12. "os"
  13. "path"
  14. "path/filepath"
  15. "time"
  16. )
  17. //go:embed web
  18. //go:embed pages
  19. var allFiles embed.FS
  20. var staticFilesHandler = func() http.Handler {
  21. if wdIsGo101ProjectRoot {
  22. return staticFilesHandler_NonEmbedding
  23. }
  24. staticFiles, err := fs.Sub(allFiles, path.Join("web", "static"))
  25. if err != nil {
  26. panic(fmt.Sprintf("construct static file system error: %s", err))
  27. }
  28. return http.FileServer(http.FS(staticFiles))
  29. }()
  30. func collectPageGroups() map[string]*PageGroup {
  31. if wdIsGo101ProjectRoot {
  32. return collectPageGroups_NonEmbedding()
  33. }
  34. entries, err := fs.ReadDir(allFiles, "pages")
  35. if err != nil {
  36. panic("collect page groups (embedding) error: " + err.Error())
  37. }
  38. pageGroups := make(map[string]*PageGroup, len(entries))
  39. for _, e := range entries {
  40. if e.IsDir() {
  41. group, handler := e.Name(), dummyHandler
  42. resFiles, err := fs.Sub(allFiles, path.Join("pages", e.Name(), "res"))
  43. if err == nil {
  44. var urlGroup string
  45. // For history reason, fundamentals pages uses "/article/xxx" URLs.
  46. if group == "fundamentals" {
  47. urlGroup = "/article"
  48. } else if group != "website" {
  49. urlGroup = "/" + group
  50. }
  51. handler = http.StripPrefix(urlGroup+"/res/", http.FileServer(http.FS(resFiles)))
  52. } else if !os.IsNotExist(err) { // !errors.Is(err, os.ErrNotExist) {
  53. log.Println(err)
  54. }
  55. pageGroups[group] = &PageGroup{resHandler: handler}
  56. }
  57. }
  58. return pageGroups
  59. }
  60. func loadArticleFile(group, file string) ([]byte, error) {
  61. if wdIsGo101ProjectRoot {
  62. return loadArticleFile_NonEmbedding(group, file)
  63. }
  64. content, err := allFiles.ReadFile(path.Join("pages", group, file))
  65. if err != nil {
  66. return nil, err
  67. }
  68. return content, nil
  69. }
  70. func parseTemplate(commonPaths []string, files ...string) *template.Template {
  71. if wdIsGo101ProjectRoot {
  72. return parseTemplate_NonEmbedding(commonPaths, files...)
  73. }
  74. cp := path.Join(commonPaths...)
  75. ts := make([]string, len(files))
  76. for i, f := range files {
  77. ts[i] = path.Join(cp, f)
  78. }
  79. return template.Must(template.ParseFS(allFiles, ts...))
  80. }
  81. func updateGolang101() {
  82. if wdIsGo101ProjectRoot {
  83. updateGolang101_NonEmbedding()
  84. return
  85. }
  86. if _, err := os.Stat(filepath.Join(".", "golang101.go")); err == nil {
  87. pullGolang101Project("")
  88. return
  89. }
  90. if filepath.Base(os.Args[0]) == "golang101" {
  91. log.Println("go", "install", "go101.org/golang101@latest")
  92. output, err := runShellCommand(time.Minute/2, "", "go", "install", "go101.org/golang101@latest")
  93. if err != nil {
  94. log.Printf("error: %s\n%s", err, output)
  95. } else {
  96. log.Printf("done.")
  97. }
  98. }
  99. // no ideas how to update
  100. }