lbkit 0.9.4__tar.gz → 0.9.5__tar.gz

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.
Files changed (70) hide show
  1. {lbkit-0.9.4/lbkit.egg-info → lbkit-0.9.5}/PKG-INFO +2 -1
  2. lbkit-0.9.5/lbkit/__init__.py +2 -0
  3. {lbkit-0.9.4 → lbkit-0.9.5}/lbkit/build_conan_parallel.py +5 -4
  4. {lbkit-0.9.4 → lbkit-0.9.5}/lbkit/ci_robot/gitee.py +3 -1
  5. {lbkit-0.9.4 → lbkit-0.9.5}/lbkit/cli.py +6 -7
  6. {lbkit-0.9.4 → lbkit-0.9.5}/lbkit/codegen/codegen.py +3 -10
  7. {lbkit-0.9.4 → lbkit-0.9.5}/lbkit/codegen/idf_interface.py +4 -15
  8. {lbkit-0.9.4 → lbkit-0.9.5}/lbkit/component/arg_parser.py +2 -0
  9. {lbkit-0.9.4 → lbkit-0.9.5}/lbkit/component/build.py +95 -47
  10. {lbkit-0.9.4 → lbkit-0.9.5}/lbkit/component/template/conanbase.mako +23 -7
  11. {lbkit-0.9.4 → lbkit-0.9.5}/lbkit/component/test.py +12 -11
  12. lbkit-0.9.5/lbkit/log.py +141 -0
  13. {lbkit-0.9.4 → lbkit-0.9.5}/lbkit/misc.py +2 -1
  14. {lbkit-0.9.4 → lbkit-0.9.5}/lbkit/tasks/config.py +1 -1
  15. {lbkit-0.9.4 → lbkit-0.9.5}/lbkit/tasks/executor.py +13 -2
  16. {lbkit-0.9.4 → lbkit-0.9.5}/lbkit/tasks/image_maker/make_qemu_image.py +1 -4
  17. {lbkit-0.9.4 → lbkit-0.9.5}/lbkit/tasks/image_maker/make_rockchip_image.py +0 -3
  18. {lbkit-0.9.4 → lbkit-0.9.5}/lbkit/tasks/task.py +1 -2
  19. {lbkit-0.9.4 → lbkit-0.9.5}/lbkit/tasks/task_build_image.py +0 -3
  20. {lbkit-0.9.4 → lbkit-0.9.5}/lbkit/tasks/task_build_manifest.py +3 -6
  21. {lbkit-0.9.4 → lbkit-0.9.5}/lbkit/tasks/task_build_prepare.py +1 -5
  22. {lbkit-0.9.4 → lbkit-0.9.5}/lbkit/tasks/task_build_rootfs.py +10 -13
  23. {lbkit-0.9.4 → lbkit-0.9.5}/lbkit/tasks/task_download.py +1 -4
  24. {lbkit-0.9.4 → lbkit-0.9.5}/lbkit/tools.py +108 -42
  25. {lbkit-0.9.4 → lbkit-0.9.5}/lbkit/ukr/build.py +9 -9
  26. {lbkit-0.9.4 → lbkit-0.9.5}/lbkit/utils/env_detector.py +1 -1
  27. {lbkit-0.9.4 → lbkit-0.9.5}/lbkit/utils/images/emmc.py +1 -1
  28. {lbkit-0.9.4 → lbkit-0.9.5/lbkit.egg-info}/PKG-INFO +2 -1
  29. {lbkit-0.9.4 → lbkit-0.9.5}/lbkit.egg-info/requires.txt +1 -0
  30. {lbkit-0.9.4 → lbkit-0.9.5}/setup.py +1 -1
  31. {lbkit-0.9.4 → lbkit-0.9.5}/test/test_codegen.py +4 -4
  32. lbkit-0.9.4/lbkit/__init__.py +0 -2
  33. lbkit-0.9.4/lbkit/log.py +0 -95
  34. {lbkit-0.9.4 → lbkit-0.9.5}/AUTHORS +0 -0
  35. {lbkit-0.9.4 → lbkit-0.9.5}/LICENSE +0 -0
  36. {lbkit-0.9.4 → lbkit-0.9.5}/MANIFEST.in +0 -0
  37. {lbkit-0.9.4 → lbkit-0.9.5}/README.md +0 -0
  38. {lbkit-0.9.4 → lbkit-0.9.5}/lbkit/ci_robot/__init__.py +0 -0
  39. {lbkit-0.9.4 → lbkit-0.9.5}/lbkit/codegen/__init__.py +0 -0
  40. {lbkit-0.9.4 → lbkit-0.9.5}/lbkit/codegen/ctype_defination.py +0 -0
  41. {lbkit-0.9.4 → lbkit-0.9.5}/lbkit/codegen/renderer.py +0 -0
  42. {lbkit-0.9.4 → lbkit-0.9.5}/lbkit/codegen/template/client.c.mako +0 -0
  43. {lbkit-0.9.4 → lbkit-0.9.5}/lbkit/codegen/template/client.h.mako +0 -0
  44. {lbkit-0.9.4 → lbkit-0.9.5}/lbkit/codegen/template/interface.c.mako +0 -0
  45. {lbkit-0.9.4 → lbkit-0.9.5}/lbkit/codegen/template/interface.introspect.xml.mako +0 -0
  46. {lbkit-0.9.4 → lbkit-0.9.5}/lbkit/codegen/template/public.c.mako +0 -0
  47. {lbkit-0.9.4 → lbkit-0.9.5}/lbkit/codegen/template/public.h.mako +0 -0
  48. {lbkit-0.9.4 → lbkit-0.9.5}/lbkit/codegen/template/server.c.mako +0 -0
  49. {lbkit-0.9.4 → lbkit-0.9.5}/lbkit/codegen/template/server.h.mako +0 -0
  50. {lbkit-0.9.4 → lbkit-0.9.5}/lbkit/component/__init__.py +0 -0
  51. {lbkit-0.9.4 → lbkit-0.9.5}/lbkit/component/template/deploy.mako +0 -0
  52. {lbkit-0.9.4 → lbkit-0.9.5}/lbkit/errors.py +0 -0
  53. {lbkit-0.9.4 → lbkit-0.9.5}/lbkit/helper.py +0 -0
  54. {lbkit-0.9.4 → lbkit-0.9.5}/lbkit/lbkit.py +0 -0
  55. {lbkit-0.9.4 → lbkit-0.9.5}/lbkit/tasks/__init__.py +0 -0
  56. {lbkit-0.9.4 → lbkit-0.9.5}/lbkit/tasks/image_maker/__init__.py +0 -0
  57. {lbkit-0.9.4 → lbkit-0.9.5}/lbkit/tasks/image_maker/make_image.py +0 -0
  58. {lbkit-0.9.4 → lbkit-0.9.5}/lbkit/tasks/template/conanfile.py.mako +0 -0
  59. {lbkit-0.9.4 → lbkit-0.9.5}/lbkit/tasks/template/rootfs.py.mako +0 -0
  60. {lbkit-0.9.4 → lbkit-0.9.5}/lbkit/ukr/__init__.py +0 -0
  61. {lbkit-0.9.4 → lbkit-0.9.5}/lbkit/utils/__init__.py +0 -0
  62. {lbkit-0.9.4 → lbkit-0.9.5}/lbkit/utils/images/__init__.py +0 -0
  63. {lbkit-0.9.4 → lbkit-0.9.5}/lbkit.egg-info/SOURCES.txt +0 -0
  64. {lbkit-0.9.4 → lbkit-0.9.5}/lbkit.egg-info/dependency_links.txt +0 -0
  65. {lbkit-0.9.4 → lbkit-0.9.5}/lbkit.egg-info/entry_points.txt +0 -0
  66. {lbkit-0.9.4 → lbkit-0.9.5}/lbkit.egg-info/top_level.txt +0 -0
  67. {lbkit-0.9.4 → lbkit-0.9.5}/setup.cfg +0 -0
  68. {lbkit-0.9.4 → lbkit-0.9.5}/test/__init__.py +0 -0
  69. {lbkit-0.9.4 → lbkit-0.9.5}/test/test_config.py +0 -0
  70. {lbkit-0.9.4 → lbkit-0.9.5}/test/test_helper.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: lbkit
