lbkit 0.9.4__tar.gz → 0.9.6__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.6}/PKG-INFO +2 -1
  2. lbkit-0.9.6/lbkit/__init__.py +2 -0
  3. {lbkit-0.9.4 → lbkit-0.9.6}/lbkit/build_conan_parallel.py +6 -5
  4. {lbkit-0.9.4 → lbkit-0.9.6}/lbkit/cli.py +6 -17
  5. {lbkit-0.9.4 → lbkit-0.9.6}/lbkit/codegen/codegen.py +3 -10
  6. {lbkit-0.9.4 → lbkit-0.9.6}/lbkit/codegen/idf_interface.py +8 -15
  7. {lbkit-0.9.4 → lbkit-0.9.6}/lbkit/codegen/template/public.c.mako +2 -2
  8. {lbkit-0.9.4 → lbkit-0.9.6}/lbkit/component/arg_parser.py +2 -0
  9. {lbkit-0.9.4 → lbkit-0.9.6}/lbkit/component/build.py +96 -49
  10. {lbkit-0.9.4 → lbkit-0.9.6}/lbkit/component/template/conanbase.mako +23 -7
  11. {lbkit-0.9.4 → lbkit-0.9.6}/lbkit/component/test.py +12 -11
  12. lbkit-0.9.6/lbkit/log.py +141 -0
  13. {lbkit-0.9.4 → lbkit-0.9.6}/lbkit/misc.py +2 -1
  14. {lbkit-0.9.4 → lbkit-0.9.6}/lbkit/tasks/config.py +1 -1
  15. {lbkit-0.9.4 → lbkit-0.9.6}/lbkit/tasks/executor.py +13 -2
  16. {lbkit-0.9.4 → lbkit-0.9.6}/lbkit/tasks/image_maker/make_qemu_image.py +1 -4
  17. {lbkit-0.9.4 → lbkit-0.9.6}/lbkit/tasks/image_maker/make_rockchip_image.py +0 -3
  18. {lbkit-0.9.4 → lbkit-0.9.6}/lbkit/tasks/task.py +1 -2
  19. {lbkit-0.9.4 → lbkit-0.9.6}/lbkit/tasks/task_build_image.py +0 -3
  20. {lbkit-0.9.4 → lbkit-0.9.6}/lbkit/tasks/task_build_manifest.py +6 -6
  21. {lbkit-0.9.4 → lbkit-0.9.6}/lbkit/tasks/task_build_prepare.py +1 -5
  22. {lbkit-0.9.4 → lbkit-0.9.6}/lbkit/tasks/task_build_rootfs.py +10 -13
  23. {lbkit-0.9.4 → lbkit-0.9.6}/lbkit/tasks/task_download.py +1 -4
  24. {lbkit-0.9.4 → lbkit-0.9.6}/lbkit/tools.py +111 -42
  25. {lbkit-0.9.4 → lbkit-0.9.6}/lbkit/ukr/build.py +9 -9
  26. {lbkit-0.9.4 → lbkit-0.9.6}/lbkit/utils/env_detector.py +1 -1
  27. {lbkit-0.9.4 → lbkit-0.9.6}/lbkit/utils/images/emmc.py +1 -1
  28. {lbkit-0.9.4 → lbkit-0.9.6/lbkit.egg-info}/PKG-INFO +2 -1
  29. {lbkit-0.9.4 → lbkit-0.9.6}/lbkit.egg-info/SOURCES.txt +0 -1
  30. {lbkit-0.9.4 → lbkit-0.9.6}/lbkit.egg-info/requires.txt +1 -0
  31. {lbkit-0.9.4 → lbkit-0.9.6}/setup.py +1 -1
  32. {lbkit-0.9.4 → lbkit-0.9.6}/test/test_codegen.py +4 -4
  33. lbkit-0.9.4/lbkit/__init__.py +0 -2
  34. lbkit-0.9.4/lbkit/ci_robot/gitee.py +0 -248
  35. lbkit-0.9.4/lbkit/log.py +0 -95
  36. {lbkit-0.9.4 → lbkit-0.9.6}/AUTHORS +0 -0
  37. {lbkit-0.9.4 → lbkit-0.9.6}/LICENSE +0 -0
  38. {lbkit-0.9.4 → lbkit-0.9.6}/MANIFEST.in +0 -0
  39. {lbkit-0.9.4 → lbkit-0.9.6}/README.md +0 -0
  40. {lbkit-0.9.4 → lbkit-0.9.6}/lbkit/ci_robot/__init__.py +0 -0
  41. {lbkit-0.9.4 → lbkit-0.9.6}/lbkit/codegen/__init__.py +0 -0
  42. {lbkit-0.9.4 → lbkit-0.9.6}/lbkit/codegen/ctype_defination.py +0 -0
  43. {lbkit-0.9.4 → lbkit-0.9.6}/lbkit/codegen/renderer.py +0 -0
  44. {lbkit-0.9.4 → lbkit-0.9.6}/lbkit/codegen/template/client.c.mako +0 -0
  45. {lbkit-0.9.4 → lbkit-0.9.6}/lbkit/codegen/template/client.h.mako +0 -0
  46. {lbkit-0.9.4 → lbkit-0.9.6}/lbkit/codegen/template/interface.c.mako +0 -0
  47. {lbkit-0.9.4 → lbkit-0.9.6}/lbkit/codegen/template/interface.introspect.xml.mako +0 -0
  48. {lbkit-0.9.4 → lbkit-0.9.6}/lbkit/codegen/template/public.h.mako +0 -0
  49. {lbkit-0.9.4 → lbkit-0.9.6}/lbkit/codegen/template/server.c.mako +0 -0
  50. {lbkit-0.9.4 → lbkit-0.9.6}/lbkit/codegen/template/server.h.mako +0 -0
  51. {lbkit-0.9.4 → lbkit-0.9.6}/lbkit/component/__init__.py +0 -0
  52. {lbkit-0.9.4 → lbkit-0.9.6}/lbkit/component/template/deploy.mako +0 -0
  53. {lbkit-0.9.4 → lbkit-0.9.6}/lbkit/errors.py +0 -0
  54. {lbkit-0.9.4 → lbkit-0.9.6}/lbkit/helper.py +0 -0
  55. {lbkit-0.9.4 → lbkit-0.9.6}/lbkit/lbkit.py +0 -0
  56. {lbkit-0.9.4 → lbkit-0.9.6}/lbkit/tasks/__init__.py +0 -0
  57. {lbkit-0.9.4 → lbkit-0.9.6}/lbkit/tasks/image_maker/__init__.py +0 -0
  58. {lbkit-0.9.4 → lbkit-0.9.6}/lbkit/tasks/image_maker/make_image.py +0 -0
  59. {lbkit-0.9.4 → lbkit-0.9.6}/lbkit/tasks/template/conanfile.py.mako +0 -0
  60. {lbkit-0.9.4 → lbkit-0.9.6}/lbkit/tasks/template/rootfs.py.mako +0 -0
  61. {lbkit-0.9.4 → lbkit-0.9.6}/lbkit/ukr/__init__.py +0 -0
  62. {lbkit-0.9.4 → lbkit-0.9.6}/lbkit/utils/__init__.py +0 -0
  63. {lbkit-0.9.4 → lbkit-0.9.6}/lbkit/utils/images/__init__.py +0 -0
  64. {lbkit-0.9.4 → lbkit-0.9.6}/lbkit.egg-info/dependency_links.txt +0 -0
  65. {lbkit-0.9.4 → lbkit-0.9.6}/lbkit.egg-info/entry_points.txt +0 -0
  66. {lbkit-0.9.4 → lbkit-0.9.6}/lbkit.egg-info/top_level.txt +0 -0
  67. {lbkit-0.9.4 → lbkit-0.9.6}/setup.cfg +0 -0
  68. {lbkit-0.9.4 → lbkit-0.9.6}/test/__init__.py +0 -0
  69. {lbkit-0.9.4 → lbkit-0.9.6}/test/test_config.py +0 -0
  70. {lbkit-0.9.4 → lbkit-0.9.6}/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.6
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.6'
@@ -8,19 +8,20 @@ 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
- tools.exec(cmd, ignore_error=True, log_name=logfile, echo_cmd=False)
24
+ tools.exec(cmd, log_name=logfile, echo_cmd=False)
24
25
  log.info("{}build finished: '{}".format(Color.GREEN, Color.RESET_ALL) + cmd + ' log file: ' + logfile)
