init.go 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. package main
  2. import (
  3. "fmt"
  4. "log"
  5. "os"
  6. "path"
  7. "path/filepath"
  8. "strings"
  9. "github.com/AlecAivazis/survey"
  10. "github.com/urfave/cli"
  11. )
  12. var (
  13. // 允许建立项目的部门
  14. depts = map[string]bool{
  15. "main": true,
  16. "live": true,
  17. "openplatform": true,
  18. "search": true,
  19. "ep": true,
  20. "bbq": true,
  21. "video": true,
  22. "bplus": true,
  23. "ops": true,
  24. }
  25. // 允许建立的项目类型
  26. types = map[string]bool{
  27. "interface": true,
  28. "admin": true,
  29. "job": true,
  30. "service": true,
  31. }
  32. )
  33. const (
  34. _textModeFastInit = "一键初始化项目"
  35. _textModeInteraction = "自定义项目参数"
  36. _textYes = "是"
  37. _textNo = "否"
  38. )
  39. func runInit(ctx *cli.Context) (err error) {
  40. if ctx.NumFlags() == 0 {
  41. if err = interact(); err != nil {
  42. return
  43. }
  44. }
  45. if ok := check(); !ok {
  46. return nil
  47. }
  48. if err = create(); err != nil {
  49. println("项目初始化失败: ", err.Error())
  50. return nil
  51. }
  52. fmt.Printf(`项目初始化成功!
  53. 注意:请先创建rider、服务树节点、在配置中心创建uat环境配置文件,否则提交mr后无法运行单元测试!
  54. 相关帮助信息见 http://info.bilibili.co/pages/viewpage.action?pageId=7567510
  55. `)
  56. return nil
  57. }
  58. func initPwd() (ok bool) {
  59. pwd, err := os.Getwd()
  60. if err != nil {
  61. return
  62. }
  63. ps := strings.Split(pwd, string(os.PathSeparator))
  64. plen := len(ps)
  65. if plen < 3 {
  66. // 至少要有三个目录层级:部门、项目类型、项目名
  67. return
  68. }
  69. name := ps[plen-1]
  70. dept := ps[plen-2]
  71. typ := ps[plen-3]
  72. if !depts[dept] {
  73. return
  74. }
  75. if !types[typ] {
  76. return
  77. }
  78. if name == "" {
  79. return
  80. }
  81. p.Name = name
  82. p.Department = dept
  83. p.Type = typ
  84. p.Path = pwd
  85. return true
  86. }
  87. func check() (ok bool) {
  88. root, err := goPath()
  89. if err != nil || root == "" {
  90. log.Printf("can not read GOPATH, use ~/go as default GOPATH")
  91. root = path.Join(os.Getenv("HOME"), "go")
  92. }
  93. if !validate() {
  94. return
  95. }
  96. p.Path = fmt.Sprintf("%s/src/go-common/app/%s/%s/%s", strings.TrimRight(root, "/"), p.Type, p.Department, p.Name)
  97. return true
  98. }
  99. func goPath() (string, error) {
  100. gopaths := strings.Split(os.Getenv("GOPATH"), ":")
  101. if len(gopaths) == 1 {
  102. return gopaths[0], nil
  103. }
  104. pwd, err := os.Getwd()
  105. if err != nil {
  106. return "", err
  107. }
  108. abspwd, err := filepath.Abs(pwd)
  109. if err != nil {
  110. return "", err
  111. }
  112. for _, gp := range gopaths {
  113. absgp, err := filepath.Abs(gp)
  114. if err != nil {
  115. return "", err
  116. }
  117. if strings.HasPrefix(abspwd, absgp) {
  118. return absgp, nil
  119. }
  120. }
  121. return "", fmt.Errorf("can't found current gopath")
  122. }
  123. func interact() (err error) {
  124. qs1 := &survey.Select{
  125. Message: "你想怎么玩?",
  126. Options: []string{_textModeFastInit, _textModeInteraction},
  127. }
  128. var ans1 string
  129. if err = survey.AskOne(qs1, &ans1, nil); err != nil {
  130. return
  131. }
  132. switch ans1 {
  133. case _textModeFastInit:
  134. if ok := initPwd(); !ok {
  135. println("Notice: Not in project directory. Skipped fast init.")
  136. }
  137. return
  138. case _textModeInteraction:
  139. // go on
  140. default:
  141. return
  142. }
  143. var ds, ts []string
  144. for d := range depts {
  145. ds = append(ds, d)
  146. }
  147. for t := range types {
  148. ts = append(ts, t)
  149. }
  150. qs := []*survey.Question{
  151. {
  152. Name: "department",
  153. Prompt: &survey.Select{
  154. Message: "请选择选择部门:",
  155. Options: ds,
  156. Default: "main",
  157. },
  158. },
  159. {
  160. Name: "type",
  161. Prompt: &survey.Select{
  162. Message: "请选择项目类型:",
  163. Options: ts,
  164. },
  165. },
  166. {
  167. Name: "name",
  168. Prompt: &survey.Input{
  169. Message: "请输入项目名称:",
  170. },
  171. Validate: survey.Required,
  172. },
  173. {
  174. Name: "owner",
  175. Prompt: &survey.Input{
  176. Message: "请输入项目负责人:",
  177. },
  178. },
  179. {
  180. Name: "useGRPC",
  181. Prompt: &survey.Select{
  182. Message: "是否使用 gRPC ?",
  183. Options: []string{_textYes, _textNo},
  184. Default: _textNo,
  185. },
  186. },
  187. }
  188. ans := struct {
  189. Department string
  190. Type string
  191. Name string
  192. Owner string
  193. UseGRPC string
  194. }{}
  195. if err = survey.Ask(qs, &ans); err != nil {
  196. return
  197. }
  198. p.Name = ans.Name
  199. p.Department = ans.Department
  200. p.Type = ans.Type
  201. p.Owner = ans.Owner
  202. if ans.UseGRPC == _textYes {
  203. p.WithGRPC = true
  204. }
  205. return
  206. }