3
- Version: 0.9.4
3
+ Version: 0.9.5
4
4
  Summary: Tools provided by litebmc.com
5
5
  Home-page: https://www.litebmc.com
6
6
  Author: xuhj@litebmc.com
@@ -22,6 +22,7 @@ Requires-Dist: gitpython
22
22
  Requires-Dist: inflection
23
23
  Requires-Dist: meson>=1.4.0
24
24
  Requires-Dist: psutil
25
+ Requires-Dist: loguru
25
26
  Dynamic: author
26
27
  Dynamic: author-email
27
28
  Dynamic: classifier
@@ -0,0 +1,2 @@
1
+
2
+ __version__ = '0.9.5'
@@ -8,17 +8,18 @@ from lbkit import misc
8
8
  from lbkit.tools import Tools
9
9
  from lbkit.misc import Color
10
10
 
11
- tools = Tools("comp_build")
12
- log = Logger("comp_build")
11
+ tools = Tools()
12
+ log = tools.log
13
13
 
14
14
 
15
15
  class BuildConanParallel(object):
16
- def __init__(self, orderinfo, remote):
16
+ def __init__(self, orderinfo, lockfile, remote):
17
17
  self.orderinfo = orderinfo
18
18
  self.remote = remote
19
+ self.lockfile = lockfile
19
20
 
20
21
  def _build_package(self, logfile, build_args, public_args):
21
- cmd = f"conan install {build_args} {public_args}"
22
+ cmd = f"conan install {build_args} {public_args} --lockfile={self.lockfile} --lockfile-partial"
22
23
  log.info("{}build start: '{}".format(Color.GREEN, Color.RESET_ALL) + cmd + ' log file: ' + logfile)
23
24
  tools.exec(cmd, ignore_error=True, log_name=logfile, echo_cmd=False)
