lbkit 0.9.3__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.
- {lbkit-0.9.3 → lbkit-0.9.5}/AUTHORS +1 -1
- {lbkit-0.9.3/lbkit.egg-info → lbkit-0.9.5}/PKG-INFO +2 -1
- lbkit-0.9.5/lbkit/__init__.py +2 -0
- lbkit-0.9.5/lbkit/build_conan_parallel.py +62 -0
- {lbkit-0.9.3 → lbkit-0.9.5}/lbkit/ci_robot/gitee.py +3 -1
- {lbkit-0.9.3 → lbkit-0.9.5}/lbkit/cli.py +6 -7
- {lbkit-0.9.3 → lbkit-0.9.5}/lbkit/codegen/codegen.py +3 -10
- {lbkit-0.9.3 → lbkit-0.9.5}/lbkit/codegen/idf_interface.py +4 -15
- {lbkit-0.9.3 → lbkit-0.9.5}/lbkit/component/arg_parser.py +2 -0
- {lbkit-0.9.3 → lbkit-0.9.5}/lbkit/component/build.py +103 -52
- {lbkit-0.9.3 → lbkit-0.9.5}/lbkit/component/template/conanbase.mako +23 -7
- {lbkit-0.9.3 → lbkit-0.9.5}/lbkit/component/test.py +15 -14
- lbkit-0.9.5/lbkit/log.py +141 -0
- {lbkit-0.9.3 → lbkit-0.9.5}/lbkit/misc.py +2 -1
- {lbkit-0.9.3 → lbkit-0.9.5}/lbkit/tasks/config.py +1 -3
- {lbkit-0.9.3 → lbkit-0.9.5}/lbkit/tasks/executor.py +13 -2
- {lbkit-0.9.3 → lbkit-0.9.5}/lbkit/tasks/image_maker/make_qemu_image.py +1 -4
- {lbkit-0.9.3 → lbkit-0.9.5}/lbkit/tasks/image_maker/make_rockchip_image.py +0 -3
- {lbkit-0.9.3 → lbkit-0.9.5}/lbkit/tasks/task.py +1 -2
- {lbkit-0.9.3 → lbkit-0.9.5}/lbkit/tasks/task_build_image.py +0 -3
- {lbkit-0.9.3 → lbkit-0.9.5}/lbkit/tasks/task_build_manifest.py +29 -45
- {lbkit-0.9.3 → lbkit-0.9.5}/lbkit/tasks/task_build_prepare.py +5 -7
- {lbkit-0.9.3 → lbkit-0.9.5}/lbkit/tasks/task_build_rootfs.py +10 -13
- {lbkit-0.9.3 → lbkit-0.9.5}/lbkit/tasks/task_download.py +1 -4
- {lbkit-0.9.3 → lbkit-0.9.5}/lbkit/tools.py +132 -40
- {lbkit-0.9.3 → lbkit-0.9.5}/lbkit/ukr/build.py +9 -9
- {lbkit-0.9.3 → lbkit-0.9.5}/lbkit/utils/env_detector.py +1 -1
- {lbkit-0.9.3 → lbkit-0.9.5}/lbkit/utils/images/emmc.py +1 -1
- {lbkit-0.9.3 → lbkit-0.9.5/lbkit.egg-info}/PKG-INFO +2 -1
- {lbkit-0.9.3 → lbkit-0.9.5}/lbkit.egg-info/requires.txt +1 -0
- {lbkit-0.9.3 → lbkit-0.9.5}/setup.py +1 -1
- {lbkit-0.9.3 → lbkit-0.9.5}/test/test_codegen.py +4 -4
- lbkit-0.9.3/lbkit/__init__.py +0 -2
- lbkit-0.9.3/lbkit/build_conan_parallel.py +0 -206
- lbkit-0.9.3/lbkit/log.py +0 -85
- {lbkit-0.9.3 → lbkit-0.9.5}/LICENSE +0 -0
- {lbkit-0.9.3 → lbkit-0.9.5}/MANIFEST.in +0 -0
- {lbkit-0.9.3 → lbkit-0.9.5}/README.md +0 -0
- {lbkit-0.9.3 → lbkit-0.9.5}/lbkit/ci_robot/__init__.py +0 -0
- {lbkit-0.9.3 → lbkit-0.9.5}/lbkit/codegen/__init__.py +0 -0
- {lbkit-0.9.3 → lbkit-0.9.5}/lbkit/codegen/ctype_defination.py +0 -0
- {lbkit-0.9.3 → lbkit-0.9.5}/lbkit/codegen/renderer.py +0 -0
- {lbkit-0.9.3 → lbkit-0.9.5}/lbkit/codegen/template/client.c.mako +0 -0
- {lbkit-0.9.3 → lbkit-0.9.5}/lbkit/codegen/template/client.h.mako +0 -0
- {lbkit-0.9.3 → lbkit-0.9.5}/lbkit/codegen/template/interface.c.mako +0 -0
- {lbkit-0.9.3 → lbkit-0.9.5}/lbkit/codegen/template/interface.introspect.xml.mako +0 -0
- {lbkit-0.9.3 → lbkit-0.9.5}/lbkit/codegen/template/public.c.mako +0 -0
- {lbkit-0.9.3 → lbkit-0.9.5}/lbkit/codegen/template/public.h.mako +0 -0
- {lbkit-0.9.3 → lbkit-0.9.5}/lbkit/codegen/template/server.c.mako +0 -0
- {lbkit-0.9.3 → lbkit-0.9.5}/lbkit/codegen/template/server.h.mako +0 -0
- {lbkit-0.9.3 → lbkit-0.9.5}/lbkit/component/__init__.py +0 -0
- {lbkit-0.9.3 → lbkit-0.9.5}/lbkit/component/template/deploy.mako +0 -0
- {lbkit-0.9.3 → lbkit-0.9.5}/lbkit/errors.py +0 -0
- {lbkit-0.9.3 → lbkit-0.9.5}/lbkit/helper.py +0 -0
- {lbkit-0.9.3 → lbkit-0.9.5}/lbkit/lbkit.py +0 -0
- {lbkit-0.9.3 → lbkit-0.9.5}/lbkit/tasks/__init__.py +0 -0
- {lbkit-0.9.3 → lbkit-0.9.5}/lbkit/tasks/image_maker/__init__.py +0 -0
- {lbkit-0.9.3 → lbkit-0.9.5}/lbkit/tasks/image_maker/make_image.py +0 -0
- {lbkit-0.9.3 → lbkit-0.9.5}/lbkit/tasks/template/conanfile.py.mako +0 -0
- {lbkit-0.9.3 → lbkit-0.9.5}/lbkit/tasks/template/rootfs.py.mako +0 -0
- {lbkit-0.9.3 → lbkit-0.9.5}/lbkit/ukr/__init__.py +0 -0
- {lbkit-0.9.3 → lbkit-0.9.5}/lbkit/utils/__init__.py +0 -0
- {lbkit-0.9.3 → lbkit-0.9.5}/lbkit/utils/images/__init__.py +0 -0
- {lbkit-0.9.3 → lbkit-0.9.5}/lbkit.egg-info/SOURCES.txt +0 -0
- {lbkit-0.9.3 → lbkit-0.9.5}/lbkit.egg-info/dependency_links.txt +0 -0
- {lbkit-0.9.3 → lbkit-0.9.5}/lbkit.egg-info/entry_points.txt +0 -0
- {lbkit-0.9.3 → lbkit-0.9.5}/lbkit.egg-info/top_level.txt +0 -0
- {lbkit-0.9.3 → lbkit-0.9.5}/setup.cfg +0 -0
- {lbkit-0.9.3 → lbkit-0.9.5}/test/__init__.py +0 -0
- {lbkit-0.9.3 → lbkit-0.9.5}/test/test_config.py +0 -0
- {lbkit-0.9.3 → 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.
|
|
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,62 @@
|
|
|
1
|
+
"""任务基础类"""
|
|
2
|
+
import os
|
|
3
|
+
import json
|
|
4
|
+
import tempfile
|
|
5
|
+
from lbkit.log import Logger
|
|
6
|
+
from concurrent.futures import ThreadPoolExecutor, Future, as_completed
|
|
7
|
+
from lbkit import misc
|
|
8
|
+
from lbkit.tools import Tools
|
|
9
|
+
from lbkit.misc import Color
|
|
10
|
+
|
|
11
|
+
tools = Tools()
|
|
12
|
+
log = tools.log
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class BuildConanParallel(object):
|
|
16
|
+
def __init__(self, orderinfo, lockfile, remote):
|
|
17
|
+
self.orderinfo = orderinfo
|
|
18
|
+
self.remote = remote
|
|
19
|
+
self.lockfile = lockfile
|
|
20
|
+
|
|
21
|
+
def _build_package(self, logfile, build_args, public_args):
|
|
22
|
+
cmd = f"conan install {build_args} {public_args} --lockfile={self.lockfile} --lockfile-partial"
|
|
23
|
+
log.info("{}build start: '{}".format(Color.GREEN, Color.RESET_ALL) + cmd + ' log file: ' + logfile)
|
|
24
|
+
tools.exec(cmd, ignore_error=True, log_name=logfile, echo_cmd=False)
|
|
25
|
+
log.info("{}build finished: '{}".format(Color.GREEN, Color.RESET_ALL) + cmd + ' log file: ' + logfile)
|
|
26
|
+
|
|
27
|
+
def _build(self):
|
|
28
|
+
with open(self.orderinfo, "r") as fp:
|
|
29
|
+
order_info = json.load(fp)
|
|
30
|
+
public_args = order_info.get("profiles", {}).get("self", {}).get("args", "")
|
|
31
|
+
for orders in order_info.get("order", []):
|
|
32
|
+
threadPool = ThreadPoolExecutor(max_workers=(os.cpu_count() + 1) // 2)
|
|
33
|
+
results: list[Future] = []
|
|
34
|
+
for order in orders:
|
|
35
|
+
ref = order.get("ref")
|
|
36
|
+
pkgname = ref.split("/")[0]
|
|
37
|
+
logfile = f"{misc.LOG_DIR}/conan_{pkgname}.log"
|
|
38
|
+
packages = order.get("packages", [])
|
|
39
|
+
for package in packages:
|
|
40
|
+
for pkg in package:
|
|
41
|
+
binary = pkg.get("binary", "")
|
|
42
|
+
if binary == 'Download':
|
|
43
|
+
pkgid = pkg.get("package_id")
|
|
44
|
+
cmd = f'conan download {ref}:{pkgid}'
|
|
45
|
+
if self.remote:
|
|
46
|
+
cmd += f' -r {self.remote}'
|
|
47
|
+
tools.exec(cmd)
|
|
48
|
+
continue
|
|
49
|
+
if binary != "Build":
|
|
50
|
+
continue
|
|
51
|
+
build_args = pkg.get("build_args", "")
|
|
52
|
+
result = threadPool.submit(self._build_package, logfile, build_args, public_args)
|
|
53
|
+
results.append(result)
|
|
54
|
+
for result in as_completed(results):
|
|
55
|
+
result.result()
|
|
56
|
+
|
|
57
|
+
def build(self):
|
|
58
|
+
cwd = os.getcwd()
|
|
59
|
+
tmp = tempfile.TemporaryDirectory()
|
|
60
|
+
os.chdir(tmp.name)
|
|
61
|
+
self._build()
|
|
62
|
+
os.chdir(cwd)
|
|
@@ -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(
|
|
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(
|
|
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(
|
|
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(
|
|
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.
|
|
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(
|
|
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.
|
|
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.
|
|
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.
|
|
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,7 +1,7 @@
|
|
|
1
1
|
"""组件构建"""
|
|
2
2
|
import os
|
|
3
3
|
import yaml
|
|
4
|
-
import
|
|
4
|
+
import shlex
|
|
5
5
|
import re
|
|
6
6
|
import json
|
|
7
7
|
from multiprocessing import Pool
|
|
@@ -11,14 +11,15 @@ from jsonschema import validate, ValidationError
|
|
|
11
11
|
from git import Repo
|
|
12
12
|
from git.exc import InvalidGitRepositoryError
|
|
13
13
|
from mako.lookup import TemplateLookup
|
|
14
|
-
from lbkit.misc import
|
|
14
|
+
from lbkit.misc import load_yml_with_json_schema_validate, get_json_schema_file, load_json_schema
|
|
15
15
|
from lbkit import errors
|
|
16
16
|
from lbkit.codegen.codegen import CodeGen, history_versions
|
|
17
17
|
from lbkit.tools import Tools
|
|
18
|
+
from lbkit.log import Logger
|
|
18
19
|
from lbkit.build_conan_parallel import BuildConanParallel
|
|
19
20
|
from lbkit.codegen.codegen import Version
|
|
20
21
|
|
|
21
|
-
tools = Tools(
|
|
22
|
+
tools = Tools()
|
|
22
23
|
log = tools.log
|
|
23
24
|
lb_cwd = os.path.split(os.path.realpath(__file__))[0]
|
|
24
25
|
|
|
@@ -52,6 +53,7 @@ class DeployComponent():
|
|
|
52
53
|
class BuildComponent():
|
|
53
54
|
def __init__(self, args_parser: ArgumentParser, args=None):
|
|
54
55
|
self.cwd = os.getcwd()
|
|
56
|
+
Logger("build_comp.log")
|
|
55
57
|
self.deploy_success = True
|
|
56
58
|
self.options = args_parser.parse_args(args)
|
|
57
59
|
self.options.build_type = self.options.build_type.capitalize()
|
|
@@ -65,8 +67,16 @@ class BuildComponent():
|
|
|
65
67
|
self.from_source = self.options.from_source
|
|
66
68
|
# 当前组件及其依赖将被部署到rootfs目录
|
|
67
69
|
self.rootfs_dir = os.path.join(self.cwd, ".temp", "rootfs")
|
|
68
|
-
|
|
69
|
-
os.
|
|
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
|
|
70
80
|
|
|
71
81
|
self.pkg = None
|
|
72
82
|
self.base_cmd = ""
|
|
@@ -90,6 +100,22 @@ class BuildComponent():
|
|
|
90
100
|
if self.name == "lb_base":
|
|
91
101
|
self.base_cmd += f" -o */*:compatible_required={self.codegen_version.info.lb_base_compatible_required}"
|
|
92
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
|
+
|
|
93
119
|
def get_package_version(self):
|
|
94
120
|
"""
|
|
95
121
|
从CMakeLists.txt读取版本号,格式需要满足正则表达式:project\((.*)VERSION ([0-9][1-9]*.[0-9][1-9]*.[0-9][1-9]*)\)
|
|
@@ -104,17 +130,40 @@ class BuildComponent():
|
|
|
104
130
|
print(str(e))
|
|
105
131
|
return None
|
|
106
132
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
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
|
+
|
|
110
151
|
try:
|
|
111
|
-
repo = Repo(
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
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}")
|
|
118
167
|
|
|
119
168
|
def gen_conaninfo(self):
|
|
120
169
|
package_yml = os.path.join(self.cwd, "metadata/package.yml")
|
|
@@ -130,10 +179,15 @@ class BuildComponent():
|
|
|
130
179
|
# 构建命令未指定channel时从package.yml中读取
|
|
131
180
|
pkg["channel"] = self.channel
|
|
132
181
|
pkg["version"] = self.get_package_version()
|
|
133
|
-
self.pkg = pkg
|
|
134
182
|
# 从package.yml加载基础信息
|
|
135
183
|
self.name = pkg.get("name")
|
|
136
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
|
|
137
191
|
|
|
138
192
|
self.package = self.name + "/" + self.version
|
|
139
193
|
if self.user != "litebmc" or self.channel != "release":
|
|
@@ -154,17 +208,14 @@ class BuildComponent():
|
|
|
154
208
|
for k, v in option.items():
|
|
155
209
|
self.base_cmd += f" -o {conan}/*:{k}={v}"
|
|
156
210
|
|
|
157
|
-
#
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
if not self._is_conanfile_tracked:
|
|
161
|
-
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")
|
|
162
214
|
|
|
163
215
|
# 使用litebmc.conanfile.mako模板生成基础litebmc公共conanfile
|
|
164
216
|
lookup = TemplateLookup(directories=os.path.join(lb_cwd, "template"))
|
|
165
217
|
template = lookup.get_template("conanbase.mako")
|
|
166
218
|
conandata = template.render(lookup=lookup, pkg=pkg,
|
|
167
|
-
conanfile_tracked=self._is_conanfile_tracked,
|
|
168
219
|
codegen_version=self.codegen_version,
|
|
169
220
|
codegen_history=history_versions)
|
|
170
221
|
# 写入文件
|
|
@@ -195,6 +246,8 @@ class BuildComponent():
|
|
|
195
246
|
context = info.get("context")
|
|
196
247
|
if context != "host":
|
|
197
248
|
continue
|
|
249
|
+
if ref.startswith(self.package):
|
|
250
|
+
self.package_id = id
|
|
198
251
|
dep = DeployComponent(ref, id, self.rootfs_dir)
|
|
199
252
|
pool.apply_async(dep.run, error_callback=self._copy_failed)
|
|
200
253
|
pool.close()
|
|
@@ -202,30 +255,29 @@ class BuildComponent():
|
|
|
202
255
|
|
|
203
256
|
def build(self):
|
|
204
257
|
log.info(os.getcwd())
|
|
205
|
-
|
|
258
|
+
os.chdir(self.conan_index)
|
|
206
259
|
export_cmd = "conan export . "
|
|
207
260
|
if self.user != "litebmc" or self.channel != "release":
|
|
208
261
|
export_cmd += f"--user={self.user} --channel={self.channel}"
|
|
209
|
-
tools.
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
graph_cmd =
|
|
218
|
-
|
|
219
|
-
log.success(f"start build dependency packages of {self.package}")
|
|
220
|
-
bcp = BuildConanParallel(graphfile, lockfile, self.base_cmd, self.from_source)
|
|
262
|
+
tools.exec(export_cmd, verbose=True)
|
|
263
|
+
|
|
264
|
+
graph_cmd = f"conan graph build-order . {self.base_cmd} --order-by=recipe -f json --out-file={self.orderfile}"
|
|
265
|
+
if self.from_source:
|
|
266
|
+
graph_cmd += " --build='*'"
|
|
267
|
+
else:
|
|
268
|
+
graph_cmd += " --build=missing"
|
|
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)
|
|
221
272
|
bcp.build()
|
|
273
|
+
cmd = f"conan create {self.base_cmd} --build='{self.name}/*'"
|
|
274
|
+
tools.exec(cmd, verbose=True)
|
|
222
275
|
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
tools.run(cmd, capture_output=False)
|
|
276
|
+
graph_cmd = f"conan graph info . {self.base_cmd} -f json --lockfile={self.lockfile}"
|
|
277
|
+
tools.pipe([graph_cmd], out_file=self.graphfile)
|
|
226
278
|
|
|
227
279
|
log.success(f"start deploy {self.package} and is's dependency packages")
|
|
228
|
-
self.deploy(graphfile)
|
|
280
|
+
self.deploy(self.graphfile)
|
|
229
281
|
|
|
230
282
|
if not self.deploy_success:
|
|
231
283
|
raise Exception("Deploy component failed")
|
|
@@ -298,10 +350,19 @@ class BuildComponent():
|
|
|
298
350
|
if not ok:
|
|
299
351
|
raise errors.OdfValidateException("Validate odf files with error, build failed")
|
|
300
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)
|
|
301
361
|
|
|
302
362
|
def run(self):
|
|
303
363
|
cmd = f"conan remove {self.package} -c"
|
|
304
364
|
tools.exec(cmd)
|
|
365
|
+
self.conan_test()
|
|
305
366
|
gen = CodeGen(["-c", "./metadata/package.yml"])
|
|
306
367
|
gen.run()
|
|
307
368
|
# 部署依赖
|
|
@@ -312,32 +373,22 @@ class BuildComponent():
|
|
|
312
373
|
self.upload()
|
|
313
374
|
log.success(f"build {self.package} successfully")
|
|
314
375
|
|
|
315
|
-
@property
|
|
316
|
-
def package_id(self):
|
|
317
|
-
cmd = f"conan graph info . {self.base_cmd} --filter=package_id"
|
|
318
|
-
res = tools.run(cmd)
|
|
319
|
-
match = re.search(r"package_id: ([a-f0-9]{40})", res.stdout)
|
|
320
|
-
if match is None:
|
|
321
|
-
raise errors.LiteBmcException(f"Get package if of {self.package} failed")
|
|
322
|
-
return match.group(1)
|
|
323
|
-
|
|
324
376
|
@staticmethod
|
|
325
377
|
def package_folder(self):
|
|
326
378
|
cmd = f"conan cache path {self.package}#latest:{self.package_id}"
|
|
327
|
-
res = tools.run(cmd)
|
|
379
|
+
res = tools.run(cmd, capture_output=True)
|
|
328
380
|
return res.stdout.strip()
|
|
329
381
|
|
|
330
382
|
@property
|
|
331
383
|
def build_folder(self):
|
|
332
384
|
cmd = f"conan cache path {self.package}#latest:{self.package_id} --folder=build"
|
|
333
|
-
res = tools.run(cmd)
|
|
385
|
+
res = tools.run(cmd, capture_output=True)
|
|
334
386
|
return res.stdout.strip()
|
|
335
387
|
|
|
336
388
|
def test(self):
|
|
337
389
|
try:
|
|
338
390
|
self.run()
|
|
339
391
|
except Exception as e:
|
|
340
|
-
log.error(
|
|
341
|
-
f"build {self.package} {Color.RED}failed{Color.RESET_ALL}")
|
|
392
|
+
log.error(f"build {self.package} failed")
|
|
342
393
|
log.info(e)
|
|
343
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
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
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":
|
|
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":
|
|
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:
|