1#!/usr/bin/env python
2# Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
3#
4# Use of this source code is governed by a BSD-style license
5# that can be found in the LICENSE file in the root of the source
6# tree. An additional intellectual property rights grant can be found
7# in the file PATENTS.  All contributing project authors may
8# be found in the AUTHORS file in the root of the source tree.
9
10"""Utilities for all our deps-management stuff."""
11
12from __future__ import absolute_import
13from __future__ import division
14from __future__ import print_function
15
16import os
17import shutil
18import subprocess
19import sys
20import tarfile
21import time
22import zipfile
23
24
25def RunSubprocessWithRetry(cmd):
26  """Invokes the subprocess and backs off exponentially on fail."""
27  for i in range(5):
28    try:
29      subprocess.check_call(cmd)
30      return
31    except subprocess.CalledProcessError as exception:
32      backoff = pow(2, i)
33      print('Got %s, retrying in %d seconds...' % (exception, backoff))
34      time.sleep(backoff)
35
36  print('Giving up.')
37  raise exception
38
39
40def DownloadFilesFromGoogleStorage(path, auto_platform=True):
41  print('Downloading files in %s...' % path)
42
43  extension = 'bat' if 'win32' in sys.platform else 'py'
44  cmd = ['download_from_google_storage.%s' % extension,
45         '--bucket=chromium-webrtc-resources',
46         '--directory', path]
47  if auto_platform:
48    cmd += ['--auto_platform', '--recursive']
49  subprocess.check_call(cmd)
50
51
52# Code partially copied from
53# https://cs.chromium.org#chromium/build/scripts/common/chromium_utils.py
54def RemoveDirectory(*path):
55  """Recursively removes a directory, even if it's marked read-only.
56
57  Remove the directory located at *path, if it exists.
58
59  shutil.rmtree() doesn't work on Windows if any of the files or directories
60  are read-only, which svn repositories and some .svn files are.  We need to
61  be able to force the files to be writable (i.e., deletable) as we traverse
62  the tree.
63
64  Even with all this, Windows still sometimes fails to delete a file, citing
65  a permission error (maybe something to do with antivirus scans or disk
66  indexing).  The best suggestion any of the user forums had was to wait a
67  bit and try again, so we do that too.  It's hand-waving, but sometimes it
68  works. :/
69  """
70  file_path = os.path.join(*path)
71  print('Deleting `{}`.'.format(file_path))
72  if not os.path.exists(file_path):
73    print('`{}` does not exist.'.format(file_path))
74    return
75
76  if sys.platform == 'win32':
77    # Give up and use cmd.exe's rd command.
78    file_path = os.path.normcase(file_path)
79    for _ in range(3):
80      print('RemoveDirectory running %s' % (' '.join(
81          ['cmd.exe', '/c', 'rd', '/q', '/s', file_path])))
82      if not subprocess.call(['cmd.exe', '/c', 'rd', '/q', '/s', file_path]):
83        break
84      print('  Failed')
85      time.sleep(3)
86    return
87  else:
88    shutil.rmtree(file_path, ignore_errors=True)
89
90
91def UnpackArchiveTo(archive_path, output_dir):
92  extension = os.path.splitext(archive_path)[1]
93  if extension == '.zip':
94    _UnzipArchiveTo(archive_path, output_dir)
95  else:
96    _UntarArchiveTo(archive_path, output_dir)
97
98
99def _UnzipArchiveTo(archive_path, output_dir):
100  print('Unzipping {} in {}.'.format(archive_path, output_dir))
101  zip_file = zipfile.ZipFile(archive_path)
102  try:
103    zip_file.extractall(output_dir)
104  finally:
105    zip_file.close()
106
107
108def _UntarArchiveTo(archive_path, output_dir):
109  print('Untarring {} in {}.'.format(archive_path, output_dir))
110  tar_file = tarfile.open(archive_path, 'r:gz')
111  try:
112    tar_file.extractall(output_dir)
113  finally:
114    tar_file.close()
115
116
117def GetPlatform():
118  if sys.platform.startswith('win'):
119    return 'win'
120  if sys.platform.startswith('linux'):
121    return 'linux'
122  if sys.platform.startswith('darwin'):
123    return 'mac'
124  raise Exception("Can't run on platform %s." % sys.platform)
125
126
127def GetExecutableExtension():
128  return '.exe' if GetPlatform() == 'win' else ''
129