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
bmcgo/__init__.py
CHANGED
bmcgo/bmcgo.py
CHANGED
|
@@ -10,13 +10,19 @@
|
|
|
10
10
|
# MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
|
11
11
|
# See the Mulan PSL v2 for more details.
|
|
12
12
|
import sys
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
import shutil
|
|
14
|
+
import os
|
|
15
15
|
|
|
16
16
|
|
|
17
17
|
def run():
|
|
18
|
+
from bmcgo import misc
|
|
19
|
+
|
|
20
|
+
shutil.rmtree(misc.CACHE_DIR, ignore_errors=True)
|
|
21
|
+
os.makedirs(misc.CACHE_DIR)
|
|
22
|
+
from bmcgo.cli.cli import main
|
|
23
|
+
|
|
18
24
|
sys.exit(main(sys.argv[1:]))
|
|
19
25
|
|
|
20
26
|
|
|
21
|
-
if __name__ ==
|
|
27
|
+
if __name__ == "__main__":
|
|
22
28
|
run()
|
bmcgo/bmcgo_config.py
CHANGED
|
@@ -140,6 +140,7 @@ class BmcgoConfig(object):
|
|
|
140
140
|
|
|
141
141
|
def _bmcgo_config_init(self):
|
|
142
142
|
"""配置初始化"""
|
|
143
|
+
self.bingo_version_range = None
|
|
143
144
|
cwd = self.cwd
|
|
144
145
|
if os.path.isfile("frame.py"):
|
|
145
146
|
self.manifest = BmcgoManifest(os.path.realpath(os.path.join(cwd, "..")), None)
|
|
@@ -185,6 +186,9 @@ class BmcgoConfig(object):
|
|
|
185
186
|
self.component = BmcgoComp(folder, conf)
|
|
186
187
|
except (NoSectionError, NoOptionError):
|
|
187
188
|
log.debug("不是一个合法的组件仓,尝试查找mds/service.json")
|
|
189
|
+
|
|
190
|
+
#检查是否需要升级
|
|
191
|
+
self._bingo_version_check(conf)
|
|
188
192
|
|
|
189
193
|
self._bmcgo_signature_config_load(conf)
|
|
190
194
|
|
|
@@ -194,6 +198,18 @@ class BmcgoConfig(object):
|
|
|
194
198
|
return
|
|
195
199
|
|
|
196
200
|
cwd = os.path.dirname(cwd)
|
|
201
|
+
|
|
202
|
+
def _bingo_version_check(self, conf: configparser.ConfigParser):
|
|
203
|
+
try:
|
|
204
|
+
version_range = conf.get("bingo", "version")
|
|
205
|
+
except Exception as e:
|
|
206
|
+
version_range = ""
|
|
207
|
+
version_range_str = version_range.strip("[").rstrip("]")
|
|
208
|
+
import semver
|
|
209
|
+
if semver.satisfies(__version__, version_range_str):
|
|
210
|
+
return
|
|
211
|
+
else:
|
|
212
|
+
self.bingo_version_range = version_range_str.replace(" ", ",")
|
|
197
213
|
|
|
198
214
|
def _bmcgo_config_load(self):
|
|
199
215
|
"""读取配置"""
|
bmcgo/cli/cli.py
CHANGED
|
@@ -12,7 +12,6 @@
|
|
|
12
12
|
import argparse
|
|
13
13
|
import inspect
|
|
14
14
|
import os
|
|
15
|
-
import signal
|
|
16
15
|
import sys
|
|
17
16
|
import textwrap
|
|
18
17
|
import importlib
|
|
@@ -39,6 +38,8 @@ from bmcgo.frame import Frame
|
|
|
39
38
|
from bmcgo.bmcgo_config import BmcgoConfig
|
|
40
39
|
from bmcgo.utils.tools import Tools
|
|
41
40
|
from bmcgo.utils.config import Config
|
|
41
|
+
from ..error_analyzer.unified_error_analyzer import UnifiedErrorAnalyzer
|
|
42
|
+
|
|
42
43
|
|
|
43
44
|
cwd = os.getcwd()
|
|
44
45
|
tools = Tools()
|
|
@@ -265,6 +266,12 @@ class Command(object):
|
|
|
265
266
|
if command in ["-h", "--help"]:
|
|
266
267
|
self._show_help()
|
|
267
268
|
return 0
|
|
269
|
+
# 检查是否需要升级
|
|
270
|
+
if self.bconfig.bingo_version_range:
|
|
271
|
+
result_code = self.bingo_upgrade()
|
|
272
|
+
if result_code == 0:
|
|
273
|
+
log.info("自动升级完成,请重新运行命令")
|
|
274
|
+
return result_code
|
|
268
275
|
valid_command = self._find_real_command(command)
|
|
269
276
|
# 命令参数
|
|
270
277
|
command_args = args[0][1:]
|
|
@@ -315,7 +322,14 @@ class Command(object):
|
|
|
315
322
|
studio_version = self._bmc_studio_version()
|
|
316
323
|
if studio_version:
|
|
317
324
|
log.info("bmc-studio 版本为: %s", studio_version)
|
|
318
|
-
|
|
325
|
+
|
|
326
|
+
def bingo_upgrade(self):
|
|
327
|
+
version_range = self.bconfig.bingo_version_range.replace(",", " ")
|
|
328
|
+
log.info(f"检测到当前版本:{client_version}与约束版本{version_range}不匹配,将自动升级,完成后请重新运行")
|
|
329
|
+
from bmcgo.functional.upgrade import BmcgoCommand as upcommand
|
|
330
|
+
cmd = upcommand(self.bconfig, (["-v", f"bingo{self.bconfig.bingo_version_range}", "-f"]))
|
|
331
|
+
return cmd.run()
|
|
332
|
+
|
|
319
333
|
def conan_init(self):
|
|
320
334
|
if misc.conan_v2():
|
|
321
335
|
tools.run_command("conan profile detect --force")
|
|
@@ -374,12 +388,6 @@ class Command(object):
|
|
|
374
388
|
if not match:
|
|
375
389
|
continue
|
|
376
390
|
import semver
|
|
377
|
-
# 临时兼容性措施,强制使用conan1构建
|
|
378
|
-
# 背景:开源组件初期未获取平台conan2.0支持,只能构建出conan1的包,但为了上库conan2.0的构建脚本
|
|
379
|
-
# 需要提供一个标记用于临时指示强制使用conan1构建
|
|
380
|
-
# 待平台版本正式上线后,删除1.60.0判断
|
|
381
|
-
if semver.satisfies("1.60.0", match[1]):
|
|
382
|
-
break
|
|
383
391
|
if semver.satisfies("2.13.0", match[1]):
|
|
384
392
|
need_conan_v2 = True
|
|
385
393
|
break
|
|
@@ -457,14 +465,6 @@ class Command(object):
|
|
|
457
465
|
"""检查当前环境中正在使用的bmc studio版本,
|
|
458
466
|
优先通过pip获取,获取不到通过bmc_studio/mds/server获取
|
|
459
467
|
"""
|
|
460
|
-
package_info = tools.run_command('pip3 show hw_ibmc_bmc_studio', sudo=True,
|
|
461
|
-
command_echo=False, ignore_error=True, capture_output=True)
|
|
462
|
-
version = ""
|
|
463
|
-
if package_info:
|
|
464
|
-
version = package_info.stdout.replace("\n", " ")
|
|
465
|
-
match = re.match(r".*([0-9]+\.[0-9]+\.[0-9]+)", version)
|
|
466
|
-
if match:
|
|
467
|
-
return match.group(1)
|
|
468
468
|
studio_path = tools.get_studio_path()
|
|
469
469
|
bmc_studio_conf = os.path.join(f"{studio_path}/mds/service.json")
|
|
470
470
|
if not os.path.isfile(bmc_studio_conf):
|
|
@@ -480,9 +480,9 @@ class Command(object):
|
|
|
480
480
|
def _gen_command_group(self):
|
|
481
481
|
self._command_group = []
|
|
482
482
|
self._command_group.append((misc.GRP_INTE, self.inte_cmds))
|
|
483
|
-
self._command_group.append((misc.GRP_COMP, self.comp_cmds))
|
|
484
|
-
self._command_group.append((misc.GRP_CONAN_IDX, self.conan_idx_cmds))
|
|
485
483
|
self._command_group.append((misc.GRP_IBMC_SDK, self.ibmc_sdk_cmds))
|
|
484
|
+
self._command_group.append((misc.GRP_CONAN_IDX, self.conan_idx_cmds))
|
|
485
|
+
self._command_group.append((misc.GRP_COMP, self.comp_cmds))
|
|
486
486
|
self._command_group.append((misc.GRP_MISC, self.misc_cmds))
|
|
487
487
|
self._command_group.append((misc.GRP_STUDIO, self.studio_cmds))
|
|
488
488
|
return self._command_group
|
|
@@ -640,6 +640,12 @@ class Command(object):
|
|
|
640
640
|
return False, None
|
|
641
641
|
|
|
642
642
|
|
|
643
|
+
class ExtraCases:
|
|
644
|
+
def __init__(self, cases_file, cases_name):
|
|
645
|
+
self.cases_file = cases_file
|
|
646
|
+
self.cases_name = cases_name
|
|
647
|
+
|
|
648
|
+
|
|
643
649
|
def prepare_conan():
|
|
644
650
|
if misc.conan_v2():
|
|
645
651
|
return
|
|
@@ -666,13 +672,11 @@ def prepare_conan():
|
|
|
666
672
|
file_handler.write(yaml.safe_dump(config_data, indent=2, sort_keys=False))
|
|
667
673
|
|
|
668
674
|
|
|
669
|
-
def run(args, command: Command = None):
|
|
675
|
+
def run(args, command: Command = None, extra_cases: ExtraCases = None):
|
|
670
676
|
"""
|
|
671
677
|
main entry point of the bmcgo application, using a Command to
|
|
672
678
|
parse parameters
|
|
673
679
|
"""
|
|
674
|
-
os.makedirs(misc.CACHE_DIR, exist_ok=True)
|
|
675
|
-
|
|
676
680
|
try:
|
|
677
681
|
tools.run_command("whoami", show_log=True)
|
|
678
682
|
prepare_conan()
|
|
@@ -688,8 +692,55 @@ def run(args, command: Command = None):
|
|
|
688
692
|
msg = str(exc)
|
|
689
693
|
log.error(msg)
|
|
690
694
|
error = -1
|
|
695
|
+
|
|
696
|
+
if error == -1:
|
|
697
|
+
error_analyzer(extra_cases)
|
|
698
|
+
|
|
691
699
|
return error
|
|
692
700
|
|
|
693
701
|
|
|
702
|
+
def error_analyzer(extra_cases: ExtraCases):
|
|
703
|
+
base_cases_file = os.path.join(os.path.dirname(__file__), "..", "error_cases", "cases.yml")
|
|
704
|
+
base_cases = merge_local_remote_cases(base_cases_file, "bingo_cases")
|
|
705
|
+
if extra_cases:
|
|
706
|
+
extra_cases = merge_local_remote_cases(extra_cases.cases_file, extra_cases.cases_name)
|
|
707
|
+
base_cases.extend(extra_cases)
|
|
708
|
+
# 使用统一错误分析器
|
|
709
|
+
analyzer = UnifiedErrorAnalyzer(base_cases)
|
|
710
|
+
# 定义要分析的日志源(支持多种格式)
|
|
711
|
+
log_sources = [
|
|
712
|
+
misc.CACHE_DIR, # 整个文件夹
|
|
713
|
+
os.path.join(cwd, "temp", "log"), # 整个文件夹
|
|
714
|
+
]
|
|
715
|
+
# 分析日志文件和命令失败信息
|
|
716
|
+
analyzer.analyze_errors(
|
|
717
|
+
log_sources=log_sources
|
|
718
|
+
)
|
|
719
|
+
|
|
720
|
+
|
|
721
|
+
def merge_local_remote_cases(local_case_file, remote_case_name):
|
|
722
|
+
with open(local_case_file, "r") as local_case:
|
|
723
|
+
local_case_data = yaml.safe_load(local_case)
|
|
724
|
+
local_version = local_case_data.get("version")
|
|
725
|
+
local_cases = local_case_data.get("cases")
|
|
726
|
+
cases = local_cases
|
|
727
|
+
cmd = f"conan install --requires='{remote_case_name}/[>=1.0.0]@openubmc/stable' -u \
|
|
728
|
+
--deployer-folder=temp -of temp -d direct_deploy"
|
|
729
|
+
_ = tools.run_command(cmd, ignore_error=True)
|
|
730
|
+
remote_case_file = os.path.join(cwd, "temp", "direct_deploy", remote_case_name, "case.yml")
|
|
731
|
+
if os.path.exists(remote_case_file):
|
|
732
|
+
with open(remote_case_file, "r") as remote_case:
|
|
733
|
+
remote_case_data = yaml.safe_load(remote_case)
|
|
734
|
+
remote_version = remote_case_data.get("version")
|
|
735
|
+
remote_cases = remote_case_data.get("cases")
|
|
736
|
+
from packaging import version
|
|
737
|
+
remote_v = version.parse(remote_version)
|
|
738
|
+
local_v = version.parse(local_version)
|
|
739
|
+
if remote_v > local_v:
|
|
740
|
+
for k, v in remote_cases.items():
|
|
741
|
+
cases[k] = v
|
|
742
|
+
return list(cases.values())
|
|
743
|
+
|
|
744
|
+
|
|
694
745
|
def main(args):
|
|
695
746
|
return run(args)
|
bmcgo/codegen/__init__.py
CHANGED
bmcgo/codegen/lua/codegen.py
CHANGED
|
@@ -134,7 +134,7 @@ class CodeGen(object):
|
|
|
134
134
|
package = self.get_mdb_interface_package()
|
|
135
135
|
cmd = ["conan", "install", f"--requires={package}", f"-of={temp_dir}", "--build=missing", "-d", "direct_deploy",
|
|
136
136
|
f"--deployer-folder={temp_dir}"]
|
|
137
|
-
cmd += ["-pr=profile.dt.ini"]
|
|
137
|
+
cmd += ["-pr=profile.dt.ini", "-pr:b=profile.dt.ini"]
|
|
138
138
|
if self.remote:
|
|
139
139
|
cmd += ["-r", self.remote]
|
|
140
140
|
subprocess.call(cmd)
|
|
@@ -153,7 +153,7 @@ class CodeGen(object):
|
|
|
153
153
|
|
|
154
154
|
cmd = ["conan", "install", f"--requires={package}", f"-of={temp_dir}", "--build=missing", "-d", "direct_deploy",
|
|
155
155
|
"--update", f"--deployer-folder={temp_dir}"]
|
|
156
|
-
cmd += ["-pr=profile.dt.ini"]
|
|
156
|
+
cmd += ["-pr=profile.dt.ini", "-pr:b=profile.dt.ini"]
|
|
157
157
|
if self.remote:
|
|
158
158
|
cmd += ["-r", self.remote]
|
|
159
159
|
|
|
@@ -33,6 +33,7 @@ class IntfPool:
|
|
|
33
33
|
self.add_from_service(os.path.join(root, file))
|
|
34
34
|
if file == "model.json":
|
|
35
35
|
self.add_from_model(os.path.join(root, file))
|
|
36
|
+
self.pool["Properties"].add("bmc.kepler.Object.Properties")
|
|
36
37
|
|
|
37
38
|
if project_name == 'hwproxy':
|
|
38
39
|
for root, _, files in os.walk(os.path.join(mdb_path, "intf/mdb/bmc/dev")):
|
|
@@ -18,6 +18,7 @@ class Options:
|
|
|
18
18
|
self.source_file_path: str = options.source_file_path
|
|
19
19
|
self.template_name: str = options.template_name
|
|
20
20
|
self.output_file_path: str = options.output_file_path
|
|
21
|
+
self.ignore_empty_input: bool = options.ignore_empty_input
|
|
21
22
|
self.enable_auto_merge: bool = options.enable_auto_merge
|
|
22
23
|
self.project_name = options.project_name
|
|
23
24
|
self.version = options.version
|
|
@@ -380,7 +380,7 @@ def rectify_local_db(historical_local_db_file, out_dict):
|
|
|
380
380
|
table_info["properties"] = new_props
|
|
381
381
|
|
|
382
382
|
|
|
383
|
-
def save_json_file(is_local, load_dict, historical_local_db_file, of_name, disable_gen
|
|
383
|
+
def save_json_file(is_local, load_dict, historical_local_db_file, of_name, disable_gen):
|
|
384
384
|
package = of_name.split("/")[-2]
|
|
385
385
|
extra_imports = set()
|
|
386
386
|
datas = make_datas(load_dict, package, extra_imports, is_local)
|
|
@@ -420,8 +420,9 @@ def generate(if_name, historical_local_db_file, of_name):
|
|
|
420
420
|
load_dict = json.load(load_f)
|
|
421
421
|
load_f.close()
|
|
422
422
|
disable_mem_db_gen = Utils.get_lua_codegen_version() >= 7 and not Utils.check_model_need_mem_db(load_dict)
|
|
423
|
-
save_json_file(False, load_dict, historical_local_db_file, of_name,
|
|
424
|
-
|
|
423
|
+
save_json_file(False, load_dict, historical_local_db_file, of_name, disable_mem_db_gen) # 保存普通持久化的表
|
|
424
|
+
disable_local_db_gen = Utils.get_lua_codegen_version() >= 19 and not Utils.check_model_need_local_db(load_dict)
|
|
425
|
+
save_json_file(True, load_dict, historical_local_db_file, of_name, disable_local_db_gen) # 保存本地持久化的表
|
|
425
426
|
|
|
426
427
|
|
|
427
428
|
def usage():
|
|
@@ -16,6 +16,7 @@ import getopt
|
|
|
16
16
|
import sys
|
|
17
17
|
import os
|
|
18
18
|
import stat
|
|
19
|
+
from collections import defaultdict
|
|
19
20
|
import mds_util as utils
|
|
20
21
|
from utils import Utils
|
|
21
22
|
|
|
@@ -43,6 +44,15 @@ PROPERTY_FLAGS = {
|
|
|
43
44
|
OPTIONS = 'options'
|
|
44
45
|
|
|
45
46
|
|
|
47
|
+
def modify_common_interface_messages(messages):
|
|
48
|
+
intf_map = Utils.get_unique_intf_map()
|
|
49
|
+
for intf_name, require_path in Utils.get_common_interface_require_paths().items():
|
|
50
|
+
unique_intf_name = intf_map.get(intf_name)
|
|
51
|
+
if unique_intf_name and unique_intf_name in messages:
|
|
52
|
+
messages[unique_intf_name]['require_path'] = require_path
|
|
53
|
+
messages[unique_intf_name]['disable_gen'] = True
|
|
54
|
+
|
|
55
|
+
|
|
46
56
|
def is_struct(prop_data):
|
|
47
57
|
if 'baseType' not in prop_data:
|
|
48
58
|
return True
|
|
@@ -166,8 +176,9 @@ def save_msg(intfs, out_dir, project_name):
|
|
|
166
176
|
"package": pkg_name,
|
|
167
177
|
"options": {},
|
|
168
178
|
"filename": file_name,
|
|
169
|
-
"require_path": f"{project_name}.{require_dir}.{pkg_name}",
|
|
179
|
+
"require_path": pkg_data.get("require_path", f"{project_name}.{require_dir}.{pkg_name}"),
|
|
170
180
|
"intf": pkg_data["data"] if "data" in pkg_data else {},
|
|
181
|
+
"disable_gen": pkg_data.get("disable_gen", False)
|
|
171
182
|
}
|
|
172
183
|
utils.save_proto_json(f"{new_out_dir}/{file_name}.json", datas)
|
|
173
184
|
|
|
@@ -219,7 +230,7 @@ def update_package(package, msg_name, struct_data, msg_package, imports):
|
|
|
219
230
|
|
|
220
231
|
|
|
221
232
|
# 为结构体生成message
|
|
222
|
-
def gen_defs(defs, msg_package, packages, imports=None):
|
|
233
|
+
def gen_defs(defs, msg_package, packages, imports=None, package_filter=None):
|
|
223
234
|
if imports is None:
|
|
224
235
|
imports = {}
|
|
225
236
|
|
|
@@ -228,6 +239,8 @@ def gen_defs(defs, msg_package, packages, imports=None):
|
|
|
228
239
|
|
|
229
240
|
package = packages[msg_package]
|
|
230
241
|
for struct_name, struct_data in defs.items():
|
|
242
|
+
if package_filter and not package_filter.get("defs", {}).get(struct_name, True):
|
|
243
|
+
continue
|
|
231
244
|
msg_name = struct_name
|
|
232
245
|
if not check_duplicate_msg(package["messages"], msg_name):
|
|
233
246
|
update_package(package, msg_name, struct_data, msg_package, imports)
|
|
@@ -265,7 +278,7 @@ def convert_property_options(intf, property_name: str, options_data: dict):
|
|
|
265
278
|
return flags
|
|
266
279
|
|
|
267
280
|
|
|
268
|
-
def generate_message(intf_data, intf, packages, imports):
|
|
281
|
+
def generate_message(intf_data, intf, packages, imports, package_filter=None):
|
|
269
282
|
msg_package = Utils.get_unique_intf_name(intf)
|
|
270
283
|
|
|
271
284
|
if msg_package not in packages:
|
|
@@ -273,7 +286,7 @@ def generate_message(intf_data, intf, packages, imports):
|
|
|
273
286
|
package = packages[msg_package]
|
|
274
287
|
package["data"] = {"name": intf, "data": intf_data}
|
|
275
288
|
|
|
276
|
-
if "methods" in intf_data:
|
|
289
|
+
if "methods" in intf_data and (not package_filter or package_filter.get("methods")):
|
|
277
290
|
for method_name, method_data in intf_data["methods"].items():
|
|
278
291
|
req_name = method_name + "Req"
|
|
279
292
|
rsp_name = method_name + "Rsp"
|
|
@@ -285,14 +298,14 @@ def generate_message(intf_data, intf, packages, imports):
|
|
|
285
298
|
update_package(package, rsp_name, get_rsp(
|
|
286
299
|
method_data), msg_package, imports)
|
|
287
300
|
|
|
288
|
-
if "signals" in intf_data:
|
|
301
|
+
if "signals" in intf_data and (not package_filter or package_filter.get("signals")):
|
|
289
302
|
for signal_name, signal_data in intf_data["signals"].items():
|
|
290
303
|
signature_name = signal_name + "Signature"
|
|
291
304
|
if not check_duplicate_msg(package["messages"], signature_name):
|
|
292
305
|
update_package(package, signature_name,
|
|
293
306
|
signal_data, msg_package, imports)
|
|
294
307
|
|
|
295
|
-
if "properties" in intf_data:
|
|
308
|
+
if "properties" in intf_data and (not package_filter or package_filter.get("properties")):
|
|
296
309
|
for property_name, property_data in intf_data["properties"].items():
|
|
297
310
|
if not check_duplicate_msg(package["messages"], property_name):
|
|
298
311
|
update_package(package, property_name,
|
|
@@ -365,6 +378,7 @@ def gen_service_msg(model_merged_file, of_name, mdb_path, project_name):
|
|
|
365
378
|
messages = {}
|
|
366
379
|
imports = {}
|
|
367
380
|
get_service_messages(mdb_path, load_dict, messages, imports)
|
|
381
|
+
modify_common_interface_messages(messages)
|
|
368
382
|
save_msg(messages, of_name, project_name)
|
|
369
383
|
load_f.close()
|
|
370
384
|
|
|
@@ -387,15 +401,57 @@ def gen_model_msg(model_merged_file, of_name):
|
|
|
387
401
|
load_f.close()
|
|
388
402
|
|
|
389
403
|
|
|
390
|
-
def gen_client_msg_intf(intf_json, intf, messages):
|
|
404
|
+
def gen_client_msg_intf(intf_json, intf, messages, package_filter=None):
|
|
391
405
|
imports = {}
|
|
392
406
|
for intf_name, intf_data in intf_json.items():
|
|
393
407
|
if intf_name == "defs":
|
|
394
|
-
gen_defs(intf_data, Utils.get_unique_intf_name(intf), messages)
|
|
408
|
+
gen_defs(intf_data, Utils.get_unique_intf_name(intf), messages, None, package_filter)
|
|
395
409
|
else:
|
|
396
410
|
prepare_intf_data(intf_json, intf_name)
|
|
397
411
|
prepare_virutal(intf_data)
|
|
398
|
-
generate_message(intf_data, intf_name, messages, imports)
|
|
412
|
+
generate_message(intf_data, intf_name, messages, imports, package_filter)
|
|
413
|
+
|
|
414
|
+
|
|
415
|
+
def parse_ref_items(input_data, refs):
|
|
416
|
+
for key, value in input_data.items():
|
|
417
|
+
if key != "$ref":
|
|
418
|
+
if isinstance(value, dict):
|
|
419
|
+
parse_ref_items(value, refs)
|
|
420
|
+
continue
|
|
421
|
+
if isinstance(value, str) and value.startswith("#/defs/"):
|
|
422
|
+
refs[value.replace("#/defs/", "")] = input_data.get("baseType") == "Enum"
|
|
423
|
+
|
|
424
|
+
|
|
425
|
+
def set_def_enbale_gen(input_data, defs_enable_gen, enabled):
|
|
426
|
+
refs = dict()
|
|
427
|
+
parse_ref_items(input_data, refs)
|
|
428
|
+
for ref, is_enum in refs.items():
|
|
429
|
+
if ref in defs_enable_gen:
|
|
430
|
+
defs_enable_gen[ref] = enabled or is_enum
|
|
431
|
+
|
|
432
|
+
|
|
433
|
+
def parse_interface_defs(intf_json, package_filter):
|
|
434
|
+
defs_data = intf_json.get("defs", {})
|
|
435
|
+
if not defs_data:
|
|
436
|
+
return {}
|
|
437
|
+
defs_enable_gen = {def_name: False for def_name in defs_data.keys()}
|
|
438
|
+
for intf_name, intf_data in intf_json.items():
|
|
439
|
+
if intf_name == "defs":
|
|
440
|
+
continue
|
|
441
|
+
for category, enable_gen in package_filter.items():
|
|
442
|
+
for item_data in intf_data.get(category, {}).values():
|
|
443
|
+
# 属性、方法、信号如果需要生成校验器,它们引用的自定义类型也需要生成校验器
|
|
444
|
+
# 枚举类型可能被用于属性默认值,也需要生成
|
|
445
|
+
set_def_enbale_gen(item_data, defs_enable_gen, enable_gen)
|
|
446
|
+
|
|
447
|
+
for def_name, def_data in defs_data.items():
|
|
448
|
+
if defs_enable_gen.get(def_name):
|
|
449
|
+
# 自定义类型如果需要生成校验器,它们引用的其它自定义类型也需要生成校验器
|
|
450
|
+
set_def_enbale_gen(def_data, defs_enable_gen, True)
|
|
451
|
+
# 没有被资源协作接口引用的枚举类型,不应该生成代码。但部分组件存在使用json_types文件的枚举定义,这里先做兼容处理
|
|
452
|
+
if utils.get_message_type(def_data) == 'enum':
|
|
453
|
+
defs_enable_gen[def_name] = True
|
|
454
|
+
return defs_enable_gen
|
|
399
455
|
|
|
400
456
|
|
|
401
457
|
def gen_client_msg(service_file, output, mdb_path, project_name):
|
|
@@ -412,8 +468,19 @@ def gen_client_msg(service_file, output, mdb_path, project_name):
|
|
|
412
468
|
intf_json = utils.get_intf(intf, mdb_path)
|
|
413
469
|
if "implement" in intf_json[intf]:
|
|
414
470
|
intf_json = utils.generate_default(intf_json, mdb_path)
|
|
415
|
-
|
|
416
|
-
|
|
471
|
+
package_filter = None
|
|
472
|
+
if Utils.get_lua_codegen_version() >= 19:
|
|
473
|
+
# 客户端用到的接口,不需要生成属性校验器、信号参数校验器,只需要生成方法参数校验器
|
|
474
|
+
# package_filter里面True表示需要生成,False表示不需要生成
|
|
475
|
+
package_filter = {
|
|
476
|
+
"properties": False,
|
|
477
|
+
"methods": True,
|
|
478
|
+
"signals": False
|
|
479
|
+
}
|
|
480
|
+
package_filter["defs"] = parse_interface_defs(intf_json, package_filter)
|
|
481
|
+
gen_client_msg_intf(intf_json, intf, messages, package_filter)
|
|
482
|
+
|
|
483
|
+
modify_common_interface_messages(messages)
|
|
417
484
|
save_msg(messages, output, project_name)
|
|
418
485
|
load_f.close()
|
|
419
486
|
|
|
@@ -154,10 +154,10 @@ def check_intf_consistency(mdb_intf, complete_intf, class_name, intf_name):
|
|
|
154
154
|
|
|
155
155
|
def check_model_consistency(class_name, complete_model, mdb_obj, mdb_path):
|
|
156
156
|
intf_complete = set(complete_model["interfaces"].keys())
|
|
157
|
+
intf_complete.discard(OBJECT_PROPERTIES_INTERFACE)
|
|
157
158
|
intf_mdb = set(mdb_obj[class_name]["interfaces"])
|
|
158
159
|
if intf_complete != intf_mdb:
|
|
159
160
|
intf_only_in_mds = intf_complete - intf_mdb
|
|
160
|
-
intf_only_in_mds.discard(OBJECT_PROPERTIES_INTERFACE)
|
|
161
161
|
if intf_only_in_mds:
|
|
162
162
|
raise RuntimeError(f"组件模型中类{class_name}的接口{intf_only_in_mds}未在mdb_interface中定义"
|
|
163
163
|
f",请检查model.json与mdb_interface定义"
|
|
@@ -206,12 +206,11 @@ class DbLuaUtils(Base, Utils):
|
|
|
206
206
|
return result + "}"
|
|
207
207
|
value_name = Utils(self.data, self.options).enum_value_name(types["name"], d_val)
|
|
208
208
|
return f'{types["package"]}.{types["name"]}.{value_name}'
|
|
209
|
-
if
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
return f"[['{json_str}']]"
|
|
209
|
+
if prop.get('repeated') and not isinstance(d_val, list):
|
|
210
|
+
raise RuntimeError(f"model.json中类{class_name}的属性{prop['name']}默认值{d_val}类型与属性类型不一致")
|
|
211
|
+
if isinstance(d_val, list) or isinstance(d_val, dict):
|
|
212
|
+
json_str = json.dumps(d_val).replace("'", "''")
|
|
213
|
+
return f"[['{json_str}']]"
|
|
215
214
|
if type_name == "string" or type_name == 'bytes':
|
|
216
215
|
return f'"\'{d_val}\'"'
|
|
217
216
|
if type_name == "bool":
|
|
@@ -215,6 +215,9 @@ class ModelLuaUtils(Base, Utils):
|
|
|
215
215
|
def get_mdb_prop_configs(self, msg):
|
|
216
216
|
string = '{'
|
|
217
217
|
for (interface, intf_msg) in msg['interfaces'].items():
|
|
218
|
+
if Utils.get_lua_codegen_version() == 19 and interface == 'bmc.kepler.Object.Properties':
|
|
219
|
+
string += f"['{interface}'] = mdb.OBJECT_PROPERTIES_INTERFACE_PROP_CONFIGS,"
|
|
220
|
+
continue
|
|
218
221
|
if not self.has_properties(intf_msg):
|
|
219
222
|
continue
|
|
220
223
|
intf_name = self.get_intf_name(interface, intf_msg)
|
|
@@ -455,7 +458,8 @@ class ModelLuaUtils(Base, Utils):
|
|
|
455
458
|
for (interface, intf_msg) in msg.get('interfaces', {}).items():
|
|
456
459
|
intf_name = self.get_intf_name(interface, intf_msg)
|
|
457
460
|
intf_type = self.get_intf_type(intf_name)
|
|
458
|
-
|
|
461
|
+
path = Utils.get_interface_require_path(interface, project_name, intf_name)
|
|
462
|
+
types[intf_type] = f"local {intf_type} = require '{path}'\n"
|
|
459
463
|
return types
|
|
460
464
|
|
|
461
465
|
def render_types(self, project_name, root):
|
|
@@ -52,6 +52,9 @@ def parse_input_args() -> Options:
|
|
|
52
52
|
parser.add_argument("-v", "--version", dest="version",
|
|
53
53
|
help="version",
|
|
54
54
|
default=-1)
|
|
55
|
+
parser.add_argument("--ignore_empty_input", dest="ignore_empty_input",
|
|
56
|
+
help="Whether to stop generating result file when input is empty",
|
|
57
|
+
action=misc.STORE_TRUE, default=False)
|
|
55
58
|
parser.add_argument("--enable_auto_merge", dest="enable_auto_merge",
|
|
56
59
|
help="Whether result files are automatically combined when customized.",
|
|
57
60
|
action=misc.STORE_TRUE, default=False)
|
|
@@ -130,6 +133,8 @@ def generate(options: Options):
|
|
|
130
133
|
if os.path.exists(options.output_file_path):
|
|
131
134
|
os.remove(options.output_file_path)
|
|
132
135
|
load_imports(data, options)
|
|
136
|
+
if not data and options.ignore_empty_input and utils.Utils.get_lua_codegen_version() >= 19:
|
|
137
|
+
return
|
|
133
138
|
os.makedirs(os.path.dirname(options.output_file_path), exist_ok=True)
|
|
134
139
|
output_file = os.fdopen(os.open(options.output_file_path,
|
|
135
140
|
os.O_WRONLY | os.O_CREAT | os.O_TRUNC, stat.S_IWUSR | stat.S_IRUSR), 'w')
|
|
@@ -86,7 +86,26 @@ class Utils:
|
|
|
86
86
|
'general_hardware',
|
|
87
87
|
'lsw',
|
|
88
88
|
'manufacture',
|
|
89
|
-
'account'
|
|
89
|
+
'account',
|
|
90
|
+
'spdm'
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
COMMON_INTERFACE_REQUIRE_PATHS = {
|
|
94
|
+
'bmc.kepler.MicroComponent': 'mdb.bmc.kepler.MicroComponentInterface',
|
|
95
|
+
'bmc.kepler.MicroComponent.ConfigManage': 'mdb.bmc.kepler.MicroComponent.ConfigManageInterface',
|
|
96
|
+
'bmc.kepler.MicroComponent.Debug': 'mdb.bmc.kepler.MicroComponent.DebugInterface',
|
|
97
|
+
'bmc.kepler.MicroComponent.Performance': 'mdb.bmc.kepler.MicroComponent.PerformanceInterface',
|
|
98
|
+
'bmc.kepler.MicroComponent.Reboot': 'mdb.bmc.kepler.MicroComponent.RebootInterface',
|
|
99
|
+
'bmc.kepler.MicroComponent.Reset': 'mdb.bmc.kepler.MicroComponent.ResetInterface',
|
|
100
|
+
'bmc.kepler.Object.Properties': 'mdb.bmc.kepler.Object.PropertiesInterface',
|
|
101
|
+
'bmc.kepler.Release.Maintenance': 'mdb.bmc.kepler.Release.MaintenanceInterface',
|
|
102
|
+
'bmc.kepler.TaskService.Task': 'mdb.bmc.kepler.TaskService.TaskInterface'
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
# 不依赖新版本lua框架的公共接口
|
|
106
|
+
COMMON_INTERFACE_REQUIRE_PATHS_LIMITED = {
|
|
107
|
+
'bmc.kepler.Object.Properties': 'mdb.bmc.kepler.Object.PropertiesInterface',
|
|
108
|
+
'bmc.kepler.TaskService.Task': 'mdb.bmc.kepler.TaskService.TaskInterface'
|
|
90
109
|
}
|
|
91
110
|
|
|
92
111
|
def __init__(self, data: dict, options: Options):
|
|
@@ -253,7 +272,7 @@ class Utils:
|
|
|
253
272
|
{6}'''
|
|
254
273
|
project_name = os.getenv('PROJECT_NAME')
|
|
255
274
|
if Utils.get_lua_codegen_version() >= 8 and project_name in Utils.OPEN_PROJECTS:
|
|
256
|
-
header = '''{5}Copyright (c)
|
|
275
|
+
header = '''{5}Copyright (c) {0} Huawei Technologies Co., Ltd.
|
|
257
276
|
{4}openUBMC is licensed under Mulan PSL v2.
|
|
258
277
|
{4}You can use this software according to the terms and conditions of the Mulan PSL v2.
|
|
259
278
|
{4}You may obtain a copy of Mulan PSL v2 at:
|
|
@@ -281,7 +300,14 @@ class Utils:
|
|
|
281
300
|
if "tableName" in class_data and class_data.get("tableLocation") != "Local":
|
|
282
301
|
return True
|
|
283
302
|
return False
|
|
284
|
-
|
|
303
|
+
|
|
304
|
+
@staticmethod
|
|
305
|
+
def check_model_need_local_db(model_json: dict):
|
|
306
|
+
for class_data in model_json.values():
|
|
307
|
+
if "tableName" in class_data and class_data.get("tableLocation") == "Local":
|
|
308
|
+
return True
|
|
309
|
+
return False
|
|
310
|
+
|
|
285
311
|
@staticmethod
|
|
286
312
|
def has_db(root: dict):
|
|
287
313
|
return Utils.check_need_mem_db(root) or Utils.check_local_poweroff_db(root) or \
|
|
@@ -348,15 +374,31 @@ class Utils:
|
|
|
348
374
|
return Utils.get_unique_intf_name(full_intf_name) + "." + slices[-1]
|
|
349
375
|
|
|
350
376
|
@staticmethod
|
|
351
|
-
def
|
|
352
|
-
check_intfs = Path(__file__).parent.parent.joinpath(
|
|
377
|
+
def get_unique_intf_map():
|
|
378
|
+
check_intfs = Path(__file__).parent.parent.joinpath('temp').joinpath('check_intfs.json')
|
|
353
379
|
with open(check_intfs, 'r') as check_intfs_fp:
|
|
354
|
-
|
|
380
|
+
return json.load(check_intfs_fp)
|
|
355
381
|
|
|
382
|
+
@staticmethod
|
|
383
|
+
def get_unique_intf_name(intf):
|
|
356
384
|
slices = intf.split('.')
|
|
357
|
-
if slices[-1] ==
|
|
385
|
+
if slices[-1] == 'Default':
|
|
358
386
|
return slices[-2] + slices[-1]
|
|
359
|
-
return
|
|
387
|
+
return Utils.get_unique_intf_map().get(intf, slices[-1])
|
|
388
|
+
|
|
389
|
+
@staticmethod
|
|
390
|
+
def get_common_interface_require_paths():
|
|
391
|
+
gen_version = Utils.get_lua_codegen_version()
|
|
392
|
+
if gen_version < 19:
|
|
393
|
+
return {}
|
|
394
|
+
if gen_version == 19:
|
|
395
|
+
return Utils.COMMON_INTERFACE_REQUIRE_PATHS
|
|
396
|
+
return Utils.COMMON_INTERFACE_REQUIRE_PATHS_LIMITED
|
|
397
|
+
|
|
398
|
+
@staticmethod
|
|
399
|
+
def get_interface_require_path(intf_name, project_name, unique_intf_name):
|
|
400
|
+
fallback = f'{project_name}.json_types.{unique_intf_name}'
|
|
401
|
+
return Utils.get_common_interface_require_paths().get(intf_name, fallback)
|
|
360
402
|
|
|
361
403
|
@staticmethod
|
|
362
404
|
def get_files(path):
|
|
@@ -80,7 +80,7 @@ message: $(foreach v, $(MESSAGE_FILES), $(GEN_OUT_DIR)/$(v).lua)
|
|
|
80
80
|
define MAKE_DATAS
|
|
81
81
|
$$(GEN_OUT_DIR)/$(1).lua: ${PROTO_OUT_DIR}/$(1).json $${TEMPLATE_BIN} datas.lua.mako
|
|
82
82
|
@mkdir -p $$(dir $$@)
|
|
83
|
-
python3 $${TEMPLATE_BIN} -d ${PROTO_DIR} -j ${PROTO_OUT_DIR} -n ${PROJECT_NAME} -i ${PROTO_OUT_DIR}/$(1).json -f ${LUA_FORMATER} -t datas.lua.mako -o $$@
|
|
83
|
+
python3 $${TEMPLATE_BIN} -d ${PROTO_DIR} -j ${PROTO_OUT_DIR} -n ${PROJECT_NAME} -i ${PROTO_OUT_DIR}/$(1).json -f ${LUA_FORMATER} -t datas.lua.mako --ignore_empty_input -o $$@
|
|
84
84
|
endef
|
|
85
85
|
$(foreach v, $(YAML_FILES), $(eval $(call MAKE_DATAS,$(v))))
|
|
86
86
|
datas: $(foreach v, $(YAML_FILES), $(GEN_OUT_DIR)/$(v).lua)
|
|
@@ -89,7 +89,7 @@ define MAKE_CONF_DATAS
|
|
|
89
89
|
$$(GEN_OUT_DIR)/$(1).lua: ${CONF_DIR}/$(1).yaml $${TEMPLATE_BIN} datas.lua.mako
|
|
90
90
|
@mkdir -p $$(dir $$@)
|
|
91
91
|
python3 ${YAML_TO_JSON_BIN} -i ${CONF_DIR}/$(1).yaml -b ${CONF_DIR} -o ${PROTO_OUT_DIR}/$(1).json
|
|
92
|
-
python3 $${TEMPLATE_BIN} -d ${CONF_DIR} -j ${PROTO_OUT_DIR} -n ${PROJECT_NAME} -i ${PROTO_OUT_DIR}/$(1).json -f ${LUA_FORMATER} -t datas.lua.mako -o $$@
|
|
92
|
+
python3 $${TEMPLATE_BIN} -d ${CONF_DIR} -j ${PROTO_OUT_DIR} -n ${PROJECT_NAME} -i ${PROTO_OUT_DIR}/$(1).json -f ${LUA_FORMATER} -t datas.lua.mako --ignore_empty_input -o $$@
|
|
93
93
|
endef
|
|
94
94
|
$(foreach v, $(YAML_FILES_CONF), $(eval $(call MAKE_CONF_DATAS,$(v))))
|
|
95
95
|
datas_conf: $(foreach v, $(YAML_FILES_CONF), $(GEN_OUT_DIR)/$(v).lua)
|