• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env python
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
4# found in the LICENSE file.
5
6"""Fetch prebuilt binaries to run PyAuto.
7
8Sets up Chrome and PyAuto binaries using prebuilt binaries from the
9continuous build archives.  Works on mac, win, linux (32 & 64 bit).
10
11Examples:
12  On Mac:
13  $ python fetch_prebuilt_pyauto.py -d xcodebuild/Release
14      http://build.chromium.org/f/chromium/continuous/mac/LATEST
15
16  On Win:
17  $ python fetch_prebuilt_pyauto.py -d chrome\Release
18      http://build.chromium.org/f/chromium/continuous/win/LATEST
19"""
20
21import glob
22import httplib
23import optparse
24import os
25import platform
26import shutil
27import sys
28import urllib
29import urllib2
30import urlparse
31
32import pyauto_utils
33
34
35class FetchPrebuilt(object):
36  """Util class to fetch prebuilt binaries to run PyAuto."""
37
38  def _ParseArgs(self):
39    parser = optparse.OptionParser()
40    parser.add_option(
41        '-d', '--outdir', type='string', default=None,
42        help='Directory in which to setup. This is typically the directory '
43        'where the binaries would go when compiled from source.')
44    parser.add_option(
45        '-p', '--platform', type='string',
46        default=pyauto_utils.GetCurrentPlatform(),
47        help='Platform. Valid options: win, mac, linux32, linux64. '
48        'Default: current platform (%s)' % pyauto_utils.GetCurrentPlatform())
49    parser.add_option(
50        '-l', '--latest', action='store_true', default=False,
51        help='Download the latest chromium build from commondatastorage. '
52        '[default=False]')
53    self._options, self._args = parser.parse_args()
54    if self._options.latest:
55      self._url = self._GetLastestDownloadURL(self._options.platform)
56    elif not self._args:
57      print >>sys.stderr, 'Need download url'
58      sys.exit(2)
59    else:
60      self._url = self._args[0]
61    if not self._options.outdir:
62      print >>sys.stderr, 'Need output directory: -d/--outdir'
63      sys.exit(1)
64    self._outdir = self._options.outdir
65    # Chromium continuous build archive has a non-standard format.
66    if 'index.html?path=' in self._url:
67      self._url = self._url.replace('index.html?path=', '')
68    self._url = self._url.rstrip('/')
69    # Determine name of zip.
70    if not self._options.platform.startswith('linux'):
71      self._chrome_zip_name = 'chrome-%s' % {'mac': 'mac',
72                                             'win': 'win32'
73                                            }[self._options.platform]
74    else:
75      linux_32_names = ['linux', 'lucid32bit']
76      linux_64_names = ['linux64', 'lucid64bit']
77      linux_names = {'linux': linux_32_names + linux_64_names,
78                     'linux32': linux_32_names,
79                     'linux64': linux_64_names
80                    }[self._options.platform]
81      for name in linux_names:
82        zip_name = 'chrome-' + name
83        if pyauto_utils.DoesUrlExist('%s/%s.zip' % (self._url, zip_name)):
84          self._chrome_zip_name = zip_name
85          break
86      else:
87        raise RuntimeError('Could not find chrome zip at ' + self._url)
88
89    # Setup urls to download.
90    self._chrome_zip_url = '%s/%s.zip' % (self._url, self._chrome_zip_name)
91    self._remoting_zip_url = self._url + '/' + 'remoting-webapp.zip'
92    chrome_test_url = '%s/%s.test' % (self._url, self._chrome_zip_name)
93    self._pyautolib_py_url = '%s/pyautolib.py' % chrome_test_url
94    if self._options.platform == 'win':
95      self._pyautolib_so_name = '_pyautolib.pyd'
96      self._chromedriver_name = 'chromedriver.exe'
97    else:
98      self._pyautolib_so_name = '_pyautolib.so'
99      self._chromedriver_name = 'chromedriver'
100    if self._options.platform == 'mac':
101      self._ffmpegsumo_so_name = 'ffmpegsumo.so'
102      self._ffmpegsumo_so_url = chrome_test_url + '/' + self._ffmpegsumo_so_name
103    self._pyautolib_so_url = chrome_test_url + '/' + self._pyautolib_so_name
104    self._chromedriver_url = chrome_test_url + '/' + self._chromedriver_name
105
106  def _GetLastestDownloadURL(self, os_platform):
107    os_type = {'win': 'Win',
108               'mac': 'Mac',
109               'linux': 'Linux',
110               'linux32': 'Linux',
111               'linux64': 'Linux_x64'}[os_platform]
112    if os_type == 'Linux' and platform.architecture()[0] == '64bit':
113      os_type = 'Linux_x64'
114    last_change_url = ('http://commondatastorage.googleapis.com/'
115                       'chromium-browser-continuous/%s/LAST_CHANGE' % os_type)
116    response = urllib2.urlopen(last_change_url)
117    last_change = response.read()
118    if not last_change:
119      print >>sys.stderr, ('Unable to get latest from %s' % last_change_url)
120      sys.exit(2)
121    last_change_url = ('http://commondatastorage.googleapis.com/'
122                       'chromium-browser-continuous/%s/%s' % (os_type,
123                                                              last_change))
124    return last_change_url
125
126  def Cleanup(self):
127    """Remove old binaries, if any."""
128    pass
129
130  def Run(self):
131    self._ParseArgs()
132    if not os.path.isdir(self._outdir):
133      os.makedirs(self._outdir)
134    get_remoting = pyauto_utils.DoesUrlExist(self._remoting_zip_url)
135
136    # Fetch chrome & pyauto binaries
137    print 'Fetching', self._chrome_zip_url
138    chrome_zip = urllib.urlretrieve(self._chrome_zip_url)[0]
139
140    if get_remoting:
141      print 'Fetching', self._remoting_zip_url
142      remoting_zip = urllib.urlretrieve(self._remoting_zip_url)[0]
143    else:
144      print 'Warning: %s does not exist.' % self._remoting_zip_url
145
146    print 'Fetching', self._pyautolib_py_url
147    pyautolib_py = urllib.urlretrieve(self._pyautolib_py_url)[0]
148
149    print 'Fetching', self._pyautolib_so_url
150    pyautolib_so = urllib.urlretrieve(self._pyautolib_so_url)[0]
151
152    if self._options.platform == 'mac':
153      print 'Fetching', self._ffmpegsumo_so_url
154      ffmpegsumo_so = urllib.urlretrieve(self._ffmpegsumo_so_url)[0]
155
156    print 'Fetching', self._chromedriver_url
157    chromedriver = urllib.urlretrieve(self._chromedriver_url)[0]
158
159    chrome_unzip_dir = os.path.join(self._outdir, self._chrome_zip_name)
160    if os.path.exists(chrome_unzip_dir):
161      print 'Cleaning', chrome_unzip_dir
162      pyauto_utils.RemovePath(chrome_unzip_dir)
163    print 'Unzipping'
164    pyauto_utils.UnzipFilenameToDir(chrome_zip, self._outdir)
165    if get_remoting:
166      pyauto_utils.UnzipFilenameToDir(remoting_zip, self._outdir)
167      shutil.move(self._outdir + '/remoting-webapp',
168                  self._outdir + '/remoting/remoting.webapp')
169
170    # Copy over the binaries to outdir
171    items_to_copy = {
172      pyautolib_py: os.path.join(self._outdir, 'pyautolib.py'),
173      pyautolib_so: os.path.join(self._outdir, self._pyautolib_so_name),
174      chromedriver: os.path.join(self._outdir, self._chromedriver_name)
175    }
176    if self._options.platform == 'mac':
177      items_to_copy[ffmpegsumo_so] = \
178          os.path.join(self._outdir, self._ffmpegsumo_so_name)
179
180    unzip_dir_contents = glob.glob(os.path.join(chrome_unzip_dir, '*'))
181    for item in unzip_dir_contents:
182      name = os.path.basename(item)
183      items_to_copy[item] = os.path.join(self._outdir, name)
184
185    for src, dest in items_to_copy.iteritems():
186      pyauto_utils.RemovePath(dest)
187      print '%s ==> %s' % (os.path.basename(src), dest)
188      shutil.move(src, dest)
189    pyauto_utils.RemovePath(chrome_unzip_dir)
190
191    # Final setup (if any)
192    # Set executable bit on chromedriver binary.
193    if not self._options.platform == 'win':
194      os.chmod(items_to_copy[chromedriver], 0700)
195
196    # Create symlink to .framework on Mac
197    if self._options.platform == 'mac':
198      mac_app_name = os.path.basename([x for x in unzip_dir_contents
199                                       if x.endswith('.app')][0])
200      os.chdir(self._outdir)
201      framework = glob.glob(os.path.join(
202          mac_app_name, 'Contents', 'Versions', '*', '*.framework'))[0]
203      print framework
204      dest = os.path.basename(framework)
205      os.path.lexists(dest) and os.remove(dest)
206      print 'Creating symlink "%s"' % dest
207      os.symlink(framework, dest)
208
209    print 'Prepared binaries in "%s"' % self._outdir
210    return 0
211
212
213if __name__ == '__main__':
214  sys.exit(FetchPrebuilt().Run())
215