25
26
 
26
27
  def _build(self):
@@ -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
@@ -12,14 +11,13 @@ from lbkit.component.build import BuildComponent
12
11
  from lbkit.component.test import TestComponent
13
12
  from lbkit.tasks.executor import Executor
14
13
  from lbkit.component.arg_parser import ArgParser
15
- from lbkit.ci_robot.gitee import Gitee
16
14
  from lbkit.log import Logger
17
15
  from lbkit import misc
18
16
  from lbkit import errors
19
17
  from lbkit.ukr.build import UKRBuild
20
18
  from lbkit.utils.env_detector import EnvDetector
21
19
 
22
- log = Logger("cli")
20
+ log = Logger()
23
21
 
24
22
 
25
23
  class Command(object):
@@ -92,14 +90,6 @@ class Command(object):
92
90
  exe = Executor(env)
93
91
  exe.run()
94
92
 
95
- def gitee(self, *args):
96
- """
97
- Call gitee api.
98
-
99
- CI场景调用gitee的API完成像标签、评论等基本操作
100
- """
101
- _ = Gitee(sys.argv[2:])
102
-
103
93
  # test package
104
94
  def test(self, *args):
105
95
  """
@@ -123,7 +113,6 @@ class Command(object):
123
113
  ("Build Component commands", ["new", "build", "test"]),
124
114
  ("Build Product commands", ["build"]),
125
115
  ("Misc commands", ["help"]),
126
- ("CI Robot commands", ["gitee"])
127
116
  ]
128
117
 
129
118
  def check_all_commands_listed():
@@ -223,7 +212,6 @@ class Command(object):
223
212
  log.error(exc)
224
213
  ret_code = 0
225
214
  except SystemExit as exc:
226
- log.error("lbk exit with exception:")
227
215
  if exc.code != 0:
228
216
  log.error("Exiting with code: %d" % exc.code)
229
217
  ret_code = exc.code
@@ -233,7 +221,7 @@ class Command(object):
233
221
  print(traceback.format_exc())
234
222
  ret_code = -1
235
223
  msg = str(exc)
236
- log.error(misc.Color.RED + msg + misc.Color.RESET_ALL)
224
+ log.error(msg)
237
225
  except errors.TestException:
238
226
  log.error("lbk exit with exception:")
239
227
  log.error(exc)
@@ -245,8 +233,6 @@ class Command(object):
245
233
  def main(args):
246
234
  # 使能revision功能
247
235
  os.environ["CONAN_REVISIONS_ENABLED"] = "1"
248
- # 创建并清空日志目录
249
- shutil.rmtree(misc.LOG_DIR, ignore_errors=True)
250
236
  os.makedirs(misc.LOG_DIR, exist_ok=True)
251
237
  def ctrl_c_handler(_, __):
252
238
  sys.exit(-3)
@@ -259,5 +245,8 @@ def main(args):
259
245
 
260
246
  command = Command()
261
247
  error = command.run(args)
248
+ if error != 0:
249
+ log.error("Build failed, You can find all build logs in the directory: " + misc.LOG_DIR)
250
+ else:
251
+ log.success("Build successfully, You can find all build logs in the directory: " + misc.LOG_DIR)
262
252
  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):
@@ -124,6 +124,8 @@ CTYPE_SIGNATURE_MAP = {
124
124
  }
125
125
 
126
126
  def get_intfname_and_ctype(class_alias: str, ctype: str):
127
+ if ctype == "self":
128
+ return class_alias, class_alias
127
129
  match = re.findall(r"([\w][\w\d]*)", ctype)
128
130
  intf = ".".join(match[:-1])
129
131
  ctype = match[-1]
@@ -426,6 +428,8 @@ class IdfCtypeRender():
426
428
  if is_array:
427
429
  # 结构体数组初始化时为二级空指针,以空指针结束
428
430
  return [f"{stru_name} *<const>*<arg_name>"]
431
+ elif stru_name == self.intf.alias:
432
+ return [f"<const>struct _{stru_name} *<arg_name>"]
429
433
  else:
430
434
  # 结构体成员初始化时为空结构体,由反序列化时填充内容
431
435
  return [f"<const>{stru_name} *<arg_name>"]
@@ -972,7 +976,7 @@ class IdfStructure(IdfBase):
972
976
  if odf is not None:
973
977
  schema[prop.name] = odf
974
978
  else:
975
- log.warning(f"the schema of prop {prop.name} is None")
979
+ log.warn(f"the schema of prop {prop.name} is None")
976
980
  odf = {
977
981
  "type": "object",
978
982
  "additionalProperties": False,
@@ -1078,7 +1082,7 @@ class IdfDictionary():
1078
1082
  if odf is not None:
1079
1083
  schema[prop.name] = odf
1080
1084
  else:
1081
- log.warning(f"the schema of prop {prop.name} is None")
1085
+ log.warn(f"the schema of prop {prop.name} is None")
1082
1086
  key_schema = self.key_obj.odf_schema(False)
1083
1087
  odf = {
1084
1088
  "type": "array",
@@ -1191,7 +1195,7 @@ class IdfInterface(IdfInterfaceBase):
1191
1195
  schema[prop.name] = odf
1192
1196
  with_schema_prop_cnt += 1
1193
1197
  else:
1194
- log.warning(f"the schema of prop {prop.name} is None")
1198
+ log.warn(f"the schema of prop {prop.name} is None")
1195
1199
  # 顶层属性可以有一个flags标记属性
1196
1200
  schema[f"_{prop.name}_flags"] = {
1197
1201
  "enum": ["per_save", "per_power_off", "per_reboot"]
@@ -1312,17 +1316,6 @@ class IdfInterface(IdfInterfaceBase):
1312
1316
  for item in items:
1313
1317
  obj = IdfPluginAction(self, item)
1314
1318
  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
1319
  # 接口本身也是一个结构体
1327
1320
  intf_stru = IdfStructure(self, idf, propety_key="properties")
1328
1321
  self.structures[self.alias] = intf_stru
@@ -971,7 +971,7 @@ static ${class_name}_Properties _${class_name}_properties =
971
971
  % if (prop.signature in ["b", "y", "n", "q", "i", "u", "x", "t", "d", "o", "s", "g", "ab", "ay", "an", "aq", "ai", "au", "ax", "at", "ad", "as", "ao", "ag"] and prop.val_validate()):
972
972
  .check = ${class_name}_check_${prop.name}_variant,
973
973
  % else:
974
- <% match = re.match(f"^array\[enum\[(.*)\]\]$", prop.ctype) %>\
974
+ <% match = re.match(rf"^array\[enum\[(.*)\]\]$", prop.ctype) %>\
975
975
  % if match:
976
976
  <% match_enum = re.findall(r"([\w][\w\d]*)", match.group(1)) %>\
977
977
  % if match_enum[0] == "self":
@@ -980,7 +980,7 @@ static ${class_name}_Properties _${class_name}_properties =
980
980
  .check = ${match_enum[0]}_${match_enum[-1]}_check_enum_variant_v,
981
981
  % endif
982
982
  % else:
983
- <% match = re.match(f"^enum\[(.*)\]$", prop.ctype) %>\
983
+ <% match = re.match(rf"^enum\[(.*)\]$", prop.ctype) %>\
984
984
  % if match:
985
985
  <% match_enum = re.findall(r"([\w][\w\d]*)", match.group(1)) %>\
986
986
  % if match_enum[0] == "self":
@@ -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 = ""
@@ -88,8 +97,23 @@ class BuildComponent():
88
97
  for pkg_option in self.options.pkg_options:
89
98
  self.base_cmd += " -o " + pkg_option
90
99
  self.base_cmd += f" -o */*:codegen_version={self.options.codegen_version}"
91
- if self.name == "lb_base":
92
- self.base_cmd += f" -o */*:compatible_required={self.codegen_version.info.lb_base_compatible_required}"
100
+ self.base_cmd += f" -o */*:compatible_required={self.codegen_version.info.lb_base_compatible_required}"
101
+
102
+ @staticmethod
103
+ def _check_conanfile_if_tracked():
104
+ """检查conanfile.py是否被git跟踪"""
105
+ tracked = False
106
+ try:
107
+ repo = Repo(".")
108
+ for entry in repo.commit().tree.traverse():
109
+ if entry.path == "conanfile.py":
110
+ tracked = True
111
+ break
112
+ except InvalidGitRepositoryError:
113
+ log.debug("Invalid git repository")
114
+ return
115
+ if tracked:
116
+ raise Exception("conanfile.py is being tracked by git. You can untrack it by executing the command `git rm --f conanfile.py`")
93
117
 
94
118
  def get_package_version(self):
95
119
  """
