openubmc-bingo 0.5.277__py3-none-any.whl → 0.6.2__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 +95 -39
- bmcgo/cli/config.conan2.yaml +9 -0
- bmcgo/codegen/lua/codegen.py +2 -2
- 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/conanbase.py.mako +1 -0
- bmcgo/component/template_v2/conanbase.py.mako +383 -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 +96 -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 +425 -53
- 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 +75 -16
- 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.2.dist-info}/METADATA +4 -2
- {openubmc_bingo-0.5.277.dist-info → openubmc_bingo-0.6.2.dist-info}/RECORD +53 -46
- {openubmc_bingo-0.5.277.dist-info → openubmc_bingo-0.6.2.dist-info}/WHEEL +0 -0
- {openubmc_bingo-0.5.277.dist-info → openubmc_bingo-0.6.2.dist-info}/entry_points.txt +0 -0
- {openubmc_bingo-0.5.277.dist-info → openubmc_bingo-0.6.2.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# coding: utf-8
|
|
3
|
+
# Copyright (c) 2025 Huawei Technologies Co., Ltd.
|
|
4
|
+
# openUBMC is licensed under Mulan PSL v2.
|
|
5
|
+
# You can use this software according to the terms and conditions of the Mulan PSL v2.
|
|
6
|
+
# You may obtain a copy of Mulan PSL v2 at:
|
|
7
|
+
# http://license.coscl.org.cn/MulanPSL2
|
|
8
|
+
# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
|
9
|
+
# EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
|
10
|
+
# MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
|
11
|
+
# See the Mulan PSL v2 for more details.
|
|
12
|
+
import argparse
|
|
13
|
+
import datetime
|
|
14
|
+
import json
|
|
15
|
+
import os
|
|
16
|
+
import re
|
|
17
|
+
import sys
|
|
18
|
+
from datetime import timezone, timedelta
|
|
19
|
+
from typing import List, Tuple, Dict, Optional, Any
|
|
20
|
+
from git import Repo, Commit, Diff
|
|
21
|
+
from git.exc import InvalidGitRepositoryError, GitCommandError
|
|
22
|
+
from bmcgo import misc
|
|
23
|
+
from bmcgo.utils.tools import Tools
|
|
24
|
+
from bmcgo.bmcgo_config import BmcgoConfig
|
|
25
|
+
from bmcgo import errors
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
tools = Tools()
|
|
29
|
+
log = tools.log
|
|
30
|
+
beijing_timezone = timezone(timedelta(hours=8))
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
command_info: misc.CommandInfo = misc.CommandInfo(
|
|
34
|
+
group=misc.GRP_COMP,
|
|
35
|
+
name="git_history",
|
|
36
|
+
description=["获取指定开始时间与结束时间之间提交信息,并生成release note"],
|
|
37
|
+
hidden=False
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def if_available(bconfig: BmcgoConfig):
|
|
42
|
+
if bconfig.component is None:
|
|
43
|
+
return False
|
|
44
|
+
return True
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
class BmcgoCommand:
|
|
48
|
+
def __init__(self, bconfig: BmcgoConfig, *args):
|
|
49
|
+
self.bconfig = bconfig
|
|
50
|
+
parser = argparse.ArgumentParser(prog="bmcgo git_history", description="生成Git仓库的Release Note", add_help=True,
|
|
51
|
+
formatter_class=argparse.RawTextHelpFormatter)
|
|
52
|
+
parser.add_argument("--start_date", "-s", help="起始日期YYYY-MM-DD", required=True)
|
|
53
|
+
parser.add_argument("--end_date", "-e", help="结束日期YYYY-MM-DD,默认为当前日期")
|
|
54
|
+
args, kwargs = parser.parse_known_args(*args)
|
|
55
|
+
self.start_date = args.start_date
|
|
56
|
+
self.end_date = args.end_date
|
|
57
|
+
self.output_file = f"./{self.start_date}_{self.end_date}_releaseNote.log"
|
|
58
|
+
self.service_json_path = "mds/service.json"
|
|
59
|
+
self.repo = Repo(".")
|
|
60
|
+
|
|
61
|
+
@staticmethod
|
|
62
|
+
def validate_date(date_str: str) -> datetime.datetime:
|
|
63
|
+
try:
|
|
64
|
+
date = datetime.datetime.strptime(date_str, "%Y-%m-%d")
|
|
65
|
+
except ValueError as e:
|
|
66
|
+
raise errors.BmcGoException(f"日期格式不正确: {date_str},请使用YYYY-MM-DD格式,错误信息{e}")
|
|
67
|
+
current_date = datetime.datetime.now(beijing_timezone)
|
|
68
|
+
if date.date() > current_date.date():
|
|
69
|
+
raise errors.BmcGoException(f"日期 {date_str} 超过当前日期")
|
|
70
|
+
return date
|
|
71
|
+
|
|
72
|
+
@staticmethod
|
|
73
|
+
def extract_version_from_diff(self, diff: Diff) -> Optional[str]:
|
|
74
|
+
try:
|
|
75
|
+
diff_text = diff.diff.decode('utf-8') if diff.diff else str(diff)
|
|
76
|
+
version_pattern = r'[-+]\s*"version"\s*:\s*"([^"]+)"'
|
|
77
|
+
matches = re.findall(version_pattern, diff_text)
|
|
78
|
+
if matches:
|
|
79
|
+
return matches[-1]
|
|
80
|
+
except (UnicodeDecodeError, AttributeError):
|
|
81
|
+
pass
|
|
82
|
+
return None
|
|
83
|
+
|
|
84
|
+
@staticmethod
|
|
85
|
+
def is_merge_into_main(s):
|
|
86
|
+
pattern = r'^merge .+ into main$'
|
|
87
|
+
# 使用re.match进行匹配,忽略大小写
|
|
88
|
+
match = re.match(pattern, s, re.IGNORECASE)
|
|
89
|
+
return match is not None
|
|
90
|
+
|
|
91
|
+
def get_current_version(self) -> str:
|
|
92
|
+
try:
|
|
93
|
+
with open(self.service_json_path, 'r') as f:
|
|
94
|
+
service_data = json.load(f)
|
|
95
|
+
return service_data.get('version', 'unknown')
|
|
96
|
+
except (FileNotFoundError, json.JSONDecodeError) as e:
|
|
97
|
+
raise errors.BmcGoException(f"无法读取或解析 {self.service_json_path}: {e}")
|
|
98
|
+
|
|
99
|
+
def get_commits_in_range(self, start_date: str, end_date: str) -> List[Commit]:
|
|
100
|
+
start_dt = self.validate_date(start_date)
|
|
101
|
+
if end_date is None:
|
|
102
|
+
end_dt = datetime.datetime.now(beijing_timezone)
|
|
103
|
+
else:
|
|
104
|
+
try:
|
|
105
|
+
end_dt = self.validate_date(end_date)
|
|
106
|
+
except errors.BmcGoException as e:
|
|
107
|
+
if "超过当前日期" in str(e):
|
|
108
|
+
log.warning(f"警告: {e},将使用当前日期作为结束日期")
|
|
109
|
+
end_dt = datetime.datetime.now(beijing_timezone).replace(tzinfo=None)
|
|
110
|
+
else:
|
|
111
|
+
raise
|
|
112
|
+
if end_dt < start_dt:
|
|
113
|
+
raise errors.BmcGoException("结束日期不能早于起始日期")
|
|
114
|
+
since_str = start_dt.strftime("%Y-%m-%d")
|
|
115
|
+
until_str = end_dt.strftime("%Y-%m-%d")
|
|
116
|
+
try:
|
|
117
|
+
commits = list(self.repo.iter_commits(
|
|
118
|
+
since=since_str,
|
|
119
|
+
until=until_str
|
|
120
|
+
))
|
|
121
|
+
except GitCommandError as e:
|
|
122
|
+
raise errors.BmcGoException(f"获取commit记录时出错: {e}")
|
|
123
|
+
return commits
|
|
124
|
+
|
|
125
|
+
def get_version_from_commit(self, commit_hash: str) -> Optional[str]:
|
|
126
|
+
try:
|
|
127
|
+
commit = self.repo.commit(commit_hash)
|
|
128
|
+
try:
|
|
129
|
+
file_content = (commit.tree / self.service_json_path).data_stream.read().decode('utf-8')
|
|
130
|
+
data = json.loads(file_content)
|
|
131
|
+
version = data.get('version')
|
|
132
|
+
return version
|
|
133
|
+
except (KeyError, AttributeError):
|
|
134
|
+
log.error(f"在commit {commit_hash} 中找不到文件: {self.service_json_path}")
|
|
135
|
+
return None
|
|
136
|
+
except json.JSONDecodeError:
|
|
137
|
+
log.error(f"在commit {commit_hash} 中的 {self.service_json_path} 文件不是有效的JSON格式")
|
|
138
|
+
return None
|
|
139
|
+
except Exception as e:
|
|
140
|
+
log.error(f"获取commit {commit_hash} 的版本信息时出错: {e}")
|
|
141
|
+
return None
|
|
142
|
+
|
|
143
|
+
def get_version_info_for_commits(self, commits: List[Commit]) -> Dict[str, Any]:
|
|
144
|
+
version_info = {
|
|
145
|
+
'current_version': self.get_current_version(),
|
|
146
|
+
'commit_versions': {}
|
|
147
|
+
}
|
|
148
|
+
# 按时间顺序处理commit(从旧到新)
|
|
149
|
+
for commit in reversed(commits):
|
|
150
|
+
try:
|
|
151
|
+
if not self.is_merge_into_main(str(commit.summary)):
|
|
152
|
+
continue
|
|
153
|
+
modified_version = self.get_version_from_commit(commit.hexsha)
|
|
154
|
+
message = commit.message.strip()
|
|
155
|
+
lines = message.splitlines()
|
|
156
|
+
if len(lines) >= 3:
|
|
157
|
+
message = lines[2]
|
|
158
|
+
version_info['commit_versions'][commit.hexsha] = {
|
|
159
|
+
'date': commit.committed_datetime.strftime("%Y-%m-%d"),
|
|
160
|
+
'message': message,
|
|
161
|
+
'version': modified_version if modified_version else version_info['current_version']
|
|
162
|
+
}
|
|
163
|
+
if modified_version:
|
|
164
|
+
version_info['current_version'] = modified_version
|
|
165
|
+
except Exception as e:
|
|
166
|
+
log.error(f"处理commit {commit.hexsha} 时出错: {e}")
|
|
167
|
+
message = commit.message.strip()
|
|
168
|
+
lines = message.splitlines()
|
|
169
|
+
if len(lines) >= 3:
|
|
170
|
+
message = lines[2]
|
|
171
|
+
version_info['commit_versions'][commit.hexsha] = {
|
|
172
|
+
'date': commit.committed_datetime.strftime("%Y-%m-%d"),
|
|
173
|
+
'message': message,
|
|
174
|
+
'version': version_info['current_version']
|
|
175
|
+
}
|
|
176
|
+
return version_info
|
|
177
|
+
|
|
178
|
+
def generate_release_note(self,
|
|
179
|
+
start_date: str,
|
|
180
|
+
end_date: str,
|
|
181
|
+
output_file: str) -> str:
|
|
182
|
+
release_note = f"从{start_date}至{end_date}特性提交如下:\n"
|
|
183
|
+
commits = self.get_commits_in_range(start_date, end_date)
|
|
184
|
+
if not commits:
|
|
185
|
+
try:
|
|
186
|
+
release_note += f"无更新\n"
|
|
187
|
+
with open(output_file, 'w', encoding='utf-8') as f:
|
|
188
|
+
f.write(release_note)
|
|
189
|
+
log.info(f"Release Note已保存到: {output_file}")
|
|
190
|
+
except IOError as e:
|
|
191
|
+
log.error(f"保存文件时出错: {e}")
|
|
192
|
+
version_info = self.get_version_info_for_commits(commits)
|
|
193
|
+
|
|
194
|
+
for commit in commits:
|
|
195
|
+
commit_info = version_info['commit_versions'].get(commit.hexsha, {})
|
|
196
|
+
if len(commit_info) == 0:
|
|
197
|
+
continue
|
|
198
|
+
release_note += f"-commit ID: {commit.hexsha}\n"
|
|
199
|
+
release_note += f"-修改描述: {commit_info.get('message')}\n"
|
|
200
|
+
release_note += f"-版本号: {commit_info.get('version')}\n"
|
|
201
|
+
release_note += f"-发布日期:{commit_info.get('date')}\n\n"
|
|
202
|
+
if output_file:
|
|
203
|
+
try:
|
|
204
|
+
with open(output_file, 'w', encoding='utf-8') as f:
|
|
205
|
+
f.write(release_note)
|
|
206
|
+
log.info(release_note)
|
|
207
|
+
log.info(f"Release Note已保存到: {output_file}")
|
|
208
|
+
except IOError as e:
|
|
209
|
+
log.error(f"保存文件时出错: {e}")
|
|
210
|
+
return release_note
|
|
211
|
+
|
|
212
|
+
def run(self):
|
|
213
|
+
try:
|
|
214
|
+
_ = self.generate_release_note(
|
|
215
|
+
start_date=self.start_date,
|
|
216
|
+
end_date=self.end_date,
|
|
217
|
+
output_file=self.output_file
|
|
218
|
+
)
|
|
219
|
+
except (ValueError, RuntimeError) as e:
|
|
220
|
+
log.error(f"错误: {e}")
|
bmcgo/functional/maintain.py
CHANGED
|
@@ -26,6 +26,7 @@ from bmcgo.component.build import BuildComp
|
|
|
26
26
|
from bmcgo import errors
|
|
27
27
|
from bmcgo.bmcgo_config import BmcgoConfig
|
|
28
28
|
from bmcgo import misc
|
|
29
|
+
from bmcgo import errors
|
|
29
30
|
|
|
30
31
|
tool = Tools("maintain")
|
|
31
32
|
log = tool.log
|
|
@@ -89,22 +90,33 @@ class BmcgoCommand:
|
|
|
89
90
|
def __init__(self, bconfig: BmcgoConfig, *args):
|
|
90
91
|
self.patch_file = []
|
|
91
92
|
self.bconfig = bconfig
|
|
92
|
-
parser = argparse.ArgumentParser(prog="
|
|
93
|
-
formatter_class=argparse.RawTextHelpFormatter)
|
|
94
|
-
|
|
93
|
+
parser = argparse.ArgumentParser(prog=f"{misc.tool_name()} maintain", description="BMC组件的维护管理工具",
|
|
94
|
+
add_help=True, formatter_class=argparse.RawTextHelpFormatter)
|
|
95
|
+
if misc.conan_v1():
|
|
96
|
+
parser.add_argument("-cp", "--conan_package", help="指定需要维护的组件版本,示例:component/1.2.3", required=True)
|
|
97
|
+
else:
|
|
98
|
+
parser.add_argument("-cp", "--conan_package",
|
|
99
|
+
help="指定需要维护的组件版本,示例:component/1.2.3@{misc.conan_user()}/stable", required=True)
|
|
95
100
|
parser.add_argument("-p", "--patch_file", help="添加patch文件,可指定多个,顺序追加到代码中", action='append')
|
|
96
101
|
parser.add_argument("-b", "--branch", help="用于提取patch的分支,与commit_id配合使用", default="master")
|
|
97
102
|
parser.add_argument("-c", "--commit_id", help="需要生成patch的提交节点,长度不低于8个字符,可指定多个,顺序追加到代码中",
|
|
98
103
|
action='append')
|
|
99
104
|
parser.add_argument("-v", "--version", help="指定需要生成的组件版本号", default=None)
|
|
100
|
-
parser.add_argument("-r", "--remote", default=misc.
|
|
105
|
+
parser.add_argument("-r", "--remote", default=misc.conan_remote(),
|
|
101
106
|
help="conan远程仓,请检查conan remote list查看已配置的conan仓")
|
|
102
107
|
parsed_args = parser.parse_args(*args)
|
|
103
108
|
cp = parsed_args.conan_package
|
|
104
|
-
if
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
109
|
+
if misc.conan_v1():
|
|
110
|
+
if (not re.match("^[a-zA-Z0-9_-]+/([1-9][0-9]*|[0-9])\.[0-9]+\.[0-9]+$", cp) and
|
|
111
|
+
not re.match("^[a-zA-Z0-9_-]+/(([1-9][0-9]*|[0-9])\.[0-9]+\.[0-9]+)(-build\.[0-9]+)$", cp) and
|
|
112
|
+
not re.match("^[a-zA-Z0-9_-]+/(([1-9][0-9]*|[0-9])\.[0-9]+\.[0-9]+)(.p[0-9]+)$" + cp)):
|
|
113
|
+
raise errors.BmcGoException("-cp参数错误,不满足格式\"<name>/<version>\"要求")
|
|
114
|
+
else:
|
|
115
|
+
restr = misc.CONAN_NAME_RESTR
|
|
116
|
+
if (not re.match(f"^{restr}/([1-9][0-9]*|[0-9])\.[0-9]+\.[0-9]+@{restr}/{restr}$", cp) and
|
|
117
|
+
not re.match(f"^{restr}/(([1-9][0-9]*|[0-9])\.[0-9]+\.[0-9]+)(-build\.[0-9]+)@{restr}/{restr}$", cp) and
|
|
118
|
+
not re.match(f"^{restr}/(([1-9][0-9]*|[0-9])\.[0-9]+\.[0-9]+)(.p[0-9]+)@{restr}/{restr}$" + cp)):
|
|
119
|
+
raise errors.BmcGoException("-cp参数错误,不满足格式\"<name>/<version>@user/channel\"要求")
|
|
108
120
|
self.conan_package = cp
|
|
109
121
|
self.name = self.conan_package.split("/")[0]
|
|
110
122
|
self.base_version = self.conan_package.split("/")[1]
|
|
@@ -127,7 +139,7 @@ class BmcgoCommand:
|
|
|
127
139
|
if re.match(r"^[a-f0-9]{8,40}$", commit) is None:
|
|
128
140
|
raise errors.ConfigException(f"参数错误, --commit_id({commit}) 格式错误")
|
|
129
141
|
self.patch_description = ""
|
|
130
|
-
self.dir = tempfile.TemporaryDirectory(prefix="
|
|
142
|
+
self.dir = tempfile.TemporaryDirectory(prefix="bingo_maint")
|
|
131
143
|
for file in self.patch_file:
|
|
132
144
|
if not os.path.isfile(file):
|
|
133
145
|
raise errors.BmcGoException(f"补丁文件 {file} 不存在")
|
|
@@ -182,11 +194,36 @@ class BmcgoCommand:
|
|
|
182
194
|
log.success(f"生成维护版本 {self.name}/{self.next_version} 成功")
|
|
183
195
|
return 0
|
|
184
196
|
|
|
185
|
-
def
|
|
186
|
-
|
|
197
|
+
def _fetch_conan_info_v2(self):
|
|
198
|
+
args = "--only-recipe" if misc.conan_v2() else "--recipe"
|
|
199
|
+
cmd = f"conan download {self.conan_package} -r {self.remote} {args}"
|
|
200
|
+
tool.run_command(cmd, error_log=f"组件 {self.conan_package} 未找到,请检查网络连接以及该版本是否已发布")
|
|
201
|
+
cmd = f"conan cache path {self.conan_package}"
|
|
202
|
+
export_path = tool.run_command(cmd, capture_output=True, shell=True).stdout.strip()
|
|
203
|
+
conanfile = os.path.join(export_path, "conanfile.py")
|
|
204
|
+
conandata = os.path.join(export_path, "conandata.yml")
|
|
205
|
+
if not os.path.isfile(conandata):
|
|
206
|
+
raise errors.BmcGoException(f"未找到组件 {self.conan_package} 的conandata.yml文件")
|
|
207
|
+
log.info(f"从 {conandata} 读取源码tag的url")
|
|
208
|
+
# 尝试从conandata中获取代码仓地址
|
|
209
|
+
with open(conandata, "r") as fp:
|
|
210
|
+
data = yaml.safe_load(fp)
|
|
211
|
+
cfg = data.get("sources", {}).get(self.base_version)
|
|
212
|
+
if cfg is None:
|
|
213
|
+
raise RuntimeError(f"${conandata}不存在组件 {self.conan_package} 配置, 请检查是否正确")
|
|
214
|
+
self.url = cfg.get("url")
|
|
215
|
+
self.tag = cfg.get("branch")
|
|
216
|
+
if re.match("^refs/tags/[0-9]+\\.[0-9]+\\.[0-9]+$", self.tag):
|
|
217
|
+
self.tag = self.tag[len("refs/tags/"):]
|
|
218
|
+
elif not self.tag:
|
|
219
|
+
self.tag = self.base_version
|
|
220
|
+
|
|
221
|
+
def _fetch_conan_info_v1(self):
|
|
222
|
+
user = misc.conan_user()
|
|
223
|
+
args = "--only-recipe" if misc.conan_v2() else "--recipe"
|
|
187
224
|
export_path = os.path.join(tool.conan_data, self.conan_package, f"{user}/stable", "export")
|
|
188
225
|
if not os.path.isdir(export_path):
|
|
189
|
-
cmd = f"conan download {self.conan_package}@{user}/stable -r {self.remote}
|
|
226
|
+
cmd = f"conan download {self.conan_package}@{user}/stable -r {self.remote} {args}"
|
|
190
227
|
tool.run_command(cmd, error_log=f"组件 {self.conan_package} 未找到,请检查网络连接以及该版本是否已发布")
|
|
191
228
|
conanfile = os.path.join(export_path, "conanfile.py")
|
|
192
229
|
conandata = os.path.join(export_path, "conandata.yml")
|
|
@@ -216,6 +253,12 @@ class BmcgoCommand:
|
|
|
216
253
|
else:
|
|
217
254
|
raise RuntimeError("无法找到版本(revision)和地址(url)字段")
|
|
218
255
|
|
|
256
|
+
def _fetch_conan_info(self):
|
|
257
|
+
if misc.conan_v1():
|
|
258
|
+
self._fetch_conan_info_v1()
|
|
259
|
+
else:
|
|
260
|
+
self._fetch_conan_info_v2()
|
|
261
|
+
|
|
219
262
|
def _update_next_version(self):
|
|
220
263
|
self.next_version = self.arg_special_version
|
|
221
264
|
if not self.next_version:
|
bmcgo/functional/new.py
CHANGED
|
@@ -54,7 +54,7 @@ _TEMPLATES = {
|
|
|
54
54
|
class BmcgoCommand:
|
|
55
55
|
def __init__(self, bconfig: BmcgoConfig, *args):
|
|
56
56
|
self.bconfig = bconfig
|
|
57
|
-
parser = argparse.ArgumentParser(prog="
|
|
57
|
+
parser = argparse.ArgumentParser(prog=f"{misc.tool_name()} new", description="创建组件", add_help=True,
|
|
58
58
|
formatter_class=argparse.RawTextHelpFormatter)
|
|
59
59
|
for item in _REQUIRES:
|
|
60
60
|
parser.add_argument(f"-{item[0]}", f"--{item[1]}", help=f"指定{item[2]}", required=True)
|
bmcgo/functional/schema_valid.py
CHANGED
|
@@ -43,8 +43,8 @@ class BmcgoCommand:
|
|
|
43
43
|
bconfig (BmcgoConfig): bmcgo 配置
|
|
44
44
|
"""
|
|
45
45
|
self.bconfig = bconfig
|
|
46
|
-
parser = argparse.ArgumentParser(prog="
|
|
47
|
-
formatter_class=argparse.RawTextHelpFormatter)
|
|
46
|
+
parser = argparse.ArgumentParser(prog=f"{misc.tool_name()} validate_yml", description="Validate yaml files",
|
|
47
|
+
add_help=True, formatter_class=argparse.RawTextHelpFormatter)
|
|
48
48
|
parser.add_argument("-t", "--target", help="目标文件夹或单个yaml文件,默认当前目录", default=".")
|
|
49
49
|
|
|
50
50
|
parsed_args = parser.parse_args(*args)
|
bmcgo/logger.py
CHANGED
|
@@ -61,7 +61,7 @@ class CustomFormatter(logging.Formatter):
|
|
|
61
61
|
|
|
62
62
|
|
|
63
63
|
class Logger(logging.Logger):
|
|
64
|
-
def __init__(self, name="
|
|
64
|
+
def __init__(self, name="bingo", level=logging.INFO, log_file=None):
|
|
65
65
|
"""初始化一个日志记录器
|
|
66
66
|
|
|
67
67
|
Args:
|
|
@@ -79,7 +79,7 @@ class Logger(logging.Logger):
|
|
|
79
79
|
ch = logging.FileHandler(filename=log_file)
|
|
80
80
|
ch.setFormatter(formatter)
|
|
81
81
|
self.addHandler(ch)
|
|
82
|
-
self.is_debug = True
|
|
82
|
+
self.is_debug = True if self.log_level_env else False
|
|
83
83
|
if self.log_level_env == "info":
|
|
84
84
|
self.setLevel(logging.INFO)
|
|
85
85
|
elif self.log_level_env == "warn":
|
|
@@ -89,7 +89,6 @@ class Logger(logging.Logger):
|
|
|
89
89
|
elif self.log_level_env == "debug":
|
|
90
90
|
self.setLevel(logging.DEBUG)
|
|
91
91
|
else:
|
|
92
|
-
self.is_debug = False
|
|
93
92
|
self.setLevel(level)
|
|
94
93
|
ch = logging.StreamHandler()
|
|
95
94
|
ch.setFormatter(formatter)
|
bmcgo/misc.py
CHANGED
|
@@ -11,11 +11,10 @@
|
|
|
11
11
|
# See the Mulan PSL v2 for more details.
|
|
12
12
|
import re
|
|
13
13
|
import os
|
|
14
|
+
import sys
|
|
14
15
|
from enum import Enum
|
|
15
|
-
from
|
|
16
|
-
from bmcgo.logger import Logger
|
|
16
|
+
from conan import conan_version
|
|
17
17
|
|
|
18
|
-
log = Logger("work_prepare")
|
|
19
18
|
|
|
20
19
|
CACHE_DIR = f"{os.path.expanduser('~')}/.bmcgo_log"
|
|
21
20
|
CONAN_REPO = "openubmc_dev"
|
|
@@ -23,7 +22,7 @@ CONAN_USER = 'openUBMC'
|
|
|
23
22
|
|
|
24
23
|
STORE_TRUE = "store_true"
|
|
25
24
|
STORE_FALSE = "store_false"
|
|
26
|
-
SCHEMA_FILE_PATH = "/usr/share/
|
|
25
|
+
SCHEMA_FILE_PATH = "/usr/share/bingo/schema"
|
|
27
26
|
GLOBAL_CFG_FILE = "/etc/bmcgo.conf"
|
|
28
27
|
CONAN = "conan"
|
|
29
28
|
# bmcgo.conf中用于定义路径的选项名
|
|
@@ -103,6 +102,12 @@ HPM_ENCRYPT = "hpm_encrypt"
|
|
|
103
102
|
HPM_ENCRYPT_ENABLE = "enable"
|
|
104
103
|
HPM_ENCRYPT_TOOL = "crypto_tool"
|
|
105
104
|
|
|
105
|
+
# CONAN包每一段的正则表达式
|
|
106
|
+
CONAN_NAME_RESTR = "[a-z0-9_][a-z0-9_+.-]{1,100}"
|
|
107
|
+
|
|
108
|
+
# 工具名称
|
|
109
|
+
BINGO_NAME = "bingo"
|
|
110
|
+
|
|
106
111
|
|
|
107
112
|
class StageEnum(Enum):
|
|
108
113
|
STAGE_DEV = "dev"
|
|
@@ -111,9 +116,31 @@ class StageEnum(Enum):
|
|
|
111
116
|
STAGE_STABLE = "stable"
|
|
112
117
|
|
|
113
118
|
|
|
114
|
-
class
|
|
115
|
-
|
|
116
|
-
|
|
119
|
+
class BuildTypeEnum(Enum):
|
|
120
|
+
DEBUG = "debug"
|
|
121
|
+
RELEASE = "release"
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
def conan_v1():
|
|
125
|
+
return conan_version.major == 1
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
def conan_v2():
|
|
129
|
+
return conan_version.major == 2
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
def build_type():
|
|
133
|
+
bt = ["debug", "release"]
|
|
134
|
+
if conan_v1():
|
|
135
|
+
bt.append("dt")
|
|
136
|
+
return bt
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
def build_type_str():
|
|
140
|
+
bt = "debug, release"
|
|
141
|
+
if conan_v1():
|
|
142
|
+
bt += ", dt"
|
|
143
|
+
return bt
|
|
117
144
|
|
|
118
145
|
|
|
119
146
|
class CommandInfo():
|
|
@@ -140,11 +167,105 @@ def get_decleared_schema_file(file) -> str:
|
|
|
140
167
|
if match is None:
|
|
141
168
|
continue
|
|
142
169
|
schema_file = match.group(1).strip()
|
|
143
|
-
log.debug("读取行: " + line)
|
|
144
170
|
if os.path.isfile(schema_file):
|
|
145
171
|
return str(schema_file)
|
|
172
|
+
if "/bmcgo/" in schema_file and tool_name() == "bingo":
|
|
173
|
+
bing_schema = schema_file.replace("/bmcgo/", "/bingo/")
|
|
174
|
+
if os.path.isfile(bing_schema):
|
|
175
|
+
return str(bing_schema)
|
|
146
176
|
schema_file = os.path.join(os.path.dirname(file), schema_file)
|
|
147
177
|
schema_file = os.path.realpath(schema_file)
|
|
148
178
|
if os.path.isfile(schema_file):
|
|
149
179
|
return str(schema_file)
|
|
150
|
-
return ""
|
|
180
|
+
return ""
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
def tool_name() -> str:
|
|
184
|
+
return os.path.basename(sys.argv[0])
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
def community_name() -> str:
|
|
188
|
+
"""
|
|
189
|
+
返回社区名称,默认为openubmc,可以通过环境变量修改
|
|
190
|
+
"""
|
|
191
|
+
return os.environ.get("OPENUBMC_COMMUNITY_NAME", "openubmc")
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
def conan_user() -> str:
|
|
195
|
+
"""
|
|
196
|
+
返回正式conan包的user字段
|
|
197
|
+
"""
|
|
198
|
+
if conan_v1():
|
|
199
|
+
return os.environ.get("OPENUBMC_DEFAULT_CONAN_USER", "openUBMC.release")
|
|
200
|
+
else:
|
|
201
|
+
return os.environ.get("OPENUBMC_DEFAULT_CONAN_USER", "openubmc")
|
|
202
|
+
|
|
203
|
+
|
|
204
|
+
def conan_user_dev() -> str:
|
|
205
|
+
"""
|
|
206
|
+
返回调试conan包的user字段
|
|
207
|
+
"""
|
|
208
|
+
if conan_v1():
|
|
209
|
+
return os.environ.get("OPENUBMC_DEFAULT_CONAN_USER", "openUBMC.release")
|
|
210
|
+
else:
|
|
211
|
+
return os.environ.get("OPENUBMC_DEFAULT_CONAN_USER_DEV", "openubmc.dev")
|
|
212
|
+
|
|
213
|
+
|
|
214
|
+
def conan_remote() -> str:
|
|
215
|
+
"""
|
|
216
|
+
返回默认远程仓名
|
|
217
|
+
"""
|
|
218
|
+
return os.environ.get("OPENUBMC_DEFAULT_CONAN_REMOTE", "openubmc_dev")
|
|
219
|
+
|
|
220
|
+
|
|
221
|
+
def boardname_default() -> str:
|
|
222
|
+
"""
|
|
223
|
+
返回默认单板名
|
|
224
|
+
"""
|
|
225
|
+
return os.environ.get("OPENUBMC_DEFAULT_BOARD_NAME", "openUBMC")
|
|
226
|
+
|
|
227
|
+
|
|
228
|
+
def logo() -> str:
|
|
229
|
+
"""
|
|
230
|
+
返回LOGO
|
|
231
|
+
"""
|
|
232
|
+
return os.environ.get("OPENUBMC_DEFAULT_LOGO", "openUBMC")
|
|
233
|
+
|
|
234
|
+
|
|
235
|
+
def boardname_default() -> str:
|
|
236
|
+
"""
|
|
237
|
+
返回默认单板名
|
|
238
|
+
"""
|
|
239
|
+
return os.environ.get("OPENUBMC_DEFAULT_BOARD_NAME", "openUBMC")
|
|
240
|
+
|
|
241
|
+
|
|
242
|
+
def schema_path() -> str:
|
|
243
|
+
return os.environ.get("OPENUBMC_SCHEMA_PATH", "/usr/share/bingo/schema")
|
|
244
|
+
|
|
245
|
+
|
|
246
|
+
def vendor() -> str:
|
|
247
|
+
"""
|
|
248
|
+
默认厂商名,用于制作HPM包时使用,生效时的优先级:
|
|
249
|
+
1. 优先manifest/base/vendor配置
|
|
250
|
+
2. 再次OPENUBMC_DEFAULT_VENDOR环境变量
|
|
251
|
+
3. 最后使用社区名
|
|
252
|
+
"""
|
|
253
|
+
return os.environ.get("OPENUBMC_DEFAULT_VENDOR", "openUBMC")
|
|
254
|
+
|
|
255
|
+
|
|
256
|
+
def need_encrypt_hpm() -> str:
|
|
257
|
+
"""
|
|
258
|
+
是否需要加密固件
|
|
259
|
+
"""
|
|
260
|
+
return os.environ.get("OPENUBMC_ENCRYPTO_HPM_PACKAGE", False)
|
|
261
|
+
|
|
262
|
+
|
|
263
|
+
def conan_package_match(name: str, valid_range=True) -> bool:
|
|
264
|
+
restr = CONAN_NAME_RESTR
|
|
265
|
+
if re.match(f"^{restr}/{restr}@{restr}/{restr}$", name):
|
|
266
|
+
return True
|
|
267
|
+
if valid_range:
|
|
268
|
+
match = re.search('\\[.*\\]', name)
|
|
269
|
+
if match:
|
|
270
|
+
return True
|
|
271
|
+
return False
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
# Copyright (c) 2024 Huawei Technologies Co., Ltd.
|
|
3
|
+
# openUBMC is licensed under Mulan PSL v2.
|
|
4
|
+
# You can use this software according to the terms and conditions of the Mulan PSL v2.
|
|
5
|
+
# You may obtain a copy of Mulan PSL v2 at:
|
|
6
|
+
# http://license.coscl.org.cn/MulanPSL2
|
|
7
|
+
# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
|
8
|
+
# EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
|
9
|
+
# MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
|
10
|
+
# See the Mulan PSL v2 for more details.
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
#!/usr/bin/python
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
# Copyright (c) 2024 Huawei Technologies Co., Ltd.
|
|
4
|
+
# openUBMC is licensed under Mulan PSL v2.
|
|
5
|
+
# You can use this software according to the terms and conditions of the Mulan PSL v2.
|
|
6
|
+
# You may obtain a copy of Mulan PSL v2 at:
|
|
7
|
+
# http://license.coscl.org.cn/MulanPSL2
|
|
8
|
+
# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
|
9
|
+
# EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
|
10
|
+
# MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
|
11
|
+
# See the Mulan PSL v2 for more details.
|
|
12
|
+
from conan import ConanFile
|
|
13
|
+
import yaml
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class OpenubmcConan(ConanFile):
|
|
17
|
+
name = "openubmc"
|
|
18
|
+
url = "https://www.huawei.com"
|
|
19
|
+
settings = "os", "compiler", "build_type", "arch"
|
|
20
|
+
requires = []
|
|
21
|
+
license = "Mulan PSL v2"
|
|
22
|
+
exports_sources = ["manifest.yml"]
|
|
23
|
+
_manifest = None
|
|
24
|
+
|
|
25
|
+
def init(self):
|
|
26
|
+
with open("manifest.yml", "r") as fp:
|
|
27
|
+
self._manifest = yaml.safe_load(fp)
|
|
28
|
+
|
|
29
|
+
def set_version(self):
|
|
30
|
+
self.version = self._manifest["base"]["version"].lower()
|
|
31
|
+
|
|
32
|
+
def requirements(self):
|
|
33
|
+
for dep in self._manifest.get("dependencies", {}):
|
|
34
|
+
require = dep["conan"] + ""
|
|
35
|
+
self.requires(require)
|
|
36
|
+
|
|
37
|
+
def build(self):
|
|
38
|
+
pass
|
|
39
|
+
|
|
40
|
+
def package(self):
|
|
41
|
+
pass
|
|
42
|
+
|
|
43
|
+
def package_info(self):
|
|
44
|
+
pass
|
|
45
|
+
|