util.py 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. #!/usr/bin/env python3
  2. import contextlib
  3. import errno
  4. import json
  5. import os
  6. import platform
  7. import shutil
  8. import subprocess
  9. import sys
  10. from urllib.request import urlopen
  11. import zipfile
  12. from lib.config import verbose_mode_print
  13. ELECTRON_DIR = os.path.abspath(
  14. os.path.dirname(os.path.dirname(os.path.dirname(__file__)))
  15. )
  16. TS_NODE = os.path.join(ELECTRON_DIR, 'node_modules', '.bin', 'ts-node')
  17. SRC_DIR = os.path.abspath(os.path.join(__file__, '..', '..', '..', '..'))
  18. if sys.platform in ['win32', 'cygwin']:
  19. TS_NODE += '.cmd'
  20. @contextlib.contextmanager
  21. def scoped_cwd(path):
  22. cwd = os.getcwd()
  23. os.chdir(path)
  24. try:
  25. yield
  26. finally:
  27. os.chdir(cwd)
  28. def download(text, url, path):
  29. safe_mkdir(os.path.dirname(path))
  30. with open(path, 'wb') as local_file, urlopen(url) as web_file:
  31. print(f"Downloading {url} to {path}")
  32. info = web_file.info()
  33. if hasattr(info, 'getheader'):
  34. file_size = int(info.getheaders("Content-Length")[0])
  35. else:
  36. file_size = int(info.get("Content-Length")[0])
  37. downloaded_size = 0
  38. block_size = 4096
  39. ci = os.environ.get('CI') is not None
  40. while True:
  41. buf = web_file.read(block_size)
  42. if not buf:
  43. break
  44. downloaded_size += len(buf)
  45. local_file.write(buf)
  46. if not ci:
  47. percent = downloaded_size * 100. / file_size
  48. status = f"\r{text} {downloaded_size:10d} [{percent:3.1f}%]"
  49. print(status, end=' ')
  50. if ci:
  51. print(f"{text} done.")
  52. else:
  53. print()
  54. return path
  55. def make_zip(zip_file_path, files, dirs):
  56. safe_unlink(zip_file_path)
  57. if sys.platform == 'darwin':
  58. allfiles = files + dirs
  59. execute(['zip', '-r', '-y', zip_file_path] + allfiles)
  60. else:
  61. with zipfile.ZipFile(zip_file_path, "w",
  62. zipfile.ZIP_DEFLATED,
  63. allowZip64=True) as zip_file:
  64. for filename in files:
  65. zip_file.write(filename, filename)
  66. for dirname in dirs:
  67. for root, _, filenames in os.walk(dirname):
  68. for f in filenames:
  69. zip_file.write(os.path.join(root, f))
  70. zip_file.close()
  71. def rm_rf(path):
  72. try:
  73. shutil.rmtree(path)
  74. except OSError:
  75. pass
  76. def safe_unlink(path):
  77. try:
  78. os.unlink(path)
  79. except OSError as e:
  80. if e.errno != errno.ENOENT:
  81. raise
  82. def safe_mkdir(path):
  83. try:
  84. os.makedirs(path)
  85. except OSError as e:
  86. if e.errno != errno.EEXIST:
  87. raise
  88. def execute(argv, env=None, cwd=None):
  89. if env is None:
  90. env = os.environ
  91. verbose_mode_print(' '.join(argv))
  92. try:
  93. output = subprocess.check_output(argv, stderr=subprocess.STDOUT,
  94. env=env, cwd=cwd)
  95. verbose_mode_print(output.decode('utf-8').strip())
  96. return output
  97. except subprocess.CalledProcessError as e:
  98. print(e.output)
  99. raise e
  100. def get_electron_branding():
  101. SOURCE_ROOT = os.path.abspath(os.path.join(__file__, '..', '..', '..'))
  102. branding_file_path = os.path.join(
  103. SOURCE_ROOT, 'shell', 'app', 'BRANDING.json')
  104. with open(branding_file_path, encoding='utf-8') as file_in:
  105. return json.load(file_in)
  106. cached_electron_version = None
  107. def get_electron_version():
  108. global cached_electron_version
  109. if cached_electron_version is None:
  110. cached_electron_version = str.strip(execute([
  111. 'node',
  112. '-p',
  113. 'require("./script/lib/get-version").getElectronVersion()'
  114. ], cwd=ELECTRON_DIR).decode())
  115. return cached_electron_version
  116. def store_artifact(prefix, key_prefix, files):
  117. # Azure Storage
  118. azput(prefix, key_prefix, files)
  119. def azput(prefix, key_prefix, files):
  120. env = os.environ.copy()
  121. output = execute([
  122. 'node',
  123. os.path.join(os.path.dirname(__file__), 'azput.js'),
  124. '--prefix', prefix,
  125. '--key_prefix', key_prefix,
  126. ] + files, env)
  127. print(output)
  128. def get_out_dir():
  129. out_dir = 'Default'
  130. override = os.environ.get('ELECTRON_OUT_DIR')
  131. if override is not None:
  132. out_dir = override
  133. return os.path.join(SRC_DIR, 'out', out_dir)
  134. # NOTE: This path is not created by gn, it is used as a scratch zone by our
  135. # upload scripts
  136. def get_dist_dir():
  137. return os.path.join(get_out_dir(), 'gen', 'electron_dist')
  138. def get_electron_exec():
  139. out_dir = get_out_dir()
  140. if sys.platform == 'darwin':
  141. return f'{out_dir}/Electron.app/Contents/MacOS/Electron'
  142. if sys.platform == 'win32':
  143. return f'{out_dir}/electron.exe'
  144. if sys.platform == 'linux':
  145. return f'{out_dir}/electron'
  146. raise Exception(
  147. f"get_electron_exec: unexpected platform '{sys.platform}'")
  148. def get_buildtools_executable(name):
  149. buildtools = os.path.realpath(os.path.join(ELECTRON_DIR, '..', 'buildtools'))
  150. if sys.platform == 'darwin':
  151. chromium_platform = 'mac_arm64' if platform.machine() == 'arm64' else 'mac'
  152. elif sys.platform in ['win32', 'cygwin']:
  153. chromium_platform = 'win'
  154. elif sys.platform in ['linux', 'linux2']:
  155. chromium_platform = 'linux64'
  156. else:
  157. raise Exception(f"Unsupported platform: {sys.platform}")
  158. if name == 'clang-format':
  159. chromium_platform += '-format'
  160. path = os.path.join(buildtools, chromium_platform, name)
  161. if sys.platform == 'win32':
  162. path += '.exe'
  163. return path
  164. def get_depot_tools_executable(name):
  165. buildtools = os.path.realpath(
  166. os.path.join(ELECTRON_DIR, '..', 'third_party', 'depot_tools'))
  167. path = os.path.join(buildtools, name)
  168. if sys.platform == 'win32':
  169. path += '.bat'
  170. return path
  171. def get_linux_binaries():
  172. return [
  173. 'chrome-sandbox',
  174. 'chrome_crashpad_handler',
  175. get_electron_branding()['project_name'],
  176. 'libEGL.so',
  177. 'libGLESv2.so',
  178. 'libffmpeg.so',
  179. 'libvk_swiftshader.so',
  180. ]