@@ -105,17 +129,40 @@ class BuildComponent():
105
129
  print(str(e))
106
130
  return None
107
131
 
108
- @property
109
- def _is_conanfile_tracked(self):
110
- """检查conanfile.py是否被git跟踪"""
132
+ def tar_source(self, tar_path):
133
+ """
134
+ 将self.cwd目录下未被git跟踪的文件使用tar命令压缩到tar_path
135
+
136
+ :param tar_path: tar压缩包路径
137
+ """
138
+ untracked_files = [".temp"]
139
+ if os.path.exists("test_package/test_interface"):
140
+ untracked_files.append("test_package/test_interface")
141
+ if os.path.exists("conanfile.py"):
142
+ untracked_files.append("conanfile.py")
143
+ if os.path.exists("__pycache__"):
144
+ untracked_files.append("__pycache__")
145
+ if os.path.exists(".git"):
146
+ untracked_files.append(".git")
147
+ if os.path.exists(".gitignore"):
148
+ untracked_files.append(".gitignore")
149
+
111
150
  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
151
+ repo = Repo(self.cwd)
152
+ # 获取未被跟踪的文件
153
+ untracked_files.extend(repo.untracked_files)
154
+ except InvalidGitRepositoryError:
155
+ raise errors.LiteBmcException(f"{self.cwd} is not a valid git repository")
156
+
157
+ # 构建tar命令,使用-C指定工作目录
158
+ cmd_parts = ["tar", "--format=gnu", "-czf", tar_path, f"--transform=s|^.|{self.version}|", "-C", self.cwd]
159
+ for file in untracked_files:
160
+ cmd_parts.append("--exclude=" + file)
161
+ cmd_parts.append(".")
162
+ cmd = " ".join(shlex.quote(part) for part in cmd_parts)
163
+
164
+ tools.exec(cmd, verbose=True)
165
+ log.info(f"Archived {len(untracked_files)} untracked files to {tar_path}")
119
166
 
