15f9996aaSopenharmony_ci#!/usr/bin/env python
25f9996aaSopenharmony_ci# -*- coding: utf-8 -*-
35f9996aaSopenharmony_ci# Copyright (c) 2021 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 subprocess
195f9996aaSopenharmony_ciimport json
205f9996aaSopenharmony_cifrom typing import List
215f9996aaSopenharmony_ci
225f9996aaSopenharmony_ci
235f9996aaSopenharmony_cidef run_command(cmd: List[str], verbose = None):
245f9996aaSopenharmony_ci    """Execute command `cmd`
255f9996aaSopenharmony_ci    :param cmd: Command to be executed.
265f9996aaSopenharmony_ci    :param verbose: Whether echo runtime infomation and output of command `cmd`.
275f9996aaSopenharmony_ci    :return output: The output of command `cmd`.
285f9996aaSopenharmony_ci    :return returncode: The return code of command `cmd`.
295f9996aaSopenharmony_ci    """
305f9996aaSopenharmony_ci    if verbose:
315f9996aaSopenharmony_ci        print("Running: {}".format(' '.join(cmd)))
325f9996aaSopenharmony_ci    p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
335f9996aaSopenharmony_ci    output, _ = p.communicate()
345f9996aaSopenharmony_ci    if verbose:
355f9996aaSopenharmony_ci        print(output.decode().rstrip())
365f9996aaSopenharmony_ci    return output, p.returncode
375f9996aaSopenharmony_ci
385f9996aaSopenharmony_ci
395f9996aaSopenharmony_cidef package_installed(pkg_name: str):
405f9996aaSopenharmony_ci    """Check whether package `pkg_name` is installed or not.
415f9996aaSopenharmony_ci    Got package `pkg_name` installation state by executing `dpkg -s pkg_name`.
425f9996aaSopenharmony_ci    :param pkg_name: Package name to check.
435f9996aaSopenharmony_ci    :return r: Check result, 0 means installed, non-zero means not installed.
445f9996aaSopenharmony_ci    """
455f9996aaSopenharmony_ci    cmd = ['dpkg', '-s', pkg_name]
465f9996aaSopenharmony_ci    _, r = run_command(cmd)
475f9996aaSopenharmony_ci    return r
485f9996aaSopenharmony_ci
495f9996aaSopenharmony_ci
505f9996aaSopenharmony_cidef check_build_requried_packages(host_version: str, check: bool = True):
515f9996aaSopenharmony_ci    """Check whether packages required by build process installed or not.
525f9996aaSopenharmony_ci    By parsing file `REPO_ROOT/build/scripts/build_package_list.json`.
535f9996aaSopenharmony_ci    Example content: `{"18.04":{"dep_package":["pkg1","pkg2",...]}, "20.04":{...}, "22.04":{...}}`
545f9996aaSopenharmony_ci    Currently there are only lists for `Ubuntu 18.04` , `Ubuntu 20.04` and `Ubuntu 22.04`.
555f9996aaSopenharmony_ci    :param host_version: OS version of the host.
565f9996aaSopenharmony_ci    :param check: Whether to prompt user of missing package.
575f9996aaSopenharmony_ci    :return _build_package_list: List of packages required by build process.
585f9996aaSopenharmony_ci    :return install_package_list: Packages installed.
595f9996aaSopenharmony_ci    :return uninstall_package_list: Packages missing.
605f9996aaSopenharmony_ci    """
615f9996aaSopenharmony_ci    sys.path.append(os.path.join(os.path.dirname(os.path.abspath(__file__)), 'util'))
625f9996aaSopenharmony_ci    from file_utils import find_top
635f9996aaSopenharmony_ci    cur_dir = find_top()
645f9996aaSopenharmony_ci    build_package_json = os.path.join(
655f9996aaSopenharmony_ci        cur_dir, 'build/scripts/build_package_list.json')
665f9996aaSopenharmony_ci    with open(build_package_json, 'r') as file:
675f9996aaSopenharmony_ci        file_json = json.load(file)
685f9996aaSopenharmony_ci        for _version in file_json.keys():
695f9996aaSopenharmony_ci            if host_version == _version or host_version.startswith(_version):
705f9996aaSopenharmony_ci                _build_package_list = file_json["{}".format(
715f9996aaSopenharmony_ci                    _version)]["dep_package"]
725f9996aaSopenharmony_ci    uninstall_package_list = []
735f9996aaSopenharmony_ci    for pkg in _build_package_list:
745f9996aaSopenharmony_ci        if package_installed(pkg):
755f9996aaSopenharmony_ci            if check:
765f9996aaSopenharmony_ci                print("\033[33m {} is not installed. please install it.\033[0m".
775f9996aaSopenharmony_ci                      format(pkg))
785f9996aaSopenharmony_ci            uninstall_package_list.append(pkg)
795f9996aaSopenharmony_ci    install_package_list = list(
805f9996aaSopenharmony_ci        set(_build_package_list).difference(uninstall_package_list))
815f9996aaSopenharmony_ci    return _build_package_list, install_package_list, uninstall_package_list
825f9996aaSopenharmony_ci
835f9996aaSopenharmony_ci
845f9996aaSopenharmony_cidef check_os_version():
855f9996aaSopenharmony_ci    """Check OS type and version.
865f9996aaSopenharmony_ci    By parsing file `/etc/issue`.
875f9996aaSopenharmony_ci    :return -1: Retuern -1 if OS is not supported.
885f9996aaSopenharmony_ci    :return host_os: Host OS type, currently only `Ubuntu` supported.
895f9996aaSopenharmony_ci    :return host_version: Host OS version, currently only `18.04[.X]`, `20.04[.X]` or `22.04[.X]` supported.
905f9996aaSopenharmony_ci    """
915f9996aaSopenharmony_ci    available_os = ('Ubuntu')
925f9996aaSopenharmony_ci    available_releases = ('18.04', '20.04', '22.04')
935f9996aaSopenharmony_ci    _os_info, _returncode = run_command(['cat', '/etc/issue'])
945f9996aaSopenharmony_ci    if _returncode != 0:
955f9996aaSopenharmony_ci        return -1
965f9996aaSopenharmony_ci
975f9996aaSopenharmony_ci    _os_info = _os_info.decode().rstrip().split()
985f9996aaSopenharmony_ci    host_os = _os_info[0]
995f9996aaSopenharmony_ci    host_version = _os_info[1]
1005f9996aaSopenharmony_ci    if host_os not in available_os:
1015f9996aaSopenharmony_ci        print("\033[33m OS {} is not supported for ohos build.\033[0m".format(
1025f9996aaSopenharmony_ci            host_os))
1035f9996aaSopenharmony_ci        return -1
1045f9996aaSopenharmony_ci    version_available = False
1055f9996aaSopenharmony_ci    for _version in available_releases:
1065f9996aaSopenharmony_ci        if host_version == _version or host_version.startswith(_version):
1075f9996aaSopenharmony_ci            version_available = True
1085f9996aaSopenharmony_ci            break
1095f9996aaSopenharmony_ci    if not version_available:
1105f9996aaSopenharmony_ci        print("\033[33m OS version {} is not supported for ohos build.\033[0m".
1115f9996aaSopenharmony_ci              format(host_version))
1125f9996aaSopenharmony_ci        print("\033[33m Available OS version are {}.\033[0m".format(
1135f9996aaSopenharmony_ci            ', '.join(available_releases)))
1145f9996aaSopenharmony_ci        return -1
1155f9996aaSopenharmony_ci    return host_os, host_version
1165f9996aaSopenharmony_ci
1175f9996aaSopenharmony_ci
1185f9996aaSopenharmony_cidef main():
1195f9996aaSopenharmony_ci    """Entrance function.
1205f9996aaSopenharmony_ci    :return -1: Return -1 on error.
1215f9996aaSopenharmony_ci    :return 0: Return 0 on success.
1225f9996aaSopenharmony_ci    """
1235f9996aaSopenharmony_ci    check_result = check_os_version()
1245f9996aaSopenharmony_ci
1255f9996aaSopenharmony_ci    if check_result == -1:
1265f9996aaSopenharmony_ci        return -1
1275f9996aaSopenharmony_ci
1285f9996aaSopenharmony_ci    _, _, missing_packages = check_build_requried_packages(
1295f9996aaSopenharmony_ci        check_result[1], check=True)
1305f9996aaSopenharmony_ci
1315f9996aaSopenharmony_ci    if (len(missing_packages) == 0):
1325f9996aaSopenharmony_ci        return 0
1335f9996aaSopenharmony_ci    else:
1345f9996aaSopenharmony_ci        print("\033[31m Missing dependencies, please check!\033[0m")
1355f9996aaSopenharmony_ci        return -1
1365f9996aaSopenharmony_ci
1375f9996aaSopenharmony_ci
1385f9996aaSopenharmony_ciif __name__ == '__main__':
1395f9996aaSopenharmony_ci    sys.exit(main())
140