24
25
  log.info("{}build finished: '{}".format(Color.GREEN, Color.RESET_ALL) + cmd + ' log file: ' + logfile)
@@ -8,9 +8,10 @@ import re
8
8
  from argparse import ArgumentParser
9
9
  from lbkit import errors
10
10
  from lbkit.tools import Tools
11
+ from lbkit.log import Logger
11
12
  from argparse import RawTextHelpFormatter
12
13
 
13
- tools = Tools("comp_build")
14
+ tools = Tools()
14
15
  log = tools.log
15
16
  cwd = os.getcwd()
16
17
  lb_cwd = os.path.split(os.path.realpath(__file__))[0]
@@ -35,6 +36,7 @@ class GiteeCommandInfo(object):
35
36
 
36
37
  class Gitee():
37
38
  def __init__(self, args=None):
39
+ Logger("gitee.log")
38
40
  parser = argparse.ArgumentParser(
39
41
  description="Build component", formatter_class=RawTextHelpFormatter)
40
42
  sub_parser = parser.add_subparsers(help="sub-commands help")
@@ -3,7 +3,6 @@ import inspect
3
3
  import os
4
4
  import signal
5
5
  import sys
6
- import shutil
7
6
  import argparse
8
7
  import traceback
9
8
  from lbkit import __version__ as client_version
@@ -19,7 +18,7 @@ from lbkit import errors
19
18
  from lbkit.ukr.build import UKRBuild
20
19
  from lbkit.utils.env_detector import EnvDetector
21
20
 
22
- log = Logger("cli")
21
+ log = Logger()
23
22
 
24
23
 
25
24
  class Command(object):
@@ -223,7 +222,6 @@ class Command(object):
223
222
  log.error(exc)
224
223
  ret_code = 0
225
224
  except SystemExit as exc:
226
- log.error("lbk exit with exception:")
227
225
  if exc.code != 0:
228
226
  log.error("Exiting with code: %d" % exc.code)
229
227
  ret_code = exc.code
@@ -233,7 +231,7 @@ class Command(object):
233
231
  print(traceback.format_exc())
234
232
  ret_code = -1
235
233
  msg = str(exc)
236
- log.error(misc.Color.RED + msg + misc.Color.RESET_ALL)
234
+ log.error(msg)
237
235
  except errors.TestException:
238
236
  log.error("lbk exit with exception:")
239
237
  log.error(exc)
@@ -245,8 +243,6 @@ class Command(object):
245
243
  def main(args):
246
244
  # 使能revision功能
247
245
  os.environ["CONAN_REVISIONS_ENABLED"] = "1"
248
- # 创建并清空日志目录
249
- shutil.rmtree(misc.LOG_DIR, ignore_errors=True)
250
246
  os.makedirs(misc.LOG_DIR, exist_ok=True)
251
247
  def ctrl_c_handler(_, __):
252
248
  sys.exit(-3)
@@ -259,5 +255,8 @@ def main(args):
259
255
 
260
256
  command = Command()
261
257
  error = command.run(args)
258
+ if error != 0:
259
+ log.error("Build failed, You can find all build logs in the directory: " + misc.LOG_DIR)
260
+ else:
261
+ log.success("Build successfully, You can find all build logs in the directory: " + misc.LOG_DIR)
262
262
  sys.exit(error)
263
-
@@ -16,7 +16,7 @@ from lbkit.errors import ArgException
16
16
  from lbkit.misc import SmartFormatter
17
17
 
18
18
  lb_cwd = os.path.split(os.path.realpath(__file__))[0]
19
- log = Logger("codegen")
19
+ log = Logger()
20
20
 
21
21
 
22
22
  class CodeGenHistory():
@@ -102,6 +102,7 @@ def codegen_version_arg(parser: argparse.ArgumentParser, default=__version__.str
102
102
 
103
103
  class CodeGen(object):
104
104
  def __init__(self, args):
105
+ Logger("codegen.log")
105
106
  self.args = args
106
107
  self.codegen_version = __version__
107
108
  self.log_level = "NOTSET"
@@ -152,11 +153,6 @@ class CodeGen(object):
152
153
  formatter_class=SmartFormatter)
153
154
  codegen_version_arg(parser)
154
155
  parser.add_argument("-d", "--directory", help='generate code directory', default=".")
155
- parser.add_argument("-l", "--log_level", help='show log level',
156
- choices=[
157
- "CRITICAL", "FATAL", "ERROR", "WARN",
158
- "WARNING", "INFO", "DEBUG", "NOTSET",
159
- ], default=None)
160
156
  parser.add_argument("-t", "--codetype", help='code type, default: all', default="all", choices=["public", "server", "client", "all"])
161
157
  group2 = parser.add_argument_group('cdf file', 'Generate code using the specified CDF file')
162
158
  group2.add_argument("-c", "--cdf_file", help='component description file, default metadata/package.yml', default=None)
@@ -164,9 +160,6 @@ class CodeGen(object):
164
160
  group1.add_argument("-i", "--idf_file", help='A IDF file to be processed e.g.: com.litebmc.Upgrade.xml', default=None)
165
161
 
166
162
  args = parser.parse_args(self.args)