120
167
  def gen_conaninfo(self):
121
168
  package_yml = os.path.join(self.cwd, "metadata/package.yml")
@@ -131,10 +178,15 @@ class BuildComponent():
131
178
  # 构建命令未指定channel时从package.yml中读取
132
179
  pkg["channel"] = self.channel
133
180
  pkg["version"] = self.get_package_version()
134
- self.pkg = pkg
135
181
  # 从package.yml加载基础信息
136
182
  self.name = pkg.get("name")
137
183
  self.version = pkg.get("version")
184
+ self.tar_source(self.source_file)
185
+ pkg["source_url"] = self.source_file
186
+ pkg["sha256"] = tools.file_digest_sha256(self.source_file)
187
+ pkg["enable_tar_source"] = self.enable_tar_source
188
+ pkg["source_dir"] = self.cwd
189
+ self.pkg = pkg
138
190
 
139
191
  self.package = self.name + "/" + self.version
140
192
  if self.user != "litebmc" or self.channel != "release":
@@ -155,17 +207,14 @@ class BuildComponent():
155
207
  for k, v in option.items():
156
208
  self.base_cmd += f" -o {conan}/*:{k}={v}"
157
209
 
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")
210
+ # 检查git是是否跟踪conanfile.py
211
+ self._check_conanfile_if_tracked()
212
+ conanfile = os.path.join(self.conan_index, "conanfile.py")
163
213
 
