• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env python
2"""Downloads a prebuilt gn binary to a place where gn.py can find it."""
3
4from __future__ import print_function
5
6import io
7import os
8try:
9    # In Python 3, we need the module urllib.reqest. In Python 2, this
10    # functionality was in the urllib2 module.
11    from urllib import request as urllib_request
12except ImportError:
13    import urllib2 as urllib_request
14import sys
15import zipfile
16
17
18def download_and_unpack(url, output_dir, gn):
19    """Download an archive from url and extract gn from it into output_dir."""
20    print('downloading %s ...' % url, end='')
21    sys.stdout.flush()
22    data = urllib_request.urlopen(url).read()
23    print(' done')
24    zipfile.ZipFile(io.BytesIO(data)).extract(gn, path=output_dir)
25
26
27def set_executable_bit(path):
28    mode = os.stat(path).st_mode
29    mode |= (mode & 0o444) >> 2 # Copy R bits to X.
30    os.chmod(path, mode) # No-op on Windows.
31
32
33def get_platform():
34    import platform
35    if sys.platform == 'darwin':
36        return 'mac-amd64' if platform.machine() != 'arm64' else 'mac-arm64'
37    if platform.machine() not in ('AMD64', 'x86_64'):
38        return None
39    if sys.platform.startswith('linux'):
40        return 'linux-amd64'
41    if sys.platform == 'win32':
42        return 'windows-amd64'
43
44
45def main():
46    platform = get_platform()
47    if not platform:
48        print('no prebuilt binary for', sys.platform)
49        return 1
50    dirname = os.path.join(os.path.dirname(__file__), 'bin', platform)
51    if not os.path.exists(dirname):
52        os.makedirs(dirname)
53
54    url = 'https://chrome-infra-packages.appspot.com/dl/gn/gn/%s/+/latest'
55    gn = 'gn' + ('.exe' if sys.platform == 'win32' else '')
56    if platform == 'mac-arm64': # For https://openradar.appspot.com/FB8914243
57        try: os.remove(os.path.join(dirname, gn))
58        except OSError: pass
59    download_and_unpack(url % platform, dirname, gn)
60    set_executable_bit(os.path.join(dirname, gn))
61
62
63if __name__ == '__main__':
64    sys.exit(main())
65