| OLD | NEW |
| 1 #!/usr/bin/python | 1 #!/usr/bin/python |
| 2 # Copyright (c) 2009 The Chromium Authors. All rights reserved. | 2 # Copyright (c) 2009 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 os | 8 import os |
| 9 import os.path | 9 import os.path |
| 10 import shutil | 10 import shutil |
| 11 import sys | 11 import sys |
| 12 import time | 12 import time |
| 13 import urllib |
| 13 | 14 |
| 14 from subprocess import Popen, PIPE | 15 from subprocess import Popen, PIPE |
| 15 from optparse import OptionParser | 16 from optparse import OptionParser |
| 16 | 17 |
| 17 _script_path = os.path.realpath(__file__) | 18 _script_path = os.path.realpath(__file__) |
| 18 _build_dir = os.path.dirname(_script_path) | 19 _build_dir = os.path.dirname(_script_path) |
| 19 _base_dir = os.path.normpath(_build_dir + "/..") | 20 _base_dir = os.path.normpath(_build_dir + "/..") |
| 20 _static_dir = _base_dir + "/static" | 21 _static_dir = _base_dir + "/static" |
| 21 _js_dir = _base_dir + "/js" | 22 _js_dir = _base_dir + "/js" |
| 22 _template_dir = _base_dir + "/template" | 23 _template_dir = _base_dir + "/template" |
| (...skipping 10 matching lines...) Expand all Loading... |
| 33 # the calling environment may not be setup to set the PYTHONPATH | 34 # the calling environment may not be setup to set the PYTHONPATH |
| 34 sys.path.append(os.path.normpath(_base_dir + | 35 sys.path.append(os.path.normpath(_base_dir + |
| 35 "/../../../../third_party")) | 36 "/../../../../third_party")) |
| 36 import simplejson as json | 37 import simplejson as json |
| 37 | 38 |
| 38 def RenderPage(name, test_shell): | 39 def RenderPage(name, test_shell): |
| 39 """ | 40 """ |
| 40 Calls test_shell --layout-tests .../generator.html?<name> and writes the | 41 Calls test_shell --layout-tests .../generator.html?<name> and writes the |
| 41 result to .../docs/<name>.html | 42 result to .../docs/<name>.html |
| 42 """ | 43 """ |
| 43 | 44 |
| 44 if not name: | 45 if not name: |
| 45 raise Exception("RenderPage called with empty name"); | 46 raise Exception("RenderPage called with empty name"); |
| 46 | 47 |
| 47 generator_url = _generator_html + "?" + name | 48 generator_url = "file:" + urllib.pathname2url(_generator_html) + "?" + name |
| 48 input_file = _base_dir + "/" + name + ".html" | 49 input_file = _base_dir + "/" + name + ".html" |
| 49 | 50 |
| 50 # Copy page_shell to destination output and move aside original, if it exists. | 51 # Copy page_shell to destination output and move aside original, if it exists. |
| 51 original = None; | 52 original = None; |
| 52 if (os.path.isfile(input_file)): | 53 if (os.path.isfile(input_file)): |
| 53 original = open(input_file, 'rb').read() | 54 original = open(input_file, 'rb').read() |
| 54 os.remove(input_file) | 55 os.remove(input_file) |
| 55 | 56 |
| 56 shutil.copy(_page_shell_html, input_file) | 57 shutil.copy(_page_shell_html, input_file) |
| 57 | 58 |
| 58 # Run test_shell and capture result | 59 # Run test_shell and capture result |
| 59 p = Popen([test_shell, "--layout-tests", generator_url], shell=True, | 60 p = Popen([test_shell, "--layout-tests", generator_url], |
| 60 stdout=PIPE) | 61 stdout=PIPE) |
| 61 | 62 |
| 62 # first output line is url that was processed by test_shell. | 63 # first output line is url that was processed by test_shell. |
| 63 firstline = p.stdout.readline() | 64 firstline = p.stdout.readline() |
| 64 | 65 |
| 65 # the remaining output will be the content of the generated page. | 66 # the remaining output will be the content of the generated page. |
| 66 result = p.stdout.read() | 67 result = p.stdout.read() |
| 67 | 68 |
| 68 # remove the trailing #EOF that test shell appends to the output. | 69 # remove the trailing #EOF that test shell appends to the output. |
| 69 result = result.replace('#EOF', '') | 70 result = result.replace('#EOF', '') |
| 70 | 71 |
| 71 # Remove page_shell | 72 # Remove page_shell |
| 72 os.remove(input_file) | 73 os.remove(input_file) |
| 73 | 74 |
| 74 if (not result.startswith(_expected_output_preamble)): | 75 if (not result.startswith(_expected_output_preamble)): |
| 75 if (firstline.startswith("#TEST_TIMED_OUT")): | 76 if (firstline.startswith("#TEST_TIMED_OUT")): |
| 76 raise Exception("test_shell returned TEST_TIMED_OUT.\n" + | 77 raise Exception("test_shell returned TEST_TIMED_OUT.\n" + |
| 77 "Their was probably a problem with generating the " + | 78 "Their was probably a problem with generating the " + |
| 78 "page\n" + | 79 "page\n" + |
| 79 "Try copying template/page_shell.html to:\n" + | 80 "Try copying template/page_shell.html to:\n" + |
| 80 input_file + | 81 input_file + |
| 81 "\nAnd open it in chrome using the file: scheme.\n" + | 82 "\nAnd open it in chrome using the file: scheme.\n" + |
| 82 "Look from javascript errors via the inspector.") | 83 "Look from javascript errors via the inspector.") |
| 83 raise Exception("test_shell returned unexpected output: " + result); | 84 raise Exception("test_shell returned unexpected output: " + result); |
| 84 | 85 |
| 85 # Remove CRs that are appearing from captured test_shell output. | 86 # Remove CRs that are appearing from captured test_shell output. |
| 86 result = result.replace('\r', '') | 87 result = result.replace('\r', '') |
| 87 | 88 |
| 88 # Write output | 89 # Write output |
| 89 open(input_file, 'wb').write(result); | 90 open(input_file, 'wb').write(result); |
| 90 if (original and result == original): | 91 if (original and result == original): |
| 91 return None | 92 return None |
| 92 else: | 93 else: |
| 93 return input_file | 94 return input_file |
| 94 | 95 |
| 95 def FindTestShell(): | 96 def FindTestShell(): |
| 96 # This is hackey. It is used to guess the location of the test_shell | 97 # This is hackey. It is used to guess the location of the test_shell |
| 97 chrome_dir = os.path.normpath(_base_dir + "/../../../") | 98 chrome_dir = os.path.normpath(_base_dir + "/../../../") |
| 98 src_dir = os.path.normpath(chrome_dir + "/../") | 99 src_dir = os.path.normpath(chrome_dir + "/../") |
| 99 | 100 |
| 100 search_locations = [] | 101 search_locations = [] |
| 101 | 102 |
| 102 if (sys.platform in ('cygwin', 'win32')): | 103 if (sys.platform in ('cygwin', 'win32')): |
| 103 search_locations.append(chrome_dir + "/Debug/test_shell.exe") | 104 search_locations.append(chrome_dir + "/Debug/test_shell.exe") |
| 104 search_locations.append(chrome_dir + "/Release/test_shell.exe") | 105 search_locations.append(chrome_dir + "/Release/test_shell.exe") |
| 105 | 106 |
| 106 if (sys.platform in ('linux', 'linux2')): | 107 if (sys.platform in ('linux', 'linux2')): |
| 107 search_locations.append(src_dir + "/sconsbuild/Debug/test_shell") | 108 search_locations.append(src_dir + "/sconsbuild/Debug/test_shell") |
| 108 search_locations.append(src_dir + "/out/Debug/test_shell") | 109 search_locations.append(src_dir + "/out/Debug/test_shell") |
| 109 search_locations.append(src_dir + "/sconsbuild/Release/test_shell") | 110 search_locations.append(src_dir + "/sconsbuild/Release/test_shell") |
| 110 search_locations.append(src_dir + "/out/Release/test_shell") | 111 search_locations.append(src_dir + "/out/Release/test_shell") |
| 111 | 112 |
| 112 if (sys.platform == 'darwin'): | 113 if (sys.platform == 'darwin'): |
| 113 search_locations.append(src_dir + | 114 search_locations.append(src_dir + |
| 114 "/xcodebuild/Debug/TestShell.app/Contents/MacOS/TestShell") | 115 "/xcodebuild/Debug/TestShell.app/Contents/MacOS/TestShell") |
| 115 search_locations.append(src_dir + | 116 search_locations.append(src_dir + |
| 116 "/xcodebuild/Release/TestShell.app/Contents/MacOS/TestShell") | 117 "/xcodebuild/Release/TestShell.app/Contents/MacOS/TestShell") |
| 117 | 118 |
| 118 for loc in search_locations: | 119 for loc in search_locations: |
| 119 if os.path.isfile(loc): | 120 if os.path.isfile(loc): |
| 120 return loc | 121 return loc |
| 121 | 122 |
| 122 raise Exception ("Could not find test_shell executable\n" + | 123 raise Exception ("Could not find test_shell executable\n" + |
| 123 "**test_shell may need to be built**\n" + | 124 "**test_shell may need to be built**\n" + |
| 124 "Searched: \n" + "\n".join(search_locations) + "\n" + | 125 "Searched: \n" + "\n".join(search_locations) + "\n" + |
| 125 "To specify a path to test_shell use --test-shell-path") | 126 "To specify a path to test_shell use --test-shell-path") |
| 126 | 127 |
| 127 def GetAPIModuleNames(): | 128 def GetAPIModuleNames(): |
| 128 contents = open(_extension_api_json, 'r').read(); | 129 contents = open(_extension_api_json, 'r').read(); |
| 129 extension_api = json.loads(contents, encoding="ASCII") | 130 extension_api = json.loads(contents, encoding="ASCII") |
| 130 return set( module['namespace'].encode() for module in extension_api) | 131 return set( module['namespace'].encode() for module in extension_api) |
| 131 | 132 |
| 132 def GetStaticFileNames(): | 133 def GetStaticFileNames(): |
| 133 static_files = os.listdir(_static_dir) | 134 static_files = os.listdir(_static_dir) |
| 134 return set(os.path.splitext(file)[0] | 135 return set(os.path.splitext(file)[0] |
| 135 for file in static_files | 136 for file in static_files |
| 136 if file.endswith(".html")) | 137 if file.endswith(".html")) |
| 137 | 138 |
| 138 def main(): | 139 def main(): |
| 139 parser = OptionParser() | 140 parser = OptionParser() |
| 140 parser.add_option("--test-shell-path", dest="test_shell_path") | 141 parser.add_option("--test-shell-path", dest="test_shell_path") |
| 141 (options, args) = parser.parse_args() | 142 (options, args) = parser.parse_args() |
| 142 | 143 |
| 143 if (options.test_shell_path and os.path.isfile(options.test_shell_path)): | 144 if (options.test_shell_path and os.path.isfile(options.test_shell_path)): |
| 144 test_shell = options.test_shell_path | 145 test_shell = options.test_shell_path |
| 145 else: | 146 else: |
| 146 test_shell = FindTestShell() | 147 test_shell = FindTestShell() |
| 147 | 148 |
| 148 # Read static file names | 149 # Read static file names |
| 149 static_names = GetStaticFileNames() | 150 static_names = GetStaticFileNames() |
| 150 | 151 |
| 151 # Read module names | 152 # Read module names |
| 152 module_names = GetAPIModuleNames() | 153 module_names = GetAPIModuleNames() |
| 153 | 154 |
| 154 # All pages to generate | 155 # All pages to generate |
| 155 page_names = static_names | module_names | 156 page_names = static_names | module_names |
| 156 | 157 |
| 157 modified_files = [] | 158 modified_files = [] |
| 158 for page in page_names: | 159 for page in page_names: |
| 159 modified_file = RenderPage(page, test_shell) | 160 modified_file = RenderPage(page, test_shell) |
| 160 if (modified_file): | 161 if (modified_file): |
| 161 modified_files.append(modified_file) | 162 modified_files.append(modified_file) |
| 162 | 163 |
| 163 if (len(modified_files) == 0): | 164 if (len(modified_files) == 0): |
| 164 print "Output files match existing files. No changes made." | 165 print "Output files match existing files. No changes made." |
| 165 else: | 166 else: |
| 166 print ("ATTENTION: EXTENSION DOCS HAVE CHANGED\n" + | 167 print ("ATTENTION: EXTENSION DOCS HAVE CHANGED\n" + |
| 167 "The following files have been modified and should be checked\n" + | 168 "The following files have been modified and should be checked\n" + |
| 168 "into source control (ideally in the same changelist as the\n" + | 169 "into source control (ideally in the same changelist as the\n" + |
| 169 "underlying files that resulting in their changing).") | 170 "underlying files that resulting in their changing).") |
| 170 for f in modified_files: | 171 for f in modified_files: |
| 171 print f; | 172 print f; |
| 172 | 173 |
| 173 # Hack. Sleep here, otherwise windows doesn't properly close the debug.log | 174 # Hack. Sleep here, otherwise windows doesn't properly close the debug.log |
| 174 # and the os.remove will fail with a "Permission denied". | 175 # and the os.remove will fail with a "Permission denied". |
| 175 time.sleep(1); | 176 time.sleep(1); |
| 176 debug_log = os.path.normpath(_build_dir + "/" + "debug.log"); | 177 debug_log = os.path.normpath(_build_dir + "/" + "debug.log"); |
| 177 if (os.path.isfile(debug_log)): | 178 if (os.path.isfile(debug_log)): |
| 178 os.remove(debug_log) | 179 os.remove(debug_log) |
| 179 | 180 |
| 180 return 0; | 181 return 0; |
| 181 | 182 |
| 182 if __name__ == '__main__': | 183 if __name__ == '__main__': |
| 183 sys.exit(main()) | 184 sys.exit(main()) |
| OLD | NEW |