openubmc-bingo 0.6.45__py3-none-any.whl → 0.6.99__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.
- bmcgo/__init__.py +1 -1
- bmcgo/bmcgo.py +9 -3
- bmcgo/bmcgo_config.py +16 -0
- bmcgo/cli/cli.py +72 -21
- bmcgo/codegen/__init__.py +1 -1
- bmcgo/codegen/lua/codegen.py +2 -2
- bmcgo/codegen/lua/script/check_intfs.py +1 -0
- bmcgo/codegen/lua/script/dto/options.py +1 -0
- bmcgo/codegen/lua/script/gen_db_json.py +4 -3
- bmcgo/codegen/lua/script/gen_rpc_msg_json.py +78 -11
- bmcgo/codegen/lua/script/model_consistency_check.py +1 -1
- bmcgo/codegen/lua/script/render_utils/db_lua.py +5 -6
- bmcgo/codegen/lua/script/render_utils/model_lua.py +5 -1
- bmcgo/codegen/lua/script/template.py +5 -0
- bmcgo/codegen/lua/script/utils.py +50 -8
- bmcgo/codegen/lua/templates/apps/Makefile +2 -2
- bmcgo/codegen/lua/templates/apps/client.lua.mako +1 -1
- bmcgo/codegen/lua/templates/apps/model.lua.mako +4 -3
- bmcgo/codegen/lua/templates/apps/service.lua.mako +1 -1
- bmcgo/codegen/lua/templates/apps/utils/mdb_intf.lua.mako +4 -0
- bmcgo/codegen/lua/templates/new_app_v2/CMakeLists.txt.mako +26 -0
- bmcgo/codegen/lua/templates/new_app_v2/conanfile.py.mako +9 -0
- bmcgo/codegen/lua/v1/script/render_utils/db_lua.py +5 -6
- bmcgo/codegen/lua/v1/script/render_utils/model_lua.py +13 -1
- bmcgo/codegen/lua/v1/templates/apps/client.lua.mako +1 -1
- bmcgo/codegen/lua/v1/templates/apps/local_db.lua.mako +0 -4
- bmcgo/codegen/lua/v1/templates/apps/message.lua.mako +3 -0
- bmcgo/codegen/lua/v1/templates/apps/model.lua.mako +3 -0
- bmcgo/codegen/lua/v1/templates/apps/utils/mdb_intf.lua.mako +6 -4
- bmcgo/component/analysis/analysis.py +9 -4
- bmcgo/component/analysis/dep-rules.json +20 -8
- bmcgo/component/analysis/dep_node.py +2 -0
- bmcgo/component/analysis/intf_validation.py +8 -7
- bmcgo/component/analysis/sr_validation.py +5 -4
- bmcgo/component/busctl_log_parse/busctl_log_parser.py +809 -0
- bmcgo/component/busctl_log_parse/mock_data_save.py +170 -0
- bmcgo/component/busctl_log_parse/test_data_save.py +49 -0
- bmcgo/component/component_helper.py +29 -0
- bmcgo/component/coverage/incremental_cov.py +5 -0
- bmcgo/component/fixture/__init__.py +29 -0
- bmcgo/component/fixture/auto_case_generator.py +490 -0
- bmcgo/component/fixture/busctl_type_converter.py +1081 -0
- bmcgo/component/fixture/common_config.py +15 -0
- bmcgo/component/fixture/dbus_gateway.py +669 -0
- bmcgo/component/fixture/dbus_library.py +250 -0
- bmcgo/component/fixture/dbus_mock_utils.py +514 -0
- bmcgo/component/fixture/dbus_response_handler.py +138 -0
- bmcgo/component/fixture/dbus_signature.py +110 -0
- bmcgo/component/template_v2/conanbase.py.mako +1 -5
- bmcgo/component/test.py +69 -10
- bmcgo/error_analyzer/__init__.py +0 -0
- bmcgo/error_analyzer/case_matcher.py +114 -0
- bmcgo/error_analyzer/log_parser.py +128 -0
- bmcgo/error_analyzer/unified_error_analyzer.py +359 -0
- bmcgo/error_cases/cases.yml +59 -0
- bmcgo/error_cases/cases_template_valid.json +71 -0
- bmcgo/error_cases/conanfile.py +58 -0
- bmcgo/frame.py +0 -4
- bmcgo/functional/analysis.py +18 -12
- bmcgo/functional/bmc_studio_action.py +21 -10
- bmcgo/functional/check.py +86 -42
- bmcgo/functional/conan_index_build.py +1 -1
- bmcgo/functional/config.py +22 -18
- bmcgo/functional/csr_build.py +63 -34
- bmcgo/functional/deploy.py +4 -3
- bmcgo/functional/diff.py +51 -34
- bmcgo/functional/full_component.py +16 -5
- bmcgo/functional/hpm_signer.py +484 -0
- bmcgo/functional/new.py +8 -2
- bmcgo/functional/schema_valid.py +111 -15
- bmcgo/functional/upgrade.py +6 -6
- bmcgo/misc.py +1 -0
- bmcgo/tasks/task_build_conan.py +27 -6
- bmcgo/tasks/task_build_rootfs_img.py +120 -83
- bmcgo/tasks/task_buildgppbin.py +30 -13
- bmcgo/tasks/task_buildhpm_ext4.py +5 -3
- bmcgo/tasks/task_download_buildtools.py +20 -11
- bmcgo/tasks/task_download_dependency.py +29 -20
- bmcgo/tasks/task_hpm_envir_prepare.py +32 -53
- bmcgo/tasks/task_packet_to_supporte.py +12 -4
- bmcgo/tasks/task_prepare.py +1 -1
- bmcgo/tasks/task_sign_and_pack_hpm.py +15 -7
- bmcgo/utils/component_version_check.py +4 -4
- bmcgo/utils/config.py +3 -0
- bmcgo/utils/fetch_component_code.py +148 -17
- bmcgo/utils/install_manager.py +2 -2
- bmcgo/utils/installations/base_installer.py +10 -27
- bmcgo/utils/installations/install_plans/studio.yml +3 -0
- bmcgo/utils/mapping_config_patch.py +5 -4
- bmcgo/utils/tools.py +49 -7
- {openubmc_bingo-0.6.45.dist-info → openubmc_bingo-0.6.99.dist-info}/METADATA +1 -1
- {openubmc_bingo-0.6.45.dist-info → openubmc_bingo-0.6.99.dist-info}/RECORD +95 -74
- bmcgo/tasks/download_buildtools_hm.py +0 -124
- {openubmc_bingo-0.6.45.dist-info → openubmc_bingo-0.6.99.dist-info}/WHEEL +0 -0
- {openubmc_bingo-0.6.45.dist-info → openubmc_bingo-0.6.99.dist-info}/entry_points.txt +0 -0
- {openubmc_bingo-0.6.45.dist-info → openubmc_bingo-0.6.99.dist-info}/top_level.txt +0 -0
|
@@ -10,14 +10,15 @@
|
|
|
10
10
|
# EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
|
11
11
|
# MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
|
12
12
|
# See the Mulan PSL v2 for more details.
|
|
13
|
+
import json
|
|
13
14
|
import os
|
|
14
15
|
import re
|
|
15
16
|
import shutil
|
|
16
17
|
import subprocess
|
|
17
|
-
from multiprocessing import Pool
|
|
18
|
+
from multiprocessing import Pool, Manager
|
|
18
19
|
import patch_ng
|
|
19
20
|
import yaml
|
|
20
|
-
from git import Repo
|
|
21
|
+
from git import Repo, exc
|
|
21
22
|
|
|
22
23
|
from bmcgo import errors
|
|
23
24
|
from bmcgo import misc
|
|
@@ -47,6 +48,7 @@ class FetchComponentCode:
|
|
|
47
48
|
f" -r {misc.conan_remote()} --only None 2>/dev/null"
|
|
48
49
|
if misc.conan_v2():
|
|
49
50
|
cmd = f"conan graph info --requires='{version_range}' --filter {component_name}"
|
|
51
|
+
|
|
50
52
|
ret, output = subprocess.getstatusoutput(cmd)
|
|
51
53
|
output = output.strip()
|
|
52
54
|
if ret != 0 or not output:
|
|
@@ -113,15 +115,17 @@ class FetchComponentCode:
|
|
|
113
115
|
log.info(f"{code_dir} 开始应用源码补丁{patch_file}")
|
|
114
116
|
try:
|
|
115
117
|
FetchComponentCode._apply_patches_direct(real_patch, patch_file, changed_files)
|
|
116
|
-
except errors.BmcGoException:
|
|
117
|
-
# 尝试还原文件修改
|
|
118
|
+
except errors.BmcGoException as e:
|
|
118
119
|
for a_file, b_file in changed_files.items():
|
|
119
120
|
cmd = f"git checkout -- {a_file}"
|
|
120
121
|
tools.run_command(cmd, ignore_error=True)
|
|
121
122
|
cmd = f"git checkout -- {b_file}"
|
|
122
123
|
tools.run_command(cmd, ignore_error=True)
|
|
123
|
-
|
|
124
|
-
|
|
124
|
+
try:
|
|
125
|
+
cmd = "git am " + real_patch
|
|
126
|
+
tools.run_command(cmd)
|
|
127
|
+
except Exception as am_e:
|
|
128
|
+
raise RuntimeError(f"git am 恢复补丁 {patch_file} 失败") from am_e
|
|
125
129
|
log.info(f"{code_dir} 应用源码补丁{patch_file}")
|
|
126
130
|
os.chdir(cwd)
|
|
127
131
|
|
|
@@ -184,6 +188,88 @@ class FetchComponentCode:
|
|
|
184
188
|
|
|
185
189
|
return revision, url
|
|
186
190
|
|
|
191
|
+
# --- 新增:MDS修补方案 1 (Install) ---
|
|
192
|
+
@staticmethod
|
|
193
|
+
def _try_mds_install_plan(conan_version, component_name):
|
|
194
|
+
"""
|
|
195
|
+
尝试使用 'conan install' 来获取 package_folder
|
|
196
|
+
"""
|
|
197
|
+
log.info(f"MDS修补 (方案1: install): 正在尝试 {conan_version}...")
|
|
198
|
+
cmd_install = f"conan install --requires={conan_version} -r openubmc_dev\
|
|
199
|
+
--build=missing -pr profile.ini --format=json --output-folder=tmp"
|
|
200
|
+
|
|
201
|
+
command_result = tools.run_command(cmd_install, capture_output=True, ignore_error=True)
|
|
202
|
+
stdout = command_result.stdout.strip()
|
|
203
|
+
stderr = command_result.stderr.strip()
|
|
204
|
+
|
|
205
|
+
if command_result.returncode != 0 or not stdout:
|
|
206
|
+
log.warning(f"MDS修补 (方案1: install) 失败: 命令执行失败。 STDERR: {stderr}")
|
|
207
|
+
raise RuntimeError(f"Install plan failed (command error). stderr: {stderr}")
|
|
208
|
+
|
|
209
|
+
try:
|
|
210
|
+
result = json.loads(stdout)
|
|
211
|
+
nodes = result.get("graph", {}).get("nodes", {})
|
|
212
|
+
package_folder = None
|
|
213
|
+
for node in nodes.values():
|
|
214
|
+
if node.get("ref") and node.get("ref").startswith(conan_version):
|
|
215
|
+
package_folder = node.get("package_folder")
|
|
216
|
+
if package_folder:
|
|
217
|
+
break
|
|
218
|
+
|
|
219
|
+
if not package_folder:
|
|
220
|
+
log.warning(f"MDS修补 (方案1: install) 失败: 未在JSON中找到 package_folder。")
|
|
221
|
+
raise RuntimeError("Install plan failed (JSON parse).")
|
|
222
|
+
|
|
223
|
+
log.info(f"MDS修补 (方案1: install) 成功。 找到 package_folder: {package_folder}")
|
|
224
|
+
return package_folder # 成功
|
|
225
|
+
except Exception as json_err:
|
|
226
|
+
log.warning(f"MDS修补 (方案1: install) 失败: JSON解析错误。 {json_err}")
|
|
227
|
+
raise RuntimeError(f"Install plan failed (JSON parse).") from json_err
|
|
228
|
+
|
|
229
|
+
# --- 新增:MDS修补方案 2 (Download) ---
|
|
230
|
+
@staticmethod
|
|
231
|
+
def _try_mds_download_plan(conan_version, component_name):
|
|
232
|
+
"""
|
|
233
|
+
尝试使用 'conan download' (不带profile) 来获取 package_folder
|
|
234
|
+
"""
|
|
235
|
+
log.warning(f"MDS修补 (方案1: install) 失败。 切换到 (方案2: download)...")
|
|
236
|
+
try:
|
|
237
|
+
cmd_download = f"conan download {conan_version} -r openubmc_dev --format=json"
|
|
238
|
+
log.info(f"MDS修补 (方案2: download): 执行: {cmd_download}")
|
|
239
|
+
command_result = tools.run_command(cmd_download, capture_output=True, ignore_error=True)
|
|
240
|
+
stdout = command_result.stdout.strip()
|
|
241
|
+
stderr = command_result.stderr.strip()
|
|
242
|
+
|
|
243
|
+
if command_result.returncode != 0 or not stdout:
|
|
244
|
+
log.error(f"MDS修补 (方案2: download) 失败: 命令执行失败。 STDERR: {stderr}")
|
|
245
|
+
raise RuntimeError(f"Download command failed. STDERR: {stderr}")
|
|
246
|
+
|
|
247
|
+
result = json.loads(stdout)
|
|
248
|
+
local_cache = result.get("Local Cache")
|
|
249
|
+
component_info = local_cache.get(conan_version)
|
|
250
|
+
revisions = component_info.get("revisions")
|
|
251
|
+
first_revision_id = next(iter(revisions))
|
|
252
|
+
first_revision_data = revisions[first_revision_id]
|
|
253
|
+
packages = first_revision_data.get("packages")
|
|
254
|
+
first_package_id = next(iter(packages))
|
|
255
|
+
full_pref = f"{conan_version}#{first_revision_id}:{first_package_id}"
|
|
256
|
+
|
|
257
|
+
cmd_cache_path = f"conan cache path {full_pref}"
|
|
258
|
+
log.info(f"MDS修补 (方案2: download): 执行: {cmd_cache_path}")
|
|
259
|
+
path_cmd_info = tools.run_command(cmd_cache_path, capture_output=True, ignore_error=True)
|
|
260
|
+
|
|
261
|
+
if path_cmd_info.returncode != 0 or not path_cmd_info.stdout:
|
|
262
|
+
log.error(f"MDS修补 (方案2: download) 失败: 'conan cache path' 失败。 STDERR: {path_cmd_info.stderr.strip()}")
|
|
263
|
+
raise RuntimeError(f"'conan cache path' 失败. STDERR: {path_cmd_info.stderr.strip()}")
|
|
264
|
+
|
|
265
|
+
package_folder = path_cmd_info.stdout.strip()
|
|
266
|
+
log.info(f"MDS修补 (方案2: download) 成功。 找到 package_folder: {package_folder}")
|
|
267
|
+
return package_folder # 成功
|
|
268
|
+
|
|
269
|
+
except Exception as download_e:
|
|
270
|
+
log.error(f"MDS修补 (方案2: download) 失败: {download_e}")
|
|
271
|
+
raise RuntimeError("Download plan failed.") from download_e
|
|
272
|
+
|
|
187
273
|
def run(self):
|
|
188
274
|
packages_to_fetch = dict()
|
|
189
275
|
for component_name, package in self.packages.items():
|
|
@@ -201,14 +287,19 @@ class FetchComponentCode:
|
|
|
201
287
|
|
|
202
288
|
process_count = min(len(packages_to_fetch), os.cpu_count())
|
|
203
289
|
log.info("创建 %u 个进程拉取代码", process_count)
|
|
290
|
+
|
|
291
|
+
manager = Manager()
|
|
292
|
+
conan_lock = manager.Lock()
|
|
293
|
+
|
|
204
294
|
pool = Pool(processes=process_count)
|
|
205
295
|
for component_name, conan_version in packages_to_fetch.items():
|
|
206
|
-
pool.apply_async(func=self.update_component_code,
|
|
296
|
+
pool.apply_async(func=self.update_component_code,
|
|
297
|
+
args=(component_name, conan_version, conan_lock),
|
|
207
298
|
error_callback=process_err_cb)
|
|
208
299
|
pool.close()
|
|
209
300
|
pool.join()
|
|
210
301
|
|
|
211
|
-
def update_component_code(self, component_name, conan_version):
|
|
302
|
+
def update_component_code(self, component_name, conan_version, conan_lock):
|
|
212
303
|
"""
|
|
213
304
|
update component code by conan version
|
|
214
305
|
"""
|
|
@@ -219,9 +310,12 @@ class FetchComponentCode:
|
|
|
219
310
|
version_split = re.split(r'[/, @]', conan_version)
|
|
220
311
|
conan_dir = os.path.join(os.path.expanduser('~'), '.conan/data/', *version_split, 'export')
|
|
221
312
|
conandata = os.path.join(conan_dir, 'conandata.yml')
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
313
|
+
|
|
314
|
+
with conan_lock:
|
|
315
|
+
if not os.path.exists(conan_dir):
|
|
316
|
+
conan_remote_list = tools.get_conan_remote_list(self.remote)
|
|
317
|
+
tools.download_conan_recipes(conan_version, conan_remote_list)
|
|
318
|
+
|
|
225
319
|
if os.path.exists(conandata):
|
|
226
320
|
self.__update_component_code_by_conandata(version_split[0], version_split[1], conandata)
|
|
227
321
|
return
|
|
@@ -233,10 +327,12 @@ class FetchComponentCode:
|
|
|
233
327
|
return
|
|
234
328
|
log.error("conandata(%s) 和 conanfile(%s) 都没有找到", conandata, conanfile)
|
|
235
329
|
else:
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
330
|
+
path_cmd_info = None
|
|
331
|
+
with conan_lock:
|
|
332
|
+
conan_remote_list = tools.get_conan_remote_list(self.remote)
|
|
333
|
+
tools.download_conan_recipes(conan_version, conan_remote_list)
|
|
334
|
+
path_cmd = f"conan cache path {conan_version}"
|
|
335
|
+
path_cmd_info = Tools().run_command(path_cmd, capture_output=True)
|
|
240
336
|
|
|
241
337
|
version_split = re.split(r'[/, @]', conan_version)
|
|
242
338
|
conan_dir = path_cmd_info.stdout.strip()
|
|
@@ -248,6 +344,41 @@ class FetchComponentCode:
|
|
|
248
344
|
log.error("conandata(%s) 没有找到", conandata)
|
|
249
345
|
log.info("更新组件 %s 代码到 %s 失败, 无法获取到 conan 信息", component_name,
|
|
250
346
|
conan_version)
|
|
347
|
+
except exc.GitError as exp:
|
|
348
|
+
log.warning("Git 操作失败 (组件: %s): %s。 尝试MDS修补...", component_name, exp)
|
|
349
|
+
package_folder = None
|
|
350
|
+
|
|
351
|
+
with conan_lock:
|
|
352
|
+
try:
|
|
353
|
+
# --- 方案 1: install (优先) ---
|
|
354
|
+
package_folder = FetchComponentCode._try_mds_install_plan(conan_version, component_name)
|
|
355
|
+
except Exception as install_e:
|
|
356
|
+
# --- 方案 2: download (后备) ---
|
|
357
|
+
try:
|
|
358
|
+
package_folder = FetchComponentCode._try_mds_download_plan(conan_version, component_name)
|
|
359
|
+
except Exception as download_e:
|
|
360
|
+
# --- 两个方案都失败了 ---
|
|
361
|
+
log.error(f"MDS修补: 方案1 和 方案2 均失败 (组件: {component_name})。")
|
|
362
|
+
raise RuntimeError(f"MDS修补方案 'install' 和 'download' 均失败 (组件: {component_name})") from exp
|
|
363
|
+
|
|
364
|
+
# --- 复制步骤 (锁外) ---
|
|
365
|
+
if package_folder:
|
|
366
|
+
mds_src_path = f"{package_folder}/include"
|
|
367
|
+
if os.path.exists(mds_src_path):
|
|
368
|
+
src = mds_src_path
|
|
369
|
+
dest = os.path.abspath(f"{component_name}")
|
|
370
|
+
shutil.copytree(src, dest, dirs_exist_ok=True)
|
|
371
|
+
log.info(f"将组件 {component_name} 复制到 {dest}.")
|
|
372
|
+
else:
|
|
373
|
+
log.warning(f"MDS修补: 在 {package_folder} 中未找到 'include/mds'。")
|
|
374
|
+
else:
|
|
375
|
+
# 这种情况不应该发生,因为如果两个方案都失败了,上面会抛出异常
|
|
376
|
+
log.error(f"MDS修补失败 (组件: {component_name}): 未能获取 package_folder。")
|
|
377
|
+
raise exp # 重新抛出原始 GitError
|
|
378
|
+
|
|
379
|
+
# 清理 'install' 方案(如果成功)创建的 'tmp' 目录
|
|
380
|
+
shutil.rmtree(f"{self.target_dir}/tmp", ignore_errors=True)
|
|
381
|
+
|
|
251
382
|
except Exception as exp:
|
|
252
|
-
log.error("
|
|
253
|
-
log.error("
|
|
383
|
+
log.error("工作状态错误 (组件: %s): %s", component_name, exp)
|
|
384
|
+
log.error("更新组件 %s 代码到 %s 失败", component_name, conan_version)
|
bmcgo/utils/install_manager.py
CHANGED
|
@@ -38,7 +38,7 @@ class InstallManager:
|
|
|
38
38
|
def custom_install_plan_path(self):
|
|
39
39
|
return self._custom_path / install_consts.PLUGIN_INSTALL_PLAN_PATH
|
|
40
40
|
|
|
41
|
-
def init(self, app_name,
|
|
41
|
+
def init(self, app_name, version_range, custom_path):
|
|
42
42
|
self._set_custom_path(custom_path)
|
|
43
43
|
|
|
44
44
|
if app_name == install_consts.INSTALL_ALL:
|
|
@@ -54,7 +54,7 @@ class InstallManager:
|
|
|
54
54
|
if not inst_type:
|
|
55
55
|
raise ValueError(f"未配置 {wname}/{install_consts.PLAN_STEPS}/{install_consts.PLAN_INSTALL_TYPE}")
|
|
56
56
|
inst = BaseInstaller.get_installer(inst_type)
|
|
57
|
-
inst.init(plan,
|
|
57
|
+
inst.init(plan, version_range)
|
|
58
58
|
self._installers.setdefault(wname, []).append(inst)
|
|
59
59
|
|
|
60
60
|
def show_versions(self):
|
|
@@ -86,11 +86,11 @@ class BaseInstaller(abc.ABC):
|
|
|
86
86
|
raise ValueError(f"未定义的安装方法:{installer_type}")
|
|
87
87
|
return installer_cls()
|
|
88
88
|
|
|
89
|
-
def init(self, plan,
|
|
89
|
+
def init(self, plan, version_range):
|
|
90
90
|
self.parse_plan(plan)
|
|
91
91
|
|
|
92
92
|
versions = self.get_versions()
|
|
93
|
-
self.resolve_constraint(versions,
|
|
93
|
+
self.resolve_constraint(versions, version_range)
|
|
94
94
|
|
|
95
95
|
self.get_current_version()
|
|
96
96
|
|
|
@@ -113,39 +113,22 @@ class BaseInstaller(abc.ABC):
|
|
|
113
113
|
return
|
|
114
114
|
self.parse_custom_plan(plan)
|
|
115
115
|
|
|
116
|
-
def resolve_constraint(self, versions,
|
|
116
|
+
def resolve_constraint(self, versions, version_range):
|
|
117
117
|
if not versions:
|
|
118
118
|
self.warning("当前没有可下载版本!")
|
|
119
119
|
return
|
|
120
120
|
|
|
121
|
-
if
|
|
121
|
+
if install_consts.INSTALL_LATEST in version_range or not version_range:
|
|
122
122
|
self._target_ver = versions[0]
|
|
123
123
|
return
|
|
124
|
-
|
|
125
|
-
|
|
124
|
+
|
|
125
|
+
import semver
|
|
126
126
|
for avl_ver in versions:
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
self._target_ver = v.origin
|
|
130
|
-
break
|
|
131
|
-
elif opt == "<=" and v <= pkg_ver:
|
|
132
|
-
self._target_ver = v.origin
|
|
133
|
-
break
|
|
134
|
-
elif opt == "!=" and v != pkg_ver:
|
|
135
|
-
self._target_ver = v.origin
|
|
127
|
+
if semver.satisfies(avl_ver, version_range):
|
|
128
|
+
self._target_ver = avl_ver
|
|
136
129
|
break
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
break
|
|
140
|
-
elif opt == ">" and v > pkg_ver:
|
|
141
|
-
self._target_ver = v.origin
|
|
142
|
-
break
|
|
143
|
-
elif opt == "=" and v == pkg_ver:
|
|
144
|
-
self._target_ver = v.origin
|
|
145
|
-
break
|
|
146
|
-
else:
|
|
147
|
-
self.warning(f"没有找到匹配的版本:{self._pkg_name}{opt}{ver}")
|
|
148
|
-
return
|
|
130
|
+
if not self._target_ver:
|
|
131
|
+
raise ValueError(f"没有找到匹配的版本:{self._pkg_name}{version_range}")
|
|
149
132
|
|
|
150
133
|
def info(self, msg):
|
|
151
134
|
self.logger and self.logger.info(f"[{self.type_name}] {msg}")
|
|
@@ -128,7 +128,7 @@ def rename_json_prop(obj, array, depth, new_key):
|
|
|
128
128
|
elif isinstance(obj, list) and array[depth] < len(obj):
|
|
129
129
|
node = obj[array[depth]]
|
|
130
130
|
if node is not None:
|
|
131
|
-
|
|
131
|
+
rename_json_prop(node, array, depth + 1, new_key)
|
|
132
132
|
|
|
133
133
|
|
|
134
134
|
class MappingConfigPatch(Task):
|
|
@@ -351,7 +351,7 @@ class MappingConfigPatch(Task):
|
|
|
351
351
|
target_uri = action.get("Uri")
|
|
352
352
|
target_method = action.get("Method")
|
|
353
353
|
if target is None or target_uri is None or target_method is None:
|
|
354
|
-
log.
|
|
354
|
+
log.info(f"属性变更场景,Target、Uri、Method参数必须存在")
|
|
355
355
|
continue
|
|
356
356
|
target_path = os.path.join(self.config_path, target)
|
|
357
357
|
if not is_valid_path(target_path, self.config_path, True):
|
|
@@ -367,7 +367,7 @@ class MappingConfigPatch(Task):
|
|
|
367
367
|
if flag:
|
|
368
368
|
save_json_file(target_path, target_object)
|
|
369
369
|
else:
|
|
370
|
-
log.
|
|
370
|
+
log.info(f"属性变更场景,没有找到Uri({target_uri})指定的配置")
|
|
371
371
|
|
|
372
372
|
|
|
373
373
|
def global_variables(self, global_variable):
|
|
@@ -411,7 +411,8 @@ class MappingConfigPatch(Task):
|
|
|
411
411
|
|
|
412
412
|
|
|
413
413
|
def run(self):
|
|
414
|
-
|
|
414
|
+
ret = self.tools.run_command(f"test -d {self.config_patch_path}", ignore_error=True, sudo=True)
|
|
415
|
+
if ret.returncode != 0:
|
|
415
416
|
return
|
|
416
417
|
|
|
417
418
|
# 给予权限方便对文件做变更
|
bmcgo/utils/tools.py
CHANGED
|
@@ -67,7 +67,6 @@ class Tools():
|
|
|
67
67
|
print_cnt = 0
|
|
68
68
|
|
|
69
69
|
def __init__(self, log_name="bingo", log_file=None):
|
|
70
|
-
os.makedirs(misc.CACHE_DIR, exist_ok=True)
|
|
71
70
|
self.lock_file = os.path.join(misc.CACHE_DIR, "frame_lock")
|
|
72
71
|
if log_file is None:
|
|
73
72
|
self.log_name = os.path.join(misc.CACHE_DIR, f"{log_name}.log")
|
|
@@ -104,6 +103,8 @@ class Tools():
|
|
|
104
103
|
|
|
105
104
|
@property
|
|
106
105
|
def conan_data(self):
|
|
106
|
+
if misc.conan_v2():
|
|
107
|
+
return os.path.join(self.conan_home, "p")
|
|
107
108
|
return os.path.join(self.conan_home, "data")
|
|
108
109
|
|
|
109
110
|
@staticmethod
|
|
@@ -245,16 +246,19 @@ class Tools():
|
|
|
245
246
|
pkg_name = pkg_info[0]
|
|
246
247
|
has_version = len(pkg_info) > 1
|
|
247
248
|
for sub in base_manifest.get(dependency_type, {}):
|
|
249
|
+
overwrite = sub.get("overwrite", False)
|
|
248
250
|
sub_name = sub.get(misc.CONAN)
|
|
249
251
|
sub_pkg_name = sub_name.split("/")[0]
|
|
250
252
|
# 上下层具有相同组件名的组件
|
|
251
253
|
if pkg_name == sub_pkg_name:
|
|
252
|
-
if has_version:
|
|
254
|
+
if not has_version:
|
|
255
|
+
com_package[misc.CONAN] = sub_name
|
|
256
|
+
elif overwrite:
|
|
257
|
+
com_package[misc.CONAN] = name
|
|
258
|
+
else:
|
|
253
259
|
raise errors.BmcGoException(
|
|
254
260
|
"配置错误: 不允许删除平台组件或定制平台组件版本号{}".format(name)
|
|
255
261
|
)
|
|
256
|
-
else:
|
|
257
|
-
com_package[misc.CONAN] = sub_name
|
|
258
262
|
break
|
|
259
263
|
|
|
260
264
|
@staticmethod
|
|
@@ -630,7 +634,7 @@ class Tools():
|
|
|
630
634
|
self.run_command(f"chown {user_group} {img_path}", sudo=True)
|
|
631
635
|
|
|
632
636
|
def get_studio_path(self):
|
|
633
|
-
ret = self.run_command("whereis bmc_studio", sudo=
|
|
637
|
+
ret = self.run_command("whereis bmc_studio", sudo=False, ignore_error=True,
|
|
634
638
|
command_echo=False, capture_output=True).stdout
|
|
635
639
|
if not ret:
|
|
636
640
|
return ""
|
|
@@ -676,7 +680,45 @@ class Tools():
|
|
|
676
680
|
try:
|
|
677
681
|
check = False if ignore_error else True
|
|
678
682
|
if show_log:
|
|
679
|
-
|
|
683
|
+
# 使用Popen来同时处理实时输出和日志文件写入
|
|
684
|
+
process = subprocess.Popen(
|
|
685
|
+
command,
|
|
686
|
+
stdout=subprocess.PIPE,
|
|
687
|
+
stderr=subprocess.STDOUT, # 将stderr合并到stdout
|
|
688
|
+
universal_newlines=True,
|
|
689
|
+
bufsize=1 # 行缓冲
|
|
690
|
+
)
|
|
691
|
+
|
|
692
|
+
# 实时读取输出并同时显示和写入日志
|
|
693
|
+
output_lines = []
|
|
694
|
+
while True:
|
|
695
|
+
line = process.stdout.readline()
|
|
696
|
+
if not line and process.poll() is not None:
|
|
697
|
+
break
|
|
698
|
+
if line:
|
|
699
|
+
# 实时显示到控制台
|
|
700
|
+
self.log.info(line.strip())
|
|
701
|
+
# 同时写入日志文件
|
|
702
|
+
log_fd.write(line)
|
|
703
|
+
log_fd.flush()
|
|
704
|
+
output_lines.append(line)
|
|
705
|
+
|
|
706
|
+
# 等待进程结束
|
|
707
|
+
returncode = process.wait()
|
|
708
|
+
stdout_str = ''.join(output_lines)
|
|
709
|
+
|
|
710
|
+
# 创建类似subprocess.run的返回对象
|
|
711
|
+
ret = subprocess.CompletedProcess(
|
|
712
|
+
args=command,
|
|
713
|
+
returncode=returncode,
|
|
714
|
+
stdout=stdout_str,
|
|
715
|
+
stderr='' # 因为stderr合并到stdout了
|
|
716
|
+
)
|
|
717
|
+
|
|
718
|
+
# 检查返回码
|
|
719
|
+
if check and returncode != 0:
|
|
720
|
+
raise subprocess.CalledProcessError(returncode, command, output=stdout_str)
|
|
721
|
+
|
|
680
722
|
elif capture_output:
|
|
681
723
|
ret = subprocess.run(command, capture_output=capture_output, check=check, timeout=timeout, text=True)
|
|
682
724
|
if ret.stdout:
|
|
@@ -786,7 +828,7 @@ class Tools():
|
|
|
786
828
|
graph_file = os.path.join(tmpdir.name, "package.json")
|
|
787
829
|
cmd = f"conan install --requires='{package}' {install_args}"
|
|
788
830
|
cmd += f" -f json --out-file={graph_file} -of temp"
|
|
789
|
-
self.run_command(cmd,
|
|
831
|
+
_ = self.run_command(cmd, show_log=True)
|
|
790
832
|
return self.get_package_folder_from_graph_file(graph_file, package)
|
|
791
833
|
|
|
792
834
|
def install_conan_package_to(self, package, install_args, outdir):
|