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
@@ -200,7 +200,7 @@ class ManifestConfigParse:
200
200
  class ComponentDtVersionParse:
201
201
  """分析组件 dt 的依赖组件版本, 实现自动配置 service.json 文件, 达成 dt 构建门禁
202
202
  """
203
- def __init__(self, parser=None, serv_file="mds/service.json", args=None):
203
+ def __init__(self, parser=None, serv_file="mds/service.json", args=None, exclude_dt=False):
204
204
  """初始化,读取配置
205
205
 
206
206
  Args:
@@ -221,7 +221,8 @@ class ComponentDtVersionParse:
221
221
  self.mds_conf = json.load(mds_conf_fp)
222
222
  mds_conf_fp.close()
223
223
  # 生成dt与build的依赖列表, 检查时如果发现问题, 直接报出组件名, 不分类
224
- conan_dt_list = Function.get_key_value(self.mds_conf, "dependencies/test") or []
224
+ if not exclude_dt:
225
+ conan_dt_list = Function.get_key_value(self.mds_conf, "dependencies/test") or []
225
226
  conan_build_list = Function.get_key_value(self.mds_conf, "dependencies/build") or []
226
227
  # 根据配置文件,已确定为列表,有告警,无需使用list转化,影响效率
227
228
  self.conan_list = conan_dt_list + conan_build_list
@@ -19,7 +19,7 @@ from tempfile import NamedTemporaryFile
19
19
  from packaging import version
20
20
 
21
21
  from bmcgo.utils.tools import Tools
22
- from bmcgo.bmcgo_config import misc
22
+ from bmcgo import misc
23
23
  from bmcgo.errors import BmcGoException
24
24
 
25
25
  STAGE_DEV = "dev"
@@ -40,9 +40,15 @@ class DownloadComponentRecipe(Process):
40
40
  self.remote_list = remote_list
41
41
 
42
42
  def run(self):
43
- dep_path = os.path.join(self.tools.conan_data, self.comp.replace("@", "/"))
44
- if os.path.isdir(dep_path):
45
- return
43
+ if misc.conan_v1():
44
+ dep_path = os.path.join(self.tools.conan_data, self.comp.replace("@", "/"))
45
+ if os.path.isdir(dep_path):
46
+ return
47
+ else:
48
+ cmd = f"conan cache path {self.comp}"
49
+ ret = self.tools.run_command(cmd, capture_output=True, ignore_error=True)
50
+ if ret.returncode == 0:
51
+ return
46
52
  self.tools.download_conan_recipes(self.comp, self.remote_list)
47
53
 
48
54
 
@@ -123,17 +129,26 @@ class ComponentHelper:
123
129
  @staticmethod
124
130
  def download_recipes(depdencies: List[str], tools: Tools, remote_list):
125
131
  pools = []
132
+ ignore_error = os.getenv("CLOUD_BUILD_IGNORE_ERROR")
126
133
  for dep in depdencies:
127
134
  task = DownloadComponentRecipe(tools, dep, remote_list)
128
135
  task.start()
129
136
  pools.append(task)
130
-
137
+ # 减少并发数,避免CI场景连接过多导致服务器无法处理导致的失败
138
+ while len(pools) > 4:
139
+ time.sleep(0.1)
140
+ for pool in pools.copy():
141
+ if pool.is_alive():
142
+ continue
143
+ if pool.exitcode is not None and pool.exitcode != 0 and not ignore_error:
144
+ tools.log.warning(f"下载组件 ({pool.comp}) 的构建配方(recipe)失败, 退出码: {pool.exitcode}")
145
+ pools.remove(pool)
131
146
  while pools:
132
147
  time.sleep(0.1)
133
148
  for pool in pools.copy():
134
149
  if pool.is_alive():
135
150
  continue
136
- if pool.exitcode is not None and pool.exitcode != 0:
151
+ if pool.exitcode is not None and pool.exitcode != 0 and not ignore_error:
137
152
  raise BmcGoException(f"下载组件 ({pool.comp}) 的构建配方(recipe)失败, 退出码: {pool.exitcode}")
138
153
  pools.remove(pool)
139
154
 
@@ -144,18 +159,31 @@ class ComponentHelper:
144
159
  dependencies = set()
145
160
  tempfile = NamedTemporaryFile()
146
161
  for comp in components:
147
- if not re.match(ComponentHelper.CONAN_PAKCAGE_RE, comp):
148
- raise BmcGoException(f"组件 {comp} 不符合正则 {ComponentHelper.CONAN_PAKCAGE_RE}")
149
- cmd = f'conan info "{comp}" --remote {remote} --json {tempfile.name}'
162
+ if misc.conan_v1():
163
+ if not re.match(ComponentHelper.CONAN_PAKCAGE_RE, comp):
164
+ raise BmcGoException(f"组件 {comp} 不符合正则 {ComponentHelper.CONAN_PAKCAGE_RE}")
165
+ cmd = f'conan info "{comp}" --remote {remote} --json {tempfile.name}'
166
+ else:
167
+ if not misc.conan_package_match(comp):
168
+ raise BmcGoException(f"组件 {comp} 不符合正则 {misc.CONAN_NAME_RESTR}")
169
+ cmd = f'conan graph info --requires="{comp}" --remote {remote} -f json --out-file={tempfile.name}'
150
170
  tools.run_command(cmd)
151
171
 
152
172
  file_handler = open(tempfile.name, "r")
153
173
  conan_comps = json.load(file_handler)
154
- for conan_comp in conan_comps:
155
- comp_ref = conan_comp.get("reference", "")
156
- if not comp_ref or comp_ref == comp:
157
- continue
158
- dependencies.add(comp_ref)
174
+ if misc.conan_v1():
175
+ for conan_comp in conan_comps:
176
+ comp_ref = conan_comp.get("reference", "")
177
+ if not comp_ref or comp_ref == comp:
178
+ continue
179
+ dependencies.add(comp_ref)
180
+ else:
181
+ deps = conan_comps.get("graph", {}).get("nodes", {}).get("0", {}).get("dependencies", {})
182
+ for _, conan_comp in deps.items():
183
+ comp_ref = conan_comp.get("ref", "")
184
+ if not comp_ref or comp_ref == comp:
185
+ continue
186
+ dependencies.add(comp_ref)
159
187
  file_handler.close()
160
188
 
161
189
  return list(dependencies)
@@ -164,5 +192,5 @@ class ComponentHelper:
164
192
  def get_user_channel(stage: str):
165
193
  if stage == misc.StageEnum.STAGE_DEV.value:
166
194
  stage = misc.StageEnum.STAGE_RC.value
167
- user_channel = f"@{Tools().conan_user}/{stage}"
195
+ user_channel = f"@{misc.conan_user()}/{stage}"
168
196
  return user_channel
@@ -85,9 +85,9 @@ class GcovHTMLParser(HTMLParser):
85
85
  for a in attrs:
86
86
  if a == ("class", "lineNum"):
87
87
  self.is_line_num = True
88
- if a == ("class", "lineNoCov"):
88
+ if a == ("class", "lineNoCov") or a == ("class", "tlaUNC"):
89
89
  self.uncovers.append(self.line_num)
90
- if a == ("class", "lineCov"):
90
+ if a == ("class", "lineCov") or a == ("class", "tlaGNC"):
91
91
  self.covers.append(self.line_num)
92
92
 
93
93
  def handle_data(self, data):
bmcgo/component/deploy.py CHANGED
@@ -12,6 +12,7 @@
12
12
  import os
13
13
  import shutil
14
14
  import stat
15
+ import json
15
16
  import yaml
16
17
 
17
18
  from mako.lookup import TemplateLookup
@@ -28,6 +29,24 @@ log = Logger("deploy")
28
29
  cwd_script = os.path.split(os.path.realpath(__file__))[0]
29
30
 
30
31
 
32
+ class GraphNode:
33
+ def __init__(self, node):
34
+ if not node:
35
+ self.name = None
36
+ self.package_folder = None
37
+ self.recipe_folder = None
38
+ self.package_id = None
39
+ self.ref = None
40
+ self.node = node
41
+ return
42
+ self.name = node.get("name")
43
+ self.package_folder = node.get("package_folder")
44
+ self.recipe_folder = node.get("recipe_folder")
45
+ self.package_id = node.get("package_id")
46
+ self.ref = node.get("ref")
47
+ self.node = node
48
+
49
+
31
50
  class DeployComp():
32
51
  def __init__(self, bconfig: BmcgoConfig, info: InfoComp = None):
33
52
  self.info: InfoComp = info
@@ -35,6 +54,19 @@ class DeployComp():
35
54
  self.folder = bconfig.component.folder
36
55
  os.chdir(self.folder)
37
56
  self.temp_path = os.path.join(self.folder, "temp")
57
+ self.graph_nodes: dict[str, GraphNode] = {}
58
+
59
+ @staticmethod
60
+ def copy_packages_v1(install_path, rootfs_path):
61
+ for sub_dir in os.listdir(install_path):
62
+ dir_path = os.path.join(install_path, sub_dir)
63
+ if os.path.isfile(dir_path):
64
+ os.unlink(dir_path)
65
+ continue
66
+ for file in os.listdir(dir_path):
67
+ source = os.path.join(dir_path, file)
68
+ cmd = ["/usr/bin/cp", "-arf", source, rootfs_path]
69
+ Helper.run(cmd)
38
70
 
39
71
  def get_dt_dependencies(self):
40
72
  user_channel = ComponentHelper.get_user_channel(self.info.stage)
@@ -61,12 +93,15 @@ class DeployComp():
61
93
  return dependencies
62
94
 
63
95
  def gen_conanfile(self):
64
- dependencies = [f"{self.info.name}/{self.info.version}{self.info.channel}"]
65
- if self.info.build_type == "dt":
96
+ dependencies = self.info.package
97
+ if self.info.test:
66
98
  dependencies += self.get_dt_dependencies()
67
99
 
68
100
  # 构建虚拟deploy组件,生成conanfile.py文件
69
- lookup = TemplateLookup(directories=os.path.join(cwd_script, "template"))
101
+ if misc.conan_v1():
102
+ lookup = TemplateLookup(directories=os.path.join(cwd_script, "template"))
103
+ else:
104
+ lookup = TemplateLookup(directories=os.path.join(cwd_script, "template_v2"))
70
105
  template = lookup.get_template("conanfile.deploy.py.mako")
71
106
  conanfile = template.render(lookup=lookup, pkg=self.info, dependencies=dependencies)
72
107
  file_handler = os.fdopen(os.open("conanfile.py", os.O_WRONLY | os.O_CREAT | os.O_TRUNC,
@@ -74,6 +109,25 @@ class DeployComp():
74
109
  file_handler.write(conanfile)
75
110
  file_handler.close()
76
111
 
112
+ def copy_packages_v2(self, graph_file, rootfs_path=None):
113
+ if not rootfs_path:
114
+ rootfs_path = self.temp_path
115
+ with open(graph_file, "r") as file_handler:
116
+ package_info = json.load(file_handler)
117
+ nodes: dict[str, dict] = package_info.get("graph", {}).get("nodes", {})
118
+ self.graph_nodes = {}
119
+ for _, node in nodes.items():
120
+ if node.get("context") != "host":
121
+ continue
122
+ gn = GraphNode(node)
123
+ self.graph_nodes[gn.name] = gn
124
+ if not gn.package_folder:
125
+ continue
126
+ for file in os.listdir(gn.package_folder):
127
+ source = os.path.join(gn.package_folder, file)
128
+ cmd = ["/usr/bin/cp", "-arf", source, rootfs_path]
129
+ Helper.run(cmd)
130
+
77
131
  def run(self):
78
132
  # 生成虚拟deploy组件,仅用于安装
79
133
  deploy_conan = os.path.join(self.temp_path, ".deploy")
@@ -86,8 +140,13 @@ class DeployComp():
86
140
  log.info("安装所有依赖到目录 %s", install_path)
87
141
  shutil.rmtree(install_path, ignore_errors=True)
88
142
  cmd = [misc.CONAN, "install"]
89
- append_cmd = ("%s -if=%s -g deploy" % (self.info.cmd_base, install_path))
90
- append_cmd = append_cmd.replace(self.info.package, self.info.channel)
143
+ graph_file = "package.info.json"
144
+ if misc.conan_v2():
145
+ append_cmd = ("%s -of=%s -d=full_deploy -f json --out-file=%s" %
146
+ (self.info.cmd_base, install_path, graph_file))
147
+ else:
148
+ append_cmd = ("%s -if=%s -g deploy" % (self.info.cmd_base, install_path))
149
+ append_cmd = append_cmd.replace(self.info.package, self.info.channel)
91
150
  cmd += append_cmd.split()
92
151
  cmd.append("--build=missing")
93
152
  log.success("运行部署命令: %s", " ".join(cmd))
@@ -96,13 +155,8 @@ class DeployComp():
96
155
  rootfs_path = self.temp_path
97
156
  log.info("复制所有依赖到目录 %s", rootfs_path)
98
157
  os.makedirs(rootfs_path, exist_ok=True)
99
- for sub_dir in os.listdir(install_path):
100
- dir_path = os.path.join(install_path, sub_dir)
101
- if os.path.isfile(dir_path):
102
- os.unlink(dir_path)
103
- continue
104
- for file in os.listdir(dir_path):
105
- source = os.path.join(dir_path, file)
106
- cmd = ["/usr/bin/cp", "-arf", source, rootfs_path]
107
- Helper.run(cmd)
158
+ if misc.conan_v2():
159
+ self.copy_packages_v2(graph_file, rootfs_path)
160
+ else:
161
+ self.copy_packages_v1(install_path, rootfs_path)
108
162
  shutil.rmtree(install_path, ignore_errors=True)
bmcgo/component/gen.py CHANGED
@@ -107,7 +107,7 @@ class GenComp():
107
107
  def run(self, base_version=-1):
108
108
  language = ComponentHelper.get_language().lower()
109
109
  parser = argparse.ArgumentParser(description="代码自动生成.",
110
- prog="bingo gen/当前只支持C和lua语言代码生成",
110
+ prog=f"{misc.tool_name()} gen/当前只支持C和lua语言代码生成",
111
111
  formatter_class=SmartFormatter)
112
112
  parser.add_argument("-v", "--version", help="use specified version", type=int, default=-1)
113
113
  parser.add_argument("-r", "--remote", help="conan remote, 如不设置则默认读取本地conan配置")
@@ -22,9 +22,11 @@ from bmcgo.codegen import __version__ as codegen_version
22
22
  from bmcgo.logger import Logger
23
23
  from bmcgo.utils.tools import Tools
24
24
  from bmcgo import misc
25
+ from bmcgo import errors
25
26
  from bmcgo.component.component_helper import ComponentHelper
26
27
 
27
28
  global log
29
+ tools = Tools()
28
30
  log = Logger()
29
31
 
30
32
  cwd = os.getcwd()
@@ -40,22 +42,28 @@ class CodegenPolicyError(OSError):
40
42
 
41
43
 
42
44
  class InfoComp():
43
- def __init__(self, args=None, service_json="mds/service.json", partner_mode=False):
44
- parser = self.arg_parser(True, partner_mode)
45
+ def __init__(self, args=None, service_json="mds/service.json", partner_mode=False, enable_upload=True):
46
+ self.enable_upload = enable_upload
47
+ self.package = ""
48
+ self.setting = ""
49
+ self.full_profile = ""
50
+ self.cmd_base = ""
51
+ parser = self.arg_parser(True, partner_mode, enable_upload)
45
52
  self.parse_args(parser, args, service_json)
46
53
 
47
54
  @staticmethod
48
- def arg_parser(add_help=False, partner_mode=False):
55
+ def arg_parser(add_help=False, partner_mode=False, enable_upload=True):
49
56
  stage_values = [member.value for member in misc.StageEnum]
50
- parser = argparse.ArgumentParser(prog="bingo build", description="Build conan", add_help=add_help,
57
+ parser = argparse.ArgumentParser(prog=f"{misc.tool_name()} build", description="Build conan", add_help=add_help,
51
58
  formatter_class=argparse.RawTextHelpFormatter)
52
- parser.add_argument("-bt", "--build_type", default="debug", help="构建类型,可选:dt,debug,release\n默认:debug")
59
+ parser.add_argument("-bt", "--build_type", default="debug", help=f"构建类型,可选:{misc.build_type_str()}\n默认:debug")
53
60
  parser.add_argument(
54
- "--stage",
55
- help=f"组件包发布阶段, 可选: {stage_values}\n默认:{misc.StageEnum.STAGE_DEV.value}",
61
+ "--stage",
62
+ help=f"组件包发布阶段, 可选: {stage_values}\n默认:{misc.StageEnum.STAGE_DEV.value}",
56
63
  default=misc.StageEnum.STAGE_DEV.value
57
64
  )
58
- parser.add_argument("-u", "--upload", action=misc.STORE_TRUE, help="上传组件包到conan仓")
65
+ if enable_upload:
66
+ parser.add_argument("-u", "--upload", action=misc.STORE_TRUE, help="上传组件包到conan仓")
59
67
  parser.add_argument(
60
68
  "-r", "--remote", help=f"conan仓别名,请检查conan remote list查看已配置的conan仓"
61
69
  )
@@ -71,14 +79,19 @@ class InfoComp():
71
79
  )
72
80
  parser.add_argument("-nc", "--no_cache",
73
81
  help="不使用~/.conan/data目录下的缓存包(构建前删除缓存)", action=misc.STORE_FALSE)
74
- parser.add_argument("-o", "--options", help="Define options values (host machine), e.g.: -o Pkg:with_qt=true",
75
- action='append', default=[])
82
+ if misc.conan_v2():
83
+ parser.add_argument("-o", "--options", action='append', default=[],
84
+ help="Define options values (host machine), e.g.: -o Pkg/*:with_qt=True")
85
+ else:
86
+ parser.add_argument("-o", "--options", action='append', default=[],
87
+ help="Define options values (host machine), e.g.: -o Pkg:with_qt=True")
76
88
  parser.add_argument(
77
89
  "--user",
78
- help=f"指定conan包的user字段,尝试从{misc.GLOBAL_CFG_FILE}文件读取conan.user字段,否则由程序管理",
90
+ help=f"指定conan包的user字段,未指定时依次尝试读取mds/service.json的user字段,都未指定时使用'{misc.conan_user()}'",
79
91
  default=None
80
92
  )
81
93
  parser.add_argument("-cov", "--coverage", help=argparse.SUPPRESS, action=misc.STORE_TRUE)
94
+ parser.add_argument("-test", "--test", help=argparse.SUPPRESS, action=misc.STORE_TRUE)
82
95
  parser.add_argument(
83
96
  "-as",
84
97
  "--asan",
@@ -92,11 +105,14 @@ class InfoComp():
92
105
  help=argparse.SUPPRESS if partner_mode else Tools.get_profile_arg_help(),
93
106
  default="",
94
107
  )
108
+ profile_name = tools.get_conan_profile("", "", True)
109
+ profile_file = os.path.join(tools.conan_profiles_dir, profile_name)
110
+ default_enable_luajit = partner_mode and os.path.isfile(profile_file)
95
111
  parser.add_argument(
96
112
  "-jit",
97
113
  "--enable_luajit",
98
- help=argparse.SUPPRESS if partner_mode else "Enable luajit",
99
- action=misc.STORE_FALSE if partner_mode else misc.STORE_TRUE,
114
+ help=argparse.SUPPRESS if default_enable_luajit else "Enable luajit",
115
+ action=misc.STORE_FALSE if default_enable_luajit else misc.STORE_TRUE,
100
116
  )
101
117
  return parser
102
118
 
@@ -104,7 +120,9 @@ class InfoComp():
104
120
  def get_codegen_policy(service_data) -> Tuple[str, int]:
105
121
  # 代码自动生成工具版本号检查
106
122
  policy = ComponentHelper.get_config_value(service_data, "codegen_policy", {})
107
- code_version = policy.get("version", ">=0")
123
+ if "codeGenPolicy" in service_data:
124
+ policy = ComponentHelper.get_config_value(service_data, "codeGenPolicy", {})
125
+ code_version = policy.get("version", "3")
108
126
  if not isinstance(code_version, str):
109
127
  code_version = str(code_version)
110
128
  code_language = policy.get("language", "c")
@@ -116,54 +134,80 @@ class InfoComp():
116
134
  if code_version.startswith(">="):
117
135
  codegen_base_version = int(code_version[2:])
118
136
  if codegen_base_version > codegen_version:
119
- raise CodegenVersionNotMatchError("代码自动生成要求的版本号大于当前bmcgo工具提供的版本号,建议升级到最新版本")
137
+ raise CodegenVersionNotMatchError(f"代码自动生成要求的版本号大于当前{misc.tool_name()}工具提供的版本号,建议升级到最新版本")
120
138
  codegen_base_version = codegen_version
121
139
  else:
122
140
  codegen_base_version = int(code_version)
123
141
  return code_language, codegen_base_version
124
142
 
143
+ @staticmethod
144
+ def get_dependencies_v2(service_data, key):
145
+ dependencies = []
146
+ user_channel = f"@{misc.conan_user()}/stable"
147
+ deps = ComponentHelper.get_config_value(service_data, key, [])
148
+ for dep in deps:
149
+ conan = dep.get(misc.CONAN)
150
+ if conan is None:
151
+ log.info("获取 conan 依赖失败, 跳过未知组件")
152
+ continue
153
+ if conan.find("@") < 0:
154
+ conan += user_channel
155
+ if not misc.conan_package_match(conan, True):
156
+ raise errors.BmcGoException(f"未正确定义依赖组件的名称: {conan}")
157
+ dependencies.append(conan)
158
+
159
+ return dependencies
160
+
125
161
  def parse_args(self, parser, args, service_json):
126
162
  self.args, _ = parser.parse_known_args(args)
127
163
  self.build_type = self.args.build_type
128
164
  self.stage = self.args.stage
129
- self.upload = self.args.upload
165
+ if self.enable_upload:
166
+ self.upload = self.args.upload
167
+ else:
168
+ self.upload = False
130
169
  self.from_source = self.args.from_source
131
170
  self.options = self.args.options
132
171
  self.coverage = self.args.coverage
133
172
  self.asan = self.args.asan
134
173
  self.remote = self.args.remote
174
+ self.user = self.args.user
175
+ self.test = self.args.test
135
176
  self.no_cache = self.args.no_cache and (not os.getenv('NOT_CLEAN_CONAN_CACHE') == 'True')
136
177
  # 是否是维护模式
137
178
  self.is_maintain = self.args.maintain
138
179
  self.enable_luajit = self.args.enable_luajit
139
- self.profile = Tools.get_conan_profile(self.args.profile, self.build_type, self.enable_luajit)
180
+ self.profile = Tools.get_conan_profile(self.args.profile, self.build_type, self.enable_luajit, self.test)
181
+ if self.profile == "profile.luajit.ini":
182
+ self.enable_luajit = True
140
183
 
141
184
  os.environ["ROOTFS_DIR"] = os.path.join(cwd, "temp")
142
185
  stage_values = [member.value for member in misc.StageEnum]
143
186
  if self.stage not in stage_values:
144
187
  raise OSError(f"参数 stage 错误, 请从 {stage_values} 中选择")
145
188
  # 构建阶段检查
146
- build_types = ["dt", "debug", "release"]
147
- if self.build_type not in build_types:
148
- raise OSError("参数 build_type 错误, 请从 [debug, release, dt] 中选择")
189
+ if self.build_type not in misc.build_type():
190
+ raise OSError(f"参数 build_type 错误, 请从 {misc.build_type_str()} 中选择")
149
191
  if self.upload and not self.remote:
150
192
  raise OSError("参数 remote 必填")
151
193
 
152
- # 只有指定为pre时才增加prerelease编码
153
- pre = ""
154
- if self.stage == misc.StageEnum.STAGE_PRE:
155
- self.stage = misc.StageEnum.STAGE_DEV
156
- now = datetime.datetime.utcnow()
157
- pre = "-pre." + now.strftime("%Y%m%d%H%M%S")
194
+ if misc.conan_v1():
195
+ # 只有指定为pre时才增加prerelease编码
196
+ pre = ""
197
+ if self.stage == misc.StageEnum.STAGE_PRE:
198
+ self.stage = misc.StageEnum.STAGE_DEV
199
+ now = datetime.datetime.utcnow()
200
+ pre = "-pre." + now.strftime("%Y%m%d%H%M%S")
158
201
 
159
- # 尝试从/etc/bmcgo.conf读取user配置
160
- user = self._get_package_user()
161
- self.channel = f"@{user}/{self.stage}"
162
-
163
- self._parse_service_json(service_json, pre)
202
+ # 尝试从/etc/bmcgo.conf读取user配置
203
+ user = self._get_package_user()
204
+ self.channel = f"@{user}/{self.stage}"
205
+ self._parse_service_json(service_json, pre)
206
+ else:
207
+ self._parse_service_json(service_json)
164
208
  self._conan_define()
165
209
 
166
- def get_dependencies(self, service_data, key):
210
+ def get_dependencies_v1(self, service_data, key):
167
211
  dependencies = []
168
212
  user_channel = ComponentHelper.get_user_channel(self.stage)
169
213
  deps = ComponentHelper.get_config_value(service_data, key, [])
@@ -178,14 +222,51 @@ class InfoComp():
178
222
  dependencies.append(conan + user_channel)
179
223
  return dependencies
180
224
 
225
+ def get_dependencies(self, service_data, key):
226
+ if misc.conan_v1():
227
+ return self.get_dependencies_v1(service_data, key)
228
+ else:
229
+ return self.get_dependencies_v2(service_data, key)
230
+
181
231
  def _conan_define(self):
232
+ if misc.conan_v1():
233
+ self._conan_define_v1()
234
+ else:
235
+ self._conan_define_v2()
236
+
237
+ def _conan_define_v2(self):
238
+ self.package = "%s/%s@%s/%s" % (self.name, self.version, self.user, self.stage)
239
+ profiles = [f"-pr:h {self.profile}"]
240
+ profiles.append("-pr:b default")
241
+ if self.enable_luajit:
242
+ self.options.append("*/*:enable_luajit=True")
243
+ if self.build_type == "debug":
244
+ self.setting = "-s:a build_type=Debug"
245
+ else:
246
+ self.setting = "-s:a build_type=Release"
247
+ self.full_profile = " ".join(profiles)
248
+ self.cmd_base = ". %s %s " % (self.full_profile, self.setting)
249
+ self.cmd_base += "%s %s " % (f"--user {self.user}", f"--channel {self.stage}")
250
+ if self.remote:
251
+ self.cmd_base += "-r %s " % self.remote
252
+ if self.options:
253
+ for option in self.options:
254
+ self.cmd_base += " -o " + option
255
+ if self.coverage:
256
+ self.cmd_base += f" -o {self.name}/*:gcov=True"
257
+ if self.asan:
258
+ self.cmd_base += f" -o {self.name}/*:asan=True"
259
+ if self.test:
260
+ self.cmd_base += f" -o */*:test=True"
261
+
262
+ def _conan_define_v1(self):
182
263
  self.package = "%s/%s%s" % (self.name, self.version, self.channel)
183
264
  profiles = [f"-pr:h {self.profile}"]
184
265
  if self.build_type == "dt":
185
266
  self.setting = "-s build_type=Dt"
186
267
  else:
187
268
  profiles.append("-pr:b profile.dt.ini")
188
- if self.enable_luajit:
269
+ if self.enable_luajit or misc.community_name() == "openubmc":
189
270
  self.options.append("skynet:enable_luajit=True")
190
271
  if self.build_type == "debug":
191
272
  self.setting = "-s build_type=Debug"
@@ -215,17 +296,26 @@ class InfoComp():
215
296
  user = None
216
297
  if user is None:
217
298
  if self.stage == misc.StageEnum.STAGE_DEV.value:
218
- user = misc.ConanUserEnum.CONAN_USER_DEV.value
299
+ user = misc.conan_user_dev()
219
300
  else:
220
- user = misc.ConanUserEnum.CONAN_USER_RELEASE.value
301
+ user = misc.conan_user()
221
302
  return user
222
303
 
223
- def _parse_service_json(self, service_json: str, pre: str):
304
+ def _parse_service_json(self, service_json: str, pre: str = ""):
224
305
  self.language = ComponentHelper.get_language(service_json=service_json)
225
306
  with open(service_json, "r", encoding="UTF-8") as file_handler:
226
307
  data = json.load(file_handler)
227
- self.version = ComponentHelper.get_config_value(data, "version") + pre
228
- self.name = data.get("name")
308
+ if misc.conan_v2():
309
+ self.language = data.get("language", "lua")
310
+ if not self.user:
311
+ self.user = data.get("user", misc.conan_user()).lower()
312
+ if self.stage == "dev":
313
+ self.user += ".dev"
314
+ self.version = ComponentHelper.get_config_value(data, "version").lower()
315
+ self.name = data.get("name").lower()
316
+ else:
317
+ self.version = ComponentHelper.get_config_value(data, "version") + pre
318
+ self.name = data.get("name")
229
319
  # 编译依赖
230
320
  self.build_dependencies = self.get_dependencies(data, "dependencies/build")
231
321
  # 开发者测试依赖