167
- if args.log_level:
168
- self.log_level = args.log_level
169
- log.setLevel(self.log_level)
170
163
 
171
164
  if args.cdf_file:
172
165
  if not os.path.isfile(args.cdf_file):
@@ -212,7 +205,7 @@ class CodeGen(object):
212
205
  if not os.path.isfile(intf_file):
213
206
  raise ArgException(f"The IDF file ({intf_file}) not exist")
214
207
  if not os.path.isdir(out_dir):
215
- log.warning(f"Directory {args.directory} not exist, try create")
208
+ log.warn(f"Directory {args.directory} not exist, try create")
216
209
  os.makedirs(out_dir)
217
210
  self._gen(intf_file, out_dir, args.codetype)
218
211
 
@@ -11,7 +11,7 @@ from lbkit.misc import load_yml_with_json_schema_validate, get_json_schema_file
11
11
  from lbkit.errors import OdfValidateException, LiteBmcException
12
12
  from lbkit.helper import SigInvalidException, validate_glib_signature
13
13
 
14
- log = Logger("gen_interface")
14
+ log = Logger()
15
15
  alias = None
16
16
 
17
17
  class IDFException(Exception):
@@ -972,7 +972,7 @@ class IdfStructure(IdfBase):
972
972
  if odf is not None:
973
973
  schema[prop.name] = odf
974
974
  else:
