| OLD | NEW |
| (Empty) |
| 1 #!/usr/bin/env python | |
| 2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | |
| 3 # Use of this source code is governed by a BSD-style license that can be | |
| 4 # found in the LICENSE file. | |
| 5 | |
| 6 """Command processor for GRIT. This is the script you invoke to run the various | |
| 7 GRIT tools. | |
| 8 """ | |
| 9 | |
| 10 import os | |
| 11 import sys | |
| 12 if __name__ == '__main__': | |
| 13 sys.path.append(os.path.join(os.path.dirname(__file__), '..')) | |
| 14 | |
| 15 import getopt | |
| 16 | |
| 17 from grit import util | |
| 18 | |
| 19 import grit.extern.FP | |
| 20 | |
| 21 # Tool info factories; these import only within each factory to avoid | |
| 22 # importing most of the GRIT code until required. | |
| 23 def ToolFactoryBuild(): | |
| 24 import grit.tool.build | |
| 25 return grit.tool.build.RcBuilder() | |
| 26 | |
| 27 def ToolFactoryBuildInfo(): | |
| 28 import grit.tool.buildinfo | |
| 29 return grit.tool.buildinfo.DetermineBuildInfo() | |
| 30 | |
| 31 def ToolFactoryCount(): | |
| 32 import grit.tool.count | |
| 33 return grit.tool.count.CountMessage() | |
| 34 | |
| 35 def ToolFactoryDiffStructures(): | |
| 36 import grit.tool.diff_structures | |
| 37 return grit.tool.diff_structures.DiffStructures() | |
| 38 | |
| 39 def ToolFactoryMenuTranslationsFromParts(): | |
| 40 import grit.tool.menu_from_parts | |
| 41 return grit.tool.menu_from_parts.MenuTranslationsFromParts() | |
| 42 | |
| 43 def ToolFactoryNewGrd(): | |
| 44 import grit.tool.newgrd | |
| 45 return grit.tool.newgrd.NewGrd() | |
| 46 | |
| 47 def ToolFactoryResizeDialog(): | |
| 48 import grit.tool.resize | |
| 49 return grit.tool.resize.ResizeDialog() | |
| 50 | |
| 51 def ToolFactoryRc2Grd(): | |
| 52 import grit.tool.rc2grd | |
| 53 return grit.tool.rc2grd.Rc2Grd() | |
| 54 | |
| 55 def ToolFactoryTest(): | |
| 56 import grit.tool.test | |
| 57 return grit.tool.test.TestTool() | |
| 58 | |
| 59 def ToolFactoryTranslationToTc(): | |
| 60 import grit.tool.transl2tc | |
| 61 return grit.tool.transl2tc.TranslationToTc() | |
| 62 | |
| 63 def ToolFactoryUnit(): | |
| 64 import grit.tool.unit | |
| 65 return grit.tool.unit.UnitTestTool() | |
| 66 | |
| 67 def ToolFactoryXmb(): | |
| 68 import grit.tool.xmb | |
| 69 return grit.tool.xmb.OutputXmb() | |
| 70 | |
| 71 def ToolAndroid2Grd(): | |
| 72 import grit.tool.android2grd | |
| 73 return grit.tool.android2grd.Android2Grd() | |
| 74 | |
| 75 # Keys for the following map | |
| 76 _FACTORY = 1 | |
| 77 _REQUIRES_INPUT = 2 | |
| 78 _HIDDEN = 3 # optional key - presence indicates tool is hidden | |
| 79 | |
| 80 # Maps tool names to the tool's module. Done as a list of (key, value) tuples | |
| 81 # instead of a map to preserve ordering. | |
| 82 _TOOLS = [ | |
| 83 ['build', { _FACTORY : ToolFactoryBuild, _REQUIRES_INPUT : True }], | |
| 84 ['buildinfo', { _FACTORY : ToolFactoryBuildInfo, _REQUIRES_INPUT : True }], | |
| 85 ['count', { _FACTORY : ToolFactoryCount, _REQUIRES_INPUT : True }], | |
| 86 ['menufromparts', { | |
| 87 _FACTORY: ToolFactoryMenuTranslationsFromParts, | |
| 88 _REQUIRES_INPUT : True, _HIDDEN : True }], | |
| 89 ['newgrd', { _FACTORY : ToolFactoryNewGrd, _REQUIRES_INPUT : False }], | |
| 90 ['rc2grd', { _FACTORY : ToolFactoryRc2Grd, _REQUIRES_INPUT : False }], | |
| 91 ['resize', { | |
| 92 _FACTORY : ToolFactoryResizeDialog, _REQUIRES_INPUT : True }], | |
| 93 ['sdiff', { _FACTORY : ToolFactoryDiffStructures, | |
| 94 _REQUIRES_INPUT : False }], | |
| 95 ['test', { | |
| 96 _FACTORY: ToolFactoryTest, _REQUIRES_INPUT : True, | |
| 97 _HIDDEN : True }], | |
| 98 ['transl2tc', { _FACTORY : ToolFactoryTranslationToTc, | |
| 99 _REQUIRES_INPUT : False }], | |
| 100 ['unit', { _FACTORY : ToolFactoryUnit, _REQUIRES_INPUT : False }], | |
| 101 ['xmb', { _FACTORY : ToolFactoryXmb, _REQUIRES_INPUT : True }], | |
| 102 ['android2grd', { | |
| 103 _FACTORY: ToolAndroid2Grd, | |
| 104 _REQUIRES_INPUT : False }], | |
| 105 ] | |
| 106 | |
| 107 | |
| 108 def PrintUsage(): | |
| 109 tool_list = '' | |
| 110 for (tool, info) in _TOOLS: | |
| 111 if not _HIDDEN in info.keys(): | |
| 112 tool_list += ' %-12s %s\n' % (tool, info[_FACTORY]().ShortDescription()
) | |
| 113 | |
| 114 # TODO(joi) Put these back into the usage when appropriate: | |
| 115 # | |
| 116 # -d Work disconnected. This causes GRIT not to attempt connections with | |
| 117 # e.g. Perforce. | |
| 118 # | |
| 119 # -c Use the specified Perforce CLIENT when talking to Perforce. | |
| 120 print """GRIT - the Google Resource and Internationalization Tool | |
| 121 | |
| 122 Usage: grit [GLOBALOPTIONS] TOOL [args to tool] | |
| 123 | |
| 124 Global options: | |
| 125 | |
| 126 -i INPUT Specifies the INPUT file to use (a .grd file). If this is not | |
| 127 specified, GRIT will look for the environment variable GRIT_INPUT. | |
| 128 If it is not present either, GRIT will try to find an input file | |
| 129 named 'resource.grd' in the current working directory. | |
| 130 | |
| 131 -h MODULE Causes GRIT to use MODULE.UnsignedFingerPrint instead of | |
| 132 grit.extern.FP.UnsignedFingerprint. MODULE must be | |
| 133 available somewhere in the PYTHONPATH search path. | |
| 134 | |
| 135 -v Print more verbose runtime information. | |
| 136 | |
| 137 -x Print extremely verbose runtime information. Implies -v | |
| 138 | |
| 139 -p FNAME Specifies that GRIT should profile its execution and output the | |
| 140 results to the file FNAME. | |
| 141 | |
| 142 Tools: | |
| 143 | |
| 144 TOOL can be one of the following: | |
| 145 %s | |
| 146 For more information on how to use a particular tool, and the specific | |
| 147 arguments you can send to that tool, execute 'grit help TOOL' | |
| 148 """ % (tool_list) | |
| 149 | |
| 150 | |
| 151 class Options(object): | |
| 152 """Option storage and parsing.""" | |
| 153 | |
| 154 def __init__(self): | |
| 155 self.disconnected = False | |
| 156 self.client = '' | |
| 157 self.hash = None | |
| 158 self.input = None | |
| 159 self.verbose = False | |
| 160 self.extra_verbose = False | |
| 161 self.output_stream = sys.stdout | |
| 162 self.profile_dest = None | |
| 163 self.psyco = False | |
| 164 | |
| 165 def ReadOptions(self, args): | |
| 166 """Reads options from the start of args and returns the remainder.""" | |
| 167 (opts, args) = getopt.getopt(args, 'g:qdvxc:i:p:h:', ('psyco',)) | |
| 168 for (key, val) in opts: | |
| 169 if key == '-d': self.disconnected = True | |
| 170 elif key == '-c': self.client = val | |
| 171 elif key == '-h': self.hash = val | |
| 172 elif key == '-i': self.input = val | |
| 173 elif key == '-v': | |
| 174 self.verbose = True | |
| 175 util.verbose = True | |
| 176 elif key == '-x': | |
| 177 self.verbose = True | |
| 178 util.verbose = True | |
| 179 self.extra_verbose = True | |
| 180 util.extra_verbose = True | |
| 181 elif key == '-p': self.profile_dest = val | |
| 182 elif key == '--psyco': self.psyco = True | |
| 183 | |
| 184 if not self.input: | |
| 185 if 'GRIT_INPUT' in os.environ: | |
| 186 self.input = os.environ['GRIT_INPUT'] | |
| 187 else: | |
| 188 self.input = 'resource.grd' | |
| 189 | |
| 190 return args | |
| 191 | |
| 192 def __repr__(self): | |
| 193 return '(disconnected: %d, verbose: %d, client: %s, input: %s)' % ( | |
| 194 self.disconnected, self.verbose, self.client, self.input) | |
| 195 | |
| 196 | |
| 197 def _GetToolInfo(tool): | |
| 198 """Returns the info map for the tool named 'tool' or None if there is no | |
| 199 such tool.""" | |
| 200 matches = [t for t in _TOOLS if t[0] == tool] | |
| 201 if not matches: | |
| 202 return None | |
| 203 else: | |
| 204 return matches[0][1] | |
| 205 | |
| 206 | |
| 207 def Main(args): | |
| 208 """Parses arguments and does the appropriate thing.""" | |
| 209 util.ChangeStdoutEncoding() | |
| 210 | |
| 211 if sys.version_info < (2, 6): | |
| 212 print "GRIT requires Python 2.6 or later." | |
| 213 return 2 | |
| 214 elif not args or (len(args) == 1 and args[0] == 'help'): | |
| 215 PrintUsage() | |
| 216 return 0 | |
| 217 elif len(args) == 2 and args[0] == 'help': | |
| 218 tool = args[1].lower() | |
| 219 if not _GetToolInfo(tool): | |
| 220 print "No such tool. Try running 'grit help' for a list of tools." | |
| 221 return 2 | |
| 222 | |
| 223 print ("Help for 'grit %s' (for general help, run 'grit help'):\n" | |
| 224 % (tool)) | |
| 225 print _GetToolInfo(tool)[_FACTORY]().__doc__ | |
| 226 return 0 | |
| 227 else: | |
| 228 options = Options() | |
| 229 args = options.ReadOptions(args) # args may be shorter after this | |
| 230 if not args: | |
| 231 print "No tool provided. Try running 'grit help' for a list of tools." | |
| 232 return 2 | |
| 233 tool = args[0] | |
| 234 if not _GetToolInfo(tool): | |
| 235 print "No such tool. Try running 'grit help' for a list of tools." | |
| 236 return 2 | |
| 237 | |
| 238 try: | |
| 239 if _GetToolInfo(tool)[_REQUIRES_INPUT]: | |
| 240 os.stat(options.input) | |
| 241 except OSError: | |
| 242 print ('Input file %s not found.\n' | |
| 243 'To specify a different input file:\n' | |
| 244 ' 1. Use the GRIT_INPUT environment variable.\n' | |
| 245 ' 2. Use the -i command-line option. This overrides ' | |
| 246 'GRIT_INPUT.\n' | |
| 247 ' 3. Specify neither GRIT_INPUT or -i and GRIT will try to load ' | |
| 248 "'resource.grd'\n" | |
| 249 ' from the current directory.' % options.input) | |
| 250 return 2 | |
| 251 | |
| 252 if options.psyco: | |
| 253 # Psyco is a specializing JIT for Python. Early tests indicate that it | |
| 254 # could speed up GRIT (at the expense of more memory) for large GRIT | |
| 255 # compilations. See http://psyco.sourceforge.net/ | |
| 256 import psyco | |
| 257 psyco.profile() | |
| 258 | |
| 259 if options.hash: | |
| 260 grit.extern.FP.UseUnsignedFingerPrintFromModule(options.hash) | |
| 261 | |
| 262 toolobject = _GetToolInfo(tool)[_FACTORY]() | |
| 263 if options.profile_dest: | |
| 264 import hotshot | |
| 265 prof = hotshot.Profile(options.profile_dest) | |
| 266 prof.runcall(toolobject.Run, options, args[1:]) | |
| 267 else: | |
| 268 toolobject.Run(options, args[1:]) | |
| 269 | |
| 270 | |
| 271 if __name__ == '__main__': | |
| 272 sys.exit(Main(sys.argv[1:])) | |
| OLD | NEW |