main.go 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. package main
  2. import (
  3. "embed"
  4. "fmt"
  5. "io/fs"
  6. "os"
  7. "os/exec"
  8. "path/filepath"
  9. "strings"
  10. "github.com/fatih/color"
  11. "github.com/manifoldco/promptui"
  12. )
  13. //go:embed admin-template
  14. var adminBox embed.FS
  15. //go:embed bare-template
  16. var bareBox embed.FS
  17. //go:embed website-template
  18. var websiteBox embed.FS
  19. const TIPS = "\nRun the following command to start your App:"
  20. func main() {
  21. validateFileExists := func(input string) error {
  22. dir := filepath.Base(input)
  23. _, err := os.Stat(dir)
  24. if err == nil {
  25. return fmt.Errorf("%s already exists, remove it first to generate.\n", err)
  26. }
  27. return nil
  28. }
  29. prompt := promptui.Prompt{
  30. Label: "Go Package",
  31. AllowEdit: true,
  32. Default: "github.com/theplant/myadmin",
  33. }
  34. pkg, err := prompt.Run()
  35. if err != nil {
  36. panic(err)
  37. }
  38. if err = validateFileExists(pkg); err != nil {
  39. sel := promptui.Select{
  40. Label: "Directory exists, Overwrite?",
  41. Items: []string{
  42. "Yes",
  43. "No",
  44. },
  45. }
  46. result, _, _ := sel.Run()
  47. if result != 0 {
  48. return
  49. }
  50. }
  51. templateSel := promptui.Select{
  52. Label: "Select a template",
  53. Items: []string{
  54. "Admin: Content Management System",
  55. "Website: Content Management System with Website Examples",
  56. "Bare: Simplest Workable Web App",
  57. },
  58. }
  59. result, _, _ := templateSel.Run()
  60. dir := filepath.Base(pkg)
  61. err = os.MkdirAll(dir, 0755)
  62. if err != nil {
  63. panic(err)
  64. }
  65. switch result {
  66. case 0:
  67. copyAndReplaceFiles(adminBox, dir, "admin-template", pkg)
  68. fmt.Println(TIPS)
  69. color.Magenta("cd %s && docker-compose up -d && source dev_env && go run main.go\n", dir)
  70. case 1:
  71. copyAndReplaceFiles(websiteBox, dir, "website-template", pkg)
  72. fmt.Println(TIPS)
  73. color.Magenta("cd %s && docker-compose up -d && source dev_env && go run main.go\n", dir)
  74. case 2:
  75. copyAndReplaceFiles(bareBox, dir, "bare-template", pkg)
  76. fmt.Println(TIPS)
  77. color.Magenta("cd %s && go run main.go\n", dir)
  78. default:
  79. panic(fmt.Errorf("wrong option"))
  80. }
  81. return
  82. }
  83. func copyAndReplaceFiles(box embed.FS, dir string, template string, pkg string) {
  84. var err error
  85. fs.WalkDir(box, template, func(path string, d fs.DirEntry, err1 error) error {
  86. if d != nil && d.IsDir() {
  87. return nil
  88. }
  89. newPath := strings.ReplaceAll(path, template+"/", "")
  90. fp := filepath.Join(dir, newPath)
  91. err := os.MkdirAll(filepath.Dir(fp), 0755)
  92. if err != nil {
  93. panic(err)
  94. }
  95. var f *os.File
  96. f, err = os.Create(fp)
  97. if err != nil {
  98. panic(err)
  99. }
  100. defer f.Close()
  101. content, err := box.ReadFile(path)
  102. if err != nil {
  103. panic(err)
  104. }
  105. err = os.WriteFile(fp, []byte(content), 0644)
  106. if err != nil {
  107. panic(err)
  108. }
  109. fmt.Println(fp, "generated")
  110. return err
  111. })
  112. fmt.Println("Done")
  113. replaceInFiles(dir, "github.com/qor5/docs/cmd/qor5/"+template, pkg)
  114. replaceInFiles(dir, "QOR5PackageName", dir)
  115. if _, err = os.Stat(filepath.Join(dir, "go.mod")); err != nil {
  116. runCmd(dir, "go", "mod", "init", pkg)
  117. runCmd(dir, "go", "get", "./...")
  118. }
  119. return
  120. }
  121. func runCmd(dir string, name string, args ...string) {
  122. cmdGet := exec.Command(name, args...)
  123. cmdGet.Dir = dir
  124. cmdGet.Stdout = os.Stdout
  125. cmdGet.Stderr = os.Stderr
  126. err := cmdGet.Run()
  127. if err != nil {
  128. panic(err)
  129. }
  130. }
  131. func replaceInFiles(baseDir string, from, to string) {
  132. var fileList []string
  133. err := filepath.Walk(baseDir, func(path string, f os.FileInfo, err error) error {
  134. if !f.IsDir() {
  135. fileList = append(fileList, path)
  136. }
  137. return nil
  138. })
  139. if err != nil {
  140. panic(err)
  141. }
  142. for _, file := range fileList {
  143. replaceInFile(file, from, to)
  144. }
  145. }
  146. func replaceInFile(filepath, from, to string) {
  147. read, err := os.ReadFile(filepath)
  148. if err != nil {
  149. panic(err)
  150. }
  151. newContents := strings.Replace(string(read), from, to, -1)
  152. // fmt.Println(newContents)
  153. err = os.WriteFile(filepath, []byte(newContents), 0)
  154. if err != nil {
  155. panic(err)
  156. }
  157. }