Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 #!/usr/bin/python | 1 #!/usr/bin/python |
| 2 | 2 |
| 3 # Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 3 # Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 4 # for details. All rights reserved. Use of this source code is governed by a | 4 # for details. All rights reserved. Use of this source code is governed by a |
| 5 # BSD-style license that can be found in the LICENSE file. | 5 # BSD-style license that can be found in the LICENSE file. |
| 6 | 6 |
| 7 # Run to install the necessary components to run webdriver on the buildbots or | 7 # Run to install the necessary components to run webdriver on the buildbots or |
| 8 # on your local machine. | 8 # on your local machine. |
| 9 # Note: The setup steps can be done fairly easily by hand. This script is | 9 # Note: The setup steps can be done fairly easily by hand. This script is |
| 10 # intended to simply and reduce the time for setup since there are a fair number | 10 # intended to simply and reduce the time for setup since there are a fair number |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 73 if 'win32' in sys.platform or 'cygwin' in sys.platform: | 73 if 'win32' in sys.platform or 'cygwin' in sys.platform: |
| 74 depot_tools = os.path.join('e:', depot_tools) | 74 depot_tools = os.path.join('e:', depot_tools) |
| 75 return depot_tools | 75 return depot_tools |
| 76 else: | 76 else: |
| 77 path = os.environ['PATH'].split(os.pathsep) | 77 path = os.environ['PATH'].split(os.pathsep) |
| 78 for loc in path: | 78 for loc in path: |
| 79 if 'depot_tools' in loc: | 79 if 'depot_tools' in loc: |
| 80 return loc | 80 return loc |
| 81 raise Exception("Could not find depot_tools in your path.") | 81 raise Exception("Could not find depot_tools in your path.") |
| 82 | 82 |
| 83 class Installer(object): | |
| 84 """Install a project from the web, pulling latest version.""" | |
|
Emily Fortuna
2013/10/22 17:12:53
maybe call this something like GoogleBasedInstalle
Andrei Mouravski
2013/10/24 18:19:34
Done.
| |
| 83 | 85 |
| 84 class GoogleCodeInstaller(object): | 86 def __init__(self, project_name, destination, download_path_func): |
| 85 """Install code that is being hosted on Google Code.""" | 87 """Create an object that will install the project. |
| 88 Arguments: | |
| 89 project_name - Name of the project, such as "selenium" or "chromedriver." | |
| 90 destination - Where to download the desired file on our filesystem. | |
| 91 download_path_func - A function that takes a dictionary (currently with keys | |
| 92 "os" and "version", but more can be added) that calculates the string | |
| 93 representing the path of the download we want. | |
| 94 """ | |
| 95 self.project_name = project_name | |
| 96 self.destination = destination | |
| 97 self.download_path_func = download_path_func | |
| 86 | 98 |
| 87 def __init__(self, project_name, download_location, download_name_func): | 99 def find_latest_version(self): |
| 88 """ Create a object that will install code from a Google Code site. | 100 """Finds the latest version of the project.""" |
| 89 Arguments: | 101 raise NotImplementedError |
|
Emily Fortuna
2013/10/22 17:12:53
Use duck typing -- you don't need to put this "uni
Andrei Mouravski
2013/10/24 18:19:34
Done.
| |
| 90 project_name - The GoogleCode project name such as "selenium" or | 102 |
| 91 "chromedriver." | 103 def source_path(self): |
| 92 download_location - Where to download the desired file on our filesystem. | 104 """Returns the base path for the download.""" |
| 93 download_name_func - A function that takes a dictionary (currently with keys | 105 raise NotImplementedError |
| 94 "os" and "version", but more can be added) that calculates the string | 106 |
| 95 representing the name of the download we want. | 107 @property |
| 96 """ | 108 def get_os_str(self): |
| 97 self.project_name = project_name | 109 """The strings to indicate what OS a download is for. |
| 98 self.download_location = download_location | 110 """ |
|
Emily Fortuna
2013/10/22 17:12:53
nit: can put this '"" on the previous line
Andrei Mouravski
2013/10/24 18:19:34
Done.
| |
| 99 self.download_name_func = download_name_func | 111 os_str = 'win' |
| 100 self.download_regex_str = self.download_name_func({'os': self.get_os_str, | 112 if 'darwin' in sys.platform: |
| 101 'version': '.+'}) | 113 os_str = 'mac' |
| 114 elif 'linux' in sys.platform: | |
| 115 os_str = 'linux32' | |
| 116 if '64bit' in platform.architecture()[0]: | |
| 117 os_str = 'linux64' | |
| 118 if self.project_name == 'chromedriver' and ( | |
| 119 os_str == 'mac' or os_str == 'win'): | |
| 120 os_str = os_str + '32' | |
| 121 return os_str | |
| 122 | |
| 123 def run(self): | |
| 124 """Download and install the project.""" | |
| 125 print 'Installing %s' % self.project_name | |
| 126 os_str = self.get_os_str | |
| 127 version = self.find_latest_version() | |
| 128 download_path = self.download_path_func({'os': os_str, 'version': version}) | |
| 129 download_name = os.path.basename(download_path) | |
| 130 urllib.urlretrieve(os.path.join(self.source_path(), download_path), | |
| 131 os.path.join(self.destination, download_name)) | |
| 132 if download_name.endswith('.zip'): | |
| 133 if platform.system() != 'Windows': | |
| 134 # The Python zip utility does not preserve executable permissions, but | |
| 135 # this does not seem to be a problem for Windows, which does not have a | |
| 136 # built in zip utility. :-/ | |
| 137 run_cmd('unzip -u %s -d %s' % (os.path.join(self.destination, | |
| 138 download_name), self.destination), stdin='y') | |
| 139 else: | |
| 140 z = zipfile.ZipFile(os.path.join(self.destination, download_name)) | |
| 141 z.extractall(self.destination) | |
| 142 z.close() | |
| 143 os.remove(os.path.join(self.destination, download_name)) | |
| 144 chrome_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), | |
| 145 'orig-chromedriver') | |
| 146 if self.project_name == 'chromedriver' and os.path.exists(chrome_path): | |
| 147 # We have one additional location to make sure chromedriver is updated. | |
| 148 # TODO(efortuna): Remove this. See move_chrome_driver_if_needed in | |
| 149 # perf_testing/run_perf_tests.py | |
| 150 driver = 'chromedriver' | |
| 151 if platform.system() == 'Windows': | |
| 152 driver += '.exe' | |
| 153 shutil.copy(os.path.join(self.destination, driver), | |
| 154 os.path.join(chrome_path, driver)) | |
| 155 | |
| 156 class ChromeDriverInstaller(Installer): | |
| 157 """Install chromedriver from Google Storage.""" | |
| 158 | |
| 159 def __init__(self, destination): | |
| 160 """Create an object to install ChromeDriver | |
| 161 destination - Where to download the desired file on our filesystem. | |
| 162 """ | |
| 163 super(ChromeDriverInstaller, self).__init__('chromedriver', destination, | |
| 164 lambda x: '%(version)s/chromedriver_%(os)s.zip' % x) | |
| 165 | |
| 166 def find_latest_version(self): | |
| 167 """Find the latest version number of ChromeDriver.""" | |
| 168 f = urllib2.urlopen(self.source_path()) | |
| 169 latest = '' | |
| 170 l = f.read() | |
|
Emily Fortuna
2013/10/22 17:12:53
better variable names please
Andrei Mouravski
2013/10/24 18:19:34
Done.
| |
| 171 r = re.compile('(?:<Key>)(\d+\.\d+)') | |
| 172 v = max(r.findall(l)) | |
| 173 return v | |
| 174 | |
| 175 def source_path(self): | |
| 176 return 'http://chromedriver.storage.googleapis.com' | |
| 177 | |
| 178 class GoogleCodeInstaller(Installer): | |
| 179 """Install a project from Google Code.""" | |
| 102 | 180 |
| 103 def google_code_downloads_page(self): | 181 def google_code_downloads_page(self): |
| 104 return 'http://code.google.com/p/%s/downloads/list' % self.project_name | 182 return 'http://code.google.com/p/%s/downloads/list' % self.project_name |
| 105 | 183 |
| 106 def google_code_download(self): | |
| 107 return 'http://%s.googlecode.com/files/' % self.project_name | |
| 108 | |
| 109 def find_latest_version(self): | 184 def find_latest_version(self): |
| 110 """Find the latest version number of some code available for download on a | 185 """Find the latest version number of some code available for download on a |
| 111 Google code page. This was unfortunately done in an ad hoc manner because | 186 Google code page. This was unfortunately done in an ad hoc manner because |
| 112 Google Code does not seem to have an API for their list of current | 187 Google Code does not seem to have an API for their list of current |
| 113 downloads(!). | 188 downloads(!). |
| 114 """ | 189 """ |
| 115 google_code_site = self.google_code_downloads_page() | 190 google_code_site = self.google_code_downloads_page() |
| 116 f = urllib2.urlopen(google_code_site) | 191 f = urllib2.urlopen(google_code_site) |
| 117 latest = '' | 192 latest = '' |
| 193 | |
| 194 download_regex_str = self.download_path_func({'os': self.get_os_str, | |
| 195 'version': '.+'}) | |
| 196 | |
| 118 for line in f.readlines(): | 197 for line in f.readlines(): |
| 119 if re.search(self.download_regex_str, line): | 198 if re.search(download_regex_str, line): |
| 120 suffix_index = line.find( | 199 suffix_index = line.find( |
| 121 self.download_regex_str[self.download_regex_str.rfind('.'):]) | 200 download_regex_str[download_regex_str.rfind('.'):]) |
| 122 name_end = self.download_regex_str.rfind('.+') | 201 name_end = download_regex_str.rfind('.+') |
| 123 name = self.download_name_func({'os': self.get_os_str, 'version': ''}) | 202 name = self.download_path_func({'os': self.get_os_str, 'version': ''}) |
| 124 name = name[:name.rfind('.')] | 203 name = name[:name.rfind('.')] |
| 125 version_str = line[line.find(name) + len(name) : suffix_index] | 204 version_str = line[line.find(name) + len(name) : suffix_index] |
| 126 orig_version_str = version_str | 205 orig_version_str = version_str |
| 127 if version_str.count('.') == 0: | 206 if version_str.count('.') == 0: |
| 128 version_str = version_str.replace('_', '.') | 207 version_str = version_str.replace('_', '.') |
| 129 version_str = re.compile(r'[^\d.]+').sub('', version_str) | 208 version_str = re.compile(r'[^\d.]+').sub('', version_str) |
| 130 if latest == '': | 209 if latest == '': |
| 131 latest = '0.' * version_str.count('.') | 210 latest = '0.' * version_str.count('.') |
| 132 latest += '0' | 211 latest += '0' |
| 133 orig_latest_str = latest | 212 orig_latest_str = latest |
| 134 else: | 213 else: |
| 135 orig_latest_str = latest | 214 orig_latest_str = latest |
| 136 latest = latest.replace('_', '.') | 215 latest = latest.replace('_', '.') |
| 137 » latest = re.compile(r'[^\d.]+').sub('', latest) | 216 latest = re.compile(r'[^\d.]+').sub('', latest) |
| 138 nums = version_str.split('.') | 217 nums = version_str.split('.') |
| 139 latest_nums = latest.split('.') | 218 latest_nums = latest.split('.') |
| 140 for (num, latest_num) in zip(nums, latest_nums): | 219 for (num, latest_num) in zip(nums, latest_nums): |
| 141 if int(num) > int(latest_num): | 220 if int(num) > int(latest_num): |
| 142 latest = orig_version_str | 221 latest = orig_version_str |
| 143 break | 222 break |
| 144 else: | 223 else: |
| 145 latest = orig_latest_str | 224 latest = orig_latest_str |
| 146 if latest == '': | 225 if latest == '': |
| 147 raise Exception("Couldn't find the desired download on " + \ | 226 raise Exception("Couldn't find the desired download on " + \ |
| 148 ' %s.' % google_code_site) | 227 ' %s.' % google_code_site) |
| 149 return latest | 228 return latest |
| 150 | 229 |
| 151 def run(self): | 230 def source_path(self): |
| 152 """Download and install the Google Code.""" | 231 return 'http://%s.googlecode.com/files/' % self.project_name |
| 153 print 'Installing from %s' % self.project_name | |
| 154 os_str = self.get_os_str | |
| 155 version = self.find_latest_version() | |
| 156 download_name = self.download_name_func({'os': os_str, 'version': version}) | |
| 157 urllib.urlretrieve(self.google_code_download() + '/' + download_name, | |
| 158 os.path.join(self.download_location, download_name)) | |
| 159 if download_name.endswith('.zip'): | |
| 160 if platform.system() != 'Windows': | |
| 161 # The Python zip utility does not preserve executable permissions, but | |
| 162 # this does not seem to be a problem for Windows, which does not have a | |
| 163 # built in zip utility. :-/ | |
| 164 run_cmd('unzip -u %s -d %s' % (os.path.join(self.download_location, | |
| 165 download_name), self.download_location), stdin='y') | |
| 166 else: | |
| 167 z = zipfile.ZipFile(os.path.join(self.download_location, download_name)) | |
| 168 z.extractall(self.download_location) | |
| 169 z.close() | |
| 170 os.remove(os.path.join(self.download_location, download_name)) | |
| 171 chrome_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), | |
| 172 'orig-chromedriver') | |
| 173 if self.project_name == 'chromedriver' and os.path.exists(chrome_path): | |
| 174 # We have one additional location to make sure chromedriver is updated. | |
| 175 # TODO(efortuna): Remove this. See move_chrome_driver_if_needed in | |
| 176 # perf_testing/run_perf_tests.py | |
| 177 driver = 'chromedriver' | |
| 178 if platform.system() == 'Windows': | |
| 179 driver += '.exe' | |
| 180 shutil.copy(os.path.join(self.download_location, driver), | |
| 181 os.path.join(chrome_path, driver)) | |
| 182 | |
| 183 @property | |
| 184 def get_os_str(self): | |
| 185 """The strings to indicate what OS a download is for as used on Google Code. | |
| 186 """ | |
| 187 os_str = 'win' | |
| 188 if 'darwin' in sys.platform: | |
| 189 os_str = 'mac' | |
| 190 elif 'linux' in sys.platform: | |
| 191 os_str = 'linux32' | |
| 192 if '64bit' in platform.architecture()[0]: | |
| 193 os_str = 'linux64' | |
| 194 if self.project_name == 'chromedriver' and ( | |
| 195 os_str == 'mac' or os_str == 'win'): | |
| 196 os_str = os_str + '32' | |
| 197 return os_str | |
| 198 | 232 |
| 199 | 233 |
| 200 class FirefoxInstaller(object): | 234 class FirefoxInstaller(object): |
| 201 """Installs the latest version of Firefox on the machine.""" | 235 """Installs the latest version of Firefox on the machine.""" |
| 202 | 236 |
| 203 def ff_download_site(self, os_name): | 237 def ff_download_site(self, os_name): |
| 204 return 'http://releases.mozilla.org/pub/mozilla.org/firefox/releases/' + \ | 238 return 'http://releases.mozilla.org/pub/mozilla.org/firefox/releases/' + \ |
| 205 'latest/%s/en-US/' % os_name | 239 'latest/%s/en-US/' % os_name |
| 206 | 240 |
| 207 @property | 241 @property |
| (...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 386 os_str = 'mac' | 420 os_str = 'mac' |
| 387 elif 'linux' in sys.platform: | 421 elif 'linux' in sys.platform: |
| 388 os_str = 'linux' | 422 os_str = 'linux' |
| 389 return os_str | 423 return os_str |
| 390 | 424 |
| 391 def main(): | 425 def main(): |
| 392 args = parse_args() | 426 args = parse_args() |
| 393 if not args.python: | 427 if not args.python: |
| 394 SeleniumBindingsInstaller(args.buildbot).run() | 428 SeleniumBindingsInstaller(args.buildbot).run() |
| 395 if not args.chromedriver: | 429 if not args.chromedriver: |
| 396 GoogleCodeInstaller('chromedriver', | 430 ChromeDriverInstaller(find_depot_tools_location(args.buildbot)).run() |
| 397 find_depot_tools_location(args.buildbot), | |
| 398 lambda x: 'chromedriver_%(os)s_%(version)s.zip' % x).run() | |
| 399 if not args.seleniumrc: | 431 if not args.seleniumrc: |
| 400 GoogleCodeInstaller('selenium', os.path.dirname(os.path.abspath(__file__)), | 432 GoogleCodeInstaller('selenium', os.path.dirname(os.path.abspath(__file__)), |
| 401 lambda x: 'selenium-server-standalone-%(version)s.jar' % x).run() | 433 lambda x: 'selenium-server-standalone-%(version)s.jar' % x).run() |
| 402 if not args.iedriver and platform.system() == 'Windows': | 434 if not args.iedriver and platform.system() == 'Windows': |
| 403 GoogleCodeInstaller('selenium', find_depot_tools_location(args.buildbot), | 435 GoogleCodeInstaller('selenium', find_depot_tools_location(args.buildbot), |
| 404 lambda x: 'IEDriverServer_Win32_%(version)s.zip' % x).run() | 436 lambda x: 'IEDriverServer_Win32_%(version)s.zip' % x).run() |
| 405 if not args.firefox: | 437 if not args.firefox: |
| 406 FirefoxInstaller().run() | 438 FirefoxInstaller().run() |
| 407 if not args.opera: | 439 if not args.opera: |
| 408 OperaInstaller().run() | 440 OperaInstaller().run() |
| 409 | 441 |
| 410 if __name__ == '__main__': | 442 if __name__ == '__main__': |
| 411 main() | 443 main() |
| OLD | NEW |