164
214
  # 使用litebmc.conanfile.mako模板生成基础litebmc公共conanfile
165
215
  lookup = TemplateLookup(directories=os.path.join(lb_cwd, "template"))
166
216
  template = lookup.get_template("conanbase.mako")
167
217
  conandata = template.render(lookup=lookup, pkg=pkg,
168
- conanfile_tracked=self._is_conanfile_tracked,
169
218
  codegen_version=self.codegen_version,
170
219
  codegen_history=history_versions)
171
220
  # 写入文件
@@ -196,6 +245,8 @@ class BuildComponent():
196
245
  context = info.get("context")
197
246
  if context != "host":
198
247
  continue
248
+ if ref.startswith(self.package):
249
+ self.package_id = id
199
250
  dep = DeployComponent(ref, id, self.rootfs_dir)
200
251
  pool.apply_async(dep.run, error_callback=self._copy_failed)
201
252
  pool.close()
@@ -203,32 +254,29 @@ class BuildComponent():
203
254
 
204
255
  def build(self):
205
256
  log.info(os.getcwd())
206
-
257
+ os.chdir(self.conan_index)
207
258
  export_cmd = "conan export . "
208
259
  if self.user != "litebmc" or self.channel != "release":
209
260
  export_cmd += f"--user={self.user} --channel={self.channel}"
