openubmc-bingo 0.5.240__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 +12 -0
- bmcgo/bmcgo.py +22 -0
- bmcgo/bmcgo_config.py +176 -0
- bmcgo/cli/__init__.py +10 -0
- bmcgo/cli/cli.py +584 -0
- bmcgo/codegen/__init__.py +14 -0
- bmcgo/codegen/c/__init__.py +9 -0
- bmcgo/codegen/c/annotation.py +52 -0
- bmcgo/codegen/c/argument.py +42 -0
- bmcgo/codegen/c/codegen.py +153 -0
- bmcgo/codegen/c/comment.py +22 -0
- bmcgo/codegen/c/ctype_defination.py +353 -0
- bmcgo/codegen/c/helper.py +87 -0
- bmcgo/codegen/c/interface.py +63 -0
- bmcgo/codegen/c/method.py +82 -0
- bmcgo/codegen/c/property.py +180 -0
- bmcgo/codegen/c/renderer.py +21 -0
- bmcgo/codegen/c/signal.py +64 -0
- bmcgo/codegen/c/template/client.c.mako +145 -0
- bmcgo/codegen/c/template/client.h.mako +36 -0
- bmcgo/codegen/c/template/interface.c.mako +0 -0
- bmcgo/codegen/c/template/interface.introspect.xml.mako +99 -0
- bmcgo/codegen/c/template/micro_component.c.mako +32 -0
- bmcgo/codegen/c/template/public.c.mako +228 -0
- bmcgo/codegen/c/template/public.h.mako +128 -0
- bmcgo/codegen/c/template/server.c.mako +104 -0
- bmcgo/codegen/c/template/server.h.mako +36 -0
- bmcgo/codegen/lua/.lua-format +7 -0
- bmcgo/codegen/lua/Makefile +101 -0
- bmcgo/codegen/lua/__init__.py +9 -0
- bmcgo/codegen/lua/codegen.py +171 -0
- bmcgo/codegen/lua/proto/Makefile +87 -0
- bmcgo/codegen/lua/proto/ipmi_types.proto +17 -0
- bmcgo/codegen/lua/proto/types.proto +52 -0
- bmcgo/codegen/lua/script/check_intfs.py +161 -0
- bmcgo/codegen/lua/script/dto/__init__.py +11 -0
- bmcgo/codegen/lua/script/dto/exception.py +53 -0
- bmcgo/codegen/lua/script/dto/kepler_abstract.py +47 -0
- bmcgo/codegen/lua/script/dto/options.py +33 -0
- bmcgo/codegen/lua/script/dto/print_simple.py +19 -0
- bmcgo/codegen/lua/script/dto/redfish_api.py +241 -0
- bmcgo/codegen/lua/script/dto/url_route.py +195 -0
- bmcgo/codegen/lua/script/gen_db_json.py +444 -0
- bmcgo/codegen/lua/script/gen_depends.py +89 -0
- bmcgo/codegen/lua/script/gen_entry.py +263 -0
- bmcgo/codegen/lua/script/gen_feature_json.py +156 -0
- bmcgo/codegen/lua/script/gen_historical_local_db_json.py +88 -0
- bmcgo/codegen/lua/script/gen_intf_json.py +261 -0
- bmcgo/codegen/lua/script/gen_intf_rpc_json.py +575 -0
- bmcgo/codegen/lua/script/gen_ipmi_json.py +485 -0
- bmcgo/codegen/lua/script/gen_mdb_json.py +117 -0
- bmcgo/codegen/lua/script/gen_rpc_msg_json.py +487 -0
- bmcgo/codegen/lua/script/gen_schema.py +302 -0
- bmcgo/codegen/lua/script/ipmi_types_pb2.py +135 -0
- bmcgo/codegen/lua/script/loader/__init__.py +11 -0
- bmcgo/codegen/lua/script/loader/file_utils.py +33 -0
- bmcgo/codegen/lua/script/loader/kepler_abstract_collect.py +79 -0
- bmcgo/codegen/lua/script/loader/kepler_abstract_loader.py +47 -0
- bmcgo/codegen/lua/script/loader/redfish_loader.py +127 -0
- bmcgo/codegen/lua/script/lua_format.py +62 -0
- bmcgo/codegen/lua/script/mds_util.py +385 -0
- bmcgo/codegen/lua/script/merge_model.py +330 -0
- bmcgo/codegen/lua/script/merge_proto_algo.py +85 -0
- bmcgo/codegen/lua/script/proto_loader.py +47 -0
- bmcgo/codegen/lua/script/proto_plugin.py +140 -0
- bmcgo/codegen/lua/script/redfish_source_tree.py +118 -0
- bmcgo/codegen/lua/script/render_utils/__init__.py +38 -0
- bmcgo/codegen/lua/script/render_utils/base.py +25 -0
- bmcgo/codegen/lua/script/render_utils/client_lua.py +98 -0
- bmcgo/codegen/lua/script/render_utils/controller_lua.py +71 -0
- bmcgo/codegen/lua/script/render_utils/db_lua.py +224 -0
- bmcgo/codegen/lua/script/render_utils/error_lua.py +185 -0
- bmcgo/codegen/lua/script/render_utils/factory.py +52 -0
- bmcgo/codegen/lua/script/render_utils/ipmi_lua.py +159 -0
- bmcgo/codegen/lua/script/render_utils/ipmi_message_lua.py +24 -0
- bmcgo/codegen/lua/script/render_utils/mdb_lua.py +177 -0
- bmcgo/codegen/lua/script/render_utils/mdb_register.py +215 -0
- bmcgo/codegen/lua/script/render_utils/message_lua.py +26 -0
- bmcgo/codegen/lua/script/render_utils/messages_lua.py +156 -0
- bmcgo/codegen/lua/script/render_utils/model_lua.py +485 -0
- bmcgo/codegen/lua/script/render_utils/old_model_lua.py +429 -0
- bmcgo/codegen/lua/script/render_utils/plugin_lua.py +38 -0
- bmcgo/codegen/lua/script/render_utils/redfish_proto.py +86 -0
- bmcgo/codegen/lua/script/render_utils/request_lua.py +76 -0
- bmcgo/codegen/lua/script/render_utils/service_lua.py +130 -0
- bmcgo/codegen/lua/script/render_utils/utils_message_lua.py +125 -0
- bmcgo/codegen/lua/script/render_utils/validate_lua.py +221 -0
- bmcgo/codegen/lua/script/sep_ipmi_message_cmds.py +217 -0
- bmcgo/codegen/lua/script/template.py +166 -0
- bmcgo/codegen/lua/script/types_pb2.py +516 -0
- bmcgo/codegen/lua/script/utils.py +663 -0
- bmcgo/codegen/lua/script/validate.py +80 -0
- bmcgo/codegen/lua/script/yaml_to_json.py +73 -0
- bmcgo/codegen/lua/templates/Makefile +114 -0
- bmcgo/codegen/lua/templates/apps/Makefile +261 -0
- bmcgo/codegen/lua/templates/apps/Makefile.mdb.mk +64 -0
- bmcgo/codegen/lua/templates/apps/app.lua.mako +19 -0
- bmcgo/codegen/lua/templates/apps/class.lua.mako +35 -0
- bmcgo/codegen/lua/templates/apps/client.lua.mako +429 -0
- bmcgo/codegen/lua/templates/apps/controller.lua.mako +276 -0
- bmcgo/codegen/lua/templates/apps/datas.lua.mako +8 -0
- bmcgo/codegen/lua/templates/apps/db.lua.mako +89 -0
- bmcgo/codegen/lua/templates/apps/entry.lua.mako +128 -0
- bmcgo/codegen/lua/templates/apps/feature.lua.mako +37 -0
- bmcgo/codegen/lua/templates/apps/generate_route.mako +25 -0
- bmcgo/codegen/lua/templates/apps/impl_feature.lua.mako +72 -0
- bmcgo/codegen/lua/templates/apps/ipmi.lua.mako +97 -0
- bmcgo/codegen/lua/templates/apps/ipmi_cmd.lua.mako +18 -0
- bmcgo/codegen/lua/templates/apps/ipmi_message.lua.mako +36 -0
- bmcgo/codegen/lua/templates/apps/local_db.lua.mako +263 -0
- bmcgo/codegen/lua/templates/apps/main.lua.mako +25 -0
- bmcgo/codegen/lua/templates/apps/mc.lua.mako +77 -0
- bmcgo/codegen/lua/templates/apps/mdb.lua.mako +45 -0
- bmcgo/codegen/lua/templates/apps/mdb_interface.lua.mako +73 -0
- bmcgo/codegen/lua/templates/apps/message.lua.mako +38 -0
- bmcgo/codegen/lua/templates/apps/model.lua.mako +239 -0
- bmcgo/codegen/lua/templates/apps/orm_classes.lua.mako +16 -0
- bmcgo/codegen/lua/templates/apps/plugin.lua.mako +8 -0
- bmcgo/codegen/lua/templates/apps/redfish.proto.mako +47 -0
- bmcgo/codegen/lua/templates/apps/service.lua.mako +440 -0
- bmcgo/codegen/lua/templates/apps/signal_listen.lua.mako +19 -0
- bmcgo/codegen/lua/templates/apps/utils/default_intf.lua.mako +41 -0
- bmcgo/codegen/lua/templates/apps/utils/enum.mako +10 -0
- bmcgo/codegen/lua/templates/apps/utils/imports.mako +13 -0
- bmcgo/codegen/lua/templates/apps/utils/mdb_intf.lua.mako +25 -0
- bmcgo/codegen/lua/templates/apps/utils/mdb_obj.lua.mako +23 -0
- bmcgo/codegen/lua/templates/apps/utils/message.mako +160 -0
- bmcgo/codegen/lua/templates/apps/utils/request.lua.mako +59 -0
- bmcgo/codegen/lua/templates/apps/utils/validate.mako +83 -0
- bmcgo/codegen/lua/templates/errors.lua.mako +36 -0
- bmcgo/codegen/lua/templates/messages.lua.mako +32 -0
- bmcgo/codegen/lua/templates/new_app/.clang-format.mako +170 -0
- bmcgo/codegen/lua/templates/new_app/.gitignore.mako +26 -0
- bmcgo/codegen/lua/templates/new_app/CHANGELOG.md.mako +0 -0
- bmcgo/codegen/lua/templates/new_app/CMakeLists.txt.mako +29 -0
- bmcgo/codegen/lua/templates/new_app/Makefile.mako +25 -0
- bmcgo/codegen/lua/templates/new_app/README.md.mako +0 -0
- bmcgo/codegen/lua/templates/new_app/conanfile.py.mako +7 -0
- bmcgo/codegen/lua/templates/new_app/config.cfg.mako +6 -0
- bmcgo/codegen/lua/templates/new_app/mds/model.json.mako +3 -0
- bmcgo/codegen/lua/templates/new_app/mds/service.json.mako +21 -0
- bmcgo/codegen/lua/templates/new_app/permissions.ini.mako +16 -0
- bmcgo/codegen/lua/templates/new_app/src/lualib/${project_name}_app.lua.mako +16 -0
- bmcgo/codegen/lua/templates/new_app/src/service/main.lua.mako +25 -0
- bmcgo/codegen/lua/templates/new_app/test/integration/test_${project_name}.conf.mako +9 -0
- bmcgo/codegen/lua/templates/new_app/test/integration/test_${project_name}.lua.mako +47 -0
- bmcgo/codegen/lua/templates/new_app/test/unit/test.lua.mako +23 -0
- bmcgo/codegen/lua/templates/new_app/user_conf/rootfs/etc/systemd/system/${project_name}.service.mako +18 -0
- bmcgo/codegen/lua/templates/new_app/user_conf/rootfs/etc/systemd/system/multi-user.target.wants/${project_name}.service.link +1 -0
- bmcgo/component/__init__.py +10 -0
- bmcgo/component/analysis/analysis.py +183 -0
- bmcgo/component/analysis/build_deps.py +165 -0
- bmcgo/component/analysis/data_deps.py +333 -0
- bmcgo/component/analysis/dep-rules.json +912 -0
- bmcgo/component/analysis/dep_node.py +110 -0
- bmcgo/component/analysis/intf_deps.py +163 -0
- bmcgo/component/analysis/intf_validation.py +254 -0
- bmcgo/component/analysis/rule.py +211 -0
- bmcgo/component/analysis/smc_dfx_whitelist.json +11 -0
- bmcgo/component/analysis/sr_validation.py +391 -0
- bmcgo/component/build.py +222 -0
- bmcgo/component/component_dt_version_parse.py +348 -0
- bmcgo/component/component_helper.py +114 -0
- bmcgo/component/coverage/__init__.py +11 -0
- bmcgo/component/coverage/c_incremental_cov_report.template +53 -0
- bmcgo/component/coverage/incremental_cov.py +464 -0
- bmcgo/component/deploy.py +110 -0
- bmcgo/component/gen.py +169 -0
- bmcgo/component/package_info.py +236 -0
- bmcgo/component/template/conanbase.py.mako +278 -0
- bmcgo/component/template/conanfile.deploy.py.mako +40 -0
- bmcgo/component/test.py +947 -0
- bmcgo/errors.py +119 -0
- bmcgo/frame.py +217 -0
- bmcgo/functional/__init__.py +10 -0
- bmcgo/functional/analysis.py +96 -0
- bmcgo/functional/bmc_studio_action.py +98 -0
- bmcgo/functional/check.py +185 -0
- bmcgo/functional/conan_index_build.py +251 -0
- bmcgo/functional/config.py +332 -0
- bmcgo/functional/csr_build.py +724 -0
- bmcgo/functional/deploy.py +263 -0
- bmcgo/functional/diff.py +235 -0
- bmcgo/functional/fetch.py +235 -0
- bmcgo/functional/full_component.py +391 -0
- bmcgo/functional/maintain.py +381 -0
- bmcgo/functional/new.py +166 -0
- bmcgo/functional/schema_valid.py +111 -0
- bmcgo/functional/simple_sign.py +104 -0
- bmcgo/functional/upgrade.py +78 -0
- bmcgo/ipmigen/__init__.py +13 -0
- bmcgo/ipmigen/ctype_defination.py +82 -0
- bmcgo/ipmigen/ipmigen.py +309 -0
- bmcgo/ipmigen/template/cmd.c.mako +366 -0
- bmcgo/ipmigen/template/ipmi.c.mako +25 -0
- bmcgo/ipmigen/template/ipmi.h.mako +51 -0
- bmcgo/logger.py +176 -0
- bmcgo/misc.py +117 -0
- bmcgo/target/app.yml +17 -0
- bmcgo/target/install_sdk.yml +15 -0
- bmcgo/target/personal.yml +53 -0
- bmcgo/target/publish.yml +45 -0
- bmcgo/tasks/__init__.py +11 -0
- bmcgo/tasks/download_buildtools_hm.py +124 -0
- bmcgo/tasks/misc.py +15 -0
- bmcgo/tasks/task.py +354 -0
- bmcgo/tasks/task_build_conan.py +714 -0
- bmcgo/tasks/task_build_rootfs_img.py +595 -0
- bmcgo/tasks/task_buildgppbin.py +88 -0
- bmcgo/tasks/task_buildhpm_ext4.py +82 -0
- bmcgo/tasks/task_create_interface_config.py +122 -0
- bmcgo/tasks/task_download_buildtools.py +99 -0
- bmcgo/tasks/task_download_dependency.py +72 -0
- bmcgo/tasks/task_hpm_envir_prepare.py +112 -0
- bmcgo/tasks/task_packet_to_supporte.py +87 -0
- bmcgo/tasks/task_prepare.py +105 -0
- bmcgo/tasks/task_sign_and_pack_hpm.py +42 -0
- bmcgo/utils/__init__.py +10 -0
- bmcgo/utils/buffer.py +128 -0
- bmcgo/utils/combine_json_schemas.py +170 -0
- bmcgo/utils/component_post.py +54 -0
- bmcgo/utils/component_version_check.py +86 -0
- bmcgo/utils/config.py +1067 -0
- bmcgo/utils/fetch_component_code.py +232 -0
- bmcgo/utils/install_manager.py +61 -0
- bmcgo/utils/installations/__init__.py +10 -0
- bmcgo/utils/installations/base_installer.py +70 -0
- bmcgo/utils/installations/install_consts.py +30 -0
- bmcgo/utils/installations/install_plans/bingo.yml +11 -0
- bmcgo/utils/installations/install_workflow.py +50 -0
- bmcgo/utils/installations/installers/apt_installer.py +177 -0
- bmcgo/utils/installations/installers/pip_installer.py +46 -0
- bmcgo/utils/installations/version_util.py +100 -0
- bmcgo/utils/mapping_config_patch.py +443 -0
- bmcgo/utils/perf_analysis.py +114 -0
- bmcgo/utils/tools.py +704 -0
- bmcgo/worker.py +417 -0
- openubmc_bingo-0.5.240.dist-info/METADATA +30 -0
- openubmc_bingo-0.5.240.dist-info/RECORD +242 -0
- openubmc_bingo-0.5.240.dist-info/WHEEL +5 -0
- openubmc_bingo-0.5.240.dist-info/entry_points.txt +2 -0
- openubmc_bingo-0.5.240.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
#!/usr/bin/python3
|
|
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.
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
|
|
3
|
+
<html lang="en">
|
|
4
|
+
|
|
5
|
+
<head>
|
|
6
|
+
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
|
7
|
+
<title>coverage report</title>
|
|
8
|
+
</head>
|
|
9
|
+
|
|
10
|
+
<body>
|
|
11
|
+
|
|
12
|
+
<table width="100%%" border=0 cellspacing=0 cellpadding=0>
|
|
13
|
+
<tr><td class="title">BMC - incremental code coverage report</td></tr>
|
|
14
|
+
<tr><td class="ruler"><img src="glass.png" width=3 height=6 alt=""></td></tr>
|
|
15
|
+
|
|
16
|
+
<tr>
|
|
17
|
+
<td width="100%%">
|
|
18
|
+
<table cellpadding=1 border=0 width="100%%">
|
|
19
|
+
<tr>
|
|
20
|
+
<td></td>
|
|
21
|
+
<td width="33%%" class="headerCovTableHead">UT covered</td>
|
|
22
|
+
<td width="33%%" class="headerCovTableHead">Total</td>
|
|
23
|
+
<td width="33%%" class="headerCovTableHead">Coverage</td>
|
|
24
|
+
</tr>
|
|
25
|
+
<tr>
|
|
26
|
+
<td class="headerItem">Incremental Lines:</td>
|
|
27
|
+
<td class="incrementalCoveredLines">%(cov_lines)s</td>
|
|
28
|
+
<td class="incrementalTotalLines">%(change_linenum)s</td>
|
|
29
|
+
<td class="incrementalLineCoverageRate">%(coverage)s %%</td>
|
|
30
|
+
</tr>
|
|
31
|
+
<tr><td><img src="glass.png" width=3 height=3 alt=""></td></tr>
|
|
32
|
+
</table>
|
|
33
|
+
</td>
|
|
34
|
+
</tr>
|
|
35
|
+
|
|
36
|
+
<tr><td class="ruler"><img src="glass.png" width=3 height=3 alt=""></td></tr>
|
|
37
|
+
</table>
|
|
38
|
+
|
|
39
|
+
<center>
|
|
40
|
+
<br>
|
|
41
|
+
<table width="100%%" cellpadding=1 cellspacing=1 border=0>
|
|
42
|
+
<tr>
|
|
43
|
+
<td width="60%%" class="tableHead">File </td>
|
|
44
|
+
<td width="40%%" class="tableHead">Uncovered Lines </td>
|
|
45
|
+
</tr>
|
|
46
|
+
%(uncover_trs)s
|
|
47
|
+
</table>
|
|
48
|
+
</center>
|
|
49
|
+
<br>
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
</body>
|
|
53
|
+
</html>
|
|
@@ -0,0 +1,464 @@
|
|
|
1
|
+
#!/usr/bin/python3
|
|
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 sys
|
|
13
|
+
import os
|
|
14
|
+
import re
|
|
15
|
+
import json
|
|
16
|
+
from html.parser import HTMLParser
|
|
17
|
+
import argparse
|
|
18
|
+
import functools
|
|
19
|
+
import fnmatch
|
|
20
|
+
|
|
21
|
+
from bmcgo.utils.tools import Tools
|
|
22
|
+
|
|
23
|
+
DOC_STRING = """
|
|
24
|
+
PURPOSE:
|
|
25
|
+
Calculate incremental coverage of git commits
|
|
26
|
+
|
|
27
|
+
USAGE:
|
|
28
|
+
./incremental_cov.py <since>..<until> <monitor_c_files> <lcov_dir> <thresholdold>
|
|
29
|
+
example:
|
|
30
|
+
./incremental_cov.py "227b032..79196ba" '["src/file"]' "coverage" 0.6 LTX--
|
|
31
|
+
|
|
32
|
+
WORK PROCESS:
|
|
33
|
+
get changed file list between <since> and <until> , filter by <monitor_c_files> options;
|
|
34
|
+
get changed lines per changed file;
|
|
35
|
+
based on <lcov_dir>, search .gcov.html per file, and get uncover lines;
|
|
36
|
+
create report file:ut_incremental_check_report.html and check <thresholdold> (cover lines/new lines).
|
|
37
|
+
|
|
38
|
+
coverage_exclude.json example:
|
|
39
|
+
{
|
|
40
|
+
"xxx": {
|
|
41
|
+
"LUA_EXCLUDED": [],
|
|
42
|
+
"C_EXCLUDED": []
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
"""
|
|
46
|
+
|
|
47
|
+
tools = Tools()
|
|
48
|
+
log = tools.log
|
|
49
|
+
|
|
50
|
+
OUTPUT_DATA = "dt_result.json"
|
|
51
|
+
|
|
52
|
+
# 组件里需要解析mds获取component名字
|
|
53
|
+
FILE_WHITE_LIST = ["src"]
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def open_file(file_name, mode="r", encoding=None, **kwargs):
|
|
57
|
+
# 尝试用不同编码方式解码该文件内容并打开
|
|
58
|
+
with open(file_name, "rb") as f:
|
|
59
|
+
context = f.read()
|
|
60
|
+
for encoding_item in ["UTF-8", "GBK", "ISO-8859-1", "GB2312"]:
|
|
61
|
+
try:
|
|
62
|
+
context.decode(encoding=encoding_item)
|
|
63
|
+
encoding = encoding_item
|
|
64
|
+
return open(file_name, mode=mode, encoding=encoding, **kwargs)
|
|
65
|
+
except UnicodeDecodeError as e:
|
|
66
|
+
pass
|
|
67
|
+
return open(file_name, mode=mode, encoding=encoding, **kwargs)
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def num_to_percentage(num):
|
|
71
|
+
percentage = num * 100
|
|
72
|
+
return f"{percentage:.1f}%"
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
class GcovHTMLParser(HTMLParser):
|
|
76
|
+
def __init__(self):
|
|
77
|
+
super().__init__()
|
|
78
|
+
self.uncovers = []
|
|
79
|
+
self.covers = []
|
|
80
|
+
self.is_line_num = False
|
|
81
|
+
self.line_num = 0
|
|
82
|
+
|
|
83
|
+
def handle_starttag(self, tag, attrs):
|
|
84
|
+
if tag == "span":
|
|
85
|
+
for a in attrs:
|
|
86
|
+
if a == ("class", "lineNum"):
|
|
87
|
+
self.is_line_num = True
|
|
88
|
+
if a == ("class", "lineNoCov"):
|
|
89
|
+
self.uncovers.append(self.line_num)
|
|
90
|
+
if a == ("class", "lineCov"):
|
|
91
|
+
self.covers.append(self.line_num)
|
|
92
|
+
|
|
93
|
+
def handle_data(self, data):
|
|
94
|
+
if self.is_line_num:
|
|
95
|
+
try:
|
|
96
|
+
self.line_num = int(data)
|
|
97
|
+
except Exception as e:
|
|
98
|
+
self.line_num = -1
|
|
99
|
+
|
|
100
|
+
def handle_endtag(self, tag):
|
|
101
|
+
if tag == "span":
|
|
102
|
+
self.is_line_num = False
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
class IncrementalCov(object):
|
|
106
|
+
def __init__(self, since_until, component_name, lcov_dir, threshold, coverage_exclude):
|
|
107
|
+
self.since, self.until = since_until.split("..")
|
|
108
|
+
self.component_name = component_name
|
|
109
|
+
self.lcov_dir = lcov_dir
|
|
110
|
+
self.threshold = float(threshold)
|
|
111
|
+
self.coverage_exclude = coverage_exclude
|
|
112
|
+
if not os.path.exists(self.lcov_dir):
|
|
113
|
+
os.makedirs(self.lcov_dir)
|
|
114
|
+
|
|
115
|
+
@functools.cached_property
|
|
116
|
+
def src_root_dir(self):
|
|
117
|
+
ret = tools.run_command("git rev-parse --show-toplevel", capture_output=True, command_echo=False)
|
|
118
|
+
if ret.returncode != 0:
|
|
119
|
+
return os.getcwd()
|
|
120
|
+
|
|
121
|
+
return ret.stdout.strip()
|
|
122
|
+
|
|
123
|
+
def is_file_matched(self, file_name, suffix_list):
|
|
124
|
+
# 校验传入的文件参数是否在设定的匹配路径下
|
|
125
|
+
for f in FILE_WHITE_LIST:
|
|
126
|
+
if file_name.startswith(f) and os.path.splitext(file_name)[1][1:] in suffix_list:
|
|
127
|
+
return True
|
|
128
|
+
return False
|
|
129
|
+
|
|
130
|
+
def get_lua_cov_map(self, path_list):
|
|
131
|
+
# 获取lua代码的校验字典
|
|
132
|
+
covers = {}
|
|
133
|
+
uncovers = {}
|
|
134
|
+
# 如果未覆盖到lua文件则返回空字典,path_list[1]为.out文件路径
|
|
135
|
+
if not os.path.exists(path_list[1]):
|
|
136
|
+
return covers, uncovers
|
|
137
|
+
whole_lines = self.parse_data(path_list[0])
|
|
138
|
+
check_list = self.parse_check_data(path_list[1])
|
|
139
|
+
for key, value_list in whole_lines.items():
|
|
140
|
+
value_check_list = check_list[key]
|
|
141
|
+
temp_uncovers = []
|
|
142
|
+
temp_covers = []
|
|
143
|
+
index = 0
|
|
144
|
+
for _ in value_list:
|
|
145
|
+
if value_list[index] == 0 and value_check_list[index] == 1:
|
|
146
|
+
temp_uncovers.append(index + 1)
|
|
147
|
+
elif value_list[index] != 0 and value_check_list[index] == 1:
|
|
148
|
+
temp_covers.append(index + 1)
|
|
149
|
+
index = index + 1
|
|
150
|
+
covers[key] = temp_covers
|
|
151
|
+
uncovers[key] = temp_uncovers
|
|
152
|
+
|
|
153
|
+
return covers, uncovers
|
|
154
|
+
|
|
155
|
+
def parse_data(self, file_path):
|
|
156
|
+
# 解析lua覆盖率的统计文件
|
|
157
|
+
lines = []
|
|
158
|
+
whole_lines = {}
|
|
159
|
+
with open(file_path, "r") as file:
|
|
160
|
+
for line in file:
|
|
161
|
+
lines.append(line.strip())
|
|
162
|
+
num_calculate = 1
|
|
163
|
+
file_locator = "init"
|
|
164
|
+
for line in lines:
|
|
165
|
+
if num_calculate % 2 == 1:
|
|
166
|
+
file_start = line.find("src")
|
|
167
|
+
file_locator = line[file_start:]
|
|
168
|
+
num_calculate += 1
|
|
169
|
+
else:
|
|
170
|
+
lines_cov = [int(num) for num in line.split() if num.isdigit()]
|
|
171
|
+
whole_lines[file_locator] = lines_cov
|
|
172
|
+
num_calculate += 1
|
|
173
|
+
return whole_lines
|
|
174
|
+
|
|
175
|
+
def parse_check_data(self, file_path):
|
|
176
|
+
# 解析lua覆盖率的过滤文件
|
|
177
|
+
lines = []
|
|
178
|
+
check_list = {}
|
|
179
|
+
with open(file_path, "r") as file:
|
|
180
|
+
for line in file:
|
|
181
|
+
lines.append(line.strip())
|
|
182
|
+
num_calculate = 1
|
|
183
|
+
file_locator = "init"
|
|
184
|
+
for line in lines:
|
|
185
|
+
if num_calculate % 2 == 1:
|
|
186
|
+
file_start = line.find("src")
|
|
187
|
+
file_locator = line[file_start:]
|
|
188
|
+
num_calculate += 1
|
|
189
|
+
else:
|
|
190
|
+
lines_cov = [int(num) for num in line.split() if num.isdigit()]
|
|
191
|
+
check_list[file_locator] = lines_cov
|
|
192
|
+
num_calculate += 1
|
|
193
|
+
return check_list
|
|
194
|
+
|
|
195
|
+
def get_excluded_files(self):
|
|
196
|
+
if not os.path.isfile(self.coverage_exclude):
|
|
197
|
+
return []
|
|
198
|
+
|
|
199
|
+
try:
|
|
200
|
+
with open(self.coverage_exclude, "r") as file:
|
|
201
|
+
excluded_data = json.load(file)
|
|
202
|
+
except json.JSONDecodeError:
|
|
203
|
+
log.info(f"Failed to decode JSON from file: {self.coverage_exclude}")
|
|
204
|
+
return []
|
|
205
|
+
|
|
206
|
+
# 展平排除文件列表
|
|
207
|
+
excluded_files = []
|
|
208
|
+
if self.component_name in excluded_data:
|
|
209
|
+
|
|
210
|
+
for file_list in excluded_data[self.component_name].values():
|
|
211
|
+
excluded_files.extend(file_list)
|
|
212
|
+
return excluded_files
|
|
213
|
+
|
|
214
|
+
def get_src(self, suffix_list):
|
|
215
|
+
# 获取节点间的变动文件
|
|
216
|
+
ret = tools.run_command(
|
|
217
|
+
f"git diff --name-only {self.since} {self.until}", capture_output=True, command_echo=False
|
|
218
|
+
)
|
|
219
|
+
|
|
220
|
+
if ret.returncode != 0:
|
|
221
|
+
log.info(f"error: git diff failed! err={ret.stderr}")
|
|
222
|
+
|
|
223
|
+
file_list = ret.stdout.split("\n")
|
|
224
|
+
src_files = []
|
|
225
|
+
for f in file_list:
|
|
226
|
+
if self.is_file_matched(f, suffix_list):
|
|
227
|
+
src_files.append(f)
|
|
228
|
+
|
|
229
|
+
# 获取需要排除的文件
|
|
230
|
+
excluded_list = self.get_excluded_files()
|
|
231
|
+
|
|
232
|
+
# 过滤掉排除的文件
|
|
233
|
+
filtered_files = [f for f in src_files if f not in excluded_list]
|
|
234
|
+
|
|
235
|
+
return filtered_files
|
|
236
|
+
|
|
237
|
+
def get_change(self, src_files):
|
|
238
|
+
# self.since, self.until
|
|
239
|
+
# 获取变动文件的change行
|
|
240
|
+
changes = {}
|
|
241
|
+
for f in src_files:
|
|
242
|
+
# commit中已删除文件不做统计
|
|
243
|
+
file_path = os.path.join(self.src_root_dir, f)
|
|
244
|
+
if not os.path.isfile(file_path):
|
|
245
|
+
continue
|
|
246
|
+
output, _ = tools.pipe_command(
|
|
247
|
+
[f"git log --oneline {self.since}..{self.until} {f}", "awk '{print $1}'"],
|
|
248
|
+
capture_output=True,
|
|
249
|
+
command_echo=False,
|
|
250
|
+
)
|
|
251
|
+
commits = [commit for commit in output.split("\n") if commit]
|
|
252
|
+
|
|
253
|
+
cmds = [f"git blame -f {f}"]
|
|
254
|
+
for commit in commits:
|
|
255
|
+
cmds.append(f"grep -E '({commit})'")
|
|
256
|
+
cmds.append("awk -F' *|)' '{print $7}'")
|
|
257
|
+
|
|
258
|
+
output, _ = tools.pipe_command(cmds, capture_output=True, command_echo=False)
|
|
259
|
+
changes[f] = [int(i) for i in output.split("\n") if i.isdigit()]
|
|
260
|
+
|
|
261
|
+
return changes
|
|
262
|
+
|
|
263
|
+
def get_ghp(self, f):
|
|
264
|
+
f = os.path.basename(f)
|
|
265
|
+
located_file = f + ".gcov.html"
|
|
266
|
+
# 以下是为了能通过点击行号跳转到对应的代码行,为原html文件的未覆盖的代码行添加一个tag
|
|
267
|
+
gcovfile = self.find_and_return_file_path(located_file)
|
|
268
|
+
if not os.path.exists(gcovfile):
|
|
269
|
+
log.info("*.gcov.html does not exits!")
|
|
270
|
+
return None
|
|
271
|
+
|
|
272
|
+
ghp = GcovHTMLParser()
|
|
273
|
+
ghp.feed(open_file(gcovfile, "r").read())
|
|
274
|
+
|
|
275
|
+
return ghp
|
|
276
|
+
|
|
277
|
+
def get_lcov_data(self, changes):
|
|
278
|
+
# self.lcov_dir
|
|
279
|
+
uncovers = {}
|
|
280
|
+
lcov_changes = {}
|
|
281
|
+
for f, lines in changes.items():
|
|
282
|
+
ghp = self.get_ghp(f)
|
|
283
|
+
if not ghp:
|
|
284
|
+
uncovers[f] = lines
|
|
285
|
+
lcov_changes[f] = lines
|
|
286
|
+
continue
|
|
287
|
+
|
|
288
|
+
# set创造一个不重复的集合
|
|
289
|
+
lcov_changes[f] = sorted(list(set(ghp.uncovers + ghp.covers) & set(lines)))
|
|
290
|
+
uncov_lines = list(set(ghp.uncovers) & set(lines))
|
|
291
|
+
if len(uncov_lines) != 0:
|
|
292
|
+
uncovers[f] = sorted(uncov_lines)
|
|
293
|
+
ghp.close()
|
|
294
|
+
|
|
295
|
+
return lcov_changes, uncovers
|
|
296
|
+
|
|
297
|
+
def get_lua_cov_data(self, changes, path):
|
|
298
|
+
path_list = [
|
|
299
|
+
os.path.join(path, "luacov.stats.out"),
|
|
300
|
+
os.path.join(path, "luacov.stats.filter"),
|
|
301
|
+
]
|
|
302
|
+
lua_covers_map, lua_uncovers_map = self.get_lua_cov_map(path_list)
|
|
303
|
+
uncovers = {}
|
|
304
|
+
lua_changes = {}
|
|
305
|
+
for f, lines in changes.items():
|
|
306
|
+
if f not in lua_covers_map and f not in lua_uncovers_map:
|
|
307
|
+
lua_changes[f] = lines
|
|
308
|
+
uncovers[f] = lines
|
|
309
|
+
continue
|
|
310
|
+
lua_changes[f] = sorted(list(set(lua_uncovers_map[f] + lua_covers_map[f]) & set(lines)))
|
|
311
|
+
uncov_lines = list(set(lua_uncovers_map[f]) & set(lines))
|
|
312
|
+
if len(uncov_lines) != 0:
|
|
313
|
+
uncovers[f] = sorted(uncov_lines)
|
|
314
|
+
return lua_changes, uncovers
|
|
315
|
+
|
|
316
|
+
def find_and_return_file_path(self, filename):
|
|
317
|
+
for root, _, files in os.walk(self.lcov_dir, topdown=True):
|
|
318
|
+
for name in files:
|
|
319
|
+
if fnmatch.fnmatch(name, filename):
|
|
320
|
+
file_path = os.path.join(root, name)
|
|
321
|
+
return file_path
|
|
322
|
+
return ""
|
|
323
|
+
|
|
324
|
+
def prepare_uncover_trs(self, path):
|
|
325
|
+
if os.path.exists(path):
|
|
326
|
+
s = ""
|
|
327
|
+
p = re.compile(r'^<span class="lineNum">\s*(?P<num>\d+)\s*</span>')
|
|
328
|
+
for line in open_file(path, "r").readlines():
|
|
329
|
+
ps = p.search(line)
|
|
330
|
+
if ps:
|
|
331
|
+
s += '<a name="%s">' % ps.group("num") + line + "</a>"
|
|
332
|
+
else:
|
|
333
|
+
s += line
|
|
334
|
+
open(path, "w").write(s)
|
|
335
|
+
|
|
336
|
+
def create_uncover_trs(self, uncovers):
|
|
337
|
+
"""
|
|
338
|
+
返回:tr_format格式的 html table
|
|
339
|
+
通过对全量报告生成的gcov.html文件解析,生成html格式的增量覆盖率的table
|
|
340
|
+
"""
|
|
341
|
+
|
|
342
|
+
tr_format = """
|
|
343
|
+
<tr>
|
|
344
|
+
<td class="coverFile"><a href="%(f_ref_path)s.gcov.html">%(file)s</a></td>
|
|
345
|
+
<td class="coverFile">%(uncov_lines)s </td>
|
|
346
|
+
</tr>
|
|
347
|
+
|
|
348
|
+
"""
|
|
349
|
+
trs = ""
|
|
350
|
+
for f, v in uncovers.items():
|
|
351
|
+
f = os.path.basename(f)
|
|
352
|
+
located_file = f + ".gcov.html"
|
|
353
|
+
# 以下是为了能通过点击行号跳转到对应的代码行,为原html文件的未覆盖的代码行添加一个tag
|
|
354
|
+
gcovfile = self.find_and_return_file_path(located_file)
|
|
355
|
+
self.prepare_uncover_trs(gcovfile)
|
|
356
|
+
|
|
357
|
+
data = {
|
|
358
|
+
"file": f,
|
|
359
|
+
"uncov_lines": ", ".join([f'<a href="{f}.gcov.html#{i}">{i}</a>' for i in v]),
|
|
360
|
+
"f_ref_path": f,
|
|
361
|
+
}
|
|
362
|
+
trs += tr_format % data
|
|
363
|
+
|
|
364
|
+
return trs
|
|
365
|
+
|
|
366
|
+
def create_report(self, changes, uncovers, type_name):
|
|
367
|
+
change_linenum, uncov_linenum = 0, 0
|
|
368
|
+
for _, v in changes.items():
|
|
369
|
+
change_linenum += len(v)
|
|
370
|
+
for _, v in uncovers.items():
|
|
371
|
+
uncov_linenum += len(v)
|
|
372
|
+
|
|
373
|
+
cov_linenum = change_linenum - uncov_linenum
|
|
374
|
+
coverage = round(cov_linenum * 1.0 / change_linenum if change_linenum > 0 else 1, 4)
|
|
375
|
+
script_dir = os.path.split(os.path.realpath(__file__))[0]
|
|
376
|
+
if type_name == "c":
|
|
377
|
+
template = open(os.path.join(script_dir, "c_incremental_cov_report.template"), "r").read()
|
|
378
|
+
data = {
|
|
379
|
+
"cov_lines": cov_linenum,
|
|
380
|
+
"change_linenum": change_linenum,
|
|
381
|
+
"coverage": coverage * 100,
|
|
382
|
+
"uncover_trs": self.create_uncover_trs(uncovers),
|
|
383
|
+
}
|
|
384
|
+
with open(os.path.join(self.lcov_dir, "c_incremental_coverage_report.html"), "w+") as f:
|
|
385
|
+
f.write(template % data)
|
|
386
|
+
if coverage < self.threshold:
|
|
387
|
+
log.info(f"{type_name} incremental coverage less than {num_to_percentage(self.threshold)}")
|
|
388
|
+
return coverage, change_linenum, cov_linenum
|
|
389
|
+
|
|
390
|
+
def calculate_cov(self):
|
|
391
|
+
# main function
|
|
392
|
+
result_path = os.path.join(self.lcov_dir, OUTPUT_DATA)
|
|
393
|
+
|
|
394
|
+
c_cov_match = ["c", "cpp"]
|
|
395
|
+
lua_cov_match = ["lua"]
|
|
396
|
+
|
|
397
|
+
c_src_files = self.get_src(c_cov_match)
|
|
398
|
+
lua_src_files = self.get_src(lua_cov_match)
|
|
399
|
+
|
|
400
|
+
c_changes = self.get_change(c_src_files)
|
|
401
|
+
lua_changes = self.get_change(lua_src_files)
|
|
402
|
+
|
|
403
|
+
c_lcov_changes, c_uncovered_lines = self.get_lcov_data(c_changes)
|
|
404
|
+
lua_lcov_changes, lua_uncovered_lines = self.get_lua_cov_data(lua_changes, self.lcov_dir)
|
|
405
|
+
|
|
406
|
+
c_cov_rate, c_change_linenum, c_cov_linenum = self.create_report(c_lcov_changes, c_uncovered_lines, "c")
|
|
407
|
+
lua_cov_rate, lua_change_linenum, lua_cov_linenum = self.create_report(
|
|
408
|
+
lua_lcov_changes, lua_uncovered_lines, "lua"
|
|
409
|
+
)
|
|
410
|
+
|
|
411
|
+
if c_change_linenum + lua_change_linenum == 0:
|
|
412
|
+
total_rate = 1
|
|
413
|
+
else:
|
|
414
|
+
total_rate = (c_cov_linenum + lua_cov_linenum) / (c_change_linenum + lua_change_linenum)
|
|
415
|
+
coverage_data = {
|
|
416
|
+
"incremental_coverage": num_to_percentage(total_rate),
|
|
417
|
+
"incremental_coverage_detail": {
|
|
418
|
+
"c_incremental_coverage": num_to_percentage(c_cov_rate),
|
|
419
|
+
"lua_incremental_coverage": num_to_percentage(lua_cov_rate),
|
|
420
|
+
"total_incremental_coverage": num_to_percentage(total_rate),
|
|
421
|
+
"c_change_lines": c_lcov_changes,
|
|
422
|
+
"c_uncovered_lines": c_uncovered_lines,
|
|
423
|
+
"lua_change_lines": lua_lcov_changes,
|
|
424
|
+
"lua_uncovered_lines": lua_uncovered_lines,
|
|
425
|
+
},
|
|
426
|
+
}
|
|
427
|
+
with open(result_path, "r", encoding="utf-8") as file:
|
|
428
|
+
data = json.load(file)
|
|
429
|
+
data[self.component_name].update(coverage_data)
|
|
430
|
+
with open(result_path, "w", encoding="utf-8") as file:
|
|
431
|
+
json.dump(data, file, indent=4)
|
|
432
|
+
return (
|
|
433
|
+
num_to_percentage(total_rate),
|
|
434
|
+
num_to_percentage(c_cov_rate),
|
|
435
|
+
num_to_percentage(lua_cov_rate),
|
|
436
|
+
)
|
|
437
|
+
|
|
438
|
+
|
|
439
|
+
if __name__ == "__main__":
|
|
440
|
+
if len(sys.argv) == 1:
|
|
441
|
+
log.info(__doc__)
|
|
442
|
+
sys.exit(0)
|
|
443
|
+
parser = argparse.ArgumentParser(description="manual to this script")
|
|
444
|
+
# 默认统计HEAD和HEAD~之间的增量覆盖率
|
|
445
|
+
parser.add_argument("--since_until", type=str, default="HEAD~..HEAD")
|
|
446
|
+
parser.add_argument("--module", type=str, default=None)
|
|
447
|
+
parser.add_argument("--lcov_dir", type=str, default=None)
|
|
448
|
+
parser.add_argument("--threshold", type=float, default=0.8)
|
|
449
|
+
parser.add_argument("--coverage_exclude", type=str, default="coverage_exclude.json")
|
|
450
|
+
args = parser.parse_args()
|
|
451
|
+
log.info(f"args.since_until={args.since_until}")
|
|
452
|
+
log.info(f"args.module={args.module}")
|
|
453
|
+
log.info(f"args.lcov_dir={args.lcov_dir}")
|
|
454
|
+
log.info(f"args.threshold={args.threshold}")
|
|
455
|
+
log.info(f"args.coverage_exclude={args.coverage_exclude}")
|
|
456
|
+
total_coverage, c_coverage, lua_coverage = IncrementalCov(
|
|
457
|
+
args.since_until,
|
|
458
|
+
args.module,
|
|
459
|
+
args.lcov_dir,
|
|
460
|
+
args.threshold,
|
|
461
|
+
args.coverage_exclude,
|
|
462
|
+
).calculate_cov()
|
|
463
|
+
|
|
464
|
+
log.info(f"incremental coverage is {total_coverage, c_coverage, lua_coverage}.")
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
#!/usr/bin/python3
|
|
2
|
+
# coding: utf-8
|
|
3
|
+
# Copyright (c) 2024 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 shutil
|
|
14
|
+
import stat
|
|
15
|
+
|
|
16
|
+
from mako.lookup import TemplateLookup
|
|
17
|
+
|
|
18
|
+
from bmcgo.component.package_info import InfoComp
|
|
19
|
+
from bmcgo.component.component_helper import ComponentHelper
|
|
20
|
+
from bmcgo.codegen.c.helper import Helper
|
|
21
|
+
from bmcgo.logger import Logger
|
|
22
|
+
from bmcgo.bmcgo_config import BmcgoConfig
|
|
23
|
+
from bmcgo import misc
|
|
24
|
+
|
|
25
|
+
log = Logger("deploy")
|
|
26
|
+
|
|
27
|
+
cwd_script = os.path.split(os.path.realpath(__file__))[0]
|
|
28
|
+
DT_DEPENDENCIES = {
|
|
29
|
+
"dtframeforlua": "dtframeforlua", # 目前定义在部分组件的service.json
|
|
30
|
+
"luaunit": "luaunit/3.2",
|
|
31
|
+
"luacov": "luacov/[>=0.16.2]",
|
|
32
|
+
"luafilesystem": "luafilesystem/1.8.0.B022",
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class DeployComp():
|
|
37
|
+
def __init__(self, bconfig: BmcgoConfig, info: InfoComp = None):
|
|
38
|
+
self.info: InfoComp = info
|
|
39
|
+
self.bconfig = bconfig
|
|
40
|
+
self.folder = bconfig.component.folder
|
|
41
|
+
os.chdir(self.folder)
|
|
42
|
+
self.temp_path = os.path.join(self.folder, "temp")
|
|
43
|
+
|
|
44
|
+
def get_dt_dependencies(self):
|
|
45
|
+
user_channel = ComponentHelper.get_user_channel(self.info.stage)
|
|
46
|
+
# DT专用的依赖,只在部署时添加
|
|
47
|
+
dependencies = []
|
|
48
|
+
lua_run_deps = [DT_DEPENDENCIES.get("luaunit")]
|
|
49
|
+
# 只有lua需要添加依赖
|
|
50
|
+
if not os.path.isdir("test_package") and self.info.coverage:
|
|
51
|
+
lua_run_deps.append(DT_DEPENDENCIES.get("luacov"))
|
|
52
|
+
lua_run_deps.append(DT_DEPENDENCIES.get("luafilesystem"))
|
|
53
|
+
for dep in lua_run_deps:
|
|
54
|
+
for build_dep in self.info.build_dependencies:
|
|
55
|
+
if build_dep.startswith(dep.split("/", -1)[0]):
|
|
56
|
+
dep = build_dep
|
|
57
|
+
break
|
|
58
|
+
if "@" not in dep:
|
|
59
|
+
dep += user_channel
|
|
60
|
+
dependencies.append(dep)
|
|
61
|
+
|
|
62
|
+
dependencies += self.info.test_dependencies
|
|
63
|
+
return dependencies
|
|
64
|
+
|
|
65
|
+
def gen_conanfile(self):
|
|
66
|
+
dependencies = [f"{self.info.name}/{self.info.version}{self.info.channel}"]
|
|
67
|
+
if self.info.build_type == "dt":
|
|
68
|
+
dependencies += self.get_dt_dependencies()
|
|
69
|
+
|
|
70
|
+
# 构建虚拟deploy组件,生成conanfile.py文件
|
|
71
|
+
lookup = TemplateLookup(directories=os.path.join(cwd_script, "template"))
|
|
72
|
+
template = lookup.get_template("conanfile.deploy.py.mako")
|
|
73
|
+
conanfile = template.render(lookup=lookup, pkg=self.info, dependencies=dependencies)
|
|
74
|
+
file_handler = os.fdopen(os.open("conanfile.py", os.O_WRONLY | os.O_CREAT | os.O_TRUNC,
|
|
75
|
+
stat.S_IWUSR | stat.S_IRUSR), 'w')
|
|
76
|
+
file_handler.write(conanfile)
|
|
77
|
+
file_handler.close()
|
|
78
|
+
|
|
79
|
+
def run(self):
|
|
80
|
+
# 生成虚拟deploy组件,仅用于安装
|
|
81
|
+
deploy_conan = os.path.join(self.temp_path, ".deploy")
|
|
82
|
+
os.makedirs(deploy_conan, exist_ok=True)
|
|
83
|
+
os.chdir(deploy_conan)
|
|
84
|
+
self.gen_conanfile()
|
|
85
|
+
|
|
86
|
+
# 安装依赖制品到install目录
|
|
87
|
+
install_path = os.path.join(self.temp_path, ".deploy", ".install")
|
|
88
|
+
log.info("安装所有依赖到目录 %s", install_path)
|
|
89
|
+
shutil.rmtree(install_path, ignore_errors=True)
|
|
90
|
+
cmd = [misc.CONAN, "install"]
|
|
91
|
+
append_cmd = ("%s -if=%s -g deploy" % (self.info.cmd_base, install_path))
|
|
92
|
+
append_cmd = append_cmd.replace(self.info.package, self.info.channel)
|
|
93
|
+
cmd += append_cmd.split()
|
|
94
|
+
cmd.append("--build=missing")
|
|
95
|
+
log.success("运行部署命令: %s", " ".join(cmd))
|
|
96
|
+
Helper.run(cmd)
|
|
97
|
+
# 复制制品到rootfs目录
|
|
98
|
+
rootfs_path = self.temp_path
|
|
99
|
+
log.info("复制所有依赖到目录 %s", rootfs_path)
|
|
100
|
+
os.makedirs(rootfs_path, exist_ok=True)
|
|
101
|
+
for sub_dir in os.listdir(install_path):
|
|
102
|
+
dir_path = os.path.join(install_path, sub_dir)
|
|
103
|
+
if os.path.isfile(dir_path):
|
|
104
|
+
os.unlink(dir_path)
|
|
105
|
+
continue
|
|
106
|
+
for file in os.listdir(dir_path):
|
|
107
|
+
source = os.path.join(dir_path, file)
|
|
108
|
+
cmd = ["/usr/bin/cp", "-arf", source, rootfs_path]
|
|
109
|
+
Helper.run(cmd)
|
|
110
|
+
shutil.rmtree(install_path, ignore_errors=True)
|