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.

Files changed (52) hide show
  1. bmcgo/__init__.py +1 -1
  2. bmcgo/bmcgo_config.py +22 -10
  3. bmcgo/cli/cli.py +86 -39
  4. bmcgo/cli/config.conan2.yaml +9 -0
  5. bmcgo/codegen/lua/codegen.py +1 -1
  6. bmcgo/codegen/lua/script/gen_intf_rpc_json.py +15 -14
  7. bmcgo/component/analysis/analysis.py +8 -8
  8. bmcgo/component/analysis/intf_validation.py +23 -12
  9. bmcgo/component/build.py +76 -14
  10. bmcgo/component/component_dt_version_parse.py +3 -2
  11. bmcgo/component/component_helper.py +43 -15
  12. bmcgo/component/coverage/incremental_cov.py +2 -2
  13. bmcgo/component/deploy.py +68 -14
  14. bmcgo/component/gen.py +1 -1
  15. bmcgo/component/package_info.py +128 -38
  16. bmcgo/component/template_v2/conanbase.py.mako +352 -0
  17. bmcgo/component/template_v2/conanfile.deploy.py.mako +26 -0
  18. bmcgo/component/test.py +53 -20
  19. bmcgo/frame.py +7 -3
  20. bmcgo/functional/analysis.py +3 -2
  21. bmcgo/functional/check.py +10 -6
  22. bmcgo/functional/conan_index_build.py +79 -20
  23. bmcgo/functional/csr_build.py +1 -1
  24. bmcgo/functional/diff.py +1 -1
  25. bmcgo/functional/fetch.py +1 -1
  26. bmcgo/functional/full_component.py +32 -24
  27. bmcgo/functional/git_history.py +220 -0
  28. bmcgo/functional/maintain.py +55 -12
  29. bmcgo/functional/new.py +1 -1
  30. bmcgo/functional/schema_valid.py +2 -2
  31. bmcgo/logger.py +2 -3
  32. bmcgo/misc.py +130 -9
  33. bmcgo/tasks/conan/__init__.py +10 -0
  34. bmcgo/tasks/conan/conanfile.py +45 -0
  35. bmcgo/tasks/task.py +27 -4
  36. bmcgo/tasks/task_build_conan.py +399 -52
  37. bmcgo/tasks/task_buildgppbin.py +8 -2
  38. bmcgo/tasks/task_download_buildtools.py +76 -0
  39. bmcgo/tasks/task_download_dependency.py +1 -0
  40. bmcgo/tasks/task_hpm_envir_prepare.py +1 -1
  41. bmcgo/utils/build_conans.py +231 -0
  42. bmcgo/utils/component_post.py +6 -4
  43. bmcgo/utils/component_version_check.py +10 -5
  44. bmcgo/utils/config.py +76 -40
  45. bmcgo/utils/fetch_component_code.py +44 -25
  46. bmcgo/utils/tools.py +239 -117
  47. bmcgo/worker.py +2 -2
  48. {openubmc_bingo-0.5.277.dist-info → openubmc_bingo-0.6.0.dist-info}/METADATA +4 -2
  49. {openubmc_bingo-0.5.277.dist-info → openubmc_bingo-0.6.0.dist-info}/RECORD +52 -45
  50. {openubmc_bingo-0.5.277.dist-info → openubmc_bingo-0.6.0.dist-info}/WHEEL +0 -0
  51. {openubmc_bingo-0.5.277.dist-info → openubmc_bingo-0.6.0.dist-info}/entry_points.txt +0 -0
  52. {openubmc_bingo-0.5.277.dist-info → openubmc_bingo-0.6.0.dist-info}/top_level.txt +0 -0
bmcgo/__init__.py CHANGED
@@ -9,4 +9,4 @@
9
9
  # MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
10
10
  # See the Mulan PSL v2 for more details.
11
11
 
12
- __version__ = '0.5.277'
12
+ __version__ = '0.6.0'
bmcgo/bmcgo_config.py CHANGED
@@ -36,16 +36,12 @@ class BmcgoComp(object):
36
36
  self.config = config
37
37
 
38
38
 
39
- class BmcgoConanIndex(object):
40
- def __init__(self, folder, config: configparser.ConfigParser):
41
- self.folder = os.path.realpath(folder)
42
- self.config = config
39
+ class BmcgoConanIndex(BmcgoComp):
40
+ pass
43
41
 
44
42
 
45
- class BmcgoManifest(object):
46
- def __init__(self, folder, config: configparser.ConfigParser):
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
- self.conf_path = os.path.join(self.bmcgo_path, "cli", "config.yaml")
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
- return True
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
- self.bconfig = BmcgoConfig()
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="bingo help")
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("这可能是一个无效的 bingo 组件, 因为 mds/service.json 文件不存在, 构建终止")
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("这可能是一个无效的 bingo 组件, 因为 mds/service.json 文件不存在, 构建终止")
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._show_version()
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' 不是 bingo 命令. 使用 'bingo -h' 查看帮助文档", command)
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}, 请执行bingo -h检查支持的命令")
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 配置文件, 当前路径可能未包含bingo项目")
526
+ log.warning(f"未找到 .bmcgo/config或mds/service.json 配置文件, 当前路径可能未包含 {misc.tool_name()} 项目")
471
527
  return
472
- log.info('输入 "bingo <command> -h" 获取子命令帮助')
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 main(args):
547
- """ main entry point of the bmcgo application, using a Command to
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
- command = Command()
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
@@ -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"@{Tools().conan_user}/{misc.StageEnum.STAGE_RC.value}"
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
- rule_file = os.path.join(script_dir, "dep-rules.json")
50
- if not os.path.isfile(rule_file):
51
- raise Exception(f"依赖规则文件 {rule_file} 不存在")
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
- user_stage = f"{misc.ConanUserEnum.CONAN_USER_DEV.value}/{misc.StageEnum.STAGE_DEV.value}"
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("openubmc"):
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("openubmc"):
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.ConanUserEnum.CONAN_USER_RELEASE.value}/{misc.StageEnum.STAGE_RC.value}"
67
- package = f"mdb_interface/[>=0.0.1]{channel}"
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 as error:
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 "@" in conan_package:
86
- package = conan_package
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
- package = f"{conan_package}{channel}"
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
- mktemp_cmd = subprocess.run(["/usr/bin/mktemp", "-d", "--suffix", "_mdb_interface"], capture_output=True)
164
- if mktemp_cmd.returncode != 0:
165
- raise OSError(f"创建文件夹失败, 错误消息: {mktemp_cmd.stderr}")
166
- temp_dir = mktemp_cmd.stdout.decode().strip('\n')
167
- cmd = [misc.CONAN, "install", pkg, f"-if={temp_dir}", "--build=missing", "-g", "deploy", "-s", "build_type=Dt"]
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 pathlib
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, service_json="mds/service.json"):
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
- lookup = TemplateLookup(directories=os.path.join(cwd_script, "template"))
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 = ComponentHelper.get_language(service_json=service_json, allow_non_service_json=True)
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("/tmp", self.info.name + ".log")
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仓执行bingo build安装产品配套构建工具")
148
- if self.info.enable_luajit and not os.path.isfile(luajit_profile):
149
- raise BmcGoException(f"Profile文件{luajit_profile} 不存在,系统可能未初始化," +
150
- "请在manifest仓(2024.07.04之后的版本)执行bingo build安装产品配套构建工具")
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 upload(self):
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 run(self):
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"):