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 |
(...skipping 24 matching lines...) Expand all Loading... |
35 | 35 |
36 # HACK! This is required because we can only depend on python 2.4 and | 36 # HACK! This is required because we can only depend on python 2.4 and |
37 # the calling environment may not be setup to set the PYTHONPATH | 37 # the calling environment may not be setup to set the PYTHONPATH |
38 sys.path.append(os.path.normpath(_base_dir + | 38 sys.path.append(os.path.normpath(_base_dir + |
39 "/../../../../third_party")) | 39 "/../../../../third_party")) |
40 import simplejson as json | 40 import simplejson as json |
41 from directory import Sample | 41 from directory import Sample |
42 from directory import ApiManifest | 42 from directory import ApiManifest |
43 from directory import SamplesManifest | 43 from directory import SamplesManifest |
44 | 44 |
45 def RenderPages(names, test_shell): | 45 def RenderPages(names, dump_render_tree): |
46 """ | 46 """ |
47 Calls test_shell --layout-tests .../generator.html?<names> and writes the | 47 Calls DumpRenderTree .../generator.html?<names> and writes the |
48 results to .../docs/<name>.html | 48 results to .../docs/<name>.html |
49 """ | 49 """ |
50 if not names: | 50 if not names: |
51 raise Exception("RenderPage called with empty names param") | 51 raise Exception("RenderPage called with empty names param") |
52 | 52 |
53 generator_url = "file:" + urllib.pathname2url(_generator_html) | 53 generator_url = "file:" + urllib.pathname2url(_generator_html) |
54 generator_url += "?" + ",".join(names) | 54 generator_url += "?" + ",".join(names) |
55 | 55 |
56 # Start with a fresh copy of page shell for each file. | 56 # Start with a fresh copy of page shell for each file. |
57 # Save the current contents so that we can look for changes later. | 57 # Save the current contents so that we can look for changes later. |
58 originals = {} | 58 originals = {} |
59 for name in names: | 59 for name in names: |
60 input_file = _base_dir + "/" + name + ".html" | 60 input_file = _base_dir + "/" + name + ".html" |
61 | 61 |
62 if (os.path.isfile(input_file)): | 62 if (os.path.isfile(input_file)): |
63 originals[name] = open(input_file, 'rb').read() | 63 originals[name] = open(input_file, 'rb').read() |
64 os.remove(input_file) | 64 os.remove(input_file) |
65 else: | 65 else: |
66 originals[name] = "" | 66 originals[name] = "" |
67 | 67 |
68 shutil.copy(_page_shell_html, input_file) | 68 shutil.copy(_page_shell_html, input_file) |
69 | 69 |
70 # Run test_shell and capture result | 70 # Run DumpRenderTree and capture result |
71 test_shell_timeout = 1000 * 60 * 5 # five minutes | 71 dump_render_tree_timeout = 1000 * 60 * 5 # five minutes |
72 p = Popen( | 72 p = Popen( |
73 [test_shell, "--layout-tests", "--time-out-ms=%s" % test_shell_timeout, | 73 [dump_render_tree, "--test-shell", |
74 generator_url], | 74 "%s %s" % (generator_url, dump_render_tree_timeout)], |
75 stdout=PIPE) | 75 stdout=PIPE) |
76 | 76 |
77 # The remaining output will be the content of the generated pages. | 77 # The remaining output will be the content of the generated pages. |
78 output = p.stdout.read() | 78 output = p.stdout.read() |
79 | 79 |
80 # Parse out just the JSON part. | 80 # Parse out just the JSON part. |
81 begin = output.find(_expected_output_preamble) | 81 begin = output.find(_expected_output_preamble) |
82 end = output.rfind(_expected_output_postamble) | 82 end = output.rfind(_expected_output_postamble) |
83 | 83 |
84 if (begin < 0 or end < 0): | 84 if (begin < 0 or end < 0): |
85 raise Exception ("test_shell returned invalid output:\n\n" + output) | 85 raise Exception("%s returned invalid output:\n\n%s" % |
| 86 (dump_render_tree, output)) |
86 | 87 |
87 begin += len(_expected_output_preamble) | 88 begin += len(_expected_output_preamble) |
88 | 89 |
89 try: | 90 try: |
90 output_parsed = json.loads(output[begin:end]) | 91 output_parsed = json.loads(output[begin:end]) |
91 except ValueError, msg: | 92 except ValueError, msg: |
92 raise Exception("Could not parse test_shell output as JSON. Error: " + msg + | 93 raise Exception("Could not parse DumpRenderTree output as JSON. Error: " + |
93 "\n\nOutput was:\n" + output) | 94 msg + "\n\nOutput was:\n" + output) |
94 | 95 |
95 changed_files = [] | 96 changed_files = [] |
96 for name in names: | 97 for name in names: |
97 result = output_parsed[name].encode("utf8") + '\n' | 98 result = output_parsed[name].encode("utf8") + '\n' |
98 | 99 |
99 # Remove CRs that are appearing from captured test_shell output. | 100 # Remove CRs that are appearing from captured DumpRenderTree output. |
100 result = result.replace('\r', '') | 101 result = result.replace('\r', '') |
101 | 102 |
102 # Remove page_shell | 103 # Remove page_shell |
103 input_file = _base_dir + "/" + name + ".html" | 104 input_file = _base_dir + "/" + name + ".html" |
104 os.remove(input_file) | 105 os.remove(input_file) |
105 | 106 |
106 # Write output | 107 # Write output |
107 open(input_file, 'wb').write(result) | 108 open(input_file, 'wb').write(result) |
108 if (originals[name] and result != originals[name]): | 109 if (originals[name] and result != originals[name]): |
109 changed_files.append(input_file) | 110 changed_files.append(input_file) |
110 | 111 |
111 return changed_files | 112 return changed_files |
112 | 113 |
113 | 114 |
114 def FindTestShell(): | 115 def FindDumpRenderTree(): |
115 # This is hacky. It is used to guess the location of the test_shell | 116 # This is hacky. It is used to guess the location of the DumpRenderTree |
116 chrome_dir = os.path.normpath(_base_dir + "/../../../") | 117 chrome_dir = os.path.normpath(_base_dir + "/../../../") |
117 src_dir = os.path.normpath(chrome_dir + "/../") | 118 src_dir = os.path.normpath(chrome_dir + "/../") |
118 | 119 |
119 search_locations = [] | 120 search_locations = [] |
120 | 121 |
121 if (sys.platform in ('cygwin', 'win32')): | 122 if (sys.platform in ('cygwin', 'win32')): |
122 home_dir = os.path.normpath(os.getenv("HOMEDRIVE") + os.getenv("HOMEPATH")) | 123 home_dir = os.path.normpath(os.getenv("HOMEDRIVE") + os.getenv("HOMEPATH")) |
123 search_locations.append(chrome_dir + "/Release/test_shell.exe") | 124 search_locations.append(chrome_dir + "/Release/DumpRenderTree.exe") |
124 search_locations.append(chrome_dir + "/Debug/test_shell.exe") | 125 search_locations.append(chrome_dir + "/Debug/DumpRenderTree.exe") |
125 search_locations.append(home_dir + "/bin/test_shell/" + | 126 search_locations.append(home_dir + "/bin/DumpRenderTree/" |
126 "test_shell.exe") | 127 "DumpRenderTree.exe") |
127 | 128 |
128 if (sys.platform in ('linux', 'linux2')): | 129 if (sys.platform in ('linux', 'linux2')): |
129 search_locations.append(src_dir + "/sconsbuild/Release/test_shell") | 130 search_locations.append(src_dir + "/sconsbuild/Release/DumpRenderTree") |
130 search_locations.append(src_dir + "/out/Release/test_shell") | 131 search_locations.append(src_dir + "/out/Release/DumpRenderTree") |
131 search_locations.append(src_dir + "/sconsbuild/Debug/test_shell") | 132 search_locations.append(src_dir + "/sconsbuild/Debug/DumpRenderTree") |
132 search_locations.append(src_dir + "/out/Debug/test_shell") | 133 search_locations.append(src_dir + "/out/Debug/DumpRenderTree") |
133 search_locations.append(os.getenv("HOME") + "/bin/test_shell/test_shell") | 134 search_locations.append(os.getenv("HOME") + "/bin/DumpRenderTree/" |
| 135 "DumpRenderTree") |
134 | 136 |
135 if (sys.platform == 'darwin'): | 137 if (sys.platform == 'darwin'): |
136 search_locations.append(src_dir + | 138 search_locations.append(src_dir + |
137 "/xcodebuild/Release/TestShell.app/Contents/MacOS/TestShell") | 139 "/xcodebuild/Release/DumpRenderTree.app/Contents/MacOS/DumpRenderTree") |
138 search_locations.append(src_dir + | 140 search_locations.append(src_dir + |
139 "/xcodebuild/Debug/TestShell.app/Contents/MacOS/TestShell") | 141 "/xcodebuild/Debug/DumpRenderTree.app/Contents/MacOS/DumpRenderTree") |
140 search_locations.append(os.getenv("HOME") + "/bin/test_shell/" + | 142 search_locations.append(os.getenv("HOME") + "/bin/DumpRenderTree/" + |
141 "TestShell.app/Contents/MacOS/TestShell") | 143 "DumpRenderTree.app/Contents/MacOS/DumpRenderTree") |
142 | 144 |
143 for loc in search_locations: | 145 for loc in search_locations: |
144 if os.path.isfile(loc): | 146 if os.path.isfile(loc): |
145 return loc | 147 return loc |
146 | 148 |
147 raise Exception("Could not find test_shell executable\n" + | 149 raise Exception("Could not find DumpRenderTree executable\n" |
148 "**test_shell may need to be built**\n" + | 150 "**DumpRenderTree may need to be built**\n" |
149 "Searched: \n" + "\n".join(search_locations) + "\n" + | 151 "Searched: \n" + "\n".join(search_locations) + "\n" |
150 "To specify a path to test_shell use --test-shell-path") | 152 "To specify a path to DumpRenderTree use " |
| 153 "--dump-render-tree-path") |
151 | 154 |
152 def GetStaticFileNames(): | 155 def GetStaticFileNames(): |
153 static_files = os.listdir(_static_dir) | 156 static_files = os.listdir(_static_dir) |
154 return set(os.path.splitext(file_name)[0] | 157 return set(os.path.splitext(file_name)[0] |
155 for file_name in static_files | 158 for file_name in static_files |
156 if file_name.endswith(".html") and not file_name.startswith(".")) | 159 if file_name.endswith(".html") and not file_name.startswith(".")) |
157 | 160 |
158 def main(): | 161 def main(): |
159 # Prevent windows from using cygwin python. | 162 # Prevent windows from using cygwin python. |
160 if (sys.platform == "cygwin"): | 163 if (sys.platform == "cygwin"): |
161 sys.exit("Building docs not supported for cygwin python. Please run the " | 164 sys.exit("Building docs not supported for cygwin python. Please run the " |
162 "build.sh script instead, which uses depot_tools python.") | 165 "build.sh script instead, which uses depot_tools python.") |
163 | 166 |
164 parser = OptionParser() | 167 parser = OptionParser() |
165 parser.add_option("--test-shell-path", dest="test_shell_path", | 168 parser.add_option("--dump-render-tree-path", dest="dump_render_tree_path", |
166 metavar="PATH", | 169 metavar="PATH", |
167 help="path to test_shell executable") | 170 help="path to DumpRenderTree executable") |
168 parser.add_option("--page-name", dest="page_name", metavar="PAGE", | 171 parser.add_option("--page-name", dest="page_name", metavar="PAGE", |
169 help="only generate docs for PAGE.html") | 172 help="only generate docs for PAGE.html") |
170 parser.add_option("--nozip", dest="zips", action="store_false", | 173 parser.add_option("--nozip", dest="zips", action="store_false", |
171 help="do not generate zip files for samples", | 174 help="do not generate zip files for samples", |
172 default=True) | 175 default=True) |
173 (options, args) = parser.parse_args() | 176 options, args = parser.parse_args() |
174 | 177 |
175 if (options.test_shell_path and os.path.isfile(options.test_shell_path)): | 178 if (options.dump_render_tree_path and |
176 test_shell = options.test_shell_path | 179 os.path.isfile(options.dump_render_tree_path)): |
| 180 dump_render_tree = options.dump_render_tree_path |
177 else: | 181 else: |
178 test_shell = FindTestShell() | 182 dump_render_tree = FindDumpRenderTree() |
179 | 183 |
180 # Load the manifest of existing API Methods | 184 # Load the manifest of existing API Methods |
181 api_manifest = ApiManifest(_extension_api_json) | 185 api_manifest = ApiManifest(_extension_api_json) |
182 | 186 |
183 # Read static file names | 187 # Read static file names |
184 static_names = GetStaticFileNames() | 188 static_names = GetStaticFileNames() |
185 | 189 |
186 # Read module names | 190 # Read module names |
187 module_names = api_manifest.getModuleNames() | 191 module_names = api_manifest.getModuleNames() |
188 | 192 |
(...skipping 12 matching lines...) Expand all Loading... |
201 samples_manifest = SamplesManifest(_samples_dir, _base_dir, api_manifest) | 205 samples_manifest = SamplesManifest(_samples_dir, _base_dir, api_manifest) |
202 samples_manifest.writeToFile(_samples_json) | 206 samples_manifest.writeToFile(_samples_json) |
203 | 207 |
204 # Write zipped versions of the samples listed in the manifest to the | 208 # Write zipped versions of the samples listed in the manifest to the |
205 # filesystem, unless the user has disabled it | 209 # filesystem, unless the user has disabled it |
206 if options.zips: | 210 if options.zips: |
207 modified_zips = samples_manifest.writeZippedSamples() | 211 modified_zips = samples_manifest.writeZippedSamples() |
208 else: | 212 else: |
209 modified_zips = [] | 213 modified_zips = [] |
210 | 214 |
211 modified_files = RenderPages(page_names, test_shell) | 215 modified_files = RenderPages(page_names, dump_render_tree) |
212 modified_files.extend(modified_zips) | 216 modified_files.extend(modified_zips) |
213 | 217 |
214 if len(modified_files) == 0: | 218 if len(modified_files) == 0: |
215 print "Output files match existing files. No changes made." | 219 print "Output files match existing files. No changes made." |
216 else: | 220 else: |
217 print ("ATTENTION: EXTENSION DOCS HAVE CHANGED\n" + | 221 print ("ATTENTION: EXTENSION DOCS HAVE CHANGED\n" + |
218 "The following files have been modified and should be checked\n" + | 222 "The following files have been modified and should be checked\n" + |
219 "into source control (ideally in the same changelist as the\n" + | 223 "into source control (ideally in the same changelist as the\n" + |
220 "underlying files that resulting in their changing).") | 224 "underlying files that resulting in their changing).") |
221 for f in modified_files: | 225 for f in modified_files: |
222 print " * %s" % f | 226 print " * %s" % f |
223 | 227 |
224 # Hack. Sleep here, otherwise windows doesn't properly close the debug.log | 228 # Hack. Sleep here, otherwise windows doesn't properly close the debug.log |
225 # and the os.remove will fail with a "Permission denied". | 229 # and the os.remove will fail with a "Permission denied". |
226 time.sleep(1) | 230 time.sleep(1) |
227 debug_log = os.path.normpath(_build_dir + "/" + "debug.log") | 231 debug_log = os.path.normpath(_build_dir + "/" + "debug.log") |
228 if (os.path.isfile(debug_log)): | 232 if (os.path.isfile(debug_log)): |
229 os.remove(debug_log) | 233 os.remove(debug_log) |
230 | 234 |
231 if 'EX_OK' in dir(os): | 235 if 'EX_OK' in dir(os): |
232 return os.EX_OK | 236 return os.EX_OK |
233 else: | 237 else: |
234 return 0 | 238 return 0 |
235 | 239 |
236 if __name__ == '__main__': | 240 if __name__ == '__main__': |
237 sys.exit(main()) | 241 sys.exit(main()) |
OLD | NEW |