975
- log.warning(f"the schema of prop {prop.name} is None")
975
+ log.warn(f"the schema of prop {prop.name} is None")
976
976
  odf = {
977
977
  "type": "object",
978
978
  "additionalProperties": False,
@@ -1078,7 +1078,7 @@ class IdfDictionary():
1078
1078
  if odf is not None:
1079
1079
  schema[prop.name] = odf
1080
1080
  else:
1081
- log.warning(f"the schema of prop {prop.name} is None")
1081
+ log.warn(f"the schema of prop {prop.name} is None")
1082
1082
  key_schema = self.key_obj.odf_schema(False)
1083
1083
  odf = {
1084
1084
  "type": "array",
@@ -1191,7 +1191,7 @@ class IdfInterface(IdfInterfaceBase):
1191
1191
  schema[prop.name] = odf
1192
1192
  with_schema_prop_cnt += 1
1193
1193
  else:
1194
- log.warning(f"the schema of prop {prop.name} is None")
1194
+ log.warn(f"the schema of prop {prop.name} is None")
1195
1195
  # 顶层属性可以有一个flags标记属性
1196
1196
  schema[f"_{prop.name}_flags"] = {
1197
1197
  "enum": ["per_save", "per_power_off", "per_reboot"]
@@ -1312,17 +1312,6 @@ class IdfInterface(IdfInterfaceBase):
1312
1312
  for item in items:
1313
1313
  obj = IdfPluginAction(self, item)
1314
1314
  self.plugin.actions.append(obj)
1315
- log.debug("interface signature: " + self.signature)
1316
- for signal in self.signals:
1317
- log.debug(f"{signal.name} signature: " + signal.signature)
1318
- for method in self.methods:
1319
- log.debug(f"{method.name} in signature: " + method.in_signature + ", out signature: " + method.out_signature)
1320
- # for name, stru in self.structures.items():
1321
- # log.debug(f"{name} signature: " + stru.signature)
1322
- # for name, enum in self.enumerations.items():
1323
- # log.debug(f"{name} signature: " + enum.signature)
1324
- # for name, dictionary in self.dictionaries.items():
1325
- # log.debug(f"{name} signature: " + dictionary.signature)
1326
1315
  # 接口本身也是一个结构体
1327
1316
  intf_stru = IdfStructure(self, idf, propety_key="properties")
1328
1317
  self.structures[self.alias] = intf_stru
@@ -25,6 +25,8 @@ class ArgParser():
25
25
  help="Upload package to remote")
26
26
  parser.add_argument("-s", "--from_source", action="store_true",
27
27
  help="Build all depencencies component from source")
28
+ parser.add_argument("-ts", "--tar_source", action="store_true",
29
+ help="Use the tar command to compress the source code package.")
28
30
  parser.add_argument("--summary", action="store_true",
29
31
  help=argparse.SUPPRESS)
30
32
  parser.add_argument("--cov", action="store_true",
@@ -1,10 +1,9 @@
1
1
  """组件构建"""
2
2
  import os
3
3
  import yaml
4
- import shutil
4
+ import shlex
5
5
  import re
6
6
  import json
7
- import sys
8
7
  from multiprocessing import Pool
9
8
  import traceback
10
9
  from argparse import ArgumentParser
@@ -12,14 +11,15 @@ from jsonschema import validate, ValidationError
12
11
  from git import Repo
13
12
  from git.exc import InvalidGitRepositoryError
14
13
  from mako.lookup import TemplateLookup
15
- from lbkit.misc import Color, load_yml_with_json_schema_validate, get_json_schema_file, load_json_schema
14
+ from lbkit.misc import load_yml_with_json_schema_validate, get_json_schema_file, load_json_schema
16
15
  from lbkit import errors
17
16
  from lbkit.codegen.codegen import CodeGen, history_versions
18
17
  from lbkit.tools import Tools
18
+ from lbkit.log import Logger
19
19
  from lbkit.build_conan_parallel import BuildConanParallel
20
20
  from lbkit.codegen.codegen import Version
21
21
 
22
- tools = Tools("comp_build")
22
+ tools = Tools()
23
23
  log = tools.log
24
24
  lb_cwd = os.path.split(os.path.realpath(__file__))[0]
25
25
 
@@ -53,6 +53,7 @@ class DeployComponent():
53
53
  class BuildComponent():
54
54
  def __init__(self, args_parser: ArgumentParser, args=None):
55
55
  self.cwd = os.getcwd()
56
+ Logger("build_comp.log")
56
57
  self.deploy_success = True
57
58
  self.options = args_parser.parse_args(args)
58
59
  self.options.build_type = self.options.build_type.capitalize()
@@ -66,8 +67,16 @@ class BuildComponent():
66
67
  self.from_source = self.options.from_source
67
68
  # 当前组件及其依赖将被部署到rootfs目录
68
69
  self.rootfs_dir = os.path.join(self.cwd, ".temp", "rootfs")
69
- shutil.rmtree(self.rootfs_dir, ignore_errors=True)
70
- os.makedirs(self.rootfs_dir, exist_ok=True)
70
+ tools.makedirs(self.rootfs_dir, True, True)
71
+ self.conan_index = os.path.join(self.cwd, ".temp", "conan-index")
72
+ tools.makedirs(self.conan_index, True, True)
73
+ self.enable_tar_source = self.options.tar_source
74
+ self.source_file = os.path.join(self.cwd, ".temp", "source.tar.gz")
75
+ self.graphfile = os.path.join(self.cwd, ".temp", "graph.info")
76
+ self.lockfile = os.path.join(self.cwd, ".temp", "conan.lock")
77
+ self.orderfile = os.path.join(self.cwd, ".temp", "graph.order")
78
+ # 当组件构建完成后可以获取到包id, 初始化时置空
79
+ self.package_id = None
71
80
 
72
81
  self.pkg = None
73
82
  self.base_cmd = ""
@@ -91,6 +100,22 @@ class BuildComponent():
91
100
  if self.name == "lb_base":
92
101
  self.base_cmd += f" -o */*:compatible_required={self.codegen_version.info.lb_base_compatible_required}"
93
102
 
103
+ @staticmethod
104
+ def _check_conanfile_if_tracked():
105
+ """检查conanfile.py是否被git跟踪"""
106
+ tracked = False
107
+ try:
108
+ repo = Repo(".")
109
+ for entry in repo.commit().tree.traverse():
110
+ if entry.path == "conanfile.py":
111
+ tracked = True
112
+ break
113
+ except InvalidGitRepositoryError:
114
+ log.debug("Invalid git repository")
115
+ return
116
+ if tracked:
117
+ raise Exception("conanfile.py is being tracked by git. You can untrack it by executing the command `git rm --f conanfile.py`")
118
+
94
119
  def get_package_version(self):
95
120
  """
96
121
  从CMakeLists.txt读取版本号,格式需要满足正则表达式:project\((.*)VERSION ([0-9][1-9]*.[0-9][1-9]*.[0-9][1-9]*)\)
@@ -105,17 +130,40 @@ class BuildComponent():
105
130
  print(str(e))
106
131
  return None
107
132
 
108
- @property
109
- def _is_conanfile_tracked(self):
110
- """检查conanfile.py是否被git跟踪"""
133
+ def tar_source(self, tar_path):
134
+ """
135
+ 将self.cwd目录下未被git跟踪的文件使用tar命令压缩到tar_path
136
+
137
+ :param tar_path: tar压缩包路径
138
+ """
139
+ untracked_files = [".temp"]
140
+ if os.path.exists("test_package/test_interface"):
141
+ untracked_files.append("test_package/test_interface")
142
+ if os.path.exists("conanfile.py"):
143
+ untracked_files.append("conanfile.py")
144
+ if os.path.exists("__pycache__"):
145
+ untracked_files.append("__pycache__")
146
+ if os.path.exists(".git"):
147
+ untracked_files.append(".git")
148
+ if os.path.exists(".gitignore"):
149
+ untracked_files.append(".gitignore")
150
+
111
151
  try:
112
- repo = Repo(".")
113
- for entry in repo.commit().tree.traverse():
114
- if entry.path == "conanfile.py":
115
- return True
116
- except InvalidGitRepositoryError as e:
117
- log.error("Invalid git repository, conanfile.py will be generated by lbkit")
118
- return False
152
+ repo = Repo(self.cwd)
153
+ # 获取未被跟踪的文件
154
+ untracked_files.extend(repo.untracked_files)
155
+ except InvalidGitRepositoryError:
156
+ raise errors.LiteBmcException(f"{self.cwd} is not a valid git repository")
157
+
158
+ # 构建tar命令,使用-C指定工作目录
159
+ cmd_parts = ["tar", "--format=gnu", "-czf", tar_path, f"--transform=s|^.|{self.version}|", "-C", self.cwd]
160
+ for file in untracked_files:
161
+ cmd_parts.append("--exclude=" + file)
162
+ cmd_parts.append(".")
163
+ cmd = " ".join(shlex.quote(part) for part in cmd_parts)
164
+
165
+ tools.exec(cmd, verbose=True)
166
+ log.info(f"Archived {len(untracked_files)} untracked files to {tar_path}")
119
167
 
120
168
  def gen_conaninfo(self):
121
169
  package_yml = os.path.join(self.cwd, "metadata/package.yml")
@@ -131,10 +179,15 @@ class BuildComponent():
131
179
  # 构建命令未指定channel时从package.yml中读取
132
180
  pkg["channel"] = self.channel
133
181
  pkg["version"] = self.get_package_version()
134
- self.pkg = pkg
135
182
  # 从package.yml加载基础信息
136
183
  self.name = pkg.get("name")
137
184
  self.version = pkg.get("version")
185
+ self.tar_source(self.source_file)
186
+ pkg["source_url"] = self.source_file
187
+ pkg["sha256"] = tools.file_digest_sha256(self.source_file)
188
+ pkg["enable_tar_source"] = self.enable_tar_source
189
+ pkg["source_dir"] = self.cwd
190
+ self.pkg = pkg
138
191
 
139
192
  self.package = self.name + "/" + self.version
140
193
  if self.user != "litebmc" or self.channel != "release":
@@ -155,17 +208,14 @@ class BuildComponent():
155
208
  for k, v in option.items():
156
209
  self.base_cmd += f" -o {conan}/*:{k}={v}"
157
210
 
158
- # 生成conan构建脚本
159
- conanfile = os.path.join(self.cwd, "conanbase.py")
160
- # 当git未跟踪conanfile.py时生成新的conanfile.py
161
- if not self._is_conanfile_tracked:
162
- conanfile = os.path.join(self.cwd, "conanfile.py")
211
+ # 检查git是是否跟踪conanfile.py
212
+ self._check_conanfile_if_tracked()
213
+ conanfile = os.path.join(self.conan_index, "conanfile.py")
163
214
 
164
215
  # 使用litebmc.conanfile.mako模板生成基础litebmc公共conanfile
165
216
  lookup = TemplateLookup(directories=os.path.join(lb_cwd, "template"))
166
217
  template = lookup.get_template("conanbase.mako")
167
218
  conandata = template.render(lookup=lookup, pkg=pkg,
168
- conanfile_tracked=self._is_conanfile_tracked,
169
219
  codegen_version=self.codegen_version,
170
220
  codegen_history=history_versions)
171
221
  # 写入文件
@@ -196,6 +246,8 @@ class BuildComponent():
196
246
  context = info.get("context")
197
247
  if context != "host":
198
248
  continue
249
+ if ref.startswith(self.package):
250
+ self.package_id = id
199
251
  dep = DeployComponent(ref, id, self.rootfs_dir)
200
252
  pool.apply_async(dep.run, error_callback=self._copy_failed)
201
253
  pool.close()
@@ -203,32 +255,29 @@ class BuildComponent():
203
255
 
204
256
  def build(self):
205
257
  log.info(os.getcwd())
206
-
258
+ os.chdir(self.conan_index)
207
259
  export_cmd = "conan export . "
208
260
  if self.user != "litebmc" or self.channel != "release":
209
261
  export_cmd += f"--user={self.user} --channel={self.channel}"
210
- tools.run(export_cmd, capture_output=False, stdout=sys.stdout, stderr=sys.stdout)
262
+ tools.exec(export_cmd, verbose=True)
211
263
 
212
- lockfile = os.path.join(self.cwd, ".temp", "conan.lock")
213
- orderfile = os.path.join(self.cwd, ".temp", "graph.order")
214
- graph_cmd = f"conan graph build-order . {self.base_cmd} --order-by=recipe -f json --out-file={orderfile}"
264
+ graph_cmd = f"conan graph build-order . {self.base_cmd} --order-by=recipe -f json --out-file={self.orderfile}"
215
265
  if self.from_source:
216
266
  graph_cmd += " --build='*'"
217
267
  else:
218
268
  graph_cmd += " --build=missing"
219
- graph_cmd += f" --lockfile-out={lockfile}"
220
- tools.run(graph_cmd)
221
- bcp = BuildConanParallel(orderfile, self.options.remote)
269
+ graph_cmd += f" --lockfile-out={self.lockfile}"
270
+ tools.exec(graph_cmd, verbose=True)
271
+ bcp = BuildConanParallel(self.orderfile, self.lockfile, self.options.remote)
222
272
  bcp.build()
223
273
  cmd = f"conan create {self.base_cmd} --build='{self.name}/*'"
224
- tools.run(cmd, capture_output=False)
274
+ tools.exec(cmd, verbose=True)
225
275
 
226
- graphfile = os.path.join(self.cwd, ".temp", "graph.info")
227
- graph_cmd = f"conan graph info . {self.base_cmd} -f json --lockfile={lockfile}"
228
- tools.pipe([graph_cmd], out_file=graphfile)
276
+ graph_cmd = f"conan graph info . {self.base_cmd} -f json --lockfile={self.lockfile}"
277
+ tools.pipe([graph_cmd], out_file=self.graphfile)
229
278
 
230
279
  log.success(f"start deploy {self.package} and is's dependency packages")
231
- self.deploy(graphfile)
280
+ self.deploy(self.graphfile)
232
281
 
233
282
  if not self.deploy_success:
234
283
  raise Exception("Deploy component failed")
@@ -301,10 +350,19 @@ class BuildComponent():
301
350
  if not ok:
302
351
  raise errors.OdfValidateException("Validate odf files with error, build failed")
303
352
 
353
+ def conan_test(self):
354
+ # 仅测试远程仓登录状态,如果需要登录的,需要输入账号密码
355
+ log.info("Test the login status of the Conan remote repository")
356
+ log.info("If glib/2.81.0 not found, you must add litebmc repository using the command: conan remote add litebmc https://litebmc.com/conan/release")
357
+ cmd = "conan search glib/2.81.0"
358
+ if self.options.remote:
359
+ cmd += f' -r {self.options.remote}'
360
+ tools.run(cmd, capture_output=False)
304
361
 
305
362
  def run(self):
306
363
  cmd = f"conan remove {self.package} -c"
307
364
  tools.exec(cmd)
365
+ self.conan_test()
308
366
  gen = CodeGen(["-c", "./metadata/package.yml"])
309
367
  gen.run()
310
368
  # 部署依赖
@@ -315,15 +373,6 @@ class BuildComponent():
315
373
  self.upload()
316
374
  log.success(f"build {self.package} successfully")
317
375
 
318
- @property
319
- def package_id(self):
320
- cmd = f"conan graph info . {self.base_cmd} --filter=package_id"
321
- res = tools.run(cmd, capture_output=True)
322
- match = re.search(r"package_id: ([a-f0-9]{40})", res.stdout)
323
- if match is None:
324
- raise errors.LiteBmcException(f"Get package if of {self.package} failed")
325
- return match.group(1)
326
-
327
376
  @staticmethod
328
377
  def package_folder(self):
329
378
  cmd = f"conan cache path {self.package}#latest:{self.package_id}"
@@ -340,7 +389,6 @@ class BuildComponent():
340
389
  try:
341
390
  self.run()
342
391
  except Exception as e:
343
- log.error(
344
- f"build {self.package} {Color.RED}failed{Color.RESET_ALL}")
392
+ log.error(f"build {self.package} failed")
345
393
  log.info(e)
346
394
  os._exit(-2)
@@ -69,15 +69,30 @@ class LiteBmcConan(ConanFile):
69
69
  % endif
70
70
  }
71
71
 
72
+ % if pkg["enable_tar_source"]:
72
73
  def export(self):
73
- % if conanfile_tracked:
74
- # files.copy(self, "conanbase.py", self.recipe_folder, self.export_folder)
75
- files.copy(self, "conanbase.py")
76
- % endif
77
- git = Git(self, self.recipe_folder)
74
+ files.update_conandata(self, {
75
+ "sources": {
76
+ "${pkg["version"]}": {
77
+ "url": "${pkg["source_url"]}",
78
+ "sha256": "${pkg["sha256"]}"
79
+ }
80
+ }
81
+ })
82
+
83
+ def source(self):
84
+ source = self.conan_data["sources"][self.version]
85
+ url = source.get("url")
86
+ if (not url.startswith("http")) and os.path.isfile(url):
87
+ files.unzip(self, url, destination=".", strip_root=True)
88
+ else:
89
+ files.get(self, **source, strip_root=True)
90
+ % else:
91
+ def export(self):
92
+ git = Git(self, "${pkg["source_dir"]}")
78
93
  if git.is_dirty():
79
94
  print(f"{Fore.YELLOW}Waring: Local repo is dirty.{Style.RESET_ALL}")
80
- files.update_conandata(self, {"sources": {"commit": None, "url": None, "pwd": os.getcwd()}})
95
+ files.update_conandata(self, {"sources": {"commit": None, "url": None, "pwd": "${pkg["source_dir"]}"}})
81
96
  return
82
97
 
83
98
  scm_url = None
@@ -89,7 +104,7 @@ class LiteBmcConan(ConanFile):
89
104
  scm_url = git.get_remote_url(remote)
90
105
  break
91
106
  if not scm_url:
92
- files.update_conandata(self, {"sources": {"commit": None, "url": None, "pwd": os.getcwd()}})
107
+ files.update_conandata(self, {"sources": {"commit": None, "url": None, "pwd": "${pkg["source_dir"]}"}})
93
108
  return
94
109
  files.update_conandata(self, {"sources": {"commit": scm_commit, "url": scm_url}})
95
110
 
@@ -101,6 +116,7 @@ class LiteBmcConan(ConanFile):
101
116
  git.checkout(commit=sources["commit"])
102
117
  else:
103
118
  files.copy(self, "*", src=sources["pwd"], dst=".")
119
+ % endif
104
120
 
105
121
  def requirements(self):
106
122
  % if len(pkg.get("requires", {})) > 0:
@@ -12,9 +12,9 @@ from lbkit.component.build import BuildComponent
12
12
  from lbkit.component.arg_parser import ArgParser
13
13
  from lbkit import errors
14
14
  from lbkit.tools import Tools
15
- from lbkit.misc import Color
15
+ from lbkit.log import Logger
16
16
 
17
- tool = Tools("comp_test")
17
+ tool = Tools()
18
18
  log = tool.log
19
19
 
20
20
 
@@ -25,13 +25,14 @@ def run_command(cmd):
25
25
  subprocess.run([cmd], check=True)
26
26
  return True
27
27
  except Exception as e:
28
- log.warning(str(e))
28
+ log.warn(str(e))
29
29
  return False
30
30
 
31
31
 
32
32
  class TestComponent():
33
33
  def __init__(self, args:list[str]=None):
34
34
  self.cwd = os.getcwd()
35
+ Logger("test_comp.log")
35
36
  self.execute_only = False
36
37
  if "-e" in args:
37
38
  self.execute_only = True
@@ -74,11 +75,11 @@ class TestComponent():
74
75
  line_level = matches.group(3)
75
76
  log.info("Coverage info:")
76
77
  if line_level == "Hi":
77
- log.info(Color.GREEN + f"Line: hit %-10d total %-10d coverage %.02f %% (High)" % (line_hit, line_total, line_cov) + Color.RESET_ALL)
78
+ log.success(f"Line: hit %-10d total %-10d coverage %.02f %% (High)" % (line_hit, line_total, line_cov))
78
79
  elif line_level == "Med":
79
- log.info(Color.YELLOW + f"Line: hit %-10d total %-10d coverage %.02f %% (Medium)" % (line_hit, line_total, line_cov) + Color.RESET_ALL)
80
+ log.warn(f"Line: hit %-10d total %-10d coverage %.02f %% (Medium)" % (line_hit, line_total, line_cov))
80
81
  elif line_level == "Lo":
81
- log.info(Color.RED + f"Line: hit %-10d total %-10d coverage %.02f %% (Low)" % (line_hit, line_total, line_cov) + Color.RESET_ALL)
82
+ log.warn(f"Line: hit %-10d total %-10d coverage %.02f %% (Low!!!)" % (line_hit, line_total, line_cov))
82
83
  matches = re.search(r"Functions:</td\>\n.*headerCovTableEntry\"\>([0-9]+).*\n.*headerCovTableEntry\"\>([0-9]+).*\n.*headerCovTableEntry(Lo|Hi|Med)\"\>([0-9.]+) %", content)
83
84
  if matches is None:
84
85
  raise errors.LiteBmcException(f"Read function coverage data from {index_file} failed")
@@ -87,11 +88,11 @@ class TestComponent():
87
88
  func_cov = float(matches.group(4))
88
89
  func_level = matches.group(3)
89
90
  if func_level == "Hi":
90
- log.info(Color.GREEN + f"Function: hit %-10d total %-10d coverage %.02f %% (High)" % (func_hit, func_total, func_cov) + Color.RESET_ALL)
91
+ log.success(f"Function: hit %-10d total %-10d coverage %.02f %% (High)" % (func_hit, func_total, func_cov))
91
92
  elif func_level == "Med":
92
- log.info(Color.YELLOW + f"Function: hit %-10d total %-10d coverage %.02f %% (Medium)" % (func_hit, func_total, func_cov) + Color.RESET_ALL)
93
+ log.warn(f"Function: hit %-10d total %-10d coverage %.02f %% (Medium)" % (func_hit, func_total, func_cov))
93
94
  elif func_level == "Lo":
94
- log.info(Color.RED + f"Function: hit %-10d total %-10d coverage %.02f %% (Low)" % (func_hit, func_total, func_cov) + Color.RESET_ALL)
95
+ log.warn(f"Function: hit %-10d total %-10d coverage %.02f %% (Low!!!)" % (func_hit, func_total, func_cov))
95
96
 
96
97
  def _make_ld_library_path(self, rootfs_dir):
97
98
  cmd = f"find {rootfs_dir} -name *.so"
@@ -131,13 +132,13 @@ class TestComponent():
131
132
  count = len(bins)
132
133
  pool = Pool(count + 1)
133
134
  if not bins:
134
- log.warning("The metadata/package.yml file does not contain executable binary program records(package_info/bins)")
135
+ log.warn("The metadata/package.yml file does not contain executable binary program records(package_info/bins)")
135
136
  return pool
136
137
 
137
138
  for bin in bins:
138
139
  bin = os.path.join(rootfs_dir, bin)
139
140
  if not os.path.isfile(bin):
140
- log.warning(f"Execute file {bin} not eixst")
141
+ log.warn(f"Execute file {bin} not eixst")
141
142
  pool.map_async(run_command, (bin, ))
142
143
  lb_im = os.path.join(rootfs_dir, "opt/litebmc/apps/lb_interface_manager/lb_interface_manager")
143
144
  if os.path.isfile(lb_im):