| Index: grit_info.py
 | 
| ===================================================================
 | 
| --- grit_info.py	(revision 0)
 | 
| +++ grit_info.py	(revision 0)
 | 
| @@ -0,0 +1,240 @@
 | 
| +#!/usr/bin/python
 | 
| +# Copyright (c) 2011 The Chromium Authors. All rights reserved.
 | 
| +# Use of this source code is governed by a BSD-style license that can be
 | 
| +# found in the LICENSE file.
 | 
| +
 | 
| +'''Tool to determine inputs and outputs of a grit file.
 | 
| +'''
 | 
| +
 | 
| +import optparse
 | 
| +import os
 | 
| +import posixpath
 | 
| +import types
 | 
| +import sys
 | 
| +
 | 
| +from grit import grd_reader
 | 
| +from grit import util
 | 
| +
 | 
| +##############################################################################
 | 
| +# os.path.relpath is python 2.6 only. Some bots still run 2.5 only, so I took
 | 
| +# the relpath implementation from the python source.
 | 
| +# TODO(thakis): Once we're on 2.6 everywhere, remove this and use
 | 
| +# os.path.relpath directly.
 | 
| +
 | 
| +# http://docs.python.org/license.html
 | 
| +# PSF LICENSE AGREEMENT FOR PYTHON 2.7.1
 | 
| +#
 | 
| +# 1. This LICENSE AGREEMENT is between the Python Software Foundation ("PSF"),
 | 
| +# and the Individual or Organization ("Licensee") accessing and otherwise using
 | 
| +# Python 2.7.1 software in source or binary form and its associated
 | 
| +# documentation.
 | 
| +#
 | 
| +# 2. Subject to the terms and conditions of this License Agreement, PSF hereby
 | 
| +# grants Licensee a nonexclusive, royalty-free, world-wide license to reproduce,
 | 
| +# analyze, test, perform and/or display publicly, prepare derivative works,
 | 
| +# distribute, and otherwise use Python 2.7.1 alone or in any derivative version,
 | 
| +# provided, however, that PSF's License Agreement and PSF's notice of copyright,
 | 
| +# i.e., "Copyright c 2001-2010 Python Software Foundation; All Rights Reserved"
 | 
| +# are retained in Python 2.7.1 alone or in any derivative version prepared by
 | 
| +# Licensee.
 | 
| +#
 | 
| +# 3. In the event Licensee prepares a derivative work that is based on or
 | 
| +# incorporates Python 2.7.1 or any part thereof, and wants to make the
 | 
| +# derivative work available to others as provided herein, then Licensee hereby
 | 
| +# agrees to include in any such work a brief summary of the changes made to
 | 
| +# Python 2.7.1.
 | 
| +#
 | 
| +# 4. PSF is making Python 2.7.1 available to Licensee on an "AS IS" basis. PSF
 | 
| +# MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED. BY WAY OF EXAMPLE,
 | 
| +# BUT NOT LIMITATION, PSF MAKES NO AND DISCLAIMS ANY REPRESENTATION OR WARRANTY
 | 
| +# OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF
 | 
| +# PYTHON 2.7.1 WILL NOT INFRINGE ANY THIRD PARTY RIGHTS.
 | 
| +#
 | 
| +# 5.1 PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON 2.7.1 FOR
 | 
| +# ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS A RESULT OF
 | 
| +# MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON 2.7.1, OR ANY DERIVATIVE
 | 
| +# THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
 | 
| +#
 | 
| +# 6. This License Agreement will automatically terminate upon a material breach
 | 
| +# of its terms and conditions.
 | 
| +#
 | 
| +# 7. Nothing in this License Agreement shall be deemed to create any
 | 
| +# relationship of agency, partnership, or joint venture between PSF and
 | 
| +# Licensee. This License Agreement does not grant permission to use PSF
 | 
| +# trademarks or trade name in a trademark sense to endorse or promote products
 | 
| +# or services of Licensee, or any third party.
 | 
| +#
 | 
| +# 8. By copying, installing or otherwise using Python 2.7.1, Licensee agrees to
 | 
| +# be bound by the terms and conditions of this License Agreement.
 | 
| +
 | 
| +# http://svn.python.org/view/python/trunk/Lib/genericpath.py?view=markup
 | 
