blob: 8c8d637590235a3667c145fd0dc4a141ce1266bc [file] [log] [blame]
#!/usr/bin/env python3
# Copyright 2012 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Command processor for GRIT. This is the script you invoke to run the various
GRIT tools.
"""
import os
import sys
if __name__ == '__main__':
sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
import getopt
from grit import util
import grit.extern.FP
# Tool info factories; these import only within each factory to avoid
# importing most of the GRIT code until required.
def ToolFactoryBuild():
import grit.tool.build
return grit.tool.build.RcBuilder()
def ToolFactoryBuildInfo():
import grit.tool.buildinfo
return grit.tool.buildinfo.DetermineBuildInfo()
def ToolFactoryCount():
import grit.tool.count
return grit.tool.count.CountMessage()
def ToolFactoryDiffStructures():
import grit.tool.diff_structures
return grit.tool.diff_structures.DiffStructures()
def ToolFactoryMenuTranslationsFromParts():
import grit.tool.menu_from_parts
return grit.tool.menu_from_parts.MenuTranslationsFromParts()
def ToolFactoryNewGrd():
import grit.tool.newgrd
return grit.tool.newgrd.NewGrd()
def ToolFactoryResizeDialog():
import grit.tool.resize
return grit.tool.resize.ResizeDialog()
def ToolFactoryRc2Grd():
import grit.tool.rc2grd
return grit.tool.rc2grd.Rc2Grd()
def ToolFactoryTest():
import grit.tool.test
return grit.tool.test.TestTool()
def ToolFactoryTranslationToTc():
import grit.tool.transl2tc
return grit.tool.transl2tc.TranslationToTc()
def ToolFactoryUnit():
import grit.tool.unit
return grit.tool.unit.UnitTestTool()
def ToolFactoryUpdateResourceIds():
import grit.tool.update_resource_ids
return grit.tool.update_resource_ids.UpdateResourceIds()
def ToolFactoryXmb():
import grit.tool.xmb
return grit.tool.xmb.OutputXmb()
def ToolAndroid2Grd():
import grit.tool.android2grd
return grit.tool.android2grd.Android2Grd()
# Keys for the following map
_FACTORY = 1
_REQUIRES_INPUT = 2
_HIDDEN = 3 # optional key - presence indicates tool is hidden
# Maps tool names to the tool's module. Done as a list of (key, value) tuples
# instead of a map to preserve ordering.
_TOOLS = [
['android2grd', {
_FACTORY: ToolAndroid2Grd,
_REQUIRES_INPUT: False
}],
['build', {
_FACTORY: ToolFactoryBuild,
_REQUIRES_INPUT: True
}],
['buildinfo', {
_FACTORY: ToolFactoryBuildInfo,
_REQUIRES_INPUT: True
}],
['count', {
_FACTORY: ToolFactoryCount,
_REQUIRES_INPUT: True
}],
[
'menufromparts',
{
_FACTORY: ToolFactoryMenuTranslationsFromParts,
_REQUIRES_INPUT: True,
_HIDDEN: True
}
],
['newgrd', {
_FACTORY: ToolFactoryNewGrd,
_REQUIRES_INPUT: False
}],
['rc2grd', {
_FACTORY: ToolFactoryRc2Grd,
_REQUIRES_INPUT: False
}],
['resize', {
_FACTORY: ToolFactoryResizeDialog,
_REQUIRES_INPUT: True
}],
['sdiff', {
_FACTORY: ToolFactoryDiffStructures,
_REQUIRES_INPUT: False
}],
['test', {
_FACTORY: ToolFactoryTest,
_REQUIRES_INPUT: True,
_HIDDEN: True
}],
[
'transl2tc',
{
_FACTORY: ToolFactoryTranslationToTc,
_REQUIRES_INPUT: False
}
],
['unit', {
_FACTORY: ToolFactoryUnit,
_REQUIRES_INPUT: False
}],
[
'update_resource_ids',
{
_FACTORY: ToolFactoryUpdateResourceIds,
_REQUIRES_INPUT: False
}
],
['xmb', {
_FACTORY: ToolFactoryXmb,
_REQUIRES_INPUT: True
}],
]
def PrintUsage():
tool_list = ''
for (tool, info) in _TOOLS:
if not _HIDDEN in info:
tool_list += ' %-12s %s\n' % (
tool, info[_FACTORY]().ShortDescription())
print("""GRIT - the Google Resource and Internationalization Tool
Usage: grit [GLOBALOPTIONS] TOOL [args to tool]
Global options:
-i INPUT Specifies the INPUT file to use (a .grd file). If this is not
specified, GRIT will look for the environment variable GRIT_INPUT.
If it is not present either, GRIT will try to find an input file
named 'resource.grd' in the current working directory.
-h MODULE Causes GRIT to use MODULE.UnsignedFingerPrint instead of
grit.extern.FP.UnsignedFingerprint. MODULE must be
available somewhere in the PYTHONPATH search path.
-v Print more verbose runtime information.
-x Print extremely verbose runtime information. Implies -v
-p FNAME Specifies that GRIT should profile its execution and output the
results to the file FNAME.
Tools:
TOOL can be one of the following:
%s
For more information on how to use a particular tool, and the specific
arguments you can send to that tool, execute 'grit help TOOL'
""" % (tool_list))
class Options:
"""Option storage and parsing."""
def __init__(self):
self.hash = None
self.input = None
self.verbose = False
self.extra_verbose = False
self.output_stream = sys.stdout
self.profile_dest = None
def ReadOptions(self, args):
"""Reads options from the start of args and returns the remainder."""
(opts, args) = getopt.getopt(args, 'vxi:p:h:', ('help',))
for (key, val) in opts:
if key == '-h': self.hash = val
elif key == '-i': self.input = val
elif key == '-v':
self.verbose = True
util.verbose = True
elif key == '-x':
self.verbose = True
util.verbose = True
self.extra_verbose = True
util.extra_verbose = True
elif key == '-p': self.profile_dest = val
elif key == '--help':
PrintUsage()
sys.exit(0)
if not self.input:
if 'GRIT_INPUT' in os.environ:
self.input = os.environ['GRIT_INPUT']
else:
self.input = 'resource.grd'
return args
def __repr__(self):
return '(verbose: %d, input: %s)' % (
self.verbose, self.input)
def _GetToolInfo(tool):
"""Returns the info map for the tool named 'tool' or None if there is no
such tool."""
matches = [t for t in _TOOLS if t[0] == tool]
if not matches:
return None
else:
return matches[0][1]
def Main(args=None):
"""Parses arguments and does the appropriate thing."""
util.ChangeStdoutEncoding()
# Support for setuptools console wrappers.
if args is None:
args = sys.argv[1:]
options = Options()
try:
args = options.ReadOptions(args) # args may be shorter after this
except getopt.GetoptError as e:
print("grit:", str(e))
print("Try running 'grit help' for valid options.")
return 1
if not args:
print("No tool provided. Try running 'grit help' for a list of tools.")
return 2
tool = args[0]
if tool == 'help':
if len(args) == 1:
PrintUsage()
return 0
else:
tool = args[1]
if not _GetToolInfo(tool):
print("No such tool. Try running 'grit help' for a list of tools.")
return 2
print("Help for 'grit %s' (for general help, run 'grit help'):\n" %
(tool,))
_GetToolInfo(tool)[_FACTORY]().ShowUsage()
return 0
if not _GetToolInfo(tool):
print("No such tool. Try running 'grit help' for a list of tools.")
return 2
try:
if _GetToolInfo(tool)[_REQUIRES_INPUT]:
os.stat(options.input)
except OSError:
print('Input file %s not found.\n'
'To specify a different input file:\n'
' 1. Use the GRIT_INPUT environment variable.\n'
' 2. Use the -i command-line option. This overrides '
'GRIT_INPUT.\n'
' 3. Specify neither GRIT_INPUT or -i and GRIT will try to load '
"'resource.grd'\n"
' from the current directory.' % options.input)
return 2
if options.hash:
grit.extern.FP.UseUnsignedFingerPrintFromModule(options.hash)
try:
toolobject = _GetToolInfo(tool)[_FACTORY]()
if options.profile_dest:
import hotshot
prof = hotshot.Profile(options.profile_dest)
return prof.runcall(toolobject.Run, options, args[1:])
else:
return toolobject.Run(options, args[1:])
except getopt.GetoptError as e:
print("grit: %s: %s" % (tool, str(e)))
print("Try running 'grit help %s' for valid options." % (tool,))
return 1
if __name__ == '__main__':
sys.path.append(
os.path.join(
os.path.dirname(
os.path.dirname(os.path.dirname(os.path.abspath(__file__)))),
'diagnosis'))
try:
import crbug_1001171
with crbug_1001171.DumpStateOnLookupError():
sys.exit(Main(sys.argv[1:]))
except ImportError:
pass
sys.exit(Main(sys.argv[1:]))