Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 #!/usr/bin/python | |
| 2 # Copyright 2014 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 #import logging | |
| 7 import os | |
| 8 import re | |
| 9 import sys | |
| 10 | |
| 11 _BASE_REGEX_STRING = '^\s*goog\.%s\(\s*[\'"](.+)[\'"]\s*\)' | |
| 12 require_regex = re.compile(_BASE_REGEX_STRING % 'require') | |
| 13 provide_regex = re.compile(_BASE_REGEX_STRING % 'provide') | |
| 14 | |
| 15 | |
| 16 def ProcessFile(filename): | |
| 17 """Extracts provided and required namespaces. | |
| 18 | |
| 19 Description: | |
| 20 Scans Javascript file for provied and required namespaces. | |
|
bruthig
2014/10/28 19:20:44
sp provied/provided
kevers
2014/10/29 14:27:19
Done.
| |
| 21 | |
| 22 Args: | |
| 23 filename: name of the file to process. | |
| 24 | |
| 25 Returns: | |
| 26 Pair of lists, where the first list contains namespaces provided by the file | |
| 27 and the second contains a list of requirements. | |
| 28 """ | |
| 29 | |
| 30 provides = [] | |
| 31 requires = [] | |
| 32 file_handle = open(filename, 'r') | |
| 33 try: | |
|
bruthig
2014/10/28 19:20:44
An alternative (and more pythonic) way to the try/
kevers
2014/10/29 14:27:19
Done.
| |
| 34 for line in file_handle: | |
|
bruthig
2014/10/28 19:20:44
Is it correct to assume that all matches will be c
kevers
2014/10/29 14:27:19
A linebreak is not allowed within a require or pro
| |
| 35 if re.match(require_regex, line): | |
| 36 requires.append(re.search(require_regex, line).group(1)) | |
|
bruthig
2014/10/28 19:20:44
You could replace the for loop and if statements w
kevers
2014/10/29 14:27:19
As this solution would loop over the file twice, I
| |
| 37 if re.match(provide_regex, line): | |
| 38 provides.append(re.search(provide_regex, line).group(1)) | |
| 39 finally: | |
| 40 file_handle.close() | |
| 41 return provides, requires | |
| 42 | |
| 43 | |
| 44 def ExtractDependencies(filename, providers, requirements): | |
| 45 """Extracts provided and required namespaces for a file. | |
| 46 | |
| 47 Description: | |
| 48 Updates maps for namespace providers and file prerequisites. | |
| 49 | |
| 50 Args: | |
| 51 filename: Path of the file to process. | |
| 52 providers: Mapping of namespace to filename that provides the namespace. | |
| 53 requirements: Mapping of filename to a list of prerequisite namespaces. | |
| 54 """ | |
| 55 | |
| 56 p, r = ProcessFile(filename) | |
| 57 | |
| 58 for name in p: | |
| 59 providers[name] = filename | |
| 60 for name in r: | |
| 61 if not filename in requirements: | |
| 62 requirements[filename] = [] | |
| 63 requirements[filename].append(name) | |
| 64 | |
| 65 | |
| 66 def Export(target_file, source_filename, providers, requirements, processed): | |
| 67 """Writes the contents of a file. | |
| 68 | |
| 69 Description: | |
| 70 Appends the contents of the source file to the target file. In order to | |
| 71 preserve proper dependencies, each file has its required namespaces | |
| 72 processed before exporting the source file itself. The set of exported files | |
| 73 is tracked to guard against multiple exports of the same file. Comments as | |
| 74 well as 'proivde' and 'require' statements are removed during to export to | |
|
bruthig
2014/10/28 19:20:44
sp proivde/provide
sp removed during to/the export
kevers
2014/10/29 14:27:19
Done.
| |
| 75 reduce file size. | |
| 76 | |
| 77 Args: | |
| 78 target_file: Handle to target file for export. | |
| 79 source_filename: Name of the file to export. | |
| 80 providers: Map of namespace to filename. | |
| 81 requirements: Map of filename to required namespaces. | |
| 82 processed: Set of processed files. | |
| 83 Returns: | |
| 84 """ | |
| 85 | |
| 86 # Filename may have already been processed if it was a requirement of a | |
| 87 # previous exported file. | |
| 88 if source_filename in processed: | |
| 89 return | |
| 90 | |
| 91 # Export requirements before file. | |
| 92 if source_filename in requirements: | |
| 93 for namespace in requirements[source_filename]: | |
| 94 if namespace in providers: | |
| 95 dependency = providers[namespace] | |
| 96 if dependency: | |
| 97 Export(target_file, dependency, providers, requirements, processed) | |
| 98 | |
| 99 # Export file | |
| 100 processed.add(source_filename) | |
| 101 for name in providers: | |
| 102 if providers[name] == source_filename: | |
| 103 target_file.write('// %s\n' % name) | |
|
bruthig
2014/10/28 19:20:44
If you care to make this platform agnostic you cou
kevers
2014/10/29 14:27:19
Done.
| |
| 104 source_file = open(source_filename, 'r') | |
| 105 try: | |
| 106 comment_block = False | |
| 107 for line in source_file: | |
| 108 # Skip require and provide statements. | |
| 109 if (not re.match(require_regex, line) and not | |
| 110 re.match(provide_regex, line)): | |
| 111 formatted = line.rstrip() | |
| 112 if comment_block: | |
| 113 # Scan for trailing */ in multi-line comment. | |
| 114 index = formatted.find('*/') | |
| 115 if index >= 0: | |
| 116 formatted = formatted[index + 2:] | |
| 117 comment_block = False | |
| 118 else: | |
| 119 formatted = '' | |
| 120 # Remove // style comments. | |
| 121 index = formatted.find('//') | |
| 122 if index >= 0: | |
| 123 formatted = formatted[:index] | |
| 124 # Remove /* */ style comments. | |
| 125 start_comment = formatted.find('/*') | |
| 126 end_comment = formatted.find('*/') | |
| 127 while start_comment >= 0: | |
| 128 if end_comment > start_comment: | |
| 129 formatted = (formatted[:start_comment] | |
| 130 + formatted[end_comment + 2:]) | |
| 131 start_comment = formatted.find('/*') | |
| 132 end_comment = formatted.find('*/') | |
|
bruthig
2014/10/28 19:20:44
It might be more readable/maintainable if there wa
kevers
2014/10/29 14:27:19
This spot is looking for potentially multiple inst
| |
| 133 else: | |
| 134 formatted = formatted[:start_comment] | |
| 135 comment_block = True | |
| 136 start_comment = -1 | |
| 137 if len(formatted.strip()) > 0: | |
|
bruthig
2014/10/28 19:20:44
The if statement below would be equivalent (assumi
kevers
2014/10/29 14:27:19
Done.
| |
| 138 target_file.write('%s\n' % formatted) | |
| 139 finally: | |
| 140 source_file.close() | |
| 141 target_file.write('\n') | |
| 142 | |
| 143 | |
| 144 def GetTargetFile(arguments): | |
| 145 """Extracts target file from the argument list. | |
| 146 | |
| 147 Args: | |
| 148 arguments: List of command line arguments. | |
| 149 """ | |
| 150 | |
| 151 for i in range(len(arguments)): | |
| 152 if arguments[i] == '--target': | |
| 153 return arguments[i + 1] | |
|
bruthig
2014/10/28 19:20:44
Is it intentional/ok that this will raise an out o
kevers
2014/10/29 14:27:19
Removed in favor of options parser.
| |
| 154 return None | |
| 155 | |
| 156 | |
| 157 def GetSourceFiles(arguments): | |
| 158 """Extract list if source files from the argument list. | |
| 159 | |
| 160 Args: | |
| 161 arguments: List of command line arguments. | |
| 162 """ | |
| 163 | |
| 164 sources = [] | |
| 165 start_index = -1 | |
| 166 for i in range(len(arguments)): | |
|
bruthig
2014/10/28 19:20:44
[applies to Python2.6 only] If arguments is going
kevers
2014/10/29 14:27:19
Removed in favor of options parser.
| |
| 167 if arguments[i] == '--sources': | |
| 168 start_index = i + 1 | |
| 169 break | |
| 170 if start_index < 0: | |
| 171 return None | |
| 172 for i in range(start_index, len(arguments)): | |
| 173 sources.append(arguments[i]) | |
| 174 return sources | |
| 175 | |
| 176 | |
| 177 def main(): | |
| 178 """The entrypoint for this script.""" | |
| 179 | |
| 180 target = GetTargetFile(sys.argv) | |
|
bruthig
2014/10/28 19:20:44
You may want to consider using pythons built in ar
kevers
2014/10/29 14:27:19
Done.
| |
| 181 sources = GetSourceFiles(sys.argv) | |
| 182 | |
| 183 providers = {} | |
| 184 requirements = {} | |
| 185 for file in sources: | |
| 186 ExtractDependencies(file, providers, requirements) | |
| 187 | |
| 188 target_file = open(target, 'w') | |
| 189 try: | |
| 190 processed = set() | |
| 191 for source_filename in sources: | |
| 192 Export(target_file, source_filename, providers, requirements, processed) | |
| 193 finally: | |
| 194 target_file.close(); | |
| 195 | |
| 196 if __name__ == '__main__': | |
| 197 main() | |
| OLD | NEW |