util.py 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. #!/usr/bin/env python
  2. import atexit
  3. import contextlib
  4. import datetime
  5. import errno
  6. import json
  7. import os
  8. import platform
  9. import re
  10. import shutil
  11. import ssl
  12. import stat
  13. import subprocess
  14. import sys
  15. import tarfile
  16. import tempfile
  17. import urllib2
  18. import zipfile
  19. from lib.config import is_verbose_mode, PLATFORM
  20. from lib.env_util import get_vs_env
  21. SRC_DIR = os.path.abspath(os.path.join(__file__, '..', '..', '..', '..'))
  22. BOTO_DIR = os.path.abspath(os.path.join(__file__, '..', '..', '..', 'vendor',
  23. 'boto'))
  24. NPM = 'npm'
  25. if sys.platform in ['win32', 'cygwin']:
  26. NPM += '.cmd'
  27. def tempdir(prefix=''):
  28. directory = tempfile.mkdtemp(prefix=prefix)
  29. atexit.register(shutil.rmtree, directory)
  30. return directory
  31. @contextlib.contextmanager
  32. def scoped_cwd(path):
  33. cwd = os.getcwd()
  34. os.chdir(path)
  35. try:
  36. yield
  37. finally:
  38. os.chdir(cwd)
  39. @contextlib.contextmanager
  40. def scoped_env(key, value):
  41. origin = ''
  42. if key in os.environ:
  43. origin = os.environ[key]
  44. os.environ[key] = value
  45. try:
  46. yield
  47. finally:
  48. os.environ[key] = origin
  49. def download(text, url, path):
  50. safe_mkdir(os.path.dirname(path))
  51. with open(path, 'wb') as local_file:
  52. if hasattr(ssl, '_create_unverified_context'):
  53. ssl._create_default_https_context = ssl._create_unverified_context
  54. print "Downloading %s to %s" % (url, path)
  55. web_file = urllib2.urlopen(url)
  56. file_size = int(web_file.info().getheaders("Content-Length")[0])
  57. downloaded_size = 0
  58. block_size = 128
  59. ci = os.environ.get('CI') is not None
  60. while True:
  61. buf = web_file.read(block_size)
  62. if not buf:
  63. break
  64. downloaded_size += len(buf)
  65. local_file.write(buf)
  66. if not ci:
  67. percent = downloaded_size * 100. / file_size
  68. status = "\r%s %10d [%3.1f%%]" % (text, downloaded_size, percent)
  69. print status,
  70. if ci:
  71. print "%s done." % (text)
  72. else:
  73. print
  74. return path
  75. def extract_tarball(tarball_path, member, destination):
  76. with tarfile.open(tarball_path) as tarball:
  77. tarball.extract(member, destination)
  78. def extract_zip(zip_path, destination):
  79. if sys.platform == 'darwin':
  80. # Use unzip command on Mac to keep symbol links in zip file work.
  81. execute(['unzip', zip_path, '-d', destination])
  82. else:
  83. with zipfile.ZipFile(zip_path) as z:
  84. z.extractall(destination)
  85. def make_zip(zip_file_path, files, dirs):
  86. safe_unlink(zip_file_path)
  87. if sys.platform == 'darwin':
  88. files += dirs
  89. execute(['zip', '-r', '-y', zip_file_path] + files)
  90. else:
  91. zip_file = zipfile.ZipFile(zip_file_path, "w", zipfile.ZIP_DEFLATED)
  92. for filename in files:
  93. zip_file.write(filename, filename)
  94. for dirname in dirs:
  95. for root, _, filenames in os.walk(dirname):
  96. for f in filenames:
  97. zip_file.write(os.path.join(root, f))
  98. zip_file.close()
  99. def rm_rf(path):
  100. try:
  101. shutil.rmtree(path)
  102. except OSError:
  103. pass
  104. def safe_unlink(path):
  105. try:
  106. os.unlink(path)
  107. except OSError as e:
  108. if e.errno != errno.ENOENT:
  109. raise
  110. def safe_mkdir(path):
  111. try:
  112. os.makedirs(path)
  113. except OSError as e:
  114. if e.errno != errno.EEXIST:
  115. raise
  116. def execute(argv, env=None, cwd=None):
  117. if env is None:
  118. env = os.environ
  119. if is_verbose_mode():
  120. print ' '.join(argv)
  121. try:
  122. output = subprocess.check_output(argv, stderr=subprocess.STDOUT,
  123. env=env, cwd=cwd)
  124. if is_verbose_mode():
  125. print output
  126. return output
  127. except subprocess.CalledProcessError as e:
  128. print e.output
  129. raise e
  130. def execute_stdout(argv, env=None, cwd=None):
  131. if env is None:
  132. env = os.environ
  133. if is_verbose_mode():
  134. print ' '.join(argv)
  135. try:
  136. subprocess.check_call(argv, env=env, cwd=cwd)
  137. except subprocess.CalledProcessError as e:
  138. print e.output
  139. raise e
  140. else:
  141. execute(argv, env, cwd)
  142. def get_electron_branding():
  143. SOURCE_ROOT = os.path.abspath(os.path.join(__file__, '..', '..', '..'))
  144. branding_file_path = os.path.join(SOURCE_ROOT, 'atom', 'app', 'BRANDING.json')
  145. with open(branding_file_path) as f:
  146. return json.load(f)
  147. def get_electron_version():
  148. SOURCE_ROOT = os.path.abspath(os.path.join(__file__, '..', '..', '..'))
  149. version_file = os.path.join(SOURCE_ROOT, 'ELECTRON_VERSION')
  150. with open(version_file) as f:
  151. return 'v' + f.read().strip()
  152. def boto_path_dirs():
  153. return [
  154. os.path.join(BOTO_DIR, 'build', 'lib'),
  155. os.path.join(BOTO_DIR, 'build', 'lib.linux-x86_64-2.7')
  156. ]
  157. def run_boto_script(access_key, secret_key, script_name, *args):
  158. env = os.environ.copy()
  159. env['AWS_ACCESS_KEY_ID'] = access_key
  160. env['AWS_SECRET_ACCESS_KEY'] = secret_key
  161. env['PYTHONPATH'] = os.path.pathsep.join(
  162. [env.get('PYTHONPATH', '')] + boto_path_dirs())
  163. boto = os.path.join(BOTO_DIR, 'bin', script_name)
  164. execute([sys.executable, boto] + list(args), env)
  165. def s3put(bucket, access_key, secret_key, prefix, key_prefix, files):
  166. args = [
  167. '--bucket', bucket,
  168. '--prefix', prefix,
  169. '--key_prefix', key_prefix,
  170. '--grant', 'public-read'
  171. ] + files
  172. run_boto_script(access_key, secret_key, 's3put', *args)
  173. def add_exec_bit(filename):
  174. os.chmod(filename, os.stat(filename).st_mode | stat.S_IEXEC)
  175. def get_out_dir():
  176. out_dir = 'Debug'
  177. override = os.environ.get('ELECTRON_OUT_DIR')
  178. if override is not None:
  179. out_dir = override
  180. return os.path.join(SRC_DIR, 'out', out_dir)
  181. # NOTE: This path is not created by gn, it is used as a scratch zone by our
  182. # upload scripts
  183. def get_dist_dir():
  184. return os.path.join(get_out_dir(), 'gen', 'electron_dist')
  185. def get_electron_exec():
  186. out_dir = get_out_dir()
  187. if sys.platform == 'darwin':
  188. return '{0}/Electron.app/Contents/MacOS/Electron'.format(out_dir)
  189. elif sys.platform == 'win32':
  190. return '{0}/electron.exe'.format(out_dir)
  191. elif sys.platform == 'linux':
  192. return '{0}/electron'.format(out_dir)
  193. raise Exception(
  194. "get_electron_exec: unexpected platform '{0}'".format(sys.platform))