| +def commonprefix(m):
 | 
| +    "Given a list of pathnames, returns the longest common leading component"
 | 
| +    if not m: return ''
 | 
| +    s1 = min(m)
 | 
| +    s2 = max(m)
 | 
| +    for i, c in enumerate(s1):
 | 
| +        if c != s2[i]:
 | 
| +            return s1[:i]
 | 
| +    return s1
 | 
| +
 | 
| +
 | 
| +# http://svn.python.org/view/python/trunk/Lib/posixpath.py?view=markup
 | 
| +def relpath(path, start=os.path.curdir):
 | 
| +    """Return a relative version of a path"""
 | 
| +
 | 
| +    if not path:
 | 
| +        raise ValueError("no path specified")
 | 
| +
 | 
| +    start_list = os.path.abspath(start).split(os.path.sep)
 | 
| +    path_list = os.path.abspath(path).split(os.path.sep)
 | 
| +
 | 
| +    # Work out how much of the filepath is shared by start and path.
 | 
| +    i = len(commonprefix([start_list, path_list]))
 | 
| +
 | 
| +    rel_list = [os.path.pardir] * (len(start_list)-i) + path_list[i:]
 | 
| +    if not rel_list:
 | 
| +        return os.path.curdir
 | 
| +    return os.path.join(*rel_list)
 | 
| +##############################################################################
 | 
| +
 | 
| +
 | 
| +class WrongNumberOfArguments(Exception):
 | 
| +  pass
 | 
| +
 | 
| +
 | 
| +def Outputs(filename, defines):
 | 
| +  grd = grd_reader.Parse(
 | 
| +      filename, defines=defines, tags_to_ignore=set(['messages']))
 | 
| +
 | 
| +  target = []
 | 
| +  lang_folders = {}
 | 
| +  # Add all explicitly-specified output files
 | 
| +  for output in grd.GetOutputFiles():
 | 
| +    path = output.GetFilename()
 | 
| +    target.append(path)
 | 
| +
 | 
| +    if path.endswith('.h'):
 | 
| +      path, filename = os.path.split(path)
 | 
| +    if output.attrs['lang']:
 | 
| +      lang_folders[output.attrs['lang']] = os.path.dirname(path)
 | 
| +
 | 
| +  # Add all generated files, once for each output language.
 | 
| +  for node in grd:
 | 
| +    if node.name == 'structure':
 | 
| +      # TODO(joi) Should remove the "if sconsdep is true" thing as it is a
 | 
| +      # hack - see grit/node/structure.py
 | 
| +      if node.HasFileForLanguage() and node.attrs['sconsdep'] == 'true':
 | 
| +        for lang in lang_folders:
 | 
| +          path = node.FileForLanguage(lang, lang_folders[lang],
 | 
| +                                      create_file=False,
 | 
| +                                      return_if_not_generated=False)
 | 
| +          if path:
 | 
| +            target.append(path)
 | 
| +
 | 
| +  return [t.replace('\\', '/') for t in target]
 | 
| +
 | 
| +
 | 
| +def GritSourceFiles():
 | 
| +  files = []
 | 
| +  grit_root_dir = relpath(os.path.dirname(__file__), os.getcwd())
 | 
| +  for root, dirs, filenames in os.walk(grit_root_dir):
 | 
| +    grit_src = [os.path.join(root, f) for f in filenames
 | 
| +                if f.endswith('.py')]
 | 
| +    files.extend(grit_src)
 | 
| +  # TODO(joi@chromium.org): Once we switch to specifying the
 | 
| +  # resource_ids file via a .grd attribute, it should be considered an
 | 
| +  # input of grit and this bit should no longer be necessary.
 | 
| +  default_resource_ids = relpath(
 | 
| +      os.path.join(grit_root_dir, '..', 'gritsettings', 'resource_ids'),
 | 
| +      os.getcwd())
 | 
| +  if os.path.exists(default_resource_ids):
 | 
| +    files.append(default_resource_ids)
 | 
| +  return files
 | 
| +
 | 
| +
 | 
| +def Inputs(filename, defines):
 | 
| +  grd = grd_reader.Parse(
 | 
| +      filename, debug=False, defines=defines, tags_to_ignore=set(['messages']))
 | 
