| OLD | NEW | 
|---|
| (Empty) |  | 
|  | 1 #!/usr/bin/python | 
|  | 2 # Copyright (c) 2011 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 '''Tool to determine inputs and outputs of a grit file. | 
|  | 7 ''' | 
|  | 8 | 
|  | 9 import optparse | 
|  | 10 import os | 
|  | 11 import posixpath | 
|  | 12 import types | 
|  | 13 import sys | 
|  | 14 | 
|  | 15 from grit import grd_reader | 
|  | 16 from grit import util | 
|  | 17 | 
|  | 18 ############################################################################## | 
|  | 19 # os.path.relpath is python 2.6 only. Some bots still run 2.5 only, so I took | 
|  | 20 # the relpath implementation from the python source. | 
|  | 21 # TODO(thakis): Once we're on 2.6 everywhere, remove this and use | 
|  | 22 # os.path.relpath directly. | 
|  | 23 | 
|  | 24 # http://docs.python.org/license.html | 
|  | 25 # PSF LICENSE AGREEMENT FOR PYTHON 2.7.1 | 
|  | 26 # | 
|  | 27 # 1. This LICENSE AGREEMENT is between the Python Software Foundation ("PSF"), | 
|  | 28 # and the Individual or Organization ("Licensee") accessing and otherwise using | 
|  | 29 # Python 2.7.1 software in source or binary form and its associated | 
|  | 30 # documentation. | 
|  | 31 # | 
|  | 32 # 2. Subject to the terms and conditions of this License Agreement, PSF hereby | 
|  | 33 # grants Licensee a nonexclusive, royalty-free, world-wide license to reproduce, | 
|  | 34 # analyze, test, perform and/or display publicly, prepare derivative works, | 
|  | 35 # distribute, and otherwise use Python 2.7.1 alone or in any derivative version, | 
|  | 36 # provided, however, that PSF's License Agreement and PSF's notice of copyright, | 
|  | 37 # i.e., "Copyright c 2001-2010 Python Software Foundation; All Rights Reserved" | 
|  | 38 # are retained in Python 2.7.1 alone or in any derivative version prepared by | 
|  | 39 # Licensee. | 
|  | 40 # | 
|  | 41 # 3. In the event Licensee prepares a derivative work that is based on or | 
|  | 42 # incorporates Python 2.7.1 or any part thereof, and wants to make the | 
|  | 43 # derivative work available to others as provided herein, then Licensee hereby | 
|  | 44 # agrees to include in any such work a brief summary of the changes made to | 
|  | 45 # Python 2.7.1. | 
|  | 46 # | 
|  | 47 # 4. PSF is making Python 2.7.1 available to Licensee on an "AS IS" basis. PSF | 
|  | 48 # MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED. BY WAY OF EXAMPLE, | 
|  | 49 # BUT NOT LIMITATION, PSF MAKES NO AND DISCLAIMS ANY REPRESENTATION OR WARRANTY | 
|  | 50 # OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF | 
|  | 51 # PYTHON 2.7.1 WILL NOT INFRINGE ANY THIRD PARTY RIGHTS. | 
|  | 52 # | 
|  | 53 # 5.1 PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON 2.7.1 FOR | 
|  | 54 # ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS A RESULT OF | 
|  | 55 # MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON 2.7.1, OR ANY DERIVATIVE | 
|  | 56 # THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF. | 
|  | 57 # | 
|  | 58 # 6. This License Agreement will automatically terminate upon a material breach | 
|  | 59 # of its terms and conditions. | 
|  | 60 # | 
|  | 61 # 7. Nothing in this License Agreement shall be deemed to create any | 
|  | 62 # relationship of agency, partnership, or joint venture between PSF and | 
|  | 63 # Licensee. This License Agreement does not grant permission to use PSF | 
|  | 64 # trademarks or trade name in a trademark sense to endorse or promote products | 
|  | 65 # or services of Licensee, or any third party. | 
|  | 66 # | 
|  | 67 # 8. By copying, installing or otherwise using Python 2.7.1, Licensee agrees to | 
|  | 68 # be bound by the terms and conditions of this License Agreement. | 
|  | 69 | 
|  | 70 # http://svn.python.org/view/python/trunk/Lib/genericpath.py?view=markup | 
|  | 71 def commonprefix(m): | 
|  | 72     "Given a list of pathnames, returns the longest common leading component" | 
|  | 73     if not m: return '' | 
|  | 74     s1 = min(m) | 
|  | 75     s2 = max(m) | 
|  | 76     for i, c in enumerate(s1): | 
|  | 77         if c != s2[i]: | 
|  | 78             return s1[:i] | 
|  | 79     return s1 | 
|  | 80 | 
|  | 81 | 
|  | 82 # http://svn.python.org/view/python/trunk/Lib/posixpath.py?view=markup | 
|  | 83 def relpath(path, start=os.path.curdir): | 
|  | 84     """Return a relative version of a path""" | 
|  | 85 | 
|  | 86     if not path: | 
|  | 87         raise ValueError("no path specified") | 
|  | 88 | 
|  | 89     start_list = os.path.abspath(start).split(os.path.sep) | 
|  | 90     path_list = os.path.abspath(path).split(os.path.sep) | 
|  | 91 | 
|  | 92     # Work out how much of the filepath is shared by start and path. | 
|  | 93     i = len(commonprefix([start_list, path_list])) | 
|  | 94 | 
|  | 95     rel_list = [os.path.pardir] * (len(start_list)-i) + path_list[i:] | 
|  | 96     if not rel_list: | 
|  | 97         return os.path.curdir | 
|  | 98     return os.path.join(*rel_list) | 
|  | 99 ############################################################################## | 
|  | 100 | 
|  | 101 | 
|  | 102 class WrongNumberOfArguments(Exception): | 
|  | 103   pass | 
|  | 104 | 
|  | 105 | 
|  | 106 def Outputs(filename, defines): | 
|  | 107   grd = grd_reader.Parse( | 
|  | 108       filename, defines=defines, tags_to_ignore=set(['messages'])) | 
|  | 109 | 
|  | 110   target = [] | 
|  | 111   lang_folders = {} | 
|  | 112   # Add all explicitly-specified output files | 
|  | 113   for output in grd.GetOutputFiles(): | 
|  | 114     path = output.GetFilename() | 
|  | 115     target.append(path) | 
|  | 116 | 
|  | 117     if path.endswith('.h'): | 
|  | 118       path, filename = os.path.split(path) | 
|  | 119     if output.attrs['lang']: | 
|  | 120       lang_folders[output.attrs['lang']] = os.path.dirname(path) | 
|  | 121 | 
|  | 122   # Add all generated files, once for each output language. | 
|  | 123   for node in grd: | 
|  | 124     if node.name == 'structure': | 
|  | 125       # TODO(joi) Should remove the "if sconsdep is true" thing as it is a | 
|  | 126       # hack - see grit/node/structure.py | 
|  | 127       if node.HasFileForLanguage() and node.attrs['sconsdep'] == 'true': | 
|  | 128         for lang in lang_folders: | 
|  | 129           path = node.FileForLanguage(lang, lang_folders[lang], | 
|  | 130                                       create_file=False, | 
|  | 131                                       return_if_not_generated=False) | 
|  | 132           if path: | 
|  | 133             target.append(path) | 
|  | 134 | 
|  | 135   return [t.replace('\\', '/') for t in target] | 
|  | 136 | 
|  | 137 | 
|  | 138 def GritSourceFiles(): | 
|  | 139   files = [] | 
|  | 140   grit_root_dir = relpath(os.path.dirname(__file__), os.getcwd()) | 
|  | 141   for root, dirs, filenames in os.walk(grit_root_dir): | 
|  | 142     grit_src = [os.path.join(root, f) for f in filenames | 
|  | 143                 if f.endswith('.py')] | 
|  | 144     files.extend(grit_src) | 
|  | 145   # TODO(joi@chromium.org): Once we switch to specifying the | 
|  | 146   # resource_ids file via a .grd attribute, it should be considered an | 
|  | 147   # input of grit and this bit should no longer be necessary. | 
|  | 148   default_resource_ids = relpath( | 
|  | 149       os.path.join(grit_root_dir, '..', 'gritsettings', 'resource_ids'), | 
|  | 150       os.getcwd()) | 
|  | 151   if os.path.exists(default_resource_ids): | 
|  | 152     files.append(default_resource_ids) | 
|  | 153   return files | 
|  | 154 | 
|  | 155 | 
|  | 156 def Inputs(filename, defines): | 
|  | 157   grd = grd_reader.Parse( | 
|  | 158       filename, debug=False, defines=defines, tags_to_ignore=set(['messages'])) | 
|  | 159   files = [] | 
|  | 160   for node in grd: | 
|  | 161     if (node.name == 'structure' or node.name == 'skeleton' or | 
|  | 162         (node.name == 'file' and node.parent and | 
|  | 163          node.parent.name == 'translations')): | 
|  | 164       files.append(node.GetFilePath()) | 
|  | 165     elif node.name == 'include': | 
|  | 166       # Only include files that we actually plan on using. | 
|  | 167       if node.SatisfiesOutputCondition(): | 
|  | 168         files.append(node.FilenameToOpen()) | 
|  | 169         # If it's a flattened node, grab inlined resources too. | 
|  | 170         if node.attrs['flattenhtml'] == 'true': | 
|  | 171           files.extend(node.GetHtmlResourceFilenames()) | 
|  | 172 | 
|  | 173   return files | 
|  | 174 | 
|  | 175 | 
|  | 176 def PrintUsage(): | 
|  | 177   print 'USAGE: ./grit_info.py --inputs [-D foo] <grd-file>' | 
|  | 178   print '       ./grit_info.py --outputs [-D foo] <out-prefix> <grd-file>' | 
|  | 179 | 
|  | 180 | 
|  | 181 def DoMain(argv): | 
|  | 182   parser = optparse.OptionParser() | 
|  | 183   parser.add_option("--inputs", action="store_true", dest="inputs") | 
|  | 184   parser.add_option("--outputs", action="store_true", dest="outputs") | 
|  | 185   parser.add_option("-D", action="append", dest="defines", default=[]) | 
|  | 186   # grit build also supports '-E KEY=VALUE', support that to share command | 
|  | 187   # line flags. | 
|  | 188   parser.add_option("-E", action="append", dest="build_env", default=[]) | 
|  | 189   parser.add_option("-w", action="append", dest="whitelist_files", default=[]) | 
|  | 190 | 
|  | 191   options, args = parser.parse_args(argv) | 
|  | 192 | 
|  | 193   defines = {} | 
|  | 194   for define in options.defines: | 
|  | 195     defines[define] = 1 | 
|  | 196 | 
|  | 197   if options.inputs: | 
|  | 198     if len(args) > 1: | 
|  | 199       raise WrongNumberOfArguments("Expected 0 or 1 arguments for --inputs.") | 
|  | 200 | 
|  | 201     inputs = [] | 
|  | 202     if len(args) == 1: | 
|  | 203       filename = args[0] | 
|  | 204       inputs = Inputs(filename, defines) | 
|  | 205 | 
|  | 206     # Add in the grit source files.  If one of these change, we want to re-run | 
|  | 207     # grit. | 
|  | 208     inputs.extend(GritSourceFiles()) | 
|  | 209     inputs = [f.replace('\\', '/') for f in inputs] | 
|  | 210 | 
|  | 211     if len(args) == 1: | 
|  | 212       # Include grd file as second input (works around gyp expecting it). | 
|  | 213       inputs = [inputs[0], args[0]] + inputs[1:] | 
|  | 214     if options.whitelist_files: | 
|  | 215       inputs.extend(options.whitelist_files) | 
|  | 216     return '\n'.join(inputs) | 
|  | 217   elif options.outputs: | 
|  | 218     if len(args) != 2: | 
|  | 219       raise WrongNumberOfArguments("Expected exactly 2 arguments for --ouputs.") | 
|  | 220 | 
|  | 221     prefix, filename = args | 
|  | 222     outputs = [posixpath.join(prefix, f) for f in Outputs(filename, defines)] | 
|  | 223     return '\n'.join(outputs) | 
|  | 224   else: | 
|  | 225     raise WrongNumberOfArguments("Expected --inputs or --outputs.") | 
|  | 226 | 
|  | 227 | 
|  | 228 def main(argv): | 
|  | 229   try: | 
|  | 230     result = DoMain(argv[1:]) | 
|  | 231   except WrongNumberOfArguments, e: | 
|  | 232     PrintUsage() | 
|  | 233     print e | 
|  | 234     return 1 | 
|  | 235   print result | 
|  | 236   return 0 | 
|  | 237 | 
|  | 238 | 
|  | 239 if __name__ == '__main__': | 
|  | 240   sys.exit(main(sys.argv)) | 
| OLD | NEW | 
|---|