github.com/asifdxtreme/cli@v6.1.3-0.20150123051144-9ead8700b4ae+incompatible/bin/remove-unused-translations.go (about) 1 package main 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "go/ast" 7 "go/parser" 8 "go/token" 9 "io/ioutil" 10 "os" 11 "path/filepath" 12 ) 13 14 // NB: this assumes that translation strings are globally unique 15 // as of the day we wrote this, they are not unique 16 func main() { 17 walkTranslationFilesAndPromptUser() 18 } 19 20 func walkTranslationFilesAndPromptUser() { 21 stringsFromCode := readSourceCode() 22 23 dir := "cf/i18n/resources" 24 filepath.Walk(dir, func(path string, info os.FileInfo, err error) error { 25 if err != nil { 26 panic(err.Error()) 27 } 28 29 if info.IsDir() { 30 return nil 31 } 32 33 if filepath.Ext(info.Name()) != ".json" { 34 return nil 35 } 36 37 file, err := os.Open(path) 38 if err != nil { 39 panic(err.Error()) 40 } 41 data, err := ioutil.ReadAll(file) 42 if err != nil { 43 panic(err.Error()) 44 } 45 maps := []map[string]string{} 46 err = json.Unmarshal(data, &maps) 47 if err != nil { 48 panic(err.Error()) 49 } 50 51 indicesToRemove := []int{} 52 for index, tmap := range maps { 53 str := tmap["id"] 54 55 foundStr := false 56 for _, codeStr := range stringsFromCode { 57 if codeStr == str { 58 foundStr = true 59 break 60 } 61 } 62 63 if !foundStr { 64 fmt.Printf("Did not find this string in the source code:\n") 65 fmt.Printf("'%s'\n", str) 66 println() 67 68 answer := "" 69 fmt.Printf("Would you like to delete it from %s? [y|n]", path) 70 fmt.Fscanln(os.Stdin, &answer) 71 72 if answer == "y" { 73 indicesToRemove = append(indicesToRemove, index) 74 } 75 } 76 } 77 78 if len(indicesToRemove) > 0 { 79 println("Removing", len(indicesToRemove), "translations from", path) 80 81 newMaps := []map[string]string{} 82 for i, mapp := range maps { 83 84 foundIndex := false 85 for _, index := range indicesToRemove { 86 if index == i { 87 foundIndex = true 88 break 89 } 90 } 91 92 if !foundIndex { 93 newMaps = append(newMaps, mapp) 94 } 95 } 96 97 bytes, err := json.Marshal(newMaps) // consider json.MarshalIndent 98 if err != nil { 99 panic(err.Error()) 100 } 101 102 newFile, err := os.Create(path) 103 if err != nil { 104 panic(err.Error()) 105 } 106 107 _, err = newFile.Write(bytes) 108 if err != nil { 109 panic(err.Error()) 110 } 111 } 112 113 return nil 114 }) 115 } 116 117 func readSourceCode() []string { 118 strings := []string{} 119 120 dir, err := os.Getwd() 121 if err != nil { 122 panic(err.Error()) 123 } 124 125 filepath.Walk(dir, func(path string, info os.FileInfo, err error) error { 126 if err != nil { 127 panic(err.Error()) 128 } 129 130 if info.IsDir() { 131 return nil 132 } 133 134 if filepath.Ext(info.Name()) != ".go" { 135 return nil 136 } 137 138 fileSet := token.NewFileSet() 139 astFile, err := parser.ParseFile(fileSet, path, nil, 0) 140 if err != nil { 141 panic(err.Error()) 142 } 143 144 for _, declaration := range astFile.Decls { 145 ast.Inspect(declaration, func(node ast.Node) bool { 146 callExpr, ok := node.(*ast.CallExpr) 147 if !ok { 148 return true 149 } 150 151 funcNode, ok := callExpr.Fun.(*ast.Ident) 152 if !ok { 153 return true 154 } 155 156 if funcNode.Name != "T" { 157 return true 158 } 159 160 firstArg := callExpr.Args[0] 161 162 argAsString, ok := firstArg.(*ast.BasicLit) 163 if !ok { 164 return true 165 } 166 167 // remove quotes around string literal 168 end := len(argAsString.Value) - 1 169 strings = append(strings, argAsString.Value[1:end]) 170 return true 171 }) 172 } 173 174 return nil 175 }) 176 177 return strings 178 }