210
- tools.run(export_cmd, capture_output=False, stdout=sys.stdout, stderr=sys.stdout)
261
+ tools.exec(export_cmd, verbose=True)
211
262
 
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}"
263
+ graph_cmd = f"conan graph build-order . {self.base_cmd} --order-by=recipe -f json --out-file={self.orderfile}"
215
264
  if self.from_source:
216
265
  graph_cmd += " --build='*'"
217
266
  else:
218
267
  graph_cmd += " --build=missing"
219
- graph_cmd += f" --lockfile-out={lockfile}"
220
- tools.run(graph_cmd)
221
- bcp = BuildConanParallel(orderfile, self.options.remote)
268
+ graph_cmd += f" --lockfile-out={self.lockfile}"
269
+ tools.exec(graph_cmd, verbose=True)
270
+ bcp = BuildConanParallel(self.orderfile, self.lockfile, self.options.remote)
222
271
  bcp.build()
223
272
  cmd = f"conan create {self.base_cmd} --build='{self.name}/*'"
224
- tools.run(cmd, capture_output=False)
273
+ tools.exec(cmd, verbose=True)
225
274
 
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)
275
+ graph_cmd = f"conan graph info . {self.base_cmd} -f json --lockfile={self.lockfile}"
276
+ tools.pipe([graph_cmd], out_file=self.graphfile)
229
277
 
230
278
  log.success(f"start deploy {self.package} and is's dependency packages")
231
- self.deploy(graphfile)
279
+ self.deploy(self.graphfile)
232
280
 
233
281
  if not self.deploy_success:
234
282
  raise Exception("Deploy component failed")
@@ -301,10 +349,19 @@ class BuildComponent():
301
349
  if not ok:
302
350
  raise errors.OdfValidateException("Validate odf files with error, build failed")
303
351
 
352
+ def conan_test(self):
353
+ # 仅测试远程仓登录状态,如果需要登录的,需要输入账号密码
354
+ log.info("Test the login status of the Conan remote repository")
355
+ 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")
356
+ cmd = "conan search glib/2.81.0"
357
+ if self.options.remote:
358
+ cmd += f' -r {self.options.remote}'
359
+ tools.run(cmd, capture_output=False)
304
360
 
305
361
  def run(self):
306
362
  cmd = f"conan remove {self.package} -c"
307
363
  tools.exec(cmd)
364
+ self.conan_test()
308
365
  gen = CodeGen(["-c", "./metadata/package.yml"])
309
366
  gen.run()
310
367
  # 部署依赖
@@ -315,15 +372,6 @@ class BuildComponent():
315
372
  self.upload()
316
373
  log.success(f"build {self.package} successfully")
317
374
 
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
375
  @staticmethod
328
376
  def package_folder(self):
329
377
  cmd = f"conan cache path {self.package}#latest:{self.package_id}"
@@ -340,7 +388,6 @@ class BuildComponent():
340
388
  try:
341
389
  self.run()
342
390
  except Exception as e:
343
- log.error(
344
- f"build {self.package} {Color.RED}failed{Color.RESET_ALL}")
391
+ log.error(f"build {self.package} failed")
345
392
  log.info(e)
346
393
  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: