openubmc-bingo 0.5.277__py3-none-any.whl → 0.6.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of openubmc-bingo might be problematic. Click here for more details.
- bmcgo/__init__.py +1 -1
- bmcgo/bmcgo_config.py +22 -10
- bmcgo/cli/cli.py +95 -39
- bmcgo/cli/config.conan2.yaml +9 -0
- bmcgo/codegen/lua/codegen.py +2 -2
- bmcgo/codegen/lua/script/gen_intf_rpc_json.py +15 -14
- bmcgo/component/analysis/analysis.py +8 -8
- bmcgo/component/analysis/intf_validation.py +23 -12
- bmcgo/component/build.py +76 -14
- bmcgo/component/component_dt_version_parse.py +3 -2
- bmcgo/component/component_helper.py +43 -15
- bmcgo/component/coverage/incremental_cov.py +2 -2
- bmcgo/component/deploy.py +68 -14
- bmcgo/component/gen.py +1 -1
- bmcgo/component/package_info.py +128 -38
- bmcgo/component/template/conanbase.py.mako +1 -0
- bmcgo/component/template_v2/conanbase.py.mako +383 -0
- bmcgo/component/template_v2/conanfile.deploy.py.mako +26 -0
- bmcgo/component/test.py +53 -20
- bmcgo/frame.py +7 -3
- bmcgo/functional/analysis.py +3 -2
- bmcgo/functional/check.py +10 -6
- bmcgo/functional/conan_index_build.py +96 -20
- bmcgo/functional/csr_build.py +1 -1
- bmcgo/functional/diff.py +1 -1
- bmcgo/functional/fetch.py +1 -1
- bmcgo/functional/full_component.py +32 -24
- bmcgo/functional/git_history.py +220 -0
- bmcgo/functional/maintain.py +55 -12
- bmcgo/functional/new.py +1 -1
- bmcgo/functional/schema_valid.py +2 -2
- bmcgo/logger.py +2 -3
- bmcgo/misc.py +130 -9
- bmcgo/tasks/conan/__init__.py +10 -0
- bmcgo/tasks/conan/conanfile.py +45 -0
- bmcgo/tasks/task.py +27 -4
- bmcgo/tasks/task_build_conan.py +425 -53
- bmcgo/tasks/task_buildgppbin.py +8 -2
- bmcgo/tasks/task_download_buildtools.py +76 -0
- bmcgo/tasks/task_download_dependency.py +1 -0
- bmcgo/tasks/task_hpm_envir_prepare.py +1 -1
- bmcgo/utils/build_conans.py +231 -0
- bmcgo/utils/component_post.py +6 -4
- bmcgo/utils/component_version_check.py +75 -16
- bmcgo/utils/config.py +76 -40
- bmcgo/utils/fetch_component_code.py +44 -25
- bmcgo/utils/tools.py +239 -117
- bmcgo/worker.py +2 -2
- {openubmc_bingo-0.5.277.dist-info → openubmc_bingo-0.6.2.dist-info}/METADATA +4 -2
- {openubmc_bingo-0.5.277.dist-info → openubmc_bingo-0.6.2.dist-info}/RECORD +53 -46
- {openubmc_bingo-0.5.277.dist-info → openubmc_bingo-0.6.2.dist-info}/WHEEL +0 -0
- {openubmc_bingo-0.5.277.dist-info → openubmc_bingo-0.6.2.dist-info}/entry_points.txt +0 -0
- {openubmc_bingo-0.5.277.dist-info → openubmc_bingo-0.6.2.dist-info}/top_level.txt +0 -0
bmcgo/tasks/task_buildgppbin.py
CHANGED
|
@@ -48,8 +48,14 @@ class TaskClass(Task):
|
|
|
48
48
|
raise errors.BmcGoException("获取 manifest.yml 中 gpp/pkg_headers 配置失败, 退出码: -1")
|
|
49
49
|
else:
|
|
50
50
|
files = []
|
|
51
|
-
|
|
52
|
-
|
|
51
|
+
src = "/usr/share/bingo/hpm_header.config"
|
|
52
|
+
if not os.path.isfile(src):
|
|
53
|
+
src = "/usr/local/bin/hpm_header.config"
|
|
54
|
+
files.append({"file": src, "dst": "hpm_header.config"})
|
|
55
|
+
src = "/usr/share/bingo/emmc_uboot_header.config"
|
|
56
|
+
if not os.path.isfile(src):
|
|
57
|
+
src = "/usr/local/bin/emmc_uboot_header.config"
|
|
58
|
+
files.append({"file": src, "dst": "emmc_uboot_header.config"})
|
|
53
59
|
|
|
54
60
|
self.copy_manifest_files(files)
|
|
55
61
|
|
|
@@ -15,7 +15,10 @@
|
|
|
15
15
|
修改记录:2021-10-11 创建
|
|
16
16
|
'''
|
|
17
17
|
import os
|
|
18
|
+
import tempfile
|
|
18
19
|
import shutil
|
|
20
|
+
from pathlib import Path
|
|
21
|
+
from urllib.parse import urlparse
|
|
19
22
|
|
|
20
23
|
from bmcgo.tasks.task import Task
|
|
21
24
|
from bmcgo.tasks.misc import BUILD_TOOLS_SHA256_PATH
|
|
@@ -72,8 +75,81 @@ class DownloadDefaultBuildtools(Task):
|
|
|
72
75
|
self.run_command(f"cp -rf {self.config.cross_compile_install_path}/{self.config.cross_prefix}/lib64/" +
|
|
73
76
|
f" {libstdcpp_install_path}")
|
|
74
77
|
self.run_command("cp -af {} {}".format(self.buildtools_new_sha256, BUILD_TOOLS_SHA256_PATH), sudo=True)
|
|
78
|
+
self.run_command("chmod a+r {}".format(BUILD_TOOLS_SHA256_PATH), sudo=True)
|
|
79
|
+
|
|
80
|
+
def download_sdk(self):
|
|
81
|
+
downloads = self.get_manufacture_config("sdk/downloads")
|
|
82
|
+
if downloads is None:
|
|
83
|
+
self.log.warning("请在 manifest.yml 配置 sdk 字段或更新 manifest 仓库")
|
|
84
|
+
return
|
|
85
|
+
|
|
86
|
+
download_path = Path.home() / "downloads"
|
|
87
|
+
download_path.mkdir(exist_ok=True, parents=True)
|
|
88
|
+
|
|
89
|
+
for item in downloads:
|
|
90
|
+
self.log.info(f"配置 {item['name']}...")
|
|
91
|
+
|
|
92
|
+
curr_file_name = Path(urlparse(item['url']).path).name
|
|
93
|
+
curr_file = download_path / curr_file_name
|
|
94
|
+
curr_file_path = curr_file.as_posix()
|
|
95
|
+
|
|
96
|
+
need_download = True
|
|
97
|
+
if curr_file.exists():
|
|
98
|
+
curr_pkg_sha256 = self.tools.sha256sum(curr_file_path)
|
|
99
|
+
if curr_pkg_sha256 == item['sha256']:
|
|
100
|
+
self.log.info(f"已下载 {item["name"]}, 跳过.")
|
|
101
|
+
need_download = False
|
|
102
|
+
|
|
103
|
+
if need_download:
|
|
104
|
+
with tempfile.TemporaryDirectory() as tmp:
|
|
105
|
+
self.log.info(f"开始下载 {item['url']}...")
|
|
106
|
+
download_pkg_path = os.path.join(tmp, curr_file_name)
|
|
107
|
+
self.tools.download_file(item['url'], download_pkg_path)
|
|
108
|
+
downloaded_sha256 = self.tools.sha256sum(download_pkg_path)
|
|
109
|
+
|
|
110
|
+
if item['sha256'] != downloaded_sha256:
|
|
111
|
+
raise RuntimeError(f"manifest.yml /sdk/downloads/{item['name']} sha256 内容和下载包体不符,请检查配置!")
|
|
112
|
+
|
|
113
|
+
shutil.move(download_pkg_path, curr_file_path)
|
|
114
|
+
|
|
115
|
+
if hasattr(self, f"install_{item['name']}"):
|
|
116
|
+
getattr(self, f"install_{item['name']}")(curr_file_path)
|
|
117
|
+
|
|
118
|
+
self.log.info(f"配置 {item['name']} 完成!")
|
|
119
|
+
|
|
120
|
+
def install_bmc_sdk(self, zip_path):
|
|
121
|
+
with tempfile.TemporaryDirectory() as tmp:
|
|
122
|
+
self.log.info("安装 bmc_sdk")
|
|
123
|
+
home_path = Path.home().as_posix()
|
|
124
|
+
real_path = zip_path
|
|
125
|
+
|
|
126
|
+
self.log.debug(f"解压 {real_path} 到 {tmp}")
|
|
127
|
+
self.run_command(f"unzip {real_path} -d {tmp}")
|
|
128
|
+
|
|
129
|
+
rtos_compiler_path = Path.home() / "rtos_compiler"
|
|
130
|
+
if rtos_compiler_path.exists():
|
|
131
|
+
shutil.rmtree(rtos_compiler_path)
|
|
132
|
+
|
|
133
|
+
sdk_path = Path.home() / "sdk"
|
|
134
|
+
if sdk_path.exists():
|
|
135
|
+
shutil.rmtree(sdk_path)
|
|
136
|
+
|
|
137
|
+
self.log.debug(f"move {tmp}/rtos_compiler -> {home_path}")
|
|
138
|
+
self.run_command(f"mv {tmp}/rtos_compiler/ {home_path}")
|
|
139
|
+
self.log.debug(f"move {tmp}/sdk -> {home_path}")
|
|
140
|
+
self.run_command(f"mv {tmp}/sdk/ {home_path}")
|
|
141
|
+
self.log.debug(f"move {tmp}/lua-format -> /usr/bin")
|
|
142
|
+
self.run_command(f"chmod +x {tmp}/lua-format")
|
|
143
|
+
self.run_command(f"mv -f {tmp}/lua-format /usr/bin/", sudo=True)
|
|
144
|
+
|
|
145
|
+
self.log.debug(f"copy {tmp}/hpm_tools/. -> {home_path}")
|
|
146
|
+
self.run_command(f"chmod -R +x {tmp}/hpm_tools")
|
|
147
|
+
self.run_command(f"cp -rf {tmp}/hpm_tools/. /usr/local/bin/", sudo=True)
|
|
148
|
+
|
|
149
|
+
self.log.info(f"安装 bmc_sdk 完成!")
|
|
75
150
|
|
|
76
151
|
def run(self):
|
|
152
|
+
self.download_sdk()
|
|
77
153
|
self.download_tools()
|
|
78
154
|
self.info("下载依赖工具结束")
|
|
79
155
|
|
|
@@ -64,6 +64,7 @@ class TaskClass(Task):
|
|
|
64
64
|
self.run_command(f"chown {user_group} {SDK_PATH} -R", sudo=True)
|
|
65
65
|
self.run_command(f"ln -s {SDK_PATH} {old_sdk_dir}", sudo=True)
|
|
66
66
|
self.run_command("cp -af {} {}".format(self.sdk_new_sha256, SDK_SHA256_PATH), sudo=True)
|
|
67
|
+
self.run_command("chmod a+r {}".format(SDK_SHA256_PATH), sudo=True)
|
|
67
68
|
|
|
68
69
|
def run(self):
|
|
69
70
|
self.download_dependency()
|
|
@@ -71,7 +71,7 @@ class TaskClass(Task):
|
|
|
71
71
|
|
|
72
72
|
def prepare_hpm(self):
|
|
73
73
|
hpm_build_dir = self.config.hpm_build_dir
|
|
74
|
-
hpm_build_dir_src = f"/usr/share/
|
|
74
|
+
hpm_build_dir_src = f"/usr/share/bingo/ipmcimage"
|
|
75
75
|
self.tools.copy_all(hpm_build_dir_src, hpm_build_dir)
|
|
76
76
|
|
|
77
77
|
self.run_command(f"cp {self.config.board_path}/update_ext4.cfg {hpm_build_dir}/update.cfg")
|
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
# coding=utf-8
|
|
3
|
+
# Copyright (c) 2025 Huawei Technologies Co., Ltd.
|
|
4
|
+
# openUBMC is licensed under Mulan PSL v2.
|
|
5
|
+
# You can use this software according to the terms and conditions of the Mulan PSL v2.
|
|
6
|
+
# You may obtain a copy of Mulan PSL v2 at:
|
|
7
|
+
# http://license.coscl.org.cn/MulanPSL2
|
|
8
|
+
# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
|
9
|
+
# EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
|
10
|
+
# MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
|
11
|
+
# See the Mulan PSL v2 for more details.
|
|
12
|
+
import os
|
|
13
|
+
import stat
|
|
14
|
+
import subprocess
|
|
15
|
+
import shlex
|
|
16
|
+
import time
|
|
17
|
+
import json
|
|
18
|
+
import tempfile
|
|
19
|
+
from queue import Queue
|
|
20
|
+
from threading import Thread
|
|
21
|
+
from bmcgo.logger import Logger
|
|
22
|
+
from bmcgo import errors
|
|
23
|
+
from bmcgo.utils.tools import Tools
|
|
24
|
+
|
|
25
|
+
tools = Tools("build_parallel")
|
|
26
|
+
log = tools.log
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class GraphNode():
|
|
30
|
+
def __init__(self, node):
|
|
31
|
+
self.node = node
|
|
32
|
+
self.host_packages: dict[str, GraphNode] = {}
|
|
33
|
+
self.build_packages: dict[str, GraphNode] = {}
|
|
34
|
+
self.ref = node.get("ref")
|
|
35
|
+
self.name = self.ref.split("/")[0]
|
|
36
|
+
self.context = node.get("context")
|
|
37
|
+
self.pkg = self.ref.split("#")[0] + "-" + self.context
|
|
38
|
+
self.is_host = self.context == "host"
|
|
39
|
+
self.building = False
|
|
40
|
+
binary = node.get("binary")
|
|
41
|
+
self.binary_exist = (binary in ["Cache"])
|
|
42
|
+
self.builded = False
|
|
43
|
+
|
|
44
|
+
@property
|
|
45
|
+
def package_options(self):
|
|
46
|
+
return self.node.get("options", {})
|
|
47
|
+
|
|
48
|
+
@property
|
|
49
|
+
def package_setting(self):
|
|
50
|
+
return self.node.get("settings", {})
|
|
51
|
+
|
|
52
|
+
@property
|
|
53
|
+
def default_options(self):
|
|
54
|
+
return self.node.get("default_options", {})
|
|
55
|
+
|
|
56
|
+
def append_host_package(self, dep):
|
|
57
|
+
self.host_packages[dep.pkg] = dep
|
|
58
|
+
|
|
59
|
+
def append_build_package(self, dep):
|
|
60
|
+
self.build_packages[dep.pkg] = dep
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
class BuildConans(object):
|
|
64
|
+
def __init__(self, graphinfo, lockfile, conan_args, force_build, log_dir):
|
|
65
|
+
self.tools = Tools()
|
|
66
|
+
self.queue = Queue()
|
|
67
|
+
self.graphinfo = os.path.realpath(graphinfo)
|
|
68
|
+
if not os.path.isfile(graphinfo):
|
|
69
|
+
raise errors.BmcGoException(f"graph file {graphinfo} not exist")
|
|
70
|
+
self.lockfile = os.path.realpath(lockfile)
|
|
71
|
+
self.cmd = ""
|
|
72
|
+
args = conan_args.split()
|
|
73
|
+
skip = False
|
|
74
|
+
for arg in args:
|
|
75
|
+
if skip:
|
|
76
|
+
skip = False
|
|
77
|
+
continue
|
|
78
|
+
if arg in ["--user", "--channel", "--version", "--name"]:
|
|
79
|
+
skip = True
|
|
80
|
+
continue
|
|
81
|
+
self.cmd += f"{arg} "
|
|
82
|
+
self.exception = None
|
|
83
|
+
self.force_build = force_build
|
|
84
|
+
self.log_dir = log_dir
|
|
85
|
+
if not os.path.isdir(log_dir):
|
|
86
|
+
os.makedirs(log_dir)
|
|
87
|
+
|
|
88
|
+
def build_task(self, node: GraphNode, options):
|
|
89
|
+
for name, value in node.package_setting.items():
|
|
90
|
+
options += f" -s {name}={value}"
|
|
91
|
+
|
|
92
|
+
cmd = f"conan install --requires={node.ref} {self.cmd} {options}"
|
|
93
|
+
cmd += f" --build=\"{node.name}/*\" --build=missing -f json --lockfile={self.lockfile}"
|
|
94
|
+
try:
|
|
95
|
+
logfile = f"{self.log_dir}/conan_build_{node.name}.log"
|
|
96
|
+
log.debug(f">>>> {cmd}")
|
|
97
|
+
log.info(f">>>> build {node.ref} start, logfile: {logfile}")
|
|
98
|
+
with os.fdopen(os.open(logfile, os.O_RDWR | os.O_CREAT, stat.S_IWUSR | stat.S_IRUSR), "a+") as f:
|
|
99
|
+
real_cmd = shlex.split(cmd)
|
|
100
|
+
pipe = subprocess.Popen(real_cmd, stdout=f, stderr=f)
|
|
101
|
+
start_time = time.time()
|
|
102
|
+
while True:
|
|
103
|
+
if pipe.poll() is not None:
|
|
104
|
+
break
|
|
105
|
+
# 1800秒超时
|
|
106
|
+
if time.time() - start_time > 1800:
|
|
107
|
+
pipe.kill()
|
|
108
|
+
raise errors.BmcGoException(f"================== {node.name} 构建超时 ==================")
|
|
109
|
+
time.sleep(1)
|
|
110
|
+
if pipe.returncode != 0:
|
|
111
|
+
log.error(f"================== {node.name} 构建失败日志起始位置 ==================")
|
|
112
|
+
f.seek(0)
|
|
113
|
+
conan_log = f.read()
|
|
114
|
+
log.error(conan_log)
|
|
115
|
+
log.error(f"================== {node.name} 构建失败日志结束位置 ==================")
|
|
116
|
+
raise errors.BmcGoException(f"================== {node.name} 构建失败 ==================")
|
|
117
|
+
log.success(f"<<<< build {node.ref} finished")
|
|
118
|
+
except Exception as e:
|
|
119
|
+
self.exception = e
|
|
120
|
+
self.queue.put(node)
|
|
121
|
+
|
|
122
|
+
def build(self):
|
|
123
|
+
cwd = os.getcwd()
|
|
124
|
+
tmp = tempfile.TemporaryDirectory()
|
|
125
|
+
os.chdir(tmp.name)
|
|
126
|
+
self._build()
|
|
127
|
+
os.chdir(cwd)
|
|
128
|
+
|
|
129
|
+
def _build(self):
|
|
130
|
+
with open(self.graphinfo, "r") as fp:
|
|
131
|
+
grapth = json.load(fp)
|
|
132
|
+
nodes = grapth.get("graph", {}).get("nodes", {})
|
|
133
|
+
dependencies: dict[str, GraphNode] = {}
|
|
134
|
+
|
|
135
|
+
build_tasks = {}
|
|
136
|
+
for refid, node in nodes.items():
|
|
137
|
+
if refid == "0":
|
|
138
|
+
continue
|
|
139
|
+
cp = GraphNode(node)
|
|
140
|
+
dependencies[cp.pkg] = cp
|
|
141
|
+
build_tasks[cp.name] = False
|
|
142
|
+
for refid, node in nodes.items():
|
|
143
|
+
if refid == "0":
|
|
144
|
+
continue
|
|
145
|
+
ref = node.get("ref")
|
|
146
|
+
context = node.get("context")
|
|
147
|
+
cp = dependencies[ref.split("#")[0] + "-" + context]
|
|
148
|
+
host_packages = node.get("dependencies", {})
|
|
149
|
+
for _, dep in host_packages.items():
|
|
150
|
+
dep_ref = dep.get("ref")
|
|
151
|
+
build = dep.get("build")
|
|
152
|
+
if build:
|
|
153
|
+
build_dep = dependencies[dep_ref + "-build"]
|
|
154
|
+
cp.append_build_package(build_dep)
|
|
155
|
+
# 存在同名host组件时,将build组件作为host的依赖,避免并发构建
|
|
156
|
+
host_dep = dependencies.get(dep_ref + "-host")
|
|
157
|
+
if host_dep:
|
|
158
|
+
host_dep.append_build_package(build_dep)
|
|
159
|
+
else:
|
|
160
|
+
host_dep = dependencies[dep_ref + "-host"]
|
|
161
|
+
cp.append_host_package(host_dep)
|
|
162
|
+
options = ""
|
|
163
|
+
for _, cp in dependencies.items():
|
|
164
|
+
# 跳过build包
|
|
165
|
+
if not cp.is_host:
|
|
166
|
+
continue
|
|
167
|
+
for name, value in cp.package_options.items():
|
|
168
|
+
if value is None:
|
|
169
|
+
continue
|
|
170
|
+
def_val = cp.default_options.get(name)
|
|
171
|
+
if name == "enable_luajit":
|
|
172
|
+
conan_name = "*"
|
|
173
|
+
else:
|
|
174
|
+
conan_name = cp.pkg.split("@")[0]
|
|
175
|
+
option = ""
|
|
176
|
+
if isinstance(def_val, bool):
|
|
177
|
+
if def_val and "False" == value:
|
|
178
|
+
option = f" -o {conan_name}:{name}={value}"
|
|
179
|
+
elif not def_val and "True" == value:
|
|
180
|
+
option = f" -o {conan_name}:{name}={value}"
|
|
181
|
+
elif def_val != value:
|
|
182
|
+
option = f" -o {conan_name}:{name}={value}"
|
|
183
|
+
if option not in options:
|
|
184
|
+
options += option
|
|
185
|
+
tasks_cnt = 0
|
|
186
|
+
while True:
|
|
187
|
+
for _, dep in dependencies.items():
|
|
188
|
+
if tasks_cnt >= 4:
|
|
189
|
+
break
|
|
190
|
+
# 如果是构建工具,不参与构建
|
|
191
|
+
if not dep.is_host:
|
|
192
|
+
continue
|
|
193
|
+
# 如果还有依赖未构建完成,不参与构建
|
|
194
|
+
if len(dep.host_packages) != 0:
|
|
195
|
+
continue
|
|
196
|
+
# 相同名称的组件正在构建时不启动新的构建
|
|
197
|
+
if build_tasks.get(dep.name):
|
|
198
|
+
continue
|
|
199
|
+
if dep.builded:
|
|
200
|
+
continue
|
|
201
|
+
if not dep.binary_exist or self.force_build:
|
|
202
|
+
# 当依赖的构建工具存在正在构建的组件时不能构建
|
|
203
|
+
skip_build = False
|
|
204
|
+
for _, build_dep in dep.build_packages.items():
|
|
205
|
+
# 正在构建且未构建出制品时
|
|
206
|
+
if build_dep.building and not build_dep.builded:
|
|
207
|
+
skip_build = True
|
|
208
|
+
break
|
|
209
|
+
if skip_build:
|
|
210
|
+
continue
|
|
211
|
+
# 启动构建前将其依赖的构建工具置为正在构建
|
|
212
|
+
for _, build_dep in dep.build_packages.items():
|
|
213
|
+
build_dep.building = True
|
|
214
|
+
tasks_cnt += 1
|
|
215
|
+
thread = Thread(target=self.build_task, args=(dep, options,))
|
|
216
|
+
thread.start()
|
|
217
|
+
build_tasks[dep.name] = True
|
|
218
|
+
if not tasks_cnt:
|
|
219
|
+
return
|
|
220
|
+
dep = self.queue.get()
|
|
221
|
+
if not dep or self.exception:
|
|
222
|
+
raise self.exception
|
|
223
|
+
dep.builded = True
|
|
224
|
+
build_tasks[dep.name] = False
|
|
225
|
+
tasks_cnt -= 1
|
|
226
|
+
for _, sub_cp in dependencies.items():
|
|
227
|
+
if sub_cp.host_packages.get(dep.pkg):
|
|
228
|
+
sub_cp.host_packages.pop(dep.pkg)
|
|
229
|
+
# 构建完成后,组件的构建依赖工具一定构建完成且制品存在
|
|
230
|
+
for _, build_dep in dep.build_packages.items():
|
|
231
|
+
build_dep.builded = True
|
bmcgo/utils/component_post.py
CHANGED
|
@@ -20,7 +20,6 @@ import importlib
|
|
|
20
20
|
import sys
|
|
21
21
|
from inspect import getmembers, isfunction
|
|
22
22
|
|
|
23
|
-
from conans.model.profile import Profile
|
|
24
23
|
from bmcgo.utils.config import Config
|
|
25
24
|
from bmcgo.utils.tools import Tools
|
|
26
25
|
from bmcgo.logger import Logger
|
|
@@ -29,9 +28,12 @@ log = Logger("component_post")
|
|
|
29
28
|
|
|
30
29
|
|
|
31
30
|
class ComponentPost():
|
|
32
|
-
def __init__(self, config: Config, component_path, profile
|
|
33
|
-
|
|
34
|
-
|
|
31
|
+
def __init__(self, config: Config, component_path, profile):
|
|
32
|
+
dir_path = os.path.dirname(component_path)
|
|
33
|
+
if dir_path not in sys.path:
|
|
34
|
+
sys.path.append(dir_path)
|
|
35
|
+
cust_py = importlib.import_module(f"{os.path.basename(component_path)}.include.customization",
|
|
36
|
+
"customization")
|
|
35
37
|
self.cust_cls = getattr(cust_py, "Customization")
|
|
36
38
|
self.config = config
|
|
37
39
|
self.component_path = component_path
|
|
@@ -15,15 +15,16 @@
|
|
|
15
15
|
功能: 对比manifest.yml生成的组件清单和自动生成的清单是否一致
|
|
16
16
|
注意: 这个文件名为work, 但不继承 Task 类 !!!!!!
|
|
17
17
|
"""
|
|
18
|
-
|
|
18
|
+
import os
|
|
19
19
|
import json
|
|
20
|
-
|
|
20
|
+
from pathlib import Path
|
|
21
21
|
import yaml
|
|
22
|
-
|
|
23
22
|
from bmcgo.logger import Logger
|
|
24
23
|
from bmcgo import misc
|
|
24
|
+
from bmcgo.utils.tools import Tools
|
|
25
25
|
|
|
26
26
|
log = Logger("component_version_check")
|
|
27
|
+
tools = Tools()
|
|
27
28
|
|
|
28
29
|
|
|
29
30
|
class ComponentVersionCheck:
|
|
@@ -31,18 +32,70 @@ class ComponentVersionCheck:
|
|
|
31
32
|
conan 目录的 manifest.yml 文件是由单板目录下的 manifest.yml 自动生成的
|
|
32
33
|
"""
|
|
33
34
|
|
|
34
|
-
def __init__(self, manifest_yml: str, ibmc_lock: str):
|
|
35
|
+
def __init__(self, manifest_yml: str, ibmc_lock: str, community_name: str, openubmcsdk: str):
|
|
35
36
|
"""读取 manifest.yml(conan目录) 文件与 openubmc.lock 文件
|
|
36
37
|
|
|
37
38
|
Args:
|
|
38
39
|
manifest_yml (str): manifest.yml文件路径
|
|
39
40
|
ibmc_lock (str): openubmc.lock文件路径
|
|
40
41
|
"""
|
|
41
|
-
|
|
42
|
+
self.manifest = ""
|
|
43
|
+
self.manifest_yml = manifest_yml
|
|
44
|
+
self.ibmc_lock = ibmc_lock
|
|
45
|
+
self.manifest_dict = {}
|
|
46
|
+
self.ibmc_lock_dict = {}
|
|
47
|
+
self.openubmcsdk_comp = openubmcsdk
|
|
48
|
+
self.openubmcsdk_dict = self.generate_openubmcsdk_dict(self.openubmcsdk_comp)
|
|
49
|
+
self.community_name = community_name
|
|
50
|
+
|
|
51
|
+
@staticmethod
|
|
52
|
+
def get_cache_path(component):
|
|
53
|
+
"""根据openubmcsdk的包名获取export文件夹路径
|
|
54
|
+
|
|
55
|
+
Returns:
|
|
56
|
+
str: 返回 openubmcsdk 的export路径
|
|
57
|
+
"""
|
|
58
|
+
if misc.conan_v1():
|
|
59
|
+
conan_home = Path(os.environ.get("CONAN_HOME", Path.home() / ".conan/data"))
|
|
60
|
+
openubmcsdk_file = os.path.join(conan_home, component.replace("@", "/"), "export", "requirements.yml")
|
|
61
|
+
else:
|
|
62
|
+
conan_home = f"conan cache path {component}"
|
|
63
|
+
openubmcsdk_file = os.path.join(
|
|
64
|
+
Tools().run_command(conan_home, capture_output=True).stdout(),
|
|
65
|
+
"requirements.yml"
|
|
66
|
+
)
|
|
67
|
+
return openubmcsdk_file
|
|
68
|
+
|
|
69
|
+
def openubmc_folder(self):
|
|
70
|
+
with open(self.manifest_yml, "r") as manifest_fp:
|
|
42
71
|
self.manifest = yaml.safe_load(manifest_fp)
|
|
43
|
-
with open(ibmc_lock, "r") as ibmc_lock_fp:
|
|
72
|
+
with open(self.ibmc_lock, "r") as ibmc_lock_fp:
|
|
44
73
|
self.ibmc_lock = json.load(ibmc_lock_fp)
|
|
45
74
|
|
|
75
|
+
def generate_openubmcsdk_dict(self, component) -> dict:
|
|
76
|
+
"""根据 requirement.yml(conan目录) 配置生成 组件名: 组件配置 的字典
|
|
77
|
+
|
|
78
|
+
Returns:
|
|
79
|
+
dict: 返回 组件名: 组件配置 的字典
|
|
80
|
+
"""
|
|
81
|
+
# component == ""表示manifest.yml未定义"base/sdk"
|
|
82
|
+
if component == "":
|
|
83
|
+
return {}
|
|
84
|
+
openubmcsdk_file = self.get_cache_path(component)
|
|
85
|
+
if not os.path.isfile(openubmcsdk_file):
|
|
86
|
+
tools.download_conan_recipes(component, misc.CONAN_REPO)
|
|
87
|
+
openubmcsdk_file = self.get_cache_path(component)
|
|
88
|
+
with open(openubmcsdk_file, "r") as openubmcsdk_fp:
|
|
89
|
+
self.openubmcsdk = yaml.safe_load(openubmcsdk_fp)
|
|
90
|
+
dependency_list = self.openubmcsdk[misc.CONAN_DEPDENCIES_KEY]
|
|
91
|
+
openubmc_dict = {x[misc.CONAN].split('/')[0]: x[misc.CONAN].split('@')[0] for x in dependency_list}
|
|
92
|
+
return openubmc_dict
|
|
93
|
+
|
|
94
|
+
def get_dict(self):
|
|
95
|
+
self.openubmc_folder()
|
|
96
|
+
self.manifest_dict = self.generate_manifest_dict()
|
|
97
|
+
self.ibmc_lock_dict = self.generate_ibmc_lock_dict()
|
|
98
|
+
|
|
46
99
|
def generate_manifest_dict(self) -> dict:
|
|
47
100
|
"""根据 manifest.yml(conan目录) 配置生成 组件名: 组件配置 的字典
|
|
48
101
|
|
|
@@ -59,25 +112,31 @@ class ComponentVersionCheck:
|
|
|
59
112
|
Returns:
|
|
60
113
|
dict: 返回 组件名: 组件配置 的字典
|
|
61
114
|
"""
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
115
|
+
if misc.conan_v1():
|
|
116
|
+
component_list = self.ibmc_lock["graph_lock"]["nodes"]
|
|
117
|
+
ibmc_lock_dict = {x["ref"].split('/')[0]: x["ref"].split('@')[0]
|
|
118
|
+
for x in [component_conf for _, component_conf in component_list.items()]}
|
|
119
|
+
ibmc_lock_dict.pop("openubmc")
|
|
120
|
+
else:
|
|
121
|
+
component_list = self.ibmc_lock["requires"]
|
|
122
|
+
ibmc_lock_dict = {x.split('/')[0]: x.split('@')[0] for x in component_list}
|
|
66
123
|
return ibmc_lock_dict
|
|
67
124
|
|
|
68
125
|
def run(self):
|
|
69
126
|
"""检查所有组件是否都在 manifest.yml(单板目录下) 中配置了
|
|
70
127
|
"""
|
|
71
|
-
manifest_dict = self.generate_manifest_dict()
|
|
72
|
-
ibmc_lock_dict = self.generate_ibmc_lock_dict()
|
|
73
128
|
# 这里使用报错退出, 为防止有多个组件未配置, 报错在方法结束后触发
|
|
129
|
+
self.get_dict()
|
|
74
130
|
report_error = False
|
|
75
|
-
for key, version in ibmc_lock_dict.items():
|
|
76
|
-
if key not in manifest_dict.keys():
|
|
131
|
+
for key, version in self.ibmc_lock_dict.items():
|
|
132
|
+
if key not in self.manifest_dict.keys() and key not in self.openubmcsdk_dict.keys():
|
|
77
133
|
log.error(f"{version} 组件没有在manifest中配置!!!!!!")
|
|
78
134
|
report_error = True
|
|
79
|
-
elif version !=
|
|
80
|
-
log.error(f"{version} 组件版本与
|
|
135
|
+
elif key in self.openubmcsdk_dict.keys() and version != self.openubmcsdk_dict.get(key, ""):
|
|
136
|
+
log.error(f"{version} 组件版本与openubmcsdk中配置{self.openubmcsdk_dict[key]}不匹配!!!!!!")
|
|
137
|
+
report_error = True
|
|
138
|
+
elif key in self.manifest_dict.keys() and version != self.manifest_dict.get(key, ""):
|
|
139
|
+
log.error(f"{version} 组件版本与manifest中配置{self.manifest_dict[key]}不匹配!!!!!!")
|
|
81
140
|
report_error = True
|
|
82
141
|
|
|
83
142
|
if report_error is True:
|