| +  files = []
 | 
| +  for node in grd:
 | 
| +    if (node.name == 'structure' or node.name == 'skeleton' or
 | 
| +        (node.name == 'file' and node.parent and
 | 
| +         node.parent.name == 'translations')):
 | 
| +      files.append(node.GetFilePath())
 | 
| +    elif node.name == 'include':
 | 
| +      # Only include files that we actually plan on using.
 | 
| +      if node.SatisfiesOutputCondition():
 | 
| +        files.append(node.FilenameToOpen())
 | 
| +        # If it's a flattened node, grab inlined resources too.
 | 
| +        if node.attrs['flattenhtml'] == 'true':
 | 
| +          files.extend(node.GetHtmlResourceFilenames())
 | 
| +
 | 
| +  return files
 | 
| +
 | 
| +
 | 
| +def PrintUsage():
 | 
| +  print 'USAGE: ./grit_info.py --inputs [-D foo] <grd-file>'
 | 
| +  print '       ./grit_info.py --outputs [-D foo] <out-prefix> <grd-file>'
 | 
| +
 | 
| +
 | 
| +def DoMain(argv):
 | 
| +  parser = optparse.OptionParser()
 | 
| +  parser.add_option("--inputs", action="store_true", dest="inputs")
 | 
| +  parser.add_option("--outputs", action="store_true", dest="outputs")
 | 
| +  parser.add_option("-D", action="append", dest="defines", default=[])
 | 
| +  # grit build also supports '-E KEY=VALUE', support that to share command
 | 
| +  # line flags.
 | 
| +  parser.add_option("-E", action="append", dest="build_env", default=[])
 | 
| +  parser.add_option("-w", action="append", dest="whitelist_files", default=[])
 | 
| +
 | 
| +  options, args = parser.parse_args(argv)
 | 
| +
 | 
| +  defines = {}
 | 
| +  for define in options.defines:
 | 
| +    defines[define] = 1
 | 
| +
 | 
| +  if options.inputs:
 | 
| +    if len(args) > 1:
 | 
| +      raise WrongNumberOfArguments("Expected 0 or 1 arguments for --inputs.")
 | 
| +
 | 
| +    inputs = []
 | 
| +    if len(args) == 1:
 | 
| +      filename = args[0]
 | 
| +      inputs = Inputs(filename, defines)
 | 
| +
 | 
| +    # Add in the grit source files.  If one of these change, we want to re-run
 | 
| +    # grit.
 | 
| +    inputs.extend(GritSourceFiles())
 | 
| +    inputs = [f.replace('\\', '/') for f in inputs]
 | 
| +
 | 
| +    if len(args) == 1:
 | 
| +      # Include grd file as second input (works around gyp expecting it).
 | 
| +      inputs = [inputs[0], args[0]] + inputs[1:]
 | 
| +    if options.whitelist_files:
 | 
| +      inputs.extend(options.whitelist_files)
 | 
| +    return '\n'.join(inputs)
 | 
| +  elif options.outputs:
 | 
| +    if len(args) != 2:
 | 
| +      raise WrongNumberOfArguments("Expected exactly 2 arguments for --ouputs.")
 | 
| +
 | 
| +    prefix, filename = args
 | 
| +    outputs = [posixpath.join(prefix, f) for f in Outputs(filename, defines)]
 | 
| +    return '\n'.join(outputs)
 | 
| +  else:
 | 
| +    raise WrongNumberOfArguments("Expected --inputs or --outputs.")
 | 
| +
 | 
| +
 | 
| +def main(argv):
 | 
| +  try:
 | 
| +    result = DoMain(argv[1:])
 | 
| +  except WrongNumberOfArguments, e:
 | 
| +    PrintUsage()
 | 
| +    print e
 | 
| +    return 1
 | 
| +  print result
 | 
| +  return 0
 | 
| +
 | 
| +
 | 
| +if __name__ == '__main__':
 | 
| +  sys.exit(main(sys.argv))
 | 
| 
 | 
| Property changes on: grit_info.py
 | 
| ___________________________________________________________________
 | 
| Added: svn:executable
 | 
|    + *
 | 
| Added: svn:eol-style
 | 
|    + LF
 | 
| 
 | 
| 
 |