import_from_translation_map.go 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. package parser
  2. import (
  3. "fmt"
  4. "go/ast"
  5. "go/format"
  6. go_parser "go/parser"
  7. "go/token"
  8. "os"
  9. go_path "path"
  10. "strings"
  11. )
  12. // compare the translation structs and translationsMap
  13. // update the new value from translationsMap
  14. // overwrite new content to files
  15. func ImportFromTranslationsMap(projectPath string, translationsMap map[string]map[string]string) (err error) {
  16. fset := token.NewFileSet()
  17. pkgs, err := ParseDir(fset, projectPath, nil, go_parser.AllErrors)
  18. if err != nil {
  19. return
  20. }
  21. visitor, err := newVisitorAndWalk(fset, pkgs, projectPath)
  22. if err != nil {
  23. return
  24. }
  25. var isChanged bool
  26. for path, pkg := range pkgs {
  27. pkgName := strings.TrimPrefix(path, strings.TrimSuffix(visitor.projectParentPath, "/")+"/")
  28. for fileName, f := range pkg.Files {
  29. var isModifiedFile bool
  30. for _, decl := range f.Decls {
  31. if decl, ok := decl.(*ast.GenDecl); ok {
  32. for _, spec := range decl.Specs {
  33. if spec, ok := spec.(*ast.ValueSpec); ok {
  34. var isMessage bool
  35. var locale string
  36. var structName string
  37. for _, name := range spec.Names {
  38. if l, exist := visitor.LocalesMap[name.Name]; exist {
  39. if _, exist := translationsMap[l]; exist {
  40. locale = l
  41. structName = name.Name
  42. isMessage = true
  43. break
  44. }
  45. }
  46. }
  47. if isMessage {
  48. isMessage = false
  49. for _, messageStruct := range visitor.RigisterMap[locale] {
  50. if messageStruct.PkgName == pkgName && messageStruct.StructName == structName {
  51. isMessage = true
  52. break
  53. }
  54. }
  55. }
  56. if !isMessage {
  57. continue
  58. }
  59. for _, values := range spec.Values {
  60. unaryExpr, ok := values.(*ast.UnaryExpr)
  61. if !ok {
  62. isMessage = false
  63. break
  64. }
  65. x, ok := unaryExpr.X.(*ast.CompositeLit)
  66. if !ok {
  67. isMessage = false
  68. break
  69. }
  70. for _, elt := range x.Elts {
  71. keyValueExpr, ok := elt.(*ast.KeyValueExpr)
  72. if !ok {
  73. isMessage = false
  74. break
  75. }
  76. key, ok := keyValueExpr.Key.(*ast.Ident)
  77. if !ok {
  78. isMessage = false
  79. break
  80. }
  81. value, ok := keyValueExpr.Value.(*ast.BasicLit)
  82. if !ok {
  83. isMessage = false
  84. break
  85. }
  86. if translationValue, exist := translationsMap[locale][getTranslationMapKey(path, key.Name, projectPath)]; isMessage && exist && value.Value != "\""+translationValue+"\"" {
  87. fmt.Printf(`
  88. ----------------------------------------------
  89. update translation:
  90. %s
  91. from:
  92. %s
  93. to:
  94. %s
  95. ----------------------------------------------
  96. `, go_path.Join(fileName, structName, key.Name), value.Value, "\""+translationValue+"\"")
  97. value.Value = "\"" + translationValue + "\""
  98. isModifiedFile = true
  99. isChanged = true
  100. }
  101. }
  102. }
  103. }
  104. }
  105. }
  106. }
  107. // overwrite new content to file
  108. if isModifiedFile {
  109. file, err := os.Create(fileName)
  110. defer file.Close()
  111. if err != nil {
  112. return err
  113. }
  114. err = format.Node(file, fset, f)
  115. if err != nil {
  116. return err
  117. }
  118. }
  119. }
  120. }
  121. if !isChanged {
  122. fmt.Printf(`
  123. ----------------------------------------------
  124. update translation:
  125. nothing changed
  126. `)
  127. }
  128. return nil
  129. }