182 lines
4.6 KiB
Python
182 lines
4.6 KiB
Python
#!/usr/bin/env python3
|
|
# -*- coding: UTF-8 -*-
|
|
# -----------------------------------------------------------------------------------------------------------
|
|
# Copyright (c) 2025 Huawei Technologies Co., Ltd.
|
|
# This program is free software, you can redistribute it and/or modify it under the terms and conditions of
|
|
# CANN Open Software License Agreement Version 2.0 (the "License").
|
|
# Please refer to the License for details. You may not use this file except in compliance with the License.
|
|
# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
|
|
# INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
|
|
# See LICENSE in the root of the software repository for the full text of the License.
|
|
# -----------------------------------------------------------------------------------------------------------
|
|
|
|
"""基础构件。"""
|
|
|
|
import os
|
|
from collections.abc import Callable, Iterator
|
|
from itertools import chain, tee
|
|
from pathlib import Path
|
|
from typing import Optional, TypeVar
|
|
|
|
TOP_DIR = str(Path(__file__).resolve().parents[5])
|
|
TOP_SOURCE_DIR = TOP_DIR + "/scripts/"
|
|
DELIVERY_PATH = "build/_CPack_Packages/makeself_staging"
|
|
CONFIG_SCRIPT_PATH = "package"
|
|
BLOCK_CONFIG_PATH = "package/module"
|
|
|
|
SUCCESS = 0
|
|
FAIL = -1
|
|
|
|
|
|
A = TypeVar("A")
|
|
|
|
|
|
class PackageError(Exception):
|
|
"""打包异常基类。"""
|
|
|
|
|
|
class PackageConfigError(PackageError):
|
|
"""打包配置错误异常。"""
|
|
|
|
|
|
class BlockConfigError(PackageError):
|
|
"""块配置错误异常。"""
|
|
|
|
|
|
class ParseOsArchError(PackageError):
|
|
"""解析os_arch失败异常。"""
|
|
|
|
|
|
class EnvNotSupported(PackageError):
|
|
"""环境变量不支持异常。"""
|
|
|
|
|
|
class ContainAsteriskError(PackageError):
|
|
"""包含星号异常。"""
|
|
|
|
def __init__(self, value: str):
|
|
super().__init__()
|
|
self.value = value
|
|
|
|
|
|
class FilelistError(PackageError):
|
|
"""文件列表异常。"""
|
|
|
|
|
|
class UnknownOperateTypeError(PackageError):
|
|
"""未知的操作类型。"""
|
|
|
|
|
|
class PackageNameEmptyError(PackageError):
|
|
"""包名为空错误。"""
|
|
|
|
|
|
class GenerateFilelistError(PackageError):
|
|
"""生成文件列表文件异常。"""
|
|
|
|
def __init__(self, filename: str):
|
|
super().__init__()
|
|
self.filename = filename
|
|
|
|
|
|
class IllegalVersionDir(PackageError):
|
|
"""version_dir配置错误。"""
|
|
|
|
|
|
class CompressError(PackageError):
|
|
"""打包错误。"""
|
|
|
|
def __init__(self, package_name: str | None):
|
|
super().__init__(package_name)
|
|
self.package_name = package_name
|
|
|
|
|
|
def flatten(list_of_lists):
|
|
"""Flatten one level of nesting"""
|
|
return chain.from_iterable(list_of_lists)
|
|
|
|
|
|
def merge_dict(base: dict, *news: dict):
|
|
"""合并两个字典。"""
|
|
result = base.copy()
|
|
for new in news:
|
|
result.update(new)
|
|
return result
|
|
|
|
|
|
def star_pipe(*funcs):
|
|
"""串联多个函数。解包结果。"""
|
|
|
|
def pipe_func(*args, **k_args):
|
|
result = funcs[0](*args, **k_args)
|
|
for func in funcs[1:]:
|
|
# 解包元组或列表结果
|
|
result = func(*result)
|
|
return result
|
|
|
|
return pipe_func
|
|
|
|
|
|
def swap_args(func):
|
|
"""交换函数前两个参数。"""
|
|
|
|
def inner(fst, snd, *args, **k_args):
|
|
return func(snd, fst, *args, **k_args)
|
|
|
|
return inner
|
|
|
|
|
|
def conditional_apply(predicate, func):
|
|
"""条件下应用函数。"""
|
|
|
|
def conditional_apply_func(arg):
|
|
if predicate(arg):
|
|
return func(arg)
|
|
return arg
|
|
|
|
return conditional_apply_func
|
|
|
|
|
|
def pairwise(iterable):
|
|
"""s -> (s0,s1), (s1,s2), (s2, s3), ..."""
|
|
a, b = tee(iterable)
|
|
next(b, None)
|
|
return zip(a, b)
|
|
|
|
|
|
def path_join(base: Optional, *others: str) -> Optional:
|
|
"""路径联合。"""
|
|
if base is None:
|
|
return None
|
|
return os.path.join(base, *others)
|
|
|
|
|
|
def yield_if(data, predicate: Callable) -> Iterator:
|
|
"""条件满足则产生。"""
|
|
if predicate(data):
|
|
yield data
|
|
|
|
|
|
def config_feature_to_set(feature_str: str, feature_type: str = "feature") -> set[str]:
|
|
"""配置feature转换为集合。"""
|
|
if feature_str is None:
|
|
return set()
|
|
|
|
if isinstance(feature_str, set):
|
|
return feature_str
|
|
|
|
if feature_str == "":
|
|
raise PackageConfigError(f"Not allow to config {feature_type} empty.")
|
|
|
|
features = set(feature_str.split(";"))
|
|
if "all" in features:
|
|
raise PackageConfigError(f"Not allow to config {feature_type} all.")
|
|
return features
|
|
|
|
|
|
def config_feature_to_string(features: set[str]) -> str:
|
|
"""配置feature集合转换为字符串。"""
|
|
if not features:
|
|
return "all"
|
|
return ";".join(sorted(features))
|