1cb93a386Sopenharmony_ci#!/usr/bin/env python
2cb93a386Sopenharmony_ci
3cb93a386Sopenharmony_ci# Copyright 2019 Google LLC.
4cb93a386Sopenharmony_ci# Use of this source code is governed by a BSD-style license that can be
5cb93a386Sopenharmony_ci# found in the LICENSE file.
6cb93a386Sopenharmony_ci
7cb93a386Sopenharmony_ci"""
8cb93a386Sopenharmony_ciupdate_fuchsia_sdk
9cb93a386Sopenharmony_ci
10cb93a386Sopenharmony_ci  Downloads both the Fuchsia SDK and Fuchsia-compatible clang
11cb93a386Sopenharmony_ci  zip archives from chrome infra (CIPD) and extracts them to
12cb93a386Sopenharmony_ci  the arg-provide |sdk_dir| and |clang_dir| respectively.  This
13cb93a386Sopenharmony_ci  provides the complete toolchain required to build Fuchsia binaries
14cb93a386Sopenharmony_ci  from the Fuchsia SDK.
15cb93a386Sopenharmony_ci
16cb93a386Sopenharmony_ci"""
17cb93a386Sopenharmony_ci
18cb93a386Sopenharmony_ciimport argparse
19cb93a386Sopenharmony_ciimport errno
20cb93a386Sopenharmony_ciimport logging
21cb93a386Sopenharmony_ciimport os
22cb93a386Sopenharmony_ciimport platform
23cb93a386Sopenharmony_ciimport shutil
24cb93a386Sopenharmony_ciimport subprocess
25cb93a386Sopenharmony_ciimport tempfile
26cb93a386Sopenharmony_ci
27cb93a386Sopenharmony_cidef MessageExit(message):
28cb93a386Sopenharmony_ci  logging.error(message)
29cb93a386Sopenharmony_ci  sys.exit(1)
30cb93a386Sopenharmony_ci
31cb93a386Sopenharmony_ci# Verify that "cipd" tool is readily available.
32cb93a386Sopenharmony_cidef CipdLives():
33cb93a386Sopenharmony_ci    err_msg = "Cipd not found, please install. See: " + \
34cb93a386Sopenharmony_ci              "https://commondatastorage.googleapis.com/chrome-infra-docs/flat" + \
35cb93a386Sopenharmony_ci              "/depot_tools/docs/html/depot_tools_tutorial.html#_setting_up"
36cb93a386Sopenharmony_ci    try:
37cb93a386Sopenharmony_ci        subprocess.call(["cipd", "--version"])
38cb93a386Sopenharmony_ci    except OSError as e:
39cb93a386Sopenharmony_ci        if e.errno == errno.ENOENT:
40cb93a386Sopenharmony_ci            MessageExit(err_msg)
41cb93a386Sopenharmony_ci        else:
42cb93a386Sopenharmony_ci            MessageExit("cipd command execution failed.")
43cb93a386Sopenharmony_ci
44cb93a386Sopenharmony_ci# Download and unzip CIPD package archive.
45cb93a386Sopenharmony_cidef DownloadAndUnzip(pkg_name, version, cipd_cache_dir, output_dir):
46cb93a386Sopenharmony_ci  pkg_suffix = pkg_name.replace('/', '-') + ".zip"
47cb93a386Sopenharmony_ci  zip_file = tempfile.NamedTemporaryFile(suffix=pkg_suffix, delete=False)
48cb93a386Sopenharmony_ci  cipd_cmd = "cipd pkg-fetch " + pkg_name + " -version \"" + version + "\" -out " + \
49cb93a386Sopenharmony_ci      zip_file.name + " -cache-dir " + cipd_cache_dir
50cb93a386Sopenharmony_ci  unzip_cmd = "unzip -q " + zip_file.name + " -d " + output_dir
51cb93a386Sopenharmony_ci  os.system(cipd_cmd)
52cb93a386Sopenharmony_ci  os.system(unzip_cmd)
53cb93a386Sopenharmony_ci
54cb93a386Sopenharmony_cidef Main():
55cb93a386Sopenharmony_ci  CipdLives()
56cb93a386Sopenharmony_ci  parser = argparse.ArgumentParser()
57cb93a386Sopenharmony_ci  parser.add_argument("-sdk_dir", type=str,
58cb93a386Sopenharmony_ci          help="Destination directory for the fuchsia SDK.")
59cb93a386Sopenharmony_ci  parser.add_argument("-clang_dir", type=str,
60cb93a386Sopenharmony_ci          help="Destination directory for the fuchsia toolchain.")
61cb93a386Sopenharmony_ci  parser.add_argument("-overwrite_dirs", type=bool, default=False,
62cb93a386Sopenharmony_ci          help="REMOVES existing sdk and clang dirs and makes new ones.  When false " +
63cb93a386Sopenharmony_ci               "  the unzip command issue will require file overwrite confirmation.")
64cb93a386Sopenharmony_ci  parser.add_argument("-cipd_cache_dir", type=str, default="/tmp", required=False,
65cb93a386Sopenharmony_ci          help="Cache directory for CIPD downloads to prevent redundant downloads.")
66cb93a386Sopenharmony_ci  parser.add_argument("-cipd_sdk_version", type=str, default="latest", required=False,
67cb93a386Sopenharmony_ci          help="CIPD sdk version to download, e.g.: git_revision:fce11c6904c888e6d39f71e03806a540852dec41")
68cb93a386Sopenharmony_ci  parser.add_argument("-cipd_clang_version", type=str, default="latest", required=False,
69cb93a386Sopenharmony_ci          help="CIPD clang version to download, e.g.: git_revision:fce11c6904c888e6d39f71e03806a540852dec41")
70cb93a386Sopenharmony_ci  args = parser.parse_args()
71cb93a386Sopenharmony_ci
72cb93a386Sopenharmony_ci  sdk_dir = args.sdk_dir
73cb93a386Sopenharmony_ci  clang_dir = args.clang_dir
74cb93a386Sopenharmony_ci  cipd_sdk_version = args.cipd_sdk_version
75cb93a386Sopenharmony_ci  cipd_clang_version = args.cipd_clang_version
76cb93a386Sopenharmony_ci
77cb93a386Sopenharmony_ci  if args.overwrite_dirs:
78cb93a386Sopenharmony_ci    dirs = [sdk_dir, clang_dir]
79cb93a386Sopenharmony_ci    for curr_dir in dirs:
80cb93a386Sopenharmony_ci      try:
81cb93a386Sopenharmony_ci        if os.path.exists(curr_dir):
82cb93a386Sopenharmony_ci            shutil.rmtree(curr_dir)
83cb93a386Sopenharmony_ci        os.makedirs(curr_dir)
84cb93a386Sopenharmony_ci      except OSError:
85cb93a386Sopenharmony_ci        MessageExit("Creation of the directory %s failed" % curr_dir)
86cb93a386Sopenharmony_ci  else:
87cb93a386Sopenharmony_ci    # Make dirs for sdk and clang.
88cb93a386Sopenharmony_ci    if not os.path.exists(sdk_dir):
89cb93a386Sopenharmony_ci        os.makedirs(sdk_dir)
90cb93a386Sopenharmony_ci    if not os.path.exists(clang_dir):
91cb93a386Sopenharmony_ci        os.makedirs(clang_dir)
92cb93a386Sopenharmony_ci
93cb93a386Sopenharmony_ci    # Verify that existing dirs are writable.
94cb93a386Sopenharmony_ci    if (not os.access(sdk_dir, os.W_OK)) or (not os.path.isdir(sdk_dir)):
95cb93a386Sopenharmony_ci      MessageExit("Can't write to sdk dir " + sdk_dir)
96cb93a386Sopenharmony_ci    if (not os.access(clang_dir, os.W_OK)) or (not os.path.isdir(clang_dir)):
97cb93a386Sopenharmony_ci      MessageExit("Can't write to clang dir " + clang_dir)
98cb93a386Sopenharmony_ci 
99cb93a386Sopenharmony_ci  ostype = platform.system()
100cb93a386Sopenharmony_ci  if ostype == "Linux":
101cb93a386Sopenharmony_ci    os_string = "linux-amd64"
102cb93a386Sopenharmony_ci  elif ostype == "Darwin":
103cb93a386Sopenharmony_ci    os_string = "mac-amd64"
104cb93a386Sopenharmony_ci  else:
105cb93a386Sopenharmony_ci    MessageExit("Unknown host " + ostype)
106cb93a386Sopenharmony_ci
107cb93a386Sopenharmony_ci  # |sdk_pkg| and |clang_pkg| below are prescribed paths defined by chrome-infra.
108cb93a386Sopenharmony_ci  sdk_pkg = "fuchsia/sdk/core/" + os_string
109cb93a386Sopenharmony_ci  DownloadAndUnzip(sdk_pkg, cipd_sdk_version, args.cipd_cache_dir, sdk_dir)
110cb93a386Sopenharmony_ci  clang_pkg = "fuchsia/clang/" + os_string
111cb93a386Sopenharmony_ci  DownloadAndUnzip(clang_pkg, cipd_clang_version, args.cipd_cache_dir, clang_dir)
112cb93a386Sopenharmony_ci
113cb93a386Sopenharmony_ciif __name__ == "__main__":
114cb93a386Sopenharmony_ci  import sys
115cb93a386Sopenharmony_ci  Main()
116