Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 #!/usr/bin/python | 1 #!/usr/bin/python |
| 2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 3 # Use of this source code is governed by a BSD-style license that can be |
| 4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
| 5 | 5 |
| 6 """Docbuilder for extension docs.""" | 6 """Docbuilder for extension docs.""" |
| 7 | 7 |
| 8 import glob | 8 import glob |
| 9 import os | 9 import os |
| 10 import os.path | 10 import os.path |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 41 # the calling environment may not be setup to set the PYTHONPATH | 41 # the calling environment may not be setup to set the PYTHONPATH |
| 42 # Insert at the front so that we pick up our simplejson even if there's a | 42 # Insert at the front so that we pick up our simplejson even if there's a |
| 43 # system simplejson installed, for predictable escaping. | 43 # system simplejson installed, for predictable escaping. |
| 44 sys.path.insert(0, os.path.normpath(_base_dir + | 44 sys.path.insert(0, os.path.normpath(_base_dir + |
| 45 "/../../../../third_party")) | 45 "/../../../../third_party")) |
| 46 import simplejson as json | 46 import simplejson as json |
| 47 from directory import Sample | 47 from directory import Sample |
| 48 from directory import ApiManifest | 48 from directory import ApiManifest |
| 49 from directory import SamplesManifest | 49 from directory import SamplesManifest |
| 50 | 50 |
| 51 def RenderPages(names, dump_render_tree): | 51 def RenderPages(family, dump_render_tree, single_page_name): |
| 52 """ | 52 output_dir = os.path.join(_base_dir, family) |
| 53 Calls DumpRenderTree .../generator.html?<names> and writes the | 53 names = set(os.path.splitext(name)[0] for name in os.listdir(output_dir) |
| 54 results to .../docs/<name>.html | 54 if not name.startswith(".") and name.endswith(".html")) |
| 55 """ | 55 |
| 56 if not names: | 56 # Allow the user to render a single page if they want |
| 57 raise Exception("RenderPage called with empty names param") | 57 if single_page_name: |
| 58 if single_page_name in names: | |
| 59 names = [single_page_name] | |
| 60 else: | |
| 61 return [] | |
|
Yoyo Zhou
2012/06/22 19:05:55
Silently fail? The old code threw an exception.
Aaron Boodman
2012/06/22 22:16:48
We now run this function twice: once with extensio
Yoyo Zhou
2012/06/22 22:26:06
I guess the user would be told that there were no
| |
| 58 | 62 |
| 59 generator_url = "file:" + urllib.pathname2url(_generator_html) | 63 generator_url = "file:" + urllib.pathname2url(_generator_html) |
| 60 generator_url += "?" + ",".join(names) | 64 generator_url += "?" + family + "|" + ",".join(names) |
| 61 | 65 |
| 62 # Start with a fresh copy of page shell for each file. | 66 # Start with a fresh copy of page shell for each file. |
| 63 # Save the current contents so that we can look for changes later. | 67 # Save the current contents so that we can look for changes later. |
| 64 originals = {} | 68 originals = {} |
| 65 for name in names: | 69 for name in names: |
| 66 input_file = _base_dir + "/" + name + ".html" | 70 input_file = os.path.join(output_dir, name + ".html") |
|
Yoyo Zhou
2012/06/22 19:05:55
input_file looks like the wrong name for this. Mor
Aaron Boodman
2012/06/22 22:16:48
Done.
| |
| 67 | 71 |
| 68 if (os.path.isfile(input_file)): | 72 if (os.path.isfile(input_file)): |
| 69 originals[name] = open(input_file, 'rb').read() | 73 originals[name] = open(input_file, 'rb').read() |
| 70 os.remove(input_file) | 74 os.remove(input_file) |
| 71 else: | 75 else: |
| 72 originals[name] = "" | 76 originals[name] = "" |
| 73 | 77 |
| 74 shutil.copy(_page_shell_html, input_file) | 78 shutil.copy(_page_shell_html, input_file) |
| 75 | 79 |
| 76 # Run DumpRenderTree and capture result | 80 # Run DumpRenderTree and capture result |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 103 for name in names: | 107 for name in names: |
| 104 result = output_parsed[name].encode("utf8") + '\n' | 108 result = output_parsed[name].encode("utf8") + '\n' |
| 105 | 109 |
| 106 # Remove CRs that are appearing from captured DumpRenderTree output. | 110 # Remove CRs that are appearing from captured DumpRenderTree output. |
| 107 result = result.replace('\r', '') | 111 result = result.replace('\r', '') |
| 108 | 112 |
| 109 # Remove empty style attributes. | 113 # Remove empty style attributes. |
| 110 result = result.replace(' style=""', '') | 114 result = result.replace(' style=""', '') |
| 111 | 115 |
| 112 # Remove page_shell | 116 # Remove page_shell |
| 113 input_file = _base_dir + "/" + name + ".html" | 117 input_file = os.path.join(output_dir, name + ".html") |
| 114 os.remove(input_file) | 118 os.remove(input_file) |
| 115 | 119 |
| 116 # Write output | 120 # Write output |
| 117 open(input_file, 'wb').write(result) | 121 open(input_file, 'wb').write(result) |
| 118 if (originals[name] and result != originals[name]): | 122 if (originals[name] and result != originals[name]): |
| 119 changed_files.append(input_file) | 123 changed_files.append(input_file) |
| 120 | 124 |
| 121 return changed_files | 125 return changed_files |
| 122 | 126 |
| 123 | 127 |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 158 for loc in search_locations: | 162 for loc in search_locations: |
| 159 if os.path.isfile(loc): | 163 if os.path.isfile(loc): |
| 160 return loc | 164 return loc |
| 161 | 165 |
| 162 raise Exception("Could not find DumpRenderTree executable\n" | 166 raise Exception("Could not find DumpRenderTree executable\n" |
| 163 "**DumpRenderTree may need to be built**\n" | 167 "**DumpRenderTree may need to be built**\n" |
| 164 "Searched: \n" + "\n".join(search_locations) + "\n" | 168 "Searched: \n" + "\n".join(search_locations) + "\n" |
| 165 "To specify a path to DumpRenderTree use " | 169 "To specify a path to DumpRenderTree use " |
| 166 "--dump-render-tree-path") | 170 "--dump-render-tree-path") |
| 167 | 171 |
| 168 def GetStaticFileNames(): | |
| 169 static_files = os.listdir(_static_dir) | |
| 170 return set(os.path.splitext(file_name)[0] | |
| 171 for file_name in static_files | |
| 172 if file_name.endswith(".html") and not file_name.startswith(".")) | |
| 173 | |
| 174 def main(): | 172 def main(): |
| 175 # Prevent windows from using cygwin python. | 173 # Prevent windows from using cygwin python. |
| 176 if (sys.platform == "cygwin"): | 174 if (sys.platform == "cygwin"): |
| 177 sys.exit("Building docs not supported for cygwin python. Please run the " | 175 sys.exit("Building docs not supported for cygwin python. Please run the " |
| 178 "build.sh script instead, which uses depot_tools python.") | 176 "build.sh script instead, which uses depot_tools python.") |
| 179 | 177 |
| 180 parser = OptionParser() | 178 parser = OptionParser() |
| 181 parser.add_option("--dump-render-tree-path", dest="dump_render_tree_path", | 179 parser.add_option("--dump-render-tree-path", dest="dump_render_tree_path", |
| 182 metavar="PATH", | 180 metavar="PATH", |
| 183 help="path to DumpRenderTree executable") | 181 help="path to DumpRenderTree executable") |
| 184 parser.add_option("--page-name", dest="page_name", metavar="PAGE", | 182 parser.add_option("--page-name", dest="page_name", metavar="PAGE", |
| 185 help="only generate docs for PAGE.html") | 183 help="only generate docs for PAGE.html") |
| 186 parser.add_option("--nozip", dest="zips", action="store_false", | 184 parser.add_option("--nozip", dest="zips", action="store_false", |
| 187 help="do not generate zip files for samples", | 185 help="do not generate zip files for samples", |
| 188 default=True) | 186 default=True) |
| 189 options, args = parser.parse_args() | 187 options, args = parser.parse_args() |
| 190 | 188 |
| 191 if (options.dump_render_tree_path and | 189 if (options.dump_render_tree_path and |
| 192 os.path.isfile(options.dump_render_tree_path)): | 190 os.path.isfile(options.dump_render_tree_path)): |
| 193 dump_render_tree = options.dump_render_tree_path | 191 dump_render_tree = options.dump_render_tree_path |
| 194 else: | 192 else: |
| 195 dump_render_tree = FindDumpRenderTree() | 193 dump_render_tree = FindDumpRenderTree() |
| 196 | 194 |
| 197 # Load the manifest of existing API Methods | 195 # Load the manifest of existing API Methods |
| 198 api_manifest = ApiManifest(_extension_api_json_schemas, | 196 api_manifest = ApiManifest(_extension_api_json_schemas, |
| 199 _extension_api_idl_schemas) | 197 _extension_api_idl_schemas) |
| 200 | 198 |
| 201 # Read static file names | |
| 202 static_names = GetStaticFileNames() | |
| 203 | |
| 204 # Read module names | |
| 205 module_names = api_manifest.getModuleNames() | |
| 206 | |
| 207 # All pages to generate | |
| 208 page_names = static_names | module_names | |
| 209 | |
| 210 # Allow the user to render a single page if they want | |
| 211 if options.page_name: | |
| 212 if options.page_name in page_names: | |
| 213 page_names = [options.page_name] | |
| 214 else: | |
| 215 raise Exception("--page-name argument must be one of %s." % | |
| 216 ', '.join(sorted(page_names))) | |
| 217 | |
| 218 # Write temporary JSON files based on the IDL inputs | 199 # Write temporary JSON files based on the IDL inputs |
| 219 api_manifest.generateJSONFromIDL() | 200 api_manifest.generateJSONFromIDL() |
| 220 | 201 |
| 221 # Render a manifest file containing metadata about all the extension samples | 202 # Render a manifest file containing metadata about all the extension samples |
| 222 samples_manifest = SamplesManifest(_samples_dir, _base_dir, api_manifest) | 203 samples_manifest = SamplesManifest(_samples_dir, _base_dir, api_manifest) |
| 223 samples_manifest.writeToFile(_samples_json) | 204 samples_manifest.writeToFile(_samples_json) |
| 224 | 205 |
| 225 # Write zipped versions of the samples listed in the manifest to the | 206 # Write zipped versions of the samples listed in the manifest to the |
| 226 # filesystem, unless the user has disabled it | 207 # filesystem, unless the user has disabled it |
| 208 modified_files = [] | |
| 227 if options.zips: | 209 if options.zips: |
| 228 modified_zips = samples_manifest.writeZippedSamples() | 210 modified_files.extend(samples_manifest.writeZippedSamples()) |
| 229 else: | |
| 230 modified_zips = [] | |
| 231 | 211 |
| 232 modified_files = RenderPages(page_names, dump_render_tree) | 212 doc_families = ["extensions", "apps"] |
| 233 modified_files.extend(modified_zips) | 213 for family in doc_families: |
| 214 modified_files.extend( | |
| 215 RenderPages(family, dump_render_tree, options.page_name)) | |
| 234 | 216 |
| 235 if len(modified_files) == 0: | 217 if len(modified_files) == 0: |
| 236 print "Output files match existing files. No changes made." | 218 print "Output files match existing files. No changes made." |
| 237 else: | 219 else: |
| 238 print ("ATTENTION: EXTENSION DOCS HAVE CHANGED\n" + | 220 print ("ATTENTION: EXTENSION DOCS HAVE CHANGED\n" + |
| 239 "The following files have been modified and should be checked\n" + | 221 "The following files have been modified and should be checked\n" + |
| 240 "into source control (ideally in the same changelist as the\n" + | 222 "into source control (ideally in the same changelist as the\n" + |
| 241 "underlying files that resulting in their changing).") | 223 "underlying files that resulting in their changing).") |
| 242 for f in modified_files: | 224 for f in modified_files: |
| 243 print " * %s" % f | 225 print " * %s" % f |
| 244 | 226 |
| 245 # Hack. Sleep here, otherwise windows doesn't properly close the debug.log | 227 # Hack. Sleep here, otherwise windows doesn't properly close the debug.log |
| 246 # and the os.remove will fail with a "Permission denied". | 228 # and the os.remove will fail with a "Permission denied". |
| 247 time.sleep(1) | 229 time.sleep(1) |
| 248 debug_log = os.path.normpath(_build_dir + "/" + "debug.log") | 230 debug_log = os.path.normpath(_build_dir + "/" + "debug.log") |
| 249 if (os.path.isfile(debug_log)): | 231 if (os.path.isfile(debug_log)): |
| 250 os.remove(debug_log) | 232 os.remove(debug_log) |
| 251 | 233 |
| 252 # Cleanup our temporary IDL->JSON files | 234 # Cleanup our temporary IDL->JSON files |
| 253 api_manifest.cleanupGeneratedFiles() | 235 api_manifest.cleanupGeneratedFiles() |
| 254 | 236 |
| 255 if 'EX_OK' in dir(os): | 237 if 'EX_OK' in dir(os): |
| 256 return os.EX_OK | 238 return os.EX_OK |
| 257 else: | 239 else: |
| 258 return 0 | 240 return 0 |
| 259 | 241 |
| 260 if __name__ == '__main__': | 242 if __name__ == '__main__': |
| 261 sys.exit(main()) | 243 sys.exit(main()) |
| OLD | NEW |