openubmc-bingo 0.5.277__py3-none-any.whl → 0.6.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of openubmc-bingo might be problematic. Click here for more details.
- bmcgo/__init__.py +1 -1
- bmcgo/bmcgo_config.py +22 -10
- bmcgo/cli/cli.py +86 -39
- bmcgo/cli/config.conan2.yaml +9 -0
- bmcgo/codegen/lua/codegen.py +1 -1
- bmcgo/codegen/lua/script/gen_intf_rpc_json.py +15 -14
- bmcgo/component/analysis/analysis.py +8 -8
- bmcgo/component/analysis/intf_validation.py +23 -12
- bmcgo/component/build.py +76 -14
- bmcgo/component/component_dt_version_parse.py +3 -2
- bmcgo/component/component_helper.py +43 -15
- bmcgo/component/coverage/incremental_cov.py +2 -2
- bmcgo/component/deploy.py +68 -14
- bmcgo/component/gen.py +1 -1
- bmcgo/component/package_info.py +128 -38
- bmcgo/component/template_v2/conanbase.py.mako +352 -0
- bmcgo/component/template_v2/conanfile.deploy.py.mako +26 -0
- bmcgo/component/test.py +53 -20
- bmcgo/frame.py +7 -3
- bmcgo/functional/analysis.py +3 -2
- bmcgo/functional/check.py +10 -6
- bmcgo/functional/conan_index_build.py +79 -20
- bmcgo/functional/csr_build.py +1 -1
- bmcgo/functional/diff.py +1 -1
- bmcgo/functional/fetch.py +1 -1
- bmcgo/functional/full_component.py +32 -24
- bmcgo/functional/git_history.py +220 -0
- bmcgo/functional/maintain.py +55 -12
- bmcgo/functional/new.py +1 -1
- bmcgo/functional/schema_valid.py +2 -2
- bmcgo/logger.py +2 -3
- bmcgo/misc.py +130 -9
- bmcgo/tasks/conan/__init__.py +10 -0
- bmcgo/tasks/conan/conanfile.py +45 -0
- bmcgo/tasks/task.py +27 -4
- bmcgo/tasks/task_build_conan.py +399 -52
- bmcgo/tasks/task_buildgppbin.py +8 -2
- bmcgo/tasks/task_download_buildtools.py +76 -0
- bmcgo/tasks/task_download_dependency.py +1 -0
- bmcgo/tasks/task_hpm_envir_prepare.py +1 -1
- bmcgo/utils/build_conans.py +231 -0
- bmcgo/utils/component_post.py +6 -4
- bmcgo/utils/component_version_check.py +10 -5
- bmcgo/utils/config.py +76 -40
- bmcgo/utils/fetch_component_code.py +44 -25
- bmcgo/utils/tools.py +239 -117
- bmcgo/worker.py +2 -2
- {openubmc_bingo-0.5.277.dist-info → openubmc_bingo-0.6.0.dist-info}/METADATA +4 -2
- {openubmc_bingo-0.5.277.dist-info → openubmc_bingo-0.6.0.dist-info}/RECORD +52 -45
- {openubmc_bingo-0.5.277.dist-info → openubmc_bingo-0.6.0.dist-info}/WHEEL +0 -0
- {openubmc_bingo-0.5.277.dist-info → openubmc_bingo-0.6.0.dist-info}/entry_points.txt +0 -0
- {openubmc_bingo-0.5.277.dist-info → openubmc_bingo-0.6.0.dist-info}/top_level.txt +0 -0
bmcgo/__init__.py
CHANGED
bmcgo/bmcgo_config.py
CHANGED
|
@@ -36,16 +36,12 @@ class BmcgoComp(object):
|
|
|
36
36
|
self.config = config
|
|
37
37
|
|
|
38
38
|
|
|
39
|
-
class BmcgoConanIndex(
|
|
40
|
-
|
|
41
|
-
self.folder = os.path.realpath(folder)
|
|
42
|
-
self.config = config
|
|
39
|
+
class BmcgoConanIndex(BmcgoComp):
|
|
40
|
+
pass
|
|
43
41
|
|
|
44
42
|
|
|
45
|
-
class BmcgoManifest(
|
|
46
|
-
|
|
47
|
-
self.folder = os.path.realpath(folder)
|
|
48
|
-
self.config = config
|
|
43
|
+
class BmcgoManifest(BmcgoComp):
|
|
44
|
+
pass
|
|
49
45
|
|
|
50
46
|
|
|
51
47
|
class BmcgoHpmServerSign(object):
|
|
@@ -115,13 +111,26 @@ class BmcgoConfig(object):
|
|
|
115
111
|
self.bmcgo_local_config = configparser.ConfigParser()
|
|
116
112
|
self.bmcgo_config_list = {}
|
|
117
113
|
self._bmcgo_config_load()
|
|
118
|
-
|
|
114
|
+
if misc.conan_v1():
|
|
115
|
+
self.conf_path = os.path.join(self.bmcgo_path, "cli", "config.yaml")
|
|
116
|
+
else:
|
|
117
|
+
self.conf_path = os.path.join(self.bmcgo_path, "cli", "config.conan2.yaml")
|
|
119
118
|
|
|
120
119
|
@functools.cached_property
|
|
121
120
|
def partner_mode(self):
|
|
122
121
|
"""是否是伙伴模式"""
|
|
123
122
|
"""勿删除,用于构建伙伴模式bmcgo,return True"""
|
|
124
|
-
|
|
123
|
+
community = (misc.community_name() == "openubmc")
|
|
124
|
+
if community:
|
|
125
|
+
return True
|
|
126
|
+
if not os.path.isfile(misc.GLOBAL_CFG_FILE):
|
|
127
|
+
return False
|
|
128
|
+
conf = configparser.ConfigParser()
|
|
129
|
+
conf.read(misc.GLOBAL_CFG_FILE)
|
|
130
|
+
try:
|
|
131
|
+
return conf.getboolean("partner", "enable")
|
|
132
|
+
except (NoSectionError, NoOptionError):
|
|
133
|
+
return False
|
|
125
134
|
|
|
126
135
|
@functools.cached_property
|
|
127
136
|
def current_branch(self):
|
|
@@ -140,6 +149,9 @@ class BmcgoConfig(object):
|
|
|
140
149
|
return
|
|
141
150
|
while cwd != "/":
|
|
142
151
|
config_file = os.path.join(cwd, ".bmcgo", "config")
|
|
152
|
+
if not os.path.isfile(config_file):
|
|
153
|
+
config_file = os.path.join(cwd, ".bingo", "config")
|
|
154
|
+
|
|
143
155
|
if os.path.isfile(config_file):
|
|
144
156
|
conf = configparser.ConfigParser()
|
|
145
157
|
conf.read(config_file)
|
bmcgo/cli/cli.py
CHANGED
|
@@ -50,8 +50,11 @@ class Command(object):
|
|
|
50
50
|
parsing of parameters and delegates functionality in collaborators. It can also show the
|
|
51
51
|
help of the tool.
|
|
52
52
|
"""
|
|
53
|
-
def __init__(self):
|
|
54
|
-
|
|
53
|
+
def __init__(self, config: BmcgoConfig = None):
|
|
54
|
+
if not config:
|
|
55
|
+
self.bconfig = BmcgoConfig()
|
|
56
|
+
else:
|
|
57
|
+
self.bconfig = config
|
|
55
58
|
# 请使用_get_command_group获取命令组
|
|
56
59
|
self._command_group = None
|
|
57
60
|
self.comp_cmds = {
|
|
@@ -86,6 +89,8 @@ class Command(object):
|
|
|
86
89
|
misc.GRP_CONAN_IDX: self.conan_idx_cmds,
|
|
87
90
|
misc.GRP_IBMC_SDK: self.ibmc_sdk_cmds
|
|
88
91
|
}
|
|
92
|
+
# 扩展targets文件存储路径,由子类定义
|
|
93
|
+
self.ext_targets_dir = ""
|
|
89
94
|
|
|
90
95
|
@property
|
|
91
96
|
def __is_valid_component(self):
|
|
@@ -119,7 +124,7 @@ class Command(object):
|
|
|
119
124
|
os.chdir(work_dir)
|
|
120
125
|
config = Config(self.bconfig)
|
|
121
126
|
frame = Frame(self.bconfig, config)
|
|
122
|
-
frame.parse(args)
|
|
127
|
+
frame.parse(args, self.ext_targets_dir)
|
|
123
128
|
return frame.run()
|
|
124
129
|
|
|
125
130
|
def help(self, *args):
|
|
@@ -128,7 +133,7 @@ class Command(object):
|
|
|
128
133
|
"""
|
|
129
134
|
|
|
130
135
|
parser = argparse.ArgumentParser(description=self.help.__doc__,
|
|
131
|
-
prog="
|
|
136
|
+
prog=misc.tool_name() + " help")
|
|
132
137
|
parser.add_argument("command", help='command', nargs="?")
|
|
133
138
|
args = parser.parse_args(*args)
|
|
134
139
|
if not args.command:
|
|
@@ -207,7 +212,7 @@ class Command(object):
|
|
|
207
212
|
test = TestComp(self.bconfig, argv)
|
|
208
213
|
test.run()
|
|
209
214
|
else:
|
|
210
|
-
log.error("这可能是一个无效的
|
|
215
|
+
log.error(f"这可能是一个无效的 {misc.tool_name()} 组件, 因为 mds/service.json 文件不存在, 构建终止")
|
|
211
216
|
|
|
212
217
|
# deploy package
|
|
213
218
|
def deploy(self, *args):
|
|
@@ -215,7 +220,7 @@ class Command(object):
|
|
|
215
220
|
将组件及其依赖部署至temp/rootfs目录
|
|
216
221
|
"""
|
|
217
222
|
if not self.__is_valid_component:
|
|
218
|
-
log.error("这可能是一个无效的
|
|
223
|
+
log.error(f"这可能是一个无效的 {misc.tool_name()} 组件, 因为 mds/service.json 文件不存在, 构建终止")
|
|
219
224
|
return -1
|
|
220
225
|
log.info("安装 package 目录到 ./temp, 开始!")
|
|
221
226
|
argv = args[0]
|
|
@@ -236,6 +241,8 @@ class Command(object):
|
|
|
236
241
|
"""HIDDEN: entry point for executing commands, dispatcher to class
|
|
237
242
|
methods
|
|
238
243
|
"""
|
|
244
|
+
if not self._check_conan():
|
|
245
|
+
return 1
|
|
239
246
|
try:
|
|
240
247
|
command = args[0][0]
|
|
241
248
|
except IndexError: # No parameters
|
|
@@ -243,7 +250,7 @@ class Command(object):
|
|
|
243
250
|
return 0
|
|
244
251
|
try:
|
|
245
252
|
if command in ["-v", "--version"]:
|
|
246
|
-
self.
|
|
253
|
+
self.show_version()
|
|
247
254
|
return 0
|
|
248
255
|
|
|
249
256
|
self._warn_python_version()
|
|
@@ -270,13 +277,19 @@ class Command(object):
|
|
|
270
277
|
return method(command_args)
|
|
271
278
|
|
|
272
279
|
except SystemExit as exc:
|
|
280
|
+
if os.environ.get("LOG"):
|
|
281
|
+
log.error(traceback.format_exc())
|
|
273
282
|
if exc.code != 0:
|
|
274
283
|
log.error("构建已退出, 退出码为: %d", exc.code)
|
|
275
284
|
return exc.code
|
|
276
285
|
except errors.ExitOk as exc:
|
|
286
|
+
if os.environ.get("LOG"):
|
|
287
|
+
log.error(traceback.format_exc())
|
|
277
288
|
log.info(str(exc))
|
|
278
289
|
return 0
|
|
279
290
|
except (errors.BmcGoException, errors.EnvironmentException, KeyboardInterrupt) as exc:
|
|
291
|
+
if os.environ.get("LOG"):
|
|
292
|
+
log.error(traceback.format_exc())
|
|
280
293
|
log.error(str(exc))
|
|
281
294
|
log.error("请查看日志信息")
|
|
282
295
|
return -1
|
|
@@ -287,9 +300,58 @@ class Command(object):
|
|
|
287
300
|
log.error(msg)
|
|
288
301
|
log.error("请查看日志信息")
|
|
289
302
|
return -1
|
|
290
|
-
log.error("'%s' 不是
|
|
303
|
+
log.error("'%s' 不是 %s 命令. 使用 '%s -h' 查看帮助文档", command, misc.tool_name(), misc.tool_name())
|
|
291
304
|
return -1
|
|
292
305
|
|
|
306
|
+
def show_version(self):
|
|
307
|
+
log.info("bingo 版本为: %s", client_version)
|
|
308
|
+
studio_version = self._bmc_studio_version()
|
|
309
|
+
if studio_version:
|
|
310
|
+
log.info("bmc-studio 版本为: %s", studio_version)
|
|
311
|
+
|
|
312
|
+
def _check_conan(self):
|
|
313
|
+
need_conan_v2 = False
|
|
314
|
+
conf = None
|
|
315
|
+
if self.bconfig.component:
|
|
316
|
+
conanfile = os.path.join(self.bconfig.component.folder, "conanfile.py")
|
|
317
|
+
conf = self.bconfig.component.config
|
|
318
|
+
if not os.path.isfile(conanfile):
|
|
319
|
+
log.info("未检测到组件的conanfile.py, 构建可能失败")
|
|
320
|
+
return True
|
|
321
|
+
with open(conanfile, "r") as fp:
|
|
322
|
+
lines = fp.readlines()
|
|
323
|
+
for line in lines:
|
|
324
|
+
if not line.startswith("required_conan_version"):
|
|
325
|
+
continue
|
|
326
|
+
match = re.search("([0-9]+\\.[0-9]+\\.[0-9]+)", line)
|
|
327
|
+
if not match:
|
|
328
|
+
continue
|
|
329
|
+
if match[0].startswith("2."):
|
|
330
|
+
need_conan_v2 = True
|
|
331
|
+
break
|
|
332
|
+
else:
|
|
333
|
+
if self.bconfig.ibmc_sdk:
|
|
334
|
+
conf = self.bconfig.ibmc_sdk.config
|
|
335
|
+
elif self.bconfig.manifest:
|
|
336
|
+
conf = self.bconfig.manifest.config
|
|
337
|
+
if conf:
|
|
338
|
+
conan_require = conf.get(misc.CONAN, "version", fallback="")
|
|
339
|
+
if conan_require.startswith("2"):
|
|
340
|
+
need_conan_v2 = True
|
|
341
|
+
else:
|
|
342
|
+
return True
|
|
343
|
+
if need_conan_v2 and misc.conan_v1():
|
|
344
|
+
log.warning("检测到依赖conan2.0但仅安装了conan1.0,尝试重新安装conan2.0")
|
|
345
|
+
tools.run_command("pip3 install conan==2.13.0 --force-reinstall --break-system-packages")
|
|
346
|
+
log.warning("检测到依赖conan2.0但仅安装了conan1.0,已安装conan2.0,任务退出,请重新执行")
|
|
347
|
+
return False
|
|
348
|
+
if not need_conan_v2 and misc.conan_v2():
|
|
349
|
+
log.warning("检测到依赖conan1.0但仅安装了conan2.0,尝试重新安装conan1.0")
|
|
350
|
+
tools.run_command("pip3 install conan==1.62.0 --force-reinstall --break-system-packages")
|
|
351
|
+
log.warning("检测到依赖conan1.0但仅安装了conan2.0,已安装conan1.0,任务退出,请重新执行")
|
|
352
|
+
return False
|
|
353
|
+
return True
|
|
354
|
+
|
|
293
355
|
def _init_bmcgo_environ(self, command):
|
|
294
356
|
if command not in SKIP_CONFIG_COMMANDS and misc.ENV_CONST in self.bconfig.bmcgo_config_list:
|
|
295
357
|
log.info("检测到配置项环境变量,开始使用")
|
|
@@ -310,7 +372,7 @@ class Command(object):
|
|
|
310
372
|
start_match_command = self._match_real_command(command, False)
|
|
311
373
|
if start_match_command:
|
|
312
374
|
return start_match_command
|
|
313
|
-
raise errors.CommandNotFoundException(f"未找到命令: {command}, 请执行
|
|
375
|
+
raise errors.CommandNotFoundException(f"未找到命令: {command}, 请执行{misc.tool_name()} -h检查支持的命令")
|
|
314
376
|
|
|
315
377
|
def _match_real_command(self, command, is_full_match=True):
|
|
316
378
|
is_integrated, _ = self._is_integrated_project()
|
|
@@ -328,12 +390,6 @@ class Command(object):
|
|
|
328
390
|
return real_method
|
|
329
391
|
return None
|
|
330
392
|
|
|
331
|
-
def _show_version(self):
|
|
332
|
-
log.info("bingo 版本为: %s", client_version)
|
|
333
|
-
studio_version = self._bmc_studio_version()
|
|
334
|
-
if studio_version:
|
|
335
|
-
log.info("bmc-studio 版本为: %s", studio_version)
|
|
336
|
-
|
|
337
393
|
def _bmc_studio_version(self):
|
|
338
394
|
"""检查当前环境中正在使用的bmc studio版本,
|
|
339
395
|
优先通过pip获取,获取不到通过bmc_studio/mds/server获取
|
|
@@ -467,9 +523,9 @@ class Command(object):
|
|
|
467
523
|
|
|
468
524
|
log.info("")
|
|
469
525
|
if self.bconfig.manifest is None and self.bconfig.component is None:
|
|
470
|
-
log.warning("未找到 .bmcgo/config或mds/service.json 配置文件, 当前路径可能未包含
|
|
526
|
+
log.warning(f"未找到 .bmcgo/config或mds/service.json 配置文件, 当前路径可能未包含 {misc.tool_name()} 项目")
|
|
471
527
|
return
|
|
472
|
-
log.info('输入 "
|
|
528
|
+
log.info(f'输入 "{misc.tool_name()} <command> -h" 获取子命令帮助')
|
|
473
529
|
|
|
474
530
|
def _doc_append(self, lines):
|
|
475
531
|
start = False
|
|
@@ -520,10 +576,12 @@ class Command(object):
|
|
|
520
576
|
|
|
521
577
|
|
|
522
578
|
def prepare_conan():
|
|
579
|
+
if misc.conan_v2():
|
|
580
|
+
return
|
|
523
581
|
home = os.environ["HOME"]
|
|
524
582
|
settings_yml = os.path.join(home, ".conan", "settings.yml")
|
|
525
583
|
if not os.path.isfile(settings_yml):
|
|
526
|
-
return
|
|
584
|
+
return
|
|
527
585
|
with open(settings_yml, mode="r") as fp:
|
|
528
586
|
config_data = yaml.safe_load(fp)
|
|
529
587
|
gcc = config_data["compiler"].get("gcc")
|
|
@@ -543,32 +601,17 @@ def prepare_conan():
|
|
|
543
601
|
file_handler.write(yaml.safe_dump(config_data, indent=2, sort_keys=False))
|
|
544
602
|
|
|
545
603
|
|
|
546
|
-
def
|
|
547
|
-
"""
|
|
604
|
+
def run(args, command: Command = None):
|
|
605
|
+
"""
|
|
606
|
+
main entry point of the bmcgo application, using a Command to
|
|
548
607
|
parse parameters
|
|
549
608
|
"""
|
|
550
|
-
|
|
551
|
-
def ctrl_c_handler(_, __):
|
|
552
|
-
log.info('你按下了 Ctrl+C! 构建终止!')
|
|
553
|
-
sys.exit(-3)
|
|
554
|
-
|
|
555
|
-
def sigterm_handler(_, __):
|
|
556
|
-
log.info('接收到信号 SIGTERM! 构建终止!')
|
|
557
|
-
sys.exit(-5)
|
|
558
|
-
|
|
559
|
-
def ctrl_break_handler(_, __):
|
|
560
|
-
log.info('你按下了 Ctrl+Break! 构建终止!')
|
|
561
|
-
sys.exit(-4)
|
|
562
|
-
|
|
563
|
-
signal.signal(signal.SIGINT, ctrl_c_handler)
|
|
564
|
-
signal.signal(signal.SIGTERM, sigterm_handler)
|
|
565
|
-
|
|
566
|
-
if sys.platform == 'win32':
|
|
567
|
-
signal.signal(signal.SIGBREAK, ctrl_break_handler)
|
|
609
|
+
os.makedirs(misc.CACHE_DIR, exist_ok=True)
|
|
568
610
|
|
|
569
611
|
try:
|
|
570
612
|
prepare_conan()
|
|
571
|
-
|
|
613
|
+
if not command:
|
|
614
|
+
command = Command()
|
|
572
615
|
error = command.run(args)
|
|
573
616
|
except errors.ExitOk as exc:
|
|
574
617
|
log.info(str(exc))
|
|
@@ -580,3 +623,7 @@ def main(args):
|
|
|
580
623
|
log.error(msg)
|
|
581
624
|
error = -1
|
|
582
625
|
return error
|
|
626
|
+
|
|
627
|
+
|
|
628
|
+
def main(args):
|
|
629
|
+
return run(args)
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
comp_type:
|
|
2
|
+
- conan_index
|
|
3
|
+
- component
|
|
4
|
+
- manifest
|
|
5
|
+
dt_dependencies:
|
|
6
|
+
dtframeforlua: dtframeforlua/0.0.24+conan2@openubmc/stable
|
|
7
|
+
luaunit: luaunit/3.2+conan2@openubmc/stable
|
|
8
|
+
luacov: luacov/0.16.3+conan2@openubmc/stable
|
|
9
|
+
luafilesystem: luafilesystem/1.8.0.b022+conan2@openubmc/stable
|
bmcgo/codegen/lua/codegen.py
CHANGED
|
@@ -51,7 +51,7 @@ class CodeGen(object):
|
|
|
51
51
|
return lua_format
|
|
52
52
|
|
|
53
53
|
def get_mdb_interface_package(self):
|
|
54
|
-
channel = f"@{
|
|
54
|
+
channel = f"@{misc.conan_user()}/{misc.StageEnum.STAGE_RC.value}"
|
|
55
55
|
package = f"mdb_interface/[>=0.0.1]{channel}"
|
|
56
56
|
dependencies = self.read_service_json().get(misc.CONAN_DEPDENCIES_KEY)
|
|
57
57
|
if not dependencies:
|
|
@@ -454,9 +454,6 @@ def generate_only_interface(intf_dep: InterfaceDep, service, imports, mdb_path):
|
|
|
454
454
|
|
|
455
455
|
def fill_client_intf(service, imports, mdb_path, required, path):
|
|
456
456
|
intf_dep = InterfaceDep(required)
|
|
457
|
-
intf_seg = (intf_dep.name).split('.')
|
|
458
|
-
if len(intf_seg) >= 3 and intf_seg[2] == 'Debug':
|
|
459
|
-
raise Exception(f"在service.json中配置了调试版本的依赖项, interface: {intf_dep.name}")
|
|
460
457
|
if path != "*":
|
|
461
458
|
class_name, path_json = utils.get_path_by_interface(mdb_path, required["interface"], path)
|
|
462
459
|
generate_path_interface(
|
|
@@ -482,10 +479,20 @@ def check_multiple_paths(interfaces):
|
|
|
482
479
|
intf_map[intf_name] = True
|
|
483
480
|
|
|
484
481
|
|
|
482
|
+
## 匹配APP下的service_json_path目录,如果是扩展组件,层级为3
|
|
483
|
+
def match_level(service_json_path):
|
|
484
|
+
path_level = 0
|
|
485
|
+
match = re.search(r'.*(/[^/]+/mds/.*)', service_json_path)
|
|
486
|
+
if match:
|
|
487
|
+
mds_path = match.group(1)
|
|
488
|
+
path_level = count_dir_level(mds_path)
|
|
489
|
+
return path_level
|
|
490
|
+
|
|
491
|
+
|
|
485
492
|
def generate_client(service_file, output, mdb_path, mds_path, path_level):
|
|
486
493
|
load_f = utils.open_file(service_file)
|
|
487
494
|
service_dict = json.load(load_f)
|
|
488
|
-
|
|
495
|
+
service_level = match_level(service_file)
|
|
489
496
|
imports = {"intf": {}, KLASS: {}}
|
|
490
497
|
if "required" not in service_dict:
|
|
491
498
|
load_f.close()
|
|
@@ -499,6 +506,10 @@ def generate_client(service_file, output, mdb_path, mds_path, path_level):
|
|
|
499
506
|
signals = []
|
|
500
507
|
service = {INTERFACES: interfaces, METHODS: methods, SIGNALS: signals}
|
|
501
508
|
for required in service_dict["required"]:
|
|
509
|
+
intf_dep = InterfaceDep(required)
|
|
510
|
+
intf_seg = (intf_dep.name).split('.')
|
|
511
|
+
if service_level == 2 and len(intf_seg) >= 3 and intf_seg[2] == 'Debug':
|
|
512
|
+
raise Exception(f"在service.json中配置了调试版本的依赖项, interface: {intf_dep.name}")
|
|
502
513
|
if PATH in required:
|
|
503
514
|
fill_client_intf(service, imports, mdb_path, required, required[PATH])
|
|
504
515
|
continue
|
|
@@ -530,16 +541,6 @@ def count_dir_level(path):
|
|
|
530
541
|
return level
|
|
531
542
|
|
|
532
543
|
|
|
533
|
-
## 匹配APP下的service_json_path目录,如果是扩展组件,层级为3
|
|
534
|
-
def match_level(service_json_path):
|
|
535
|
-
path_level = 0
|
|
536
|
-
match = re.search(r'.*(/[^/]+/mds/.*)', service_json_path)
|
|
537
|
-
if match:
|
|
538
|
-
mds_path = match.group(1)
|
|
539
|
-
path_level = count_dir_level(mds_path)
|
|
540
|
-
return path_level
|
|
541
|
-
|
|
542
|
-
|
|
543
544
|
def main(argv):
|
|
544
545
|
m_input = ""
|
|
545
546
|
output = ""
|
|
@@ -44,12 +44,12 @@ class AnalysisComp():
|
|
|
44
44
|
self.nodes: list[DepNode] = []
|
|
45
45
|
self.subsystems = {}
|
|
46
46
|
self.rules: list[Rules] = []
|
|
47
|
+
self.rule_file = os.path.join(script_dir, "dep-rules.json")
|
|
47
48
|
|
|
48
49
|
def read_rules(self):
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
with open(rule_file) as file_descriptor:
|
|
50
|
+
if not os.path.isfile(self.rule_file):
|
|
51
|
+
raise Exception(f"依赖规则文件 {self.rule_file} 不存在")
|
|
52
|
+
with open(self.rule_file) as file_descriptor:
|
|
53
53
|
rules = json.load(file_descriptor)
|
|
54
54
|
data = rules.get("Subsystems", [])
|
|
55
55
|
for sub in data:
|
|
@@ -108,17 +108,17 @@ class AnalysisComp():
|
|
|
108
108
|
break
|
|
109
109
|
node = DepNode(node_data, i)
|
|
110
110
|
# busybox是调测包,当dev包引入时忽略架构治理分析(由schema模型看护)
|
|
111
|
-
|
|
112
|
-
if node.package_name == "busybox" and user_stage in node.ref:
|
|
111
|
+
if node.package_name == "busybox" and "/dev" in node.ref:
|
|
113
112
|
continue
|
|
114
113
|
packages[node.index] = node
|
|
115
114
|
requires[node.index] = node_data.get("requires", [])
|
|
115
|
+
comm_name = misc.community_name()
|
|
116
116
|
for index, pkg in packages.items():
|
|
117
|
-
if not pkg.name.startswith(
|
|
117
|
+
if not pkg.name.startswith(comm_name):
|
|
118
118
|
self.set_node_subsys(pkg)
|
|
119
119
|
for require_id in requires.get(index, []):
|
|
120
120
|
pkg.requires.append(packages.get(int(require_id), None))
|
|
121
|
-
if not pkg.name.startswith(
|
|
121
|
+
if not pkg.name.startswith(comm_name):
|
|
122
122
|
self.nodes.append(pkg)
|
|
123
123
|
|
|
124
124
|
def run(self):
|
|
@@ -17,6 +17,7 @@ import os
|
|
|
17
17
|
import re
|
|
18
18
|
import shutil
|
|
19
19
|
import subprocess
|
|
20
|
+
from tempfile import TemporaryDirectory
|
|
20
21
|
|
|
21
22
|
from bmcgo.logger import Logger
|
|
22
23
|
from bmcgo.codegen.c.helper import Helper
|
|
@@ -63,15 +64,18 @@ class InterfaceValidation:
|
|
|
63
64
|
|
|
64
65
|
@staticmethod
|
|
65
66
|
def _parse_mds_package_deps():
|
|
66
|
-
channel = f"@{misc.
|
|
67
|
-
|
|
67
|
+
channel = f"@{misc.conan_user()}/{misc.StageEnum.STAGE_RC.value}"
|
|
68
|
+
if misc.conan_v1():
|
|
69
|
+
package = f"mdb_interface/[>=0.0.1]{channel}"
|
|
70
|
+
else:
|
|
71
|
+
package = f"mdb_interface/[>=0.0.1]@{misc.conan_user()}/stable"
|
|
68
72
|
service_path = os.path.join(os.getcwd(), "mds/service.json")
|
|
69
73
|
if not os.path.exists(service_path):
|
|
70
74
|
return package
|
|
71
75
|
with open(service_path, "r") as service_fp:
|
|
72
76
|
try:
|
|
73
77
|
content = json.load(service_fp)
|
|
74
|
-
except json.decoder.JSONDecodeError
|
|
78
|
+
except json.decoder.JSONDecodeError:
|
|
75
79
|
return package
|
|
76
80
|
dependencies = content.get("dependencies")
|
|
77
81
|
if not dependencies:
|
|
@@ -82,10 +86,13 @@ class InterfaceValidation:
|
|
|
82
86
|
conan_package = dep.get(misc.CONAN, "")
|
|
83
87
|
if not conan_package.startswith("mdb_interface"):
|
|
84
88
|
continue
|
|
85
|
-
if
|
|
86
|
-
|
|
89
|
+
if misc.conan_v1():
|
|
90
|
+
if "@" in conan_package:
|
|
91
|
+
package = conan_package
|
|
92
|
+
else:
|
|
93
|
+
package = f"{conan_package}{channel}"
|
|
87
94
|
else:
|
|
88
|
-
|
|
95
|
+
return conan_package
|
|
89
96
|
return package
|
|
90
97
|
|
|
91
98
|
def run(self):
|
|
@@ -160,11 +167,16 @@ class InterfaceValidation:
|
|
|
160
167
|
|
|
161
168
|
def _pull_interfaces_from_conan(self):
|
|
162
169
|
pkg = self._parse_mds_package_deps()
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
170
|
+
temp = TemporaryDirectory()
|
|
171
|
+
temp_dir = temp.name
|
|
172
|
+
if misc.conan_v1():
|
|
173
|
+
cmd = [misc.CONAN, "install", pkg, f"-if={temp_dir}",
|
|
174
|
+
"--build=missing", "-g", "deploy", "-s", "build_type=Dt"]
|
|
175
|
+
else:
|
|
176
|
+
ins_dir = os.path.join(temp_dir, "mdb_interface")
|
|
177
|
+
os.makedirs(ins_dir)
|
|
178
|
+
cmd = [misc.CONAN, "install", f"--requires={pkg}", f"-of={ins_dir}", "--build=missing", "-d",
|
|
179
|
+
"direct_deploy", "-pr", "profile.dt.ini", "-o", "test=True"]
|
|
168
180
|
if self.remote:
|
|
169
181
|
cmd += ["-r", self.remote]
|
|
170
182
|
subprocess.call(cmd)
|
|
@@ -176,7 +188,6 @@ class InterfaceValidation:
|
|
|
176
188
|
continue
|
|
177
189
|
file_path = os.path.join(root, file_name)
|
|
178
190
|
self.all_predefined_intfs.update(intf for intf in self.extract_dbus_intf_in_file(file_path))
|
|
179
|
-
shutil.rmtree(temp_dir, ignore_errors=True)
|
|
180
191
|
|
|
181
192
|
def _pull_interfaces_from_codegen(self):
|
|
182
193
|
service_path = os.path.join(os.getcwd(), "mds/service.json")
|
bmcgo/component/build.py
CHANGED
|
@@ -14,7 +14,8 @@ import os
|
|
|
14
14
|
import shutil
|
|
15
15
|
import subprocess
|
|
16
16
|
import stat
|
|
17
|
-
import
|
|
17
|
+
from tempfile import NamedTemporaryFile
|
|
18
|
+
import yaml
|
|
18
19
|
|
|
19
20
|
from mako.lookup import TemplateLookup
|
|
20
21
|
|
|
@@ -26,7 +27,9 @@ from bmcgo.errors import BmcGoException
|
|
|
26
27
|
from bmcgo.component.package_info import InfoComp
|
|
27
28
|
from bmcgo.component.component_helper import ComponentHelper
|
|
28
29
|
from bmcgo import misc
|
|
30
|
+
from bmcgo import errors
|
|
29
31
|
from bmcgo.utils.json_validator import JSONValidator
|
|
32
|
+
from bmcgo.component.gen import GenComp
|
|
30
33
|
|
|
31
34
|
log = Logger()
|
|
32
35
|
tool = Tools()
|
|
@@ -35,12 +38,14 @@ cwd_script = os.path.split(os.path.realpath(__file__))[0]
|
|
|
35
38
|
|
|
36
39
|
|
|
37
40
|
class BuildComp():
|
|
38
|
-
def __init__(self, bconfig: BmcgoConfig, args=None, gen_conanbase=True,
|
|
41
|
+
def __init__(self, bconfig: BmcgoConfig, args=None, gen_conanbase=True,
|
|
42
|
+
service_json="mds/service.json", enable_upload=True):
|
|
39
43
|
self.init_common_params(bconfig)
|
|
40
|
-
self.info: InfoComp = InfoComp(args, service_json, self.bconfig.partner_mode)
|
|
44
|
+
self.info: InfoComp = InfoComp(args, service_json, self.bconfig.partner_mode, enable_upload)
|
|
41
45
|
self.set_remote_url()
|
|
42
46
|
self.gen_conanbase(gen_conanbase, service_json)
|
|
43
47
|
self.gen_log()
|
|
48
|
+
self.graph_file = NamedTemporaryFile(suffix=".graph.json")
|
|
44
49
|
|
|
45
50
|
@staticmethod
|
|
46
51
|
def get_remote_urls():
|
|
@@ -66,10 +71,17 @@ class BuildComp():
|
|
|
66
71
|
os.environ["LUA_PATH"] = f"{conan_bin}/?.lua"
|
|
67
72
|
|
|
68
73
|
def gen_conanbase(self, gen_conanbase, service_json):
|
|
69
|
-
|
|
74
|
+
if misc.conan_v1():
|
|
75
|
+
lookup = TemplateLookup(directories=os.path.join(cwd_script, "template"))
|
|
76
|
+
else:
|
|
77
|
+
lookup = TemplateLookup(directories=os.path.join(cwd_script, "template_v2"))
|
|
70
78
|
if gen_conanbase:
|
|
71
79
|
template = lookup.get_template("conanbase.py.mako")
|
|
72
|
-
language =
|
|
80
|
+
language = self.info.language
|
|
81
|
+
if language == "c" and misc.conan_v2():
|
|
82
|
+
args = ["-s", service_json]
|
|
83
|
+
gen = GenComp(args)
|
|
84
|
+
gen.run(self.info.codegen_base_version)
|
|
73
85
|
conanbase = template.render(lookup=lookup, pkg=self.info, remote_url=self.remote_url,
|
|
74
86
|
codegen_version=self.info.codegen_base_version,
|
|
75
87
|
language=language)
|
|
@@ -79,7 +91,7 @@ class BuildComp():
|
|
|
79
91
|
file_handler.close()
|
|
80
92
|
|
|
81
93
|
def gen_log(self):
|
|
82
|
-
self.log_file = os.path.join(
|
|
94
|
+
self.log_file = os.path.join(misc.CACHE_DIR, self.info.name + ".log")
|
|
83
95
|
file_handler = os.fdopen(os.open(self.log_file, os.O_WRONLY | os.O_CREAT | os.O_TRUNC,
|
|
84
96
|
stat.S_IWUSR | stat.S_IRUSR), 'w')
|
|
85
97
|
file_handler.close()
|
|
@@ -141,15 +153,36 @@ class BuildComp():
|
|
|
141
153
|
|
|
142
154
|
def check_conan_profile(self):
|
|
143
155
|
profile = os.path.join(tool.conan_profiles_dir, self.info.profile)
|
|
144
|
-
luajit_profile = os.path.join(tool.conan_profiles_dir, "profile.luajit.ini")
|
|
145
156
|
if not os.path.isfile(profile):
|
|
146
157
|
raise BmcGoException(f"Profile文件{profile} 不存在,系统可能未初始化," +
|
|
147
|
-
"请在manifest仓执行
|
|
148
|
-
if
|
|
149
|
-
|
|
150
|
-
|
|
158
|
+
f"请在manifest仓执行{misc.tool_name()} build安装产品配套构建工具")
|
|
159
|
+
if misc.conan_v1():
|
|
160
|
+
luajit_profile = os.path.join(tool.conan_profiles_dir, "profile.luajit.ini")
|
|
161
|
+
if self.info.enable_luajit and not os.path.isfile(luajit_profile):
|
|
162
|
+
raise BmcGoException(f"Profile文件{luajit_profile} 不存在,系统可能未初始化," +
|
|
163
|
+
"请在manifest仓(2024.07.04之后的版本)执行bingo build安装产品配套构建工具")
|
|
164
|
+
|
|
165
|
+
def upload_conan_v2(self):
|
|
166
|
+
cmd = f"conan cache path {self.info.package}"
|
|
167
|
+
ret = tool.run_command(cmd, capture_output=True)
|
|
168
|
+
recipe_path = ret.stdout.strip()
|
|
169
|
+
conandata = os.path.join(recipe_path, "conandata.yml")
|
|
170
|
+
with open(conandata, mode="r") as fp:
|
|
171
|
+
config_data = yaml.safe_load(fp)
|
|
172
|
+
cfg = config_data.get("sources", {}).get(self.info.version, {})
|
|
173
|
+
if not cfg:
|
|
174
|
+
raise errors.BmcGoException(f"conandata.yml不存在sources/{self.info.version}配置或配置为空")
|
|
175
|
+
if cfg.get("pwd"):
|
|
176
|
+
log.error("检查到错误的conandata.yml配置")
|
|
177
|
+
fp.seek(0, os.SEEK_SET)
|
|
178
|
+
log.error(fp.read())
|
|
179
|
+
raise errors.BmcGoException(f"组件目录存在脏数据或未推送到远程仓,禁止上传")
|
|
180
|
+
|
|
181
|
+
cmd = [misc.CONAN, "upload"]
|
|
182
|
+
cmd += ("%s -r %s --force" % (self.info.package, self.info.remote)).split()
|
|
183
|
+
tool.run_command(cmd, show_log=True)
|
|
151
184
|
|
|
152
|
-
def
|
|
185
|
+
def upload_conanv1(self):
|
|
153
186
|
if not self.info.upload:
|
|
154
187
|
return
|
|
155
188
|
pkg = "%s/%s%s" % (self.info.name, self.info.version, self.info.channel)
|
|
@@ -172,7 +205,7 @@ class BuildComp():
|
|
|
172
205
|
cmd += ("%s:%s -r %s --all" % (pkg, pkg_id, self.info.remote)).split()
|
|
173
206
|
tool.run_command(cmd, show_log=True)
|
|
174
207
|
|
|
175
|
-
def
|
|
208
|
+
def run_conan_v1(self):
|
|
176
209
|
tool.clean_locks()
|
|
177
210
|
self.check_conan_profile()
|
|
178
211
|
self.check_luac()
|
|
@@ -184,11 +217,40 @@ class BuildComp():
|
|
|
184
217
|
shutil.rmtree(cache_dir, ignore_errors=True)
|
|
185
218
|
# 构建当前组件
|
|
186
219
|
append = "%s %s -tf None" % (self.info.cmd_base, from_source)
|
|
220
|
+
if self.info.no_cache:
|
|
221
|
+
append += " -u"
|
|
187
222
|
cmd = [misc.CONAN, "create"]
|
|
188
223
|
cmd += append.split()
|
|
189
224
|
tool.run_command(cmd, show_log=True)
|
|
190
225
|
self._check_sr_validation(os.path.join(cache_dir, "package"))
|
|
191
|
-
self.upload
|
|
226
|
+
if self.info.upload:
|
|
227
|
+
self.upload_conanv1()
|
|
228
|
+
|
|
229
|
+
def run_conan_v2(self):
|
|
230
|
+
self.check_conan_profile()
|
|
231
|
+
from_source = f"--build={self.info.name}/*"
|
|
232
|
+
if self.info.from_source:
|
|
233
|
+
from_source = "--build=*"
|
|
234
|
+
else:
|
|
235
|
+
from_source += " --build=missing"
|
|
236
|
+
# # 构建当前组件
|
|
237
|
+
args = "%s %s" % (self.info.cmd_base, from_source)
|
|
238
|
+
if self.info.no_cache:
|
|
239
|
+
args += " -u"
|
|
240
|
+
cmd = [misc.CONAN, "create", "--name", self.info.name, "--version", self.info.version]
|
|
241
|
+
args += f" -f json --out-file={self.graph_file.name}"
|
|
242
|
+
cmd += args.split()
|
|
243
|
+
tool.run_command(cmd, show_log=True)
|
|
244
|
+
package_folder = tool.get_package_folder_from_graph_file(self.graph_file.name, self.info.package)
|
|
245
|
+
self._check_sr_validation(package_folder)
|
|
246
|
+
if self.info.upload:
|
|
247
|
+
self.upload_conan_v2()
|
|
248
|
+
|
|
249
|
+
def run(self):
|
|
250
|
+
if misc.conan_v1():
|
|
251
|
+
self.run_conan_v1()
|
|
252
|
+
else:
|
|
253
|
+
self.run_conan_v2()
|
|
192
254
|
|
|
193
255
|
def test(self):
|
|
194
256
|
if os.path.isdir("test_package"):
|