init.go 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300
  1. package commands
  2. import (
  3. "bufio"
  4. "fmt"
  5. "os"
  6. "strings"
  7. "git.eugeniocarvalho.dev/eugeniucarvalho/apicodegen/common"
  8. )
  9. var (
  10. project = common.NewProject()
  11. initHeaderText = `
  12. This utility will walk you through creating a project.json file.
  13. It only covers the most common items, and tries to guess sensible defaults.
  14. Press ^C at any time to quit.
  15. `
  16. questionFormats = map[bool]string{true: "%s: ", false: "%s: (%s) "}
  17. userInputQuestions = []struct {
  18. ask string
  19. inputType string
  20. value interface{}
  21. _default interface{}
  22. }{
  23. {
  24. "project name",
  25. "",
  26. &project.Name,
  27. "",
  28. },
  29. {
  30. "author",
  31. "",
  32. &project.OwnerName,
  33. "",
  34. },
  35. {
  36. "version",
  37. "",
  38. &project.Version,
  39. "0.0.1",
  40. },
  41. {
  42. "description",
  43. "",
  44. &project.Description,
  45. "",
  46. },
  47. // {
  48. // "git repository",
  49. // "",
  50. // &project.Custom["go.package.repository"],
  51. // "",
  52. // },
  53. }
  54. )
  55. func initialize() (err error) {
  56. if common.FileExists("project.json") {
  57. err = fmt.Errorf("This folder already contains a project.")
  58. return
  59. }
  60. if err = readInitialUserInputData(); err != nil {
  61. return
  62. }
  63. if err = initializeProjectPropertires(); err != nil {
  64. return
  65. }
  66. if err = initializeBaseFilesAndSamples(); err != nil {
  67. return
  68. }
  69. if err = createRootDirectories(); err != nil {
  70. return
  71. }
  72. return
  73. }
  74. func readInitialUserInputData() (err error) {
  75. reader := bufio.NewReader(os.Stdin)
  76. fmt.Println(initHeaderText)
  77. for _, question := range userInputQuestions {
  78. args := []interface{}{question.ask}
  79. hasDefault := !common.IsEmpty(question._default)
  80. if hasDefault {
  81. args = append(args, question._default)
  82. }
  83. fmt.Printf(
  84. questionFormats[len(args) == 1],
  85. args...,
  86. )
  87. input, _ := reader.ReadString('\n')
  88. switch question.inputType {
  89. // case "int64":
  90. // case "float64":
  91. default:
  92. reference := question.value.(*string)
  93. input = strings.Replace(input, "\n", "", -1)
  94. if input == "" && hasDefault {
  95. input = question._default.(string)
  96. }
  97. *reference = input
  98. }
  99. }
  100. return
  101. }
  102. func initializeProjectPropertires() (err error) {
  103. project.ID = strings.ToLower(project.Name)
  104. return
  105. }
  106. func createRootDirectories() (err error) {
  107. three := []string{
  108. "build",
  109. EntitiesPath,
  110. ResourcesPath,
  111. EnvironmentPath,
  112. "include/go",
  113. }
  114. for index, path := range three {
  115. three[index] = basePathWithComplement(path)
  116. }
  117. err = common.Mkdir(0777, three...)
  118. return
  119. }
  120. func initializeBaseFilesAndSamples() (err error) {
  121. // Create main project description
  122. if err = common.WriteToJson(basePathWithComplement("project.json"), project); err != nil {
  123. return
  124. }
  125. if err = createEnvironmentFiles(); err != nil {
  126. return
  127. }
  128. if err = createQueriesFile(); err != nil {
  129. return
  130. }
  131. if err = createCommonFile(); err != nil {
  132. return
  133. }
  134. return
  135. }
  136. func createEnvironmentFiles() (err error) {
  137. var (
  138. environment = common.Environment{
  139. "APP_ADDRS": {
  140. Default: "",
  141. Required: true,
  142. Description: "Server address will listen for requests.",
  143. },
  144. }
  145. production = common.Environment{}
  146. test = common.Environment{}
  147. )
  148. // Create main project description
  149. if err = common.WriteToJson(basePathWithComplement("env/environment.json"), environment); err != nil {
  150. return
  151. }
  152. if err = common.WriteToJson(basePathWithComplement("env/environment.prod.json"), production); err != nil {
  153. return
  154. }
  155. if err = common.WriteToJson(basePathWithComplement("env/environment.prod.json"), test); err != nil {
  156. return
  157. }
  158. return
  159. }
  160. func createCommonFile() (err error) {
  161. commonProperties := `
  162. {
  163. "commonParams": {
  164. "userId": {
  165. "id": "userId",
  166. "type": "string",
  167. "description": "Identificação do usuário que esta realizando a consulta.",
  168. "default": "me",
  169. "required": true,
  170. "location": "path"
  171. },
  172. "resource": {
  173. "id": "resource",
  174. "type": "string",
  175. "description": "Identificação do recurso do conjunto de regras de acesso.",
  176. "required": true,
  177. "location": "path"
  178. },
  179. "id": {
  180. "id": "id",
  181. "type": "string",
  182. "description": "Identificação da conta de usuário consultado.",
  183. "required": true,
  184. "location": "path"
  185. },
  186. "fields": {
  187. "id": "fields",
  188. "type": "string",
  189. "description": "Identifica um subconjunto de campos do modelo.",
  190. "required": false,
  191. "location": "query"
  192. },
  193. "includeInTrash": {
  194. "id": "includeInTrash",
  195. "type": "bool",
  196. "description": "Especifica se a consulta deve levar em consideração os registros deletados.",
  197. "required": false,
  198. "location": "query",
  199. "accept": [
  200. "true"
  201. ]
  202. },
  203. "format": {
  204. "id": "format",
  205. "type": "string",
  206. "description": "Especifica configurações de campos predefinidas.",
  207. "required": false,
  208. "location": "query",
  209. "accept": [
  210. "minimal",
  211. "full"
  212. ]
  213. },
  214. "maxResults": {
  215. "id": "maxResults",
  216. "type": "int",
  217. "description": "Identifica a quantidade de itens retornados da consulta.",
  218. "required": false,
  219. "location": "query"
  220. },
  221. "q": {
  222. "id": "q",
  223. "type": "string",
  224. "description": "Filtra as entidades de acordo com o criterio.",
  225. "required": false,
  226. "location": "query"
  227. },
  228. "nextPageToken": {
  229. "id": "nextPageToken",
  230. "type": "string",
  231. "description": "Token para consultar a proxima pagina contendo a lista de resultados.",
  232. "required": false,
  233. "location": "query"
  234. }
  235. }
  236. }`
  237. if err = common.FilePutContents(
  238. basePathWithComplement("common.json"),
  239. commonProperties,
  240. 0777,
  241. ); err != nil {
  242. return
  243. }
  244. return
  245. }
  246. func createQueriesFile() (err error) {
  247. template := `
  248. {
  249. "common": {
  250. "@mongo.empty": "{}",
  251. "@mongo.undelete": "{\"_id\":{\"$oid\":\"{{.id}}\"}}",
  252. "@mongo.listWithACL": "{\"$and\":[{ \"permissions.user._id\": \"{{.user}}\", \"deleted\": {{._deleted_}}},{{._transclude_}}]}",
  253. "@mongo.getWithACL": "{\"_id\":{\"$oid\":\"{{.id}}\"},\"permissions.user._id\":\"{{.user}}\",\"deleted\": {{._deleted_}}}",
  254. "@mongo.list": "{\"$and\":[{ \"deleted\": {{._deleted_}}},{{._transclude_}}]}",
  255. "@mongo.get": "{\"_id\":{\"$oid\":\"{{.id}}\"},\"deleted\": {{._deleted_}}}"
  256. },
  257. "queries": {}
  258. }`
  259. err = common.FilePutContents(
  260. basePathWithComplement("queries.json"),
  261. template,
  262. 0777,
  263. )
  264. return
  265. }