15f9996aaSopenharmony_ci#!/usr/bin/env python3
25f9996aaSopenharmony_ci# -*- coding: utf-8 -*-
35f9996aaSopenharmony_ci# Copyright (c) 2022 Huawei Device Co., Ltd.
45f9996aaSopenharmony_ci# Licensed under the Apache License, Version 2.0 (the "License");
55f9996aaSopenharmony_ci# you may not use this file except in compliance with the License.
65f9996aaSopenharmony_ci# You may obtain a copy of the License at
75f9996aaSopenharmony_ci#
85f9996aaSopenharmony_ci#     http://www.apache.org/licenses/LICENSE-2.0
95f9996aaSopenharmony_ci#
105f9996aaSopenharmony_ci# Unless required by applicable law or agreed to in writing, software
115f9996aaSopenharmony_ci# distributed under the License is distributed on an "AS IS" BASIS,
125f9996aaSopenharmony_ci# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
135f9996aaSopenharmony_ci# See the License for the specific language governing permissions and
145f9996aaSopenharmony_ci# limitations under the License.
155f9996aaSopenharmony_ci
165f9996aaSopenharmony_ciimport os
175f9996aaSopenharmony_ciimport sys
185f9996aaSopenharmony_ciimport argparse
195f9996aaSopenharmony_ciimport subprocess
205f9996aaSopenharmony_ciimport ssl
215f9996aaSopenharmony_ciimport shutil
225f9996aaSopenharmony_ciimport importlib
235f9996aaSopenharmony_ciimport time
245f9996aaSopenharmony_ciimport pathlib
255f9996aaSopenharmony_ciimport re
265f9996aaSopenharmony_cifrom multiprocessing import cpu_count
275f9996aaSopenharmony_cifrom concurrent.futures import ThreadPoolExecutor, as_completed
285f9996aaSopenharmony_cifrom functools import partial
295f9996aaSopenharmony_cifrom urllib.request import urlopen
305f9996aaSopenharmony_ciimport urllib.error
315f9996aaSopenharmony_cifrom scripts.util.file_utils import read_json_file
325f9996aaSopenharmony_ci
335f9996aaSopenharmony_ci
345f9996aaSopenharmony_cidef _run_cmd(cmd: str):
355f9996aaSopenharmony_ci    res = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE,
365f9996aaSopenharmony_ci                           stderr=subprocess.PIPE)
375f9996aaSopenharmony_ci    sout, serr = res.communicate()
385f9996aaSopenharmony_ci    return sout.rstrip().decode('utf-8'), serr, res.returncode
395f9996aaSopenharmony_ci
405f9996aaSopenharmony_ci
415f9996aaSopenharmony_cidef _check_sha256(check_url: str, local_file: str) -> bool:
425f9996aaSopenharmony_ci    check_sha256_cmd = 'curl -s -k ' + check_url + '.sha256'
435f9996aaSopenharmony_ci    local_sha256_cmd = 'sha256sum ' + local_file + "|cut -d ' ' -f1"
445f9996aaSopenharmony_ci    check_sha256, err, returncode = _run_cmd(check_sha256_cmd)
455f9996aaSopenharmony_ci    local_sha256, err, returncode = _run_cmd(local_sha256_cmd)
465f9996aaSopenharmony_ci    if check_sha256 != local_sha256:
475f9996aaSopenharmony_ci        print('remote file {}.sha256 is not found, begin check SHASUMS256.txt'.format(check_url))
485f9996aaSopenharmony_ci        check_sha256 = _obtain_sha256_by_sha_sums256(check_url)
495f9996aaSopenharmony_ci    return check_sha256 == local_sha256
505f9996aaSopenharmony_ci
515f9996aaSopenharmony_ci
525f9996aaSopenharmony_cidef _check_sha256_by_mark(args, check_url: str, code_dir: str, unzip_dir: str, unzip_filename: str) -> bool:
535f9996aaSopenharmony_ci    check_sha256_cmd = 'curl -s -k ' + check_url + '.sha256'
545f9996aaSopenharmony_ci    check_sha256, err, returncode = _run_cmd(check_sha256_cmd)
555f9996aaSopenharmony_ci    mark_file_dir = os.path.join(code_dir, unzip_dir)
565f9996aaSopenharmony_ci    mark_file_name = check_sha256 + '.' + unzip_filename + '.mark'
575f9996aaSopenharmony_ci    mark_file_path = os.path.join(mark_file_dir, mark_file_name)
585f9996aaSopenharmony_ci    args.mark_file_path = mark_file_path
595f9996aaSopenharmony_ci    return os.path.exists(mark_file_path)
605f9996aaSopenharmony_ci
615f9996aaSopenharmony_ci
625f9996aaSopenharmony_cidef _obtain_sha256_by_sha_sums256(check_url: str) -> str:
635f9996aaSopenharmony_ci    sha_sums256 = 'SHASUMS256.txt'
645f9996aaSopenharmony_ci    sha_sums256_path = os.path.join(os.path.dirname(check_url), sha_sums256)
655f9996aaSopenharmony_ci    file_name = os.path.basename(check_url)
665f9996aaSopenharmony_ci    cmd = 'curl -s -k ' + sha_sums256_path
675f9996aaSopenharmony_ci    data_sha_sums256, err, returncode = _run_cmd(cmd)
685f9996aaSopenharmony_ci    check_sha256 = None
695f9996aaSopenharmony_ci    for line in data_sha_sums256.split('\n'):
705f9996aaSopenharmony_ci        if file_name in line:
715f9996aaSopenharmony_ci            check_sha256 = line.split(' ')[0]
725f9996aaSopenharmony_ci    return check_sha256
735f9996aaSopenharmony_ci
745f9996aaSopenharmony_ci
755f9996aaSopenharmony_cidef _config_parse(config: dict, tool_repo: str, glibc_version: str) -> dict:
765f9996aaSopenharmony_ci    parse_dict = dict()
775f9996aaSopenharmony_ci    parse_dict['unzip_dir'] = config.get('unzip_dir')
785f9996aaSopenharmony_ci    file_path = config.get('file_path')
795f9996aaSopenharmony_ci    if 'python' in file_path and glibc_version is not None:
805f9996aaSopenharmony_ci        file_path = re.sub(r'GLIBC[0-9]\.[0-9]{2}', glibc_version, file_path)
815f9996aaSopenharmony_ci    parse_dict['huaweicloud_url'] = tool_repo + file_path
825f9996aaSopenharmony_ci    parse_dict['unzip_filename'] = config.get('unzip_filename')
835f9996aaSopenharmony_ci    md5_huaweicloud_url_cmd = 'echo ' + parse_dict.get('huaweicloud_url') + "|md5sum|cut -d ' ' -f1"
845f9996aaSopenharmony_ci    parse_dict['md5_huaweicloud_url'], err, returncode = _run_cmd(md5_huaweicloud_url_cmd)
855f9996aaSopenharmony_ci    parse_dict['bin_file'] = os.path.basename(parse_dict.get('huaweicloud_url'))
865f9996aaSopenharmony_ci    return parse_dict
875f9996aaSopenharmony_ci
885f9996aaSopenharmony_ci
895f9996aaSopenharmony_cidef _uncompress(args, src_file: str, code_dir: str, unzip_dir: str, unzip_filename: str, mark_file_path: str):
905f9996aaSopenharmony_ci    dest_dir = os.path.join(code_dir, unzip_dir)
915f9996aaSopenharmony_ci    if src_file[-3:] == 'zip':
925f9996aaSopenharmony_ci        cmd = 'unzip -o {} -d {};echo 0 > {}'.format(src_file, dest_dir, mark_file_path)
935f9996aaSopenharmony_ci    elif src_file[-6:] == 'tar.gz':
945f9996aaSopenharmony_ci        cmd = 'tar -xvzf {} -C {};echo 0 > {}'.format(src_file, dest_dir, mark_file_path)
955f9996aaSopenharmony_ci    else:
965f9996aaSopenharmony_ci        cmd = 'tar -xvf {} -C {};echo 0 > {}'.format(src_file, dest_dir, mark_file_path)
975f9996aaSopenharmony_ci    _run_cmd(cmd)
985f9996aaSopenharmony_ci
995f9996aaSopenharmony_ci
1005f9996aaSopenharmony_cidef _copy_url(args, task_id: int, url: str, local_file: str, code_dir: str, unzip_dir: str,
1015f9996aaSopenharmony_ci              unzip_filename: str, mark_file_path: str, progress):
1025f9996aaSopenharmony_ci    retry_times = 0
1035f9996aaSopenharmony_ci    max_retry_times = 3
1045f9996aaSopenharmony_ci    while retry_times < max_retry_times:
1055f9996aaSopenharmony_ci        # download files
1065f9996aaSopenharmony_ci        download_buffer_size = 32768
1075f9996aaSopenharmony_ci        progress.console.log('Requesting {}'.format(url))
1085f9996aaSopenharmony_ci        try:
1095f9996aaSopenharmony_ci            response = urlopen(url)
1105f9996aaSopenharmony_ci        except urllib.error.HTTPError as e:
1115f9996aaSopenharmony_ci            progress.console.log("Failed to open {}, HTTPError: {}".format(url, e.code), style='red')
1125f9996aaSopenharmony_ci        progress.update(task_id, total=int(response.info()["Content-length"]))
1135f9996aaSopenharmony_ci        with open(local_file, "wb") as dest_file:
1145f9996aaSopenharmony_ci            progress.start_task(task_id)
1155f9996aaSopenharmony_ci            for data in iter(partial(response.read, download_buffer_size), b""):
1165f9996aaSopenharmony_ci                dest_file.write(data)
1175f9996aaSopenharmony_ci                progress.update(task_id, advance=len(data))
1185f9996aaSopenharmony_ci        progress.console.log("Downloaded {}".format(local_file))
1195f9996aaSopenharmony_ci
1205f9996aaSopenharmony_ci        if os.path.exists(local_file):
1215f9996aaSopenharmony_ci            if _check_sha256(url, local_file):
1225f9996aaSopenharmony_ci                # decompressing files
1235f9996aaSopenharmony_ci                progress.console.log("Decompressing {}".format(local_file))
1245f9996aaSopenharmony_ci                _uncompress(args, local_file, code_dir, unzip_dir, unzip_filename, mark_file_path)
1255f9996aaSopenharmony_ci                progress.console.log("Decompressed {}".format(local_file))
1265f9996aaSopenharmony_ci                break
1275f9996aaSopenharmony_ci            else:
1285f9996aaSopenharmony_ci                os.remove(local_file)
1295f9996aaSopenharmony_ci        retry_times += 1
1305f9996aaSopenharmony_ci    if retry_times == max_retry_times:
1315f9996aaSopenharmony_ci        print('{}, download failed with three times retry, please check network status. Prebuilts download exit.'.format(local_file))
1325f9996aaSopenharmony_ci        # todo, merge with copy_url_disable_rich
1335f9996aaSopenharmony_ci        sys.exit(1)
1345f9996aaSopenharmony_ci
1355f9996aaSopenharmony_ci
1365f9996aaSopenharmony_cidef _copy_url_disable_rich(args, url: str, local_file: str, code_dir: str, unzip_dir: str,
1375f9996aaSopenharmony_ci                           unzip_filename: str, mark_file_path: str):
1385f9996aaSopenharmony_ci    # download files
1395f9996aaSopenharmony_ci    download_buffer_size = 32768
1405f9996aaSopenharmony_ci    print('Requesting {}, please wait'.format(url))
1415f9996aaSopenharmony_ci    try:
1425f9996aaSopenharmony_ci        response = urlopen(url)
1435f9996aaSopenharmony_ci    except urllib.error.HTTPError as e:
1445f9996aaSopenharmony_ci        print("Failed to open {}, HTTPError: {}".format(url, e.code))
1455f9996aaSopenharmony_ci    with open(local_file, "wb") as dest_file:
1465f9996aaSopenharmony_ci        for data in iter(partial(response.read, download_buffer_size), b""):
1475f9996aaSopenharmony_ci            dest_file.write(data)
1485f9996aaSopenharmony_ci    print("Downloaded {}".format(local_file))
1495f9996aaSopenharmony_ci
1505f9996aaSopenharmony_ci    # decompressing files
1515f9996aaSopenharmony_ci    print("Decompressing {}, please wait".format(local_file))
1525f9996aaSopenharmony_ci    _uncompress(args, local_file, code_dir, unzip_dir, unzip_filename, mark_file_path)
1535f9996aaSopenharmony_ci    print("Decompressed {}".format(local_file))
1545f9996aaSopenharmony_ci
1555f9996aaSopenharmony_ci
1565f9996aaSopenharmony_cidef _is_system_component() -> bool:
1575f9996aaSopenharmony_ci    root_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
1585f9996aaSopenharmony_ci    if pathlib.Path(os.path.join(root_dir, 'interface', 'sdk-js')).exists() or pathlib.Path(
1595f9996aaSopenharmony_ci            os.path.join(root_dir, 'foundation', 'arkui')).exists() or pathlib.Path(
1605f9996aaSopenharmony_ci            os.path.join(root_dir, 'arkcompiler')).exists():
1615f9996aaSopenharmony_ci        return True
1625f9996aaSopenharmony_ci    else:
1635f9996aaSopenharmony_ci        return False
1645f9996aaSopenharmony_ci
1655f9996aaSopenharmony_ci
1665f9996aaSopenharmony_cidef _hwcloud_download(args, config: dict, bin_dir: str, code_dir: str, glibc_version: str):
1675f9996aaSopenharmony_ci    try:
1685f9996aaSopenharmony_ci        cnt = cpu_count()
1695f9996aaSopenharmony_ci    except Exception as e:
1705f9996aaSopenharmony_ci        cnt = 1
1715f9996aaSopenharmony_ci    with ThreadPoolExecutor(max_workers=cnt) as pool:
1725f9996aaSopenharmony_ci        tasks = dict()
1735f9996aaSopenharmony_ci        for config_info in config:
1745f9996aaSopenharmony_ci            parse_dict = _config_parse(config_info, args.tool_repo, glibc_version)
1755f9996aaSopenharmony_ci            unzip_dir = parse_dict.get('unzip_dir')
1765f9996aaSopenharmony_ci            huaweicloud_url = parse_dict.get('huaweicloud_url')
1775f9996aaSopenharmony_ci            unzip_filename = parse_dict.get('unzip_filename')
1785f9996aaSopenharmony_ci            md5_huaweicloud_url = parse_dict.get('md5_huaweicloud_url')
1795f9996aaSopenharmony_ci            bin_file = parse_dict.get('bin_file')
1805f9996aaSopenharmony_ci            abs_unzip_dir = os.path.join(code_dir, unzip_dir)
1815f9996aaSopenharmony_ci            if not os.path.exists(abs_unzip_dir):
1825f9996aaSopenharmony_ci                os.makedirs(abs_unzip_dir, exist_ok=True)
1835f9996aaSopenharmony_ci            if _check_sha256_by_mark(args, huaweicloud_url, code_dir, unzip_dir, unzip_filename):
1845f9996aaSopenharmony_ci                if not args.disable_rich:
1855f9996aaSopenharmony_ci                    args.progress.console.log('{}, Sha256 markword check OK.'.format(huaweicloud_url), style='green')
1865f9996aaSopenharmony_ci                else:
1875f9996aaSopenharmony_ci                    print('{}, Sha256 markword check OK.'.format(huaweicloud_url))
1885f9996aaSopenharmony_ci            else:
1895f9996aaSopenharmony_ci                _run_cmd(('rm -rf {}/{}/*.{}.mark').format(code_dir, unzip_dir, unzip_filename))
1905f9996aaSopenharmony_ci                _run_cmd(('rm -rf {}/{}/{}').format(code_dir, unzip_dir, unzip_filename))
1915f9996aaSopenharmony_ci                local_file = os.path.join(bin_dir, '{}.{}'.format(md5_huaweicloud_url, bin_file))
1925f9996aaSopenharmony_ci                if os.path.exists(local_file):
1935f9996aaSopenharmony_ci                    if _check_sha256(huaweicloud_url, local_file):
1945f9996aaSopenharmony_ci                        if not args.disable_rich:
1955f9996aaSopenharmony_ci                            args.progress.console.log('{}, Sha256 check download OK.'.format(local_file), style='green')
1965f9996aaSopenharmony_ci                        else:
1975f9996aaSopenharmony_ci                            print('{}, Sha256 check download OK. Start decompression, please wait'.format(local_file))
1985f9996aaSopenharmony_ci                        task = pool.submit(_uncompress, args, local_file, code_dir,
1995f9996aaSopenharmony_ci                                           unzip_dir, unzip_filename, args.mark_file_path)
2005f9996aaSopenharmony_ci                        tasks[task] = os.path.basename(huaweicloud_url)
2015f9996aaSopenharmony_ci                        continue
2025f9996aaSopenharmony_ci                    else:
2035f9996aaSopenharmony_ci                        os.remove(local_file)
2045f9996aaSopenharmony_ci                filename = huaweicloud_url.split("/")[-1]
2055f9996aaSopenharmony_ci                if not args.disable_rich:
2065f9996aaSopenharmony_ci                    task_id = args.progress.add_task("download", filename=filename, start=False)
2075f9996aaSopenharmony_ci                    task = pool.submit(_copy_url, args, task_id, huaweicloud_url, local_file, code_dir,
2085f9996aaSopenharmony_ci                                    unzip_dir, unzip_filename, args.mark_file_path, args.progress)
2095f9996aaSopenharmony_ci                    tasks[task] = os.path.basename(huaweicloud_url)
2105f9996aaSopenharmony_ci                else:
2115f9996aaSopenharmony_ci                    task = pool.submit(_copy_url_disable_rich, args, huaweicloud_url, local_file, code_dir,
2125f9996aaSopenharmony_ci                                        unzip_dir, unzip_filename, args.mark_file_path)
2135f9996aaSopenharmony_ci
2145f9996aaSopenharmony_ci        for task in as_completed(tasks):
2155f9996aaSopenharmony_ci            if not args.disable_rich:
2165f9996aaSopenharmony_ci                args.progress.console.log('{}, download and decompress completed'.format(tasks.get(task)),
2175f9996aaSopenharmony_ci                style='green')
2185f9996aaSopenharmony_ci            else:
2195f9996aaSopenharmony_ci                print('{}, download and decompress completed'.format(tasks.get(task)))
2205f9996aaSopenharmony_ci
2215f9996aaSopenharmony_ci
2225f9996aaSopenharmony_cidef _npm_install(args):
2235f9996aaSopenharmony_ci    node_path = 'prebuilts/build-tools/common/nodejs/current/bin'
2245f9996aaSopenharmony_ci    os.environ['PATH'] = '{}/{}:{}'.format(args.code_dir, node_path, os.environ.get('PATH'))
2255f9996aaSopenharmony_ci    npm = os.path.join(args.code_dir, node_path, 'npm')
2265f9996aaSopenharmony_ci    if args.skip_ssl:
2275f9996aaSopenharmony_ci        skip_ssl_cmd = '{} config set strict-ssl false;'.format(npm)
2285f9996aaSopenharmony_ci        out, err, retcode = _run_cmd(skip_ssl_cmd)
2295f9996aaSopenharmony_ci        if retcode != 0:
2305f9996aaSopenharmony_ci            return False, err.decode()
2315f9996aaSopenharmony_ci    npm_clean_cmd = '{} cache clean -f'.format(npm)
2325f9996aaSopenharmony_ci    npm_package_lock_cmd = '{} config set package-lock true'.format(npm)
2335f9996aaSopenharmony_ci    out, err, retcode = _run_cmd(npm_clean_cmd)
2345f9996aaSopenharmony_ci    if retcode != 0:
2355f9996aaSopenharmony_ci        return False, err.decode()
2365f9996aaSopenharmony_ci    out, err, retcode = _run_cmd(npm_package_lock_cmd)
2375f9996aaSopenharmony_ci    if retcode != 0:
2385f9996aaSopenharmony_ci        return False, err.decode()
2395f9996aaSopenharmony_ci    print('start npm install, please wait.')
2405f9996aaSopenharmony_ci    for install_info in args.npm_install_config:
2415f9996aaSopenharmony_ci        full_code_path = os.path.join(args.code_dir, install_info)
2425f9996aaSopenharmony_ci        basename = os.path.basename(full_code_path)
2435f9996aaSopenharmony_ci        node_modules_path = os.path.join(full_code_path, "node_modules")
2445f9996aaSopenharmony_ci        npm_cache_dir = os.path.join('~/.npm/_cacache', basename)
2455f9996aaSopenharmony_ci
2465f9996aaSopenharmony_ci        if os.path.exists(node_modules_path):
2475f9996aaSopenharmony_ci            print('remove node_modules %s' % node_modules_path)
2485f9996aaSopenharmony_ci            _run_cmd(('rm -rf {}'.format(node_modules_path)))
2495f9996aaSopenharmony_ci        if os.path.exists(full_code_path):
2505f9996aaSopenharmony_ci            cmd = ['timeout', '-s', '9', '90s', npm, 'install', '--registry', args.npm_registry, '--cache', npm_cache_dir]
2515f9996aaSopenharmony_ci            if args.host_platform == 'darwin':
2525f9996aaSopenharmony_ci                cmd = [npm, 'install', '--registry', args.npm_registry, '--cache', npm_cache_dir]
2535f9996aaSopenharmony_ci            if args.unsafe_perm:
2545f9996aaSopenharmony_ci                cmd.append('--unsafe-perm')
2555f9996aaSopenharmony_ci            proc = subprocess.Popen(cmd, cwd=full_code_path, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
2565f9996aaSopenharmony_ci            # wait proc Popen with 0.1 second
2575f9996aaSopenharmony_ci            time.sleep(0.1)
2585f9996aaSopenharmony_ci            out, err = proc.communicate()
2595f9996aaSopenharmony_ci            if proc.returncode:
2605f9996aaSopenharmony_ci                print("in dir:{}, executing:{}".format(full_code_path, ' '.join(cmd)))
2615f9996aaSopenharmony_ci                return False, err.decode()
2625f9996aaSopenharmony_ci        else:
2635f9996aaSopenharmony_ci            raise Exception("{} not exist, it shouldn't happen, pls check...".format(full_code_path))
2645f9996aaSopenharmony_ci    return True, None
2655f9996aaSopenharmony_ci
2665f9996aaSopenharmony_ci
2675f9996aaSopenharmony_cidef _node_modules_copy(config: dict, code_dir: str, enable_symlink: bool):
2685f9996aaSopenharmony_ci    for config_info in config:
2695f9996aaSopenharmony_ci        src_dir = os.path.join(code_dir, config_info.get('src'))
2705f9996aaSopenharmony_ci        if not os.path.exists(src_dir):
2715f9996aaSopenharmony_ci            print(f"{src_dir} not exist, skip node_modules copy.")
2725f9996aaSopenharmony_ci            continue
2735f9996aaSopenharmony_ci        dest_dir = os.path.join(code_dir, config_info.get('dest'))
2745f9996aaSopenharmony_ci        use_symlink = config_info.get('use_symlink')
2755f9996aaSopenharmony_ci        if os.path.exists(os.path.dirname(dest_dir)):
2765f9996aaSopenharmony_ci            shutil.rmtree(os.path.dirname(dest_dir))
2775f9996aaSopenharmony_ci        if use_symlink == 'True' and enable_symlink == True:
2785f9996aaSopenharmony_ci            os.makedirs(os.path.dirname(dest_dir), exist_ok=True)
2795f9996aaSopenharmony_ci            os.symlink(src_dir, dest_dir)
2805f9996aaSopenharmony_ci        else:
2815f9996aaSopenharmony_ci            shutil.copytree(src_dir, dest_dir, symlinks=True)
2825f9996aaSopenharmony_ci
2835f9996aaSopenharmony_ci
2845f9996aaSopenharmony_cidef _file_handle(config: dict, code_dir: str, host_platform: str):
2855f9996aaSopenharmony_ci    for config_info in config:
2865f9996aaSopenharmony_ci        src_dir = code_dir + config_info.get('src')
2875f9996aaSopenharmony_ci        dest_dir = code_dir + config_info.get('dest')
2885f9996aaSopenharmony_ci        tmp_dir = config_info.get('tmp')
2895f9996aaSopenharmony_ci        symlink_src = config_info.get('symlink_src')
2905f9996aaSopenharmony_ci        symlink_dest = config_info.get('symlink_dest')
2915f9996aaSopenharmony_ci        rename = config_info.get('rename')
2925f9996aaSopenharmony_ci        if os.path.exists(src_dir):
2935f9996aaSopenharmony_ci            if tmp_dir:
2945f9996aaSopenharmony_ci                tmp_dir = code_dir + tmp_dir
2955f9996aaSopenharmony_ci                shutil.move(src_dir, tmp_dir)
2965f9996aaSopenharmony_ci                cmd = 'mv {}/*.mark {}'.format(dest_dir, tmp_dir)
2975f9996aaSopenharmony_ci                _run_cmd(cmd)
2985f9996aaSopenharmony_ci                if os.path.exists(dest_dir):
2995f9996aaSopenharmony_ci                    shutil.rmtree(dest_dir)
3005f9996aaSopenharmony_ci                shutil.move(tmp_dir, dest_dir)
3015f9996aaSopenharmony_ci            elif rename:
3025f9996aaSopenharmony_ci                if os.path.exists(dest_dir) and dest_dir != src_dir:
3035f9996aaSopenharmony_ci                    shutil.rmtree(dest_dir)
3045f9996aaSopenharmony_ci                shutil.move(src_dir, dest_dir)
3055f9996aaSopenharmony_ci                if symlink_src and symlink_dest:
3065f9996aaSopenharmony_ci                    if os.path.exists(dest_dir + symlink_dest):
3075f9996aaSopenharmony_ci                        os.remove(dest_dir + symlink_dest)
3085f9996aaSopenharmony_ci                    if host_platform == 'darwin' and os.path.basename(dest_dir) == "nodejs":
3095f9996aaSopenharmony_ci                        symlink_src = symlink_src.replace('linux', 'darwin')
3105f9996aaSopenharmony_ci                    os.symlink(os.path.basename(symlink_src), dest_dir + symlink_dest)
3115f9996aaSopenharmony_ci            else:
3125f9996aaSopenharmony_ci                _run_cmd('chmod 755 {} -R'.format(dest_dir))
3135f9996aaSopenharmony_ci
3145f9996aaSopenharmony_ci
3155f9996aaSopenharmony_cidef _import_rich_module():
3165f9996aaSopenharmony_ci    module = importlib.import_module('rich.progress')
3175f9996aaSopenharmony_ci    progress = module.Progress(
3185f9996aaSopenharmony_ci        module.TextColumn("[bold blue]{task.fields[filename]}", justify="right"),
3195f9996aaSopenharmony_ci        module.BarColumn(bar_width=None),
3205f9996aaSopenharmony_ci        "[progress.percentage]{task.percentage:>3.1f}%",
3215f9996aaSopenharmony_ci        "•",
3225f9996aaSopenharmony_ci        module.DownloadColumn(),
3235f9996aaSopenharmony_ci        "•",
3245f9996aaSopenharmony_ci        module.TransferSpeedColumn(),
3255f9996aaSopenharmony_ci        "•",
3265f9996aaSopenharmony_ci        module.TimeRemainingColumn(),
3275f9996aaSopenharmony_ci    )
3285f9996aaSopenharmony_ci    return progress
3295f9996aaSopenharmony_ci
3305f9996aaSopenharmony_ci
3315f9996aaSopenharmony_cidef _install(config: dict, code_dir: str):
3325f9996aaSopenharmony_ci    for config_info in config:
3335f9996aaSopenharmony_ci        install_dir = '{}/{}'.format(code_dir, config_info.get('install_dir'))
3345f9996aaSopenharmony_ci        script = config_info.get('script')
3355f9996aaSopenharmony_ci        cmd = '{}/{}'.format(install_dir, script)
3365f9996aaSopenharmony_ci        args = config_info.get('args')
3375f9996aaSopenharmony_ci        for arg in args:
3385f9996aaSopenharmony_ci            for key in arg.keys():
3395f9996aaSopenharmony_ci                cmd = '{} --{}={}'.format(cmd, key, arg[key])
3405f9996aaSopenharmony_ci        dest_dir = '{}/{}'.format(code_dir, config_info.get('destdir'))
3415f9996aaSopenharmony_ci        cmd = '{} --destdir={}'.format(cmd, dest_dir)
3425f9996aaSopenharmony_ci        _run_cmd(cmd)
3435f9996aaSopenharmony_ci
3445f9996aaSopenharmony_ci
3455f9996aaSopenharmony_cidef main():
3465f9996aaSopenharmony_ci    parser = argparse.ArgumentParser()
3475f9996aaSopenharmony_ci    parser.add_argument('--skip-ssl', action='store_true', help='skip ssl authentication')
3485f9996aaSopenharmony_ci    parser.add_argument('--unsafe-perm', action='store_true', help='add "--unsafe-perm" for npm install')
3495f9996aaSopenharmony_ci    parser.add_argument('--disable-rich', action='store_true', help='disable the rich module')
3505f9996aaSopenharmony_ci    parser.add_argument('--enable-symlink', action='store_true', help='enable symlink while copying node_modules')
3515f9996aaSopenharmony_ci    parser.add_argument('--build-arkuix', action='store_true', help='build ArkUI-X SDK')
3525f9996aaSopenharmony_ci    parser.add_argument('--tool-repo', default='https://repo.huaweicloud.com', help='prebuilt file download source')
3535f9996aaSopenharmony_ci    parser.add_argument('--npm-registry', default='https://repo.huaweicloud.com/repository/npm/',
3545f9996aaSopenharmony_ci                        help='npm download source')
3555f9996aaSopenharmony_ci    parser.add_argument('--host-cpu', help='host cpu', required=True)
3565f9996aaSopenharmony_ci    parser.add_argument('--host-platform', help='host platform', required=True)
3575f9996aaSopenharmony_ci    parser.add_argument('--glibc-version', help='glibc version', required=False)
3585f9996aaSopenharmony_ci    parser.add_argument('--config-file', help='prebuilts download config file')
3595f9996aaSopenharmony_ci    args = parser.parse_args()
3605f9996aaSopenharmony_ci    args.code_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
3615f9996aaSopenharmony_ci    if args.skip_ssl:
3625f9996aaSopenharmony_ci        ssl._create_default_https_context = ssl._create_unverified_context
3635f9996aaSopenharmony_ci
3645f9996aaSopenharmony_ci    host_platform = args.host_platform
3655f9996aaSopenharmony_ci    host_cpu = args.host_cpu
3665f9996aaSopenharmony_ci    glibc_version = args.glibc_version
3675f9996aaSopenharmony_ci    tool_repo = args.tool_repo
3685f9996aaSopenharmony_ci    if args.build_arkuix:
3695f9996aaSopenharmony_ci        config_file = os.path.join(args.code_dir, 'build_plugins/prebuilts_download_config.json')
3705f9996aaSopenharmony_ci    elif args.config_file:
3715f9996aaSopenharmony_ci        config_file = args.config_file
3725f9996aaSopenharmony_ci    else:
3735f9996aaSopenharmony_ci        config_file = os.path.join(args.code_dir, 'build/prebuilts_download_config.json')
3745f9996aaSopenharmony_ci    config_info = read_json_file(config_file)
3755f9996aaSopenharmony_ci    if _is_system_component():
3765f9996aaSopenharmony_ci        args.npm_install_config = config_info.get('npm_install_path')
3775f9996aaSopenharmony_ci        node_modules_copy_config = config_info.get('node_modules_copy')
3785f9996aaSopenharmony_ci    else:
3795f9996aaSopenharmony_ci        args.npm_install_config = []
3805f9996aaSopenharmony_ci        node_modules_copy_config = []
3815f9996aaSopenharmony_ci    file_handle_config = config_info.get('file_handle_config')
3825f9996aaSopenharmony_ci
3835f9996aaSopenharmony_ci    args.bin_dir = os.path.join(args.code_dir, config_info.get('prebuilts_download_dir'))
3845f9996aaSopenharmony_ci    if not os.path.exists(args.bin_dir):
3855f9996aaSopenharmony_ci        os.makedirs(args.bin_dir, exist_ok=True)
3865f9996aaSopenharmony_ci    copy_config = config_info.get(host_platform).get(host_cpu).get('copy_config')
3875f9996aaSopenharmony_ci    node_config = config_info.get(host_platform).get('node_config')
3885f9996aaSopenharmony_ci    copy_config.extend(node_config)
3895f9996aaSopenharmony_ci    install_config = config_info.get(host_platform).get(host_cpu).get('install')
3905f9996aaSopenharmony_ci    if host_platform == 'linux':
3915f9996aaSopenharmony_ci        linux_copy_config = config_info.get(host_platform).get(host_cpu).get('linux_copy_config')
3925f9996aaSopenharmony_ci        copy_config.extend(linux_copy_config)
3935f9996aaSopenharmony_ci    elif host_platform == 'darwin':
3945f9996aaSopenharmony_ci        darwin_copy_config = config_info.get(host_platform).get(host_cpu).get('darwin_copy_config')
3955f9996aaSopenharmony_ci        copy_config.extend(darwin_copy_config)
3965f9996aaSopenharmony_ci    if args.disable_rich:
3975f9996aaSopenharmony_ci        _hwcloud_download(args, copy_config, args.bin_dir, args.code_dir, glibc_version)
3985f9996aaSopenharmony_ci    else:
3995f9996aaSopenharmony_ci        args.progress = _import_rich_module()
4005f9996aaSopenharmony_ci        with args.progress:
4015f9996aaSopenharmony_ci            _hwcloud_download(args, copy_config, args.bin_dir, args.code_dir, glibc_version)
4025f9996aaSopenharmony_ci
4035f9996aaSopenharmony_ci    _file_handle(file_handle_config, args.code_dir, args.host_platform)
4045f9996aaSopenharmony_ci    retry_times = 0
4055f9996aaSopenharmony_ci    max_retry_times = 2
4065f9996aaSopenharmony_ci    while retry_times <= max_retry_times:
4075f9996aaSopenharmony_ci        result, error = _npm_install(args)
4085f9996aaSopenharmony_ci        if result:
4095f9996aaSopenharmony_ci            break
4105f9996aaSopenharmony_ci        print("npm install error, error info: %s" % error)
4115f9996aaSopenharmony_ci        if retry_times == max_retry_times:
4125f9996aaSopenharmony_ci            for error_info in error.split('\n'):
4135f9996aaSopenharmony_ci                if error_info.endswith('debug.log'):
4145f9996aaSopenharmony_ci                    log_path = error_info.split()[-1]
4155f9996aaSopenharmony_ci                    cmd = ['cat', log_path]
4165f9996aaSopenharmony_ci                    process_cat = subprocess.Popen(cmd)
4175f9996aaSopenharmony_ci                    process_cat.communicate(timeout=60)
4185f9996aaSopenharmony_ci                    raise Exception("npm install error with three times, prebuilts download exit")
4195f9996aaSopenharmony_ci        retry_times += 1
4205f9996aaSopenharmony_ci    _node_modules_copy(node_modules_copy_config, args.code_dir, args.enable_symlink)
4215f9996aaSopenharmony_ci    if install_config:
4225f9996aaSopenharmony_ci        _install(install_config, args.code_dir)
4235f9996aaSopenharmony_ci
4245f9996aaSopenharmony_ci    # delete uninstalled tools
4255f9996aaSopenharmony_ci    uninstalled_tools = config_info.get('uninstalled_tools')
4265f9996aaSopenharmony_ci    for tool_path in uninstalled_tools:
4275f9996aaSopenharmony_ci        subprocess.run(['rm', '-rf', tool_path])
4285f9996aaSopenharmony_ci
4295f9996aaSopenharmony_ciif __name__ == '__main__':
4305f9996aaSopenharmony_ci    sys.exit(main())
431