OLD | NEW |
1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
2 # Copyright 2014 The Chromium Authors. All rights reserved. | 2 # Copyright 2014 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 """A git command for managing a local cache of git repositories.""" | 6 """A git command for managing a local cache of git repositories.""" |
7 | 7 |
8 from __future__ import print_function | 8 from __future__ import print_function |
9 import errno | 9 import errno |
10 import logging | 10 import logging |
11 import optparse | 11 import optparse |
12 import os | 12 import os |
13 import tempfile | 13 import tempfile |
14 import time | 14 import time |
15 import subprocess | 15 import subprocess |
16 import sys | 16 import sys |
17 import urlparse | 17 import urlparse |
| 18 import zipfile |
18 | 19 |
19 from download_from_google_storage import Gsutil | 20 from download_from_google_storage import Gsutil |
20 import gclient_utils | 21 import gclient_utils |
21 import subcommand | 22 import subcommand |
22 | 23 |
23 try: | 24 try: |
24 # pylint: disable=E0602 | 25 # pylint: disable=E0602 |
25 WinErr = WindowsError | 26 WinErr = WindowsError |
26 except NameError: | 27 except NameError: |
27 class WinErr(Exception): | 28 class WinErr(Exception): |
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
215 '+refs/heads/*:refs/heads/*'], cwd=cwd) | 216 '+refs/heads/*:refs/heads/*'], cwd=cwd) |
216 for ref in self.refs: | 217 for ref in self.refs: |
217 ref = ref.lstrip('+').rstrip('/') | 218 ref = ref.lstrip('+').rstrip('/') |
218 if ref.startswith('refs/'): | 219 if ref.startswith('refs/'): |
219 refspec = '+%s:%s' % (ref, ref) | 220 refspec = '+%s:%s' % (ref, ref) |
220 else: | 221 else: |
221 refspec = '+refs/%s/*:refs/%s/*' % (ref, ref) | 222 refspec = '+refs/%s/*:refs/%s/*' % (ref, ref) |
222 self.RunGit(['config', '--add', 'remote.origin.fetch', refspec], cwd=cwd) | 223 self.RunGit(['config', '--add', 'remote.origin.fetch', refspec], cwd=cwd) |
223 | 224 |
224 def bootstrap_repo(self, directory): | 225 def bootstrap_repo(self, directory): |
225 """Bootstrap the repo from Google Stroage if possible. | 226 """Bootstrap the repo from Google Stroage if possible.""" |
226 | 227 |
227 Requires 7z on Windows and Unzip on Linux/Mac. | 228 python_fallback = False |
228 """ | 229 if sys.platform.startswith('win') and not self.FindExecutable('7z'): |
229 if sys.platform.startswith('win'): | 230 python_fallback = True |
230 if not self.FindExecutable('7z'): | 231 elif sys.platform.startswith('darwin'): |
231 self.print(''' | 232 # The OSX version of unzip doesn't support zip64. |
232 Cannot find 7z in the path. If you want git cache to be able to bootstrap from | 233 python_fallback = True |
233 Google Storage, please install 7z from: | 234 elif not self.FindExecutable('unzip'): |
234 | 235 python_fallback = True |
235 http://www.7-zip.org/download.html | |
236 ''') | |
237 return False | |
238 else: | |
239 if not self.FindExecutable('unzip'): | |
240 self.print(''' | |
241 Cannot find unzip in the path. If you want git cache to be able to bootstrap | |
242 from Google Storage, please ensure unzip is present on your system. | |
243 ''') | |
244 return False | |
245 | 236 |
246 gs_folder = 'gs://%s/%s' % (self.bootstrap_bucket, self.basedir) | 237 gs_folder = 'gs://%s/%s' % (self.bootstrap_bucket, self.basedir) |
247 gsutil = Gsutil( | 238 gsutil = Gsutil( |
248 self.gsutil_exe, boto_path=os.devnull, bypass_prodaccess=True) | 239 self.gsutil_exe, boto_path=os.devnull, bypass_prodaccess=True) |
249 # Get the most recent version of the zipfile. | 240 # Get the most recent version of the zipfile. |
250 _, ls_out, _ = gsutil.check_call('ls', gs_folder) | 241 _, ls_out, _ = gsutil.check_call('ls', gs_folder) |
251 ls_out_sorted = sorted(ls_out.splitlines()) | 242 ls_out_sorted = sorted(ls_out.splitlines()) |
252 if not ls_out_sorted: | 243 if not ls_out_sorted: |
253 # This repo is not on Google Storage. | 244 # This repo is not on Google Storage. |
254 return False | 245 return False |
255 latest_checkout = ls_out_sorted[-1] | 246 latest_checkout = ls_out_sorted[-1] |
256 | 247 |
257 # Download zip file to a temporary directory. | 248 # Download zip file to a temporary directory. |
258 try: | 249 try: |
259 tempdir = tempfile.mkdtemp() | 250 tempdir = tempfile.mkdtemp() |
260 self.print('Downloading %s' % latest_checkout) | 251 self.print('Downloading %s' % latest_checkout) |
261 code, out, err = gsutil.check_call('cp', latest_checkout, tempdir) | 252 code, out, err = gsutil.check_call('cp', latest_checkout, tempdir) |
262 if code: | 253 if code: |
263 self.print('%s\n%s' % (out, err)) | 254 self.print('%s\n%s' % (out, err)) |
264 return False | 255 return False |
265 filename = os.path.join(tempdir, latest_checkout.split('/')[-1]) | 256 filename = os.path.join(tempdir, latest_checkout.split('/')[-1]) |
266 | 257 |
267 # Unpack the file with 7z on Windows, or unzip everywhere else. | 258 # Unpack the file with 7z on Windows, unzip on linux, or fallback. |
268 if sys.platform.startswith('win'): | 259 if not python_fallback: |
269 cmd = ['7z', 'x', '-o%s' % directory, '-tzip', filename] | 260 if sys.platform.startswith('win'): |
| 261 cmd = ['7z', 'x', '-o%s' % directory, '-tzip', filename] |
| 262 else: |
| 263 cmd = ['unzip', filename, '-d', directory] |
| 264 retcode = subprocess.call(cmd) |
270 else: | 265 else: |
271 cmd = ['unzip', filename, '-d', directory] | 266 try: |
272 retcode = subprocess.call(cmd) | 267 with zipfile.ZipFile(filename, 'r') as f: |
| 268 f.printdir() |
| 269 f.extractall(directory) |
| 270 except Exception as e: |
| 271 self.print('Encountered error: %s' % str(e), file=sys.stderr) |
| 272 retcode = 1 |
| 273 else: |
| 274 retcode = 0 |
273 finally: | 275 finally: |
274 # Clean up the downloaded zipfile. | 276 # Clean up the downloaded zipfile. |
275 gclient_utils.rmtree(tempdir) | 277 gclient_utils.rmtree(tempdir) |
276 | 278 |
277 if retcode: | 279 if retcode: |
278 self.print( | 280 self.print( |
279 'Extracting bootstrap zipfile %s failed.\n' | 281 'Extracting bootstrap zipfile %s failed.\n' |
280 'Resuming normal operations.' % filename) | 282 'Resuming normal operations.' % filename) |
281 return False | 283 return False |
282 return True | 284 return True |
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
505 return options, args | 507 return options, args |
506 | 508 |
507 | 509 |
508 def main(argv): | 510 def main(argv): |
509 dispatcher = subcommand.CommandDispatcher(__name__) | 511 dispatcher = subcommand.CommandDispatcher(__name__) |
510 return dispatcher.execute(OptionParser(), argv) | 512 return dispatcher.execute(OptionParser(), argv) |
511 | 513 |
512 | 514 |
513 if __name__ == '__main__': | 515 if __name__ == '__main__': |
514 sys.exit(main(sys.argv[1:])) | 516 sys.exit(main(sys.argv[1:])) |
OLD | NEW |