lbkit 0.7.4__tar.gz → 0.8.1__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 (60) hide show
  1. {lbkit-0.7.4/lbkit.egg-info → lbkit-0.8.1}/PKG-INFO +1 -1
  2. lbkit-0.8.1/lbkit/__init__.py +2 -0
  3. {lbkit-0.7.4 → lbkit-0.8.1}/lbkit/codegen/codegen.py +48 -44
  4. {lbkit-0.7.4 → lbkit-0.8.1}/lbkit/codegen/ctype_defination.py +7 -14
  5. {lbkit-0.7.4 → lbkit-0.8.1}/lbkit/codegen/idf_interface.py +6 -2
  6. {lbkit-0.7.4 → lbkit-0.8.1}/lbkit/codegen/template/client.c.mako +7 -2
  7. {lbkit-0.7.4 → lbkit-0.8.1}/lbkit/codegen/template/client.h.mako +2 -7
  8. {lbkit-0.7.4 → lbkit-0.8.1}/lbkit/codegen/template/public.c.mako +22 -10
  9. {lbkit-0.7.4 → lbkit-0.8.1}/lbkit/codegen/template/public.h.mako +6 -14
  10. {lbkit-0.7.4 → lbkit-0.8.1}/lbkit/codegen/template/server.c.mako +8 -3
  11. {lbkit-0.7.4 → lbkit-0.8.1}/lbkit/codegen/template/server.h.mako +2 -7
  12. {lbkit-0.7.4 → lbkit-0.8.1}/lbkit/component/arg_parser.py +5 -2
  13. {lbkit-0.7.4 → lbkit-0.8.1}/lbkit/component/build.py +2 -0
  14. {lbkit-0.7.4 → lbkit-0.8.1}/lbkit/component/test.py +9 -6
  15. {lbkit-0.7.4 → lbkit-0.8.1}/lbkit/integration/build_manifest.py +15 -4
  16. {lbkit-0.7.4 → lbkit-0.8.1}/lbkit/integration/config.py +7 -1
  17. {lbkit-0.7.4 → lbkit-0.8.1}/lbkit/misc.py +3 -0
  18. {lbkit-0.7.4 → lbkit-0.8.1}/lbkit/tools.py +4 -3
  19. {lbkit-0.7.4 → lbkit-0.8.1}/lbkit/utils/version.py +6 -9
  20. {lbkit-0.7.4 → lbkit-0.8.1/lbkit.egg-info}/PKG-INFO +1 -1
  21. {lbkit-0.7.4 → lbkit-0.8.1}/test/test_codegen.py +51 -28
  22. lbkit-0.7.4/lbkit/__init__.py +0 -2
  23. {lbkit-0.7.4 → lbkit-0.8.1}/AUTHORS +0 -0
  24. {lbkit-0.7.4 → lbkit-0.8.1}/LICENSE +0 -0
  25. {lbkit-0.7.4 → lbkit-0.8.1}/MANIFEST.in +0 -0
  26. {lbkit-0.7.4 → lbkit-0.8.1}/README.md +0 -0
  27. {lbkit-0.7.4 → lbkit-0.8.1}/lbkit/build_conan_parallel.py +0 -0
  28. {lbkit-0.7.4 → lbkit-0.8.1}/lbkit/ci_robot/__init__.py +0 -0
  29. {lbkit-0.7.4 → lbkit-0.8.1}/lbkit/ci_robot/gitee.py +0 -0
  30. {lbkit-0.7.4 → lbkit-0.8.1}/lbkit/cli.py +0 -0
  31. {lbkit-0.7.4 → lbkit-0.8.1}/lbkit/codegen/__init__.py +0 -0
  32. {lbkit-0.7.4 → lbkit-0.8.1}/lbkit/codegen/renderer.py +0 -0
  33. {lbkit-0.7.4 → lbkit-0.8.1}/lbkit/codegen/template/interface.c.mako +0 -0
  34. {lbkit-0.7.4 → lbkit-0.8.1}/lbkit/codegen/template/interface.introspect.xml.mako +0 -0
  35. {lbkit-0.7.4 → lbkit-0.8.1}/lbkit/component/__init__.py +0 -0
  36. {lbkit-0.7.4 → lbkit-0.8.1}/lbkit/component/template/conanbase.mako +0 -0
  37. {lbkit-0.7.4 → lbkit-0.8.1}/lbkit/component/template/deploy.mako +0 -0
  38. {lbkit-0.7.4 → lbkit-0.8.1}/lbkit/errors.py +0 -0
  39. {lbkit-0.7.4 → lbkit-0.8.1}/lbkit/helper.py +0 -0
  40. {lbkit-0.7.4 → lbkit-0.8.1}/lbkit/integration/__init__.py +0 -0
  41. {lbkit-0.7.4 → lbkit-0.8.1}/lbkit/integration/build_image.py +0 -0
  42. {lbkit-0.7.4 → lbkit-0.8.1}/lbkit/integration/build_prepare.py +0 -0
  43. {lbkit-0.7.4 → lbkit-0.8.1}/lbkit/integration/build_rootfs.py +0 -0
  44. {lbkit-0.7.4 → lbkit-0.8.1}/lbkit/integration/task.py +0 -0
  45. {lbkit-0.7.4 → lbkit-0.8.1}/lbkit/integration/template/conanfile.py.mako +0 -0
  46. {lbkit-0.7.4 → lbkit-0.8.1}/lbkit/integration/template/rootfs.py.mako +0 -0
  47. {lbkit-0.7.4 → lbkit-0.8.1}/lbkit/lbkit.py +0 -0
  48. {lbkit-0.7.4 → lbkit-0.8.1}/lbkit/log.py +0 -0
  49. {lbkit-0.7.4 → lbkit-0.8.1}/lbkit/utils/__init__.py +0 -0
  50. {lbkit-0.7.4 → lbkit-0.8.1}/lbkit/utils/images/__init__.py +0 -0
  51. {lbkit-0.7.4 → lbkit-0.8.1}/lbkit/utils/images/emmc.py +0 -0
  52. {lbkit-0.7.4 → lbkit-0.8.1}/lbkit.egg-info/SOURCES.txt +0 -0
  53. {lbkit-0.7.4 → lbkit-0.8.1}/lbkit.egg-info/dependency_links.txt +0 -0
  54. {lbkit-0.7.4 → lbkit-0.8.1}/lbkit.egg-info/entry_points.txt +0 -0
  55. {lbkit-0.7.4 → lbkit-0.8.1}/lbkit.egg-info/requires.txt +0 -0
  56. {lbkit-0.7.4 → lbkit-0.8.1}/lbkit.egg-info/top_level.txt +0 -0
  57. {lbkit-0.7.4 → lbkit-0.8.1}/setup.cfg +0 -0
  58. {lbkit-0.7.4 → lbkit-0.8.1}/setup.py +0 -0
  59. {lbkit-0.7.4 → lbkit-0.8.1}/test/__init__.py +0 -0
  60. {lbkit-0.7.4 → lbkit-0.8.1}/test/test_helper.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: lbkit
3
- Version: 0.7.4
3
+ Version: 0.8.1
4
4
  Summary: Tools provided by litebmc.com
5
5
  Home-page: https://www.litebmc.com
6
6
  Author: xuhj@litebmc.com
@@ -0,0 +1,2 @@
1
+
2
+ __version__ = '0.8.1'
@@ -3,6 +3,7 @@
3
3
  """
4
4
  import os
5
5
  import sys
6
+ import re
6
7
  import json
7
8
  import yaml
8
9
  import argparse
@@ -18,50 +19,69 @@ from lbkit.misc import SmartFormatter
18
19
  lb_cwd = os.path.split(os.path.realpath(__file__))[0]
19
20
  log = Logger("codegen")
20
21
 
22
+
23
+ class CodeGenHistory():
24
+ def __init__(self, lb_base: str, description: str):
25
+ self.lb_base = lb_base
26
+ self.description = description
27
+
21
28
  # 历史自动生成版本号,计划用于用于生成代码稳定性测试
22
29
  # TODO: 支持生成代码稳定性测试,确保生成的代码一致性
23
30
  history_versions = {
24
- "5.0": "简化枚举变更在接口间传递时的字符串定义"
31
+ "5.0": CodeGenHistory("lb_base/[>=0.8.1 <0.9.0]", "简化接口类名定义;简化枚举变量在接口间传递时的字符串定义")
25
32
  }
26
33
  __version__=Version("5.0")
27
34
 
28
35
 
29
36
  def version_check(ver_str: str):
30
- ver = Version(ver_str)
31
- if history_versions.get(ver_str):
32
- return ver
33
- found = False
34
- if ver.minor == X_VER:
35
- major_str = str(ver.major) + "."
36
- for v, _ in history_versions.items():
37
- if v.startswith(major_str):
38
- found = True
39
- break
40
- if not found:
37
+ if not re.match("^([0-9]|([1-9][0-9]*))\\.([0-9]|([1-9][0-9]*))$", ver_str):
38
+ raise Exception(f"Version string {ver_str} not match with regex ^([0-9]|([1-9][0-9]*))\\.([0-9]|([1-9][0-9]*))$")
39
+ if "x" not in ver_str:
40
+ return ver_str
41
+ if not history_versions.get(ver_str):
41
42
  log.error(f"Unkonw codegen version {ver_str}, supported versions:")
42
43
  for ver, msg in history_versions.items():
43
44
  log.error(f" {ver}: {msg}")
44
- raise Exception("Unkonw codegen version get")
45
- return ver
45
+ raise Exception(f"Can't found the valid version for {ver_str}")
46
+
47
+
48
+ def codegen_version_arg(parser: argparse.ArgumentParser, default=__version__.str, short_arg="-cv", full_arg="--codegen_version"):
49
+ # 默认的自动生成工具版本号为2
50
+ help=f'''must less than or equal to {__version__.str}, default: {default}
51
+
52
+ codegen versions:
53
+ '''
54
+ for ver, detail in history_versions.items():
55
+ help += f"- {ver}: compatible with {detail.lb_base}, {detail.description}\n"
56
+ parser.add_argument(short_arg, full_arg, help=help, type=str, default=__version__.str)
57
+
46
58
 
47
59
  class CodeGen(object):
48
60
  def __init__(self, args):
49
61
  self.args = args
50
62
  self.codegen_version = __version__
51
63
 
52
- def _gen(self, idf_file, directory="."):
64
+ def _gen(self, idf_file, directory=".", code_type="all"):
53
65
  directory = os.path.realpath(directory)
54
- os.makedirs(os.path.join(directory, "public"), exist_ok=True)
55
- os.makedirs(os.path.join(directory, "server"), exist_ok=True)
56
- os.makedirs(os.path.join(directory, "client"), exist_ok=True)
57
66
  interface = self.get_interface(idf_file)
58
- out_file = os.path.join(directory, "public", interface.name + ".xml")
59
- interface.render_dbus_xml("interface.introspect.xml.mako", out_file)
60
- for code_type in ["server", "client", "public"]:
61
- out_file = os.path.join(directory, code_type, interface.name + ".h")
62
- interface.render_c_source(code_type + ".h.mako", out_file)
63
- out_file = os.path.join(directory, code_type, interface.name + ".c")
64
- interface.render_c_source(code_type + ".c.mako", out_file)
67
+ code_types = ["server", "client", "public"]
68
+ if code_type != "all":
69
+ code_types = [code_type]
70
+ for ct in code_types:
71
+ os.makedirs(os.path.join(directory, ct), exist_ok=True)
72
+ out_file = os.path.join(directory, ct, interface.name + ".xml")
73
+ interface.render_dbus_xml("interface.introspect.xml.mako", out_file)
74
+ out_file = os.path.join(directory, ct, interface.name + ".h")
75
+ interface.render_c_source(ct + ".h.mako", out_file)
76
+ out_file = os.path.join(directory, ct, interface.name + ".c")
77
+ interface.render_c_source(ct + ".c.mako", out_file)
78
+ if "server" == ct:
79
+ # 生成接口schema文件
80
+ odf_file = os.path.join(directory, "server", "schema", f"{interface.name}.json")
81
+ os.makedirs(os.path.dirname(odf_file), exist_ok=True)
82
+ odf_data = interface.odf_schema
83
+ with open(odf_file, "w", encoding="utf-8") as fp:
84
+ json.dump(odf_data, fp, sort_keys=False, indent=4)
65
85
  json_file = os.path.join(directory, "package.yml")
66
86
  data = {
67
87
  "version": interface.version,
@@ -70,13 +90,6 @@ class CodeGen(object):
70
90
  with open(json_file, "w", encoding="utf-8") as fp:
71
91
  yaml.dump(data, fp, encoding='utf-8', allow_unicode=True)
72
92
 
73
- # 生成接口schema文件
74
- odf_file = os.path.join(directory, "server", "schema", f"{interface.name}.json")
75
- os.makedirs(os.path.dirname(odf_file), exist_ok=True)
76
- odf_data = interface.odf_schema
77
- with open(odf_file, "w", encoding="utf-8") as fp:
78
- json.dump(odf_data, fp, sort_keys=False, indent=4)
79
-
80
93
  def get_interface(self, idf_file):
81
94
  lookup = TemplateLookup(directories=os.path.join(lb_cwd, "template"))
82
95
  return IdfInterface(lookup, idf_file, self.codegen_version)
@@ -90,18 +103,9 @@ class CodeGen(object):
90
103
  parser = argparse.ArgumentParser(description=self.run.__doc__,
91
104
  prog="lbkit gen",
92
105
  formatter_class=SmartFormatter)
93
- # 默认的自动生成工具版本号为2
94
- parser.add_argument("-cv", "--codegen_version", help=f'''must less than or equal to {__version__.str}, default: {__version__.str}
95
- format: major.version
96
- for example: 1.3、2.4、3.3
97
-
98
- description of changes:
99
- 4.x: compatible with lb_base/0.8.x
100
- 3.x: compatible with lb_base/0.7.x
101
- 2.x: compatible with lb_base/0.6.x
102
- ''',
103
- type=str, default=__version__.str)
106
+ codegen_version_arg(parser)
104
107
  parser.add_argument("-d", "--directory", help='generate code directory', default=".")
108
+ parser.add_argument("-t", "--codetype", help='code type, default: all', default="all", choices=["public", "server", "client", "all"])
105
109
  group2 = parser.add_argument_group('cdf file', 'Generate code using the specified CDF file')
106
110
  group2.add_argument("-c", "--cdf_file", help='component description file, default metadata/package.yml', default=None)
107
111
  group1 = parser.add_argument_group('idf file', 'Generate code using the specified IDF file')
@@ -150,7 +154,7 @@ class CodeGen(object):
150
154
  if not os.path.isdir(out_dir):
151
155
  log.warning(f"Directory {args.directory} not exist, try create")
152
156
  os.makedirs(out_dir)
153
- self._gen(intf_file, out_dir)
157
+ self._gen(intf_file, out_dir, args.codetype)
154
158
 
155
159
  if __name__ == "__main__":
156
160
  gen = CodeGen(sys.argv)
@@ -4,20 +4,19 @@ from lbkit.errors import OdfValidateException
4
4
 
5
5
 
6
6
  class IdfValidator():
7
- validator = {}
8
- name = ""
7
+ def __init__(self):
8
+ self.validator = {}
9
+ self.name = ""
9
10
 
10
11
  def set_validator(self, value, name):
11
12
  self.validator = value
12
13
  self.name = name
13
14
 
14
15
  def odf_validate(self):
15
- idf_validator = idf_validator
16
16
  return []
17
17
 
18
18
  def odf_schema(self, allow_ref):
19
19
  allow_ref = allow_ref
20
- idf_validator = idf_validator
21
20
  return None
22
21
 
23
22
 
@@ -73,9 +72,6 @@ class BoolArrayValidator(BoolValidator):
73
72
 
74
73
 
75
74
  class IntegerValidator(IdfValidator):
76
- maximum = sys.maxsize * 2
77
- minimum = -(sys.maxsize + 1) * 2
78
-
79
75
  def __init__(self, max, min, signed=False):
80
76
  self.maximum = max
81
77
  self.minimum = min
@@ -188,13 +184,11 @@ class IntegerArrayValidator(IntegerValidator):
188
184
 
189
185
 
190
186
  class FloatValidator(IdfValidator):
191
- maximum = sys.float_info.max
192
- minimum = -sys.float_info.max
193
-
194
- exclusive_max = None
195
- exclusive_min = None
196
-
197
187
  def __init__(self):
188
+ self.maximum = sys.float_info.max
189
+ self.minimum = -sys.float_info.max
190
+ self.exclusive_max = None
191
+ self.exclusive_min = None
198
192
  self.max_key = "maximum"
199
193
  self.max_val = self.maximum
200
194
  self.min_key = "minimum"
@@ -294,7 +288,6 @@ class FloatArrayValidator(FloatValidator):
294
288
 
295
289
 
296
290
  class StringValidator(IdfValidator):
297
- pattern = None
298
291
  def __init__(self, pattern):
299
292
  self.pattern = pattern
300
293
  super().__init__()
@@ -240,7 +240,7 @@ class IdfCtypeRender():
240
240
  if "refobj" in self.flags:
241
241
  valiator = RefObjValidator()
242
242
  return valiator.odf_schema(allow_ref)
243
- ctype_obj = CTYPE_OBJS.get(self.ctype)
243
+ ctype_obj = copy.deepcopy(CTYPE_OBJS.get(self.ctype))
244
244
  validator = ctype_obj.validator
245
245
  if validator_cfg:
246
246
  validator.set_validator(validator_cfg, self.name)
@@ -1067,13 +1067,17 @@ class IdfInterface(IdfInterfaceBase):
1067
1067
  realpath = None
1068
1068
  while cwd != "/":
1069
1069
  tmp_path = os.path.join(cwd, intf_path)
1070
+ if os.path.isfile(tmp_path):
1071
+ realpath = tmp_path
1072
+ break
1073
+ tmp_path = os.path.join(cwd, intf + ".yaml")
1070
1074
  if os.path.isfile(tmp_path):
1071
1075
  realpath = tmp_path
1072
1076
  break
1073
1077
  cwd = os.path.dirname(cwd)
1074
1078
 
1075
1079
  if not realpath:
1076
- raise FileNotFoundError(f"Dependency interface {intf} not exist")
1080
+ raise FileNotFoundError(f"Dependency interface {intf} not exist, cwd: {os.getcwd()}")
1077
1081
  log.debug(f"Found dependency interface: {realpath}")
1078
1082
  deps[intf] = (IdfInterface(self.lookup, realpath, self.codegen_version))
1079
1083
  return deps
@@ -296,9 +296,14 @@ GSList *${class_name}_list(void)
296
296
 
297
297
  % for prop in intf.properties:
298
298
  /* 监听属性${prop.name}变更 */
299
- void ${class_name}_${prop.name}_hook(const ${class_name}_property_hook *hook)
299
+ void ${class_name}_${prop.name}_hook(${class_name}_before_change_hook before, ${class_name}_after_changed_hook after, gpointer user_data)
300
300
  {
301
- lb_impl._prop_hook(&${properties}.${prop.name}, (const LBPropertyHook *)hook);
301
+ LBPropertyHook hook = {
302
+ .before = (lbo_before_change_hook)before,
303
+ .after = (lbo_after_changed_hook)after,
304
+ .user_data = user_data
305
+ };
306
+ lb_impl._prop_hook(&${properties}.${prop.name}, &hook);
302
307
  }
303
308
 
304
309
  % endfor
@@ -118,12 +118,6 @@ typedef void (*${class_name}_after_changed_hook)(${class_name} object, const LBP
118
118
  /* notes: 属性变更前回调,返回-1表示阻止值变更,一般用于值合法性校验,只在被远程操作时才会生效,本地变更值不会回调 */
119
119
  typedef gint (*${class_name}_before_change_hook)(${class_name} object, const LBProperty *prop, GVariant *value, gpointer user_data, GError **error);
120
120
 
121
- /* 属性值变更回调钩子 */
122
- typedef struct {
123
- ${class_name}_after_changed_hook after; /* 属性变更(写入对象数据区后)后回调函数 */
124
- ${class_name}_before_change_hook before; /* 属性变更前回调函数,返回0后继续调用,返回非0时中止,所有before都成功时执行属性变更 */
125
- gpointer user_data;
126
- } ${class_name}_property_hook;
127
121
  /* 查询对象 */
128
122
  ${class_name} ${class_name}_get(const gchar *well_known, const gchar *name);
129
123
  /* 创建对象 */
@@ -165,7 +159,8 @@ void ${class_name}_unlock(${class_name} obj);
165
159
  GSList *${class_name}_list(void);
166
160
  /* 监听属性 */
167
161
  % for prop in intf.properties:
168
- void ${class_name}_${prop.name}_hook(const ${class_name}_property_hook *hook);
162
+ void ${class_name}_${prop.name}_hook(${class_name}_before_change_hook before, ${class_name}_after_changed_hook after,
163
+ gpointer user_data);
169
164
  % endfor
170
165
 
171
166
  static inline void ${class_name}_unref_p(${class_name} obj)
@@ -962,9 +962,20 @@ const ${class_name}_Properties *${class_name}_properties_const(void)
962
962
 
963
963
  % for method in intf.fake_methods:
964
964
  % if not method.is_plugin:
965
+ ## 方法${method.name}的默认实现
966
+ /* 方法${class_name}_${method.name}的默认实现 */
967
+ __weak int ${class_name}_${method.name}(${class_name} object,
968
+ const ${class_name}_${method.name}_Req *req,
969
+ ${class_name}_${method.name}_Rsp **rsp,
970
+ GError **error, gpointer ext_data)
971
+ {
972
+ *error = LbError_MethodNotImplament_new("${method.name}");
973
+ return -1;
974
+ }
975
+
965
976
  ## 方法${method.name}的请求体序列化函数
966
977
  /* ${class_name}_${method.name}_Req请求结构体类型序列化(struct转GVariant)函数 */
967
- GVariant *${class_name}_${method.name}_Req_encode(${class_name}_${method.name}_Req *value)
978
+ static GVariant *${class_name}_${method.name}_Req_encode(${class_name}_${method.name}_Req *value)
968
979
  {
969
980
  static ${class_name}_${method.name}_Req default_val;
970
981
  if (!value) {
@@ -985,7 +996,7 @@ GVariant *${class_name}_${method.name}_Req_encode(${class_name}_${method.name}_R
985
996
 
986
997
  ## 方法${method.name}的请求体反序列化函数
987
998
  /* ${class_name}_${method.name}_Req结构体类型反序列化(GVariant转struct)函数,返回以NULL结束的指针数组 */
988
- ${class_name}_${method.name}_Req *${class_name}_${method.name}_Req_decode(GVariant *in)
999
+ static ${class_name}_${method.name}_Req *${class_name}_${method.name}_Req_decode(GVariant *in)
989
1000
  {
990
1001
  GVariantIter iter;
991
1002
  __attribute__((unused)) GVariant *tmp = NULL;
@@ -1005,11 +1016,11 @@ ${class_name}_${method.name}_Req *${class_name}_${method.name}_Req_decode(GVaria
1005
1016
  % endfor
1006
1017
  return output;
1007
1018
  }
1008
- % endif
1009
1019
 
1020
+ % endif
1010
1021
  ## 方法${method.name}的请求体释放函数
1011
1022
  /* ${class_name}_${method.name}_Req结构体指针释放 */
1012
- void ${class_name}_${method.name}_Req_free(${class_name}_${method.name}_Req **value)
1023
+ static void ${class_name}_${method.name}_Req_free(${class_name}_${method.name}_Req **value)
1013
1024
  {
1014
1025
  if (!value || !(*value)) {
1015
1026
  return;
@@ -1025,7 +1036,7 @@ void ${class_name}_${method.name}_Req_free(${class_name}_${method.name}_Req **va
1025
1036
 
1026
1037
  % if not method.is_plugin:
1027
1038
  /* ${class_name}_${method.name}_Rsp请求结构体类型序列化(struct转GVariant)函数 */
1028
- GVariant *${class_name}_${method.name}_Rsp_encode(${class_name}_${method.name}_Rsp *value)
1039
+ static GVariant *${class_name}_${method.name}_Rsp_encode(${class_name}_${method.name}_Rsp *value)
1029
1040
  {
1030
1041
  static ${class_name}_${method.name}_Rsp default_val;
1031
1042
  if (!value) {
@@ -1046,7 +1057,7 @@ GVariant *${class_name}_${method.name}_Rsp_encode(${class_name}_${method.name}_R
1046
1057
 
1047
1058
  ## 方法${method.name}的响应体反序列化函数
1048
1059
  /* ${class_name}_${method.name}_Rsp结构体类型反序列化(GVariant转struct)函数,返回以NULL结束的指针数组 */
1049
- ${class_name}_${method.name}_Rsp *${class_name}_${method.name}_Rsp_decode(GVariant *in)
1060
+ static ${class_name}_${method.name}_Rsp *${class_name}_${method.name}_Rsp_decode(GVariant *in)
1050
1061
  {
1051
1062
  GVariantIter iter;
1052
1063
  __attribute__((unused)) GVariant *tmp = NULL;
@@ -1066,8 +1077,8 @@ ${class_name}_${method.name}_Rsp *${class_name}_${method.name}_Rsp_decode(GVaria
1066
1077
  % endfor
1067
1078
  return output;
1068
1079
  }
1069
- % endif
1070
1080
 
1081
+ % endif
1071
1082
  ## 方法${method.name}的响应体释放函数
1072
1083
  /* ${class_name}_${method.name}_Rsp结构体指针释放 */
1073
1084
  void ${class_name}_${method.name}_Rsp_free(${class_name}_${method.name}_Rsp **value)
@@ -1098,6 +1109,7 @@ static ${class_name}_Methods _${class_name}_methods =
1098
1109
  .rsp_decode = (lbo_message_decode_handler)${class_name}_${method.name}_Rsp_decode,
1099
1110
  .rsp_encode = (lbo_message_encode_handler)${class_name}_${method.name}_Rsp_encode,
1100
1111
  .rsp_free = (lbo_message_free_handler)${class_name}_${method.name}_Rsp_free,
1112
+ .handler = ${class_name}_${method.name},
1101
1113
  },
1102
1114
  % endfor
1103
1115
  .__reserved__ = {
@@ -1217,7 +1229,7 @@ int ${class_name}_${action.name}_run(${class_name} object${REQ_PARA}${RSP_PARA})
1217
1229
  % for signal in intf.signals:
1218
1230
  ## 方法${method.name}的响应体序列化函数
1219
1231
  /* ${class_name}_${signal.name}_Msg请求结构体类型序列化(struct转GVariant)函数 */
1220
- GVariant *${class_name}_${signal.name}_Msg_encode(${class_name}_${signal.name}_Msg *value)
1232
+ static GVariant *${class_name}_${signal.name}_Msg_encode(${class_name}_${signal.name}_Msg *value)
1221
1233
  {
1222
1234
  static ${class_name}_${signal.name}_Msg default_val;
1223
1235
  if (!value) {
@@ -1238,7 +1250,7 @@ GVariant *${class_name}_${signal.name}_Msg_encode(${class_name}_${signal.name}_M
1238
1250
 
1239
1251
  ## 方法${signal.name}的响应体反序列化函数
1240
1252
  /* ${class_name}_${signal.name}_Msg结构体类型反序列化(GVariant转struct)函数,返回以NULL结束的指针数组 */
1241
- ${class_name}_${signal.name}_Msg *${class_name}_${signal.name}_Msg_decode(GVariant *in)
1253
+ static ${class_name}_${signal.name}_Msg *${class_name}_${signal.name}_Msg_decode(GVariant *in)
1242
1254
  {
1243
1255
  GVariantIter iter;
1244
1256
  __attribute__((unused)) GVariant *tmp = NULL;
@@ -1261,7 +1273,7 @@ ${class_name}_${signal.name}_Msg *${class_name}_${signal.name}_Msg_decode(GVaria
1261
1273
 
1262
1274
  ## 方法${signal.name}的响应体释放函数
1263
1275
  /* ${class_name}_${signal.name}_Msg结构体指针释放 */
1264
- void ${class_name}_${signal.name}_Msg_free(${class_name}_${signal.name}_Msg **value)
1276
+ static void ${class_name}_${signal.name}_Msg_free(${class_name}_${signal.name}_Msg **value)
1265
1277
  {
1266
1278
  if (!value || !(*value)) {
1267
1279
  return;
@@ -217,18 +217,12 @@ typedef struct {
217
217
  % endfor
218
218
  } ${class_name}_${method.name}_Rsp;
219
219
 
220
+ void ${class_name}_${method.name}_Rsp_free(${class_name}_${method.name}_Rsp **value);
221
+
220
222
  % if not method.is_plugin:
221
- typedef int (*${class_name}_${method.name}_Method)(${class_name} object,
222
- const ${class_name}_${method.name}_Req *req,
223
- ${class_name}_${method.name}_Rsp **rsp,
224
- GError **error, gpointer ext_data);
223
+ int ${class_name}_${method.name}(${class_name} object, const ${class_name}_${method.name}_Req *req,
224
+ ${class_name}_${method.name}_Rsp **rsp, GError **error, gpointer ext_data);
225
225
  % endif
226
- GVariant *${class_name}_${method.name}_Req_encode(${class_name}_${method.name}_Req *value);
227
- ${class_name}_${method.name}_Req *${class_name}_${method.name}_Req_decode(GVariant *in);
228
- void ${class_name}_${method.name}_Req_free(${class_name}_${method.name}_Req **value);
229
- GVariant *${class_name}_${method.name}_Rsp_encode(${class_name}_${method.name}_Rsp *value);
230
- ${class_name}_${method.name}_Rsp *${class_name}_${method.name}_Rsp_decode(GVariant *in);
231
- void ${class_name}_${method.name}_Rsp_free(${class_name}_${method.name}_Rsp **value);
232
226
  %endfor
233
227
 
234
228
  /* ${intf.name}的方法集合 */
@@ -244,7 +238,8 @@ typedef struct {
244
238
  lbo_message_decode_handler rsp_decode;
245
239
  lbo_message_encode_handler rsp_encode;
246
240
  lbo_message_free_handler rsp_free;
247
- ${class_name}_${method.name}_Method handler;
241
+ int (*handler)(${class_name} object, const ${class_name}_${method.name}_Req *req,
242
+ ${class_name}_${method.name}_Rsp **rsp, GError **error, gpointer ext_data);
248
243
  } ${method.name};
249
244
  % endfor
250
245
  LBMethod __reserved__;
@@ -280,9 +275,6 @@ typedef struct {
280
275
  % endfor
281
276
  % endfor
282
277
  } ${class_name}_${signal.name}_Msg;
283
- ${class_name}_${signal.name}_Msg *${class_name}_${signal.name}_Msg_decode(GVariant *in);
284
- GVariant *${class_name}_${signal.name}_Msg_encode(${class_name}_${signal.name}_Msg *value);
285
- void ${class_name}_${signal.name}_Msg_free(${class_name}_${signal.name}_Msg **value);
286
278
 
287
279
  %endfor
288
280
  typedef struct {
@@ -585,9 +585,14 @@ GSList *${class_name}_list(void)
585
585
 
586
586
  % for prop in intf.properties:
587
587
  /* 监听属性${prop.name}变更 */
588
- void ${class_name}_${prop.name}_hook(const ${class_name}_property_hook *hook)
589
- {
590
- lb_impl._prop_hook(&${properties}.${prop.name}, (const LBPropertyHook *)hook);
588
+ void ${class_name}_${prop.name}_hook(${class_name}_before_change_hook before, ${class_name}_after_changed_hook after, gpointer user_data)
589
+ {
590
+ LBPropertyHook hook = {
591
+ .before = (lbo_before_change_hook)before,
592
+ .after = (lbo_after_changed_hook)after,
593
+ .user_data = user_data
594
+ };
595
+ lb_impl._prop_hook(&${properties}.${prop.name}, &hook);
591
596
  }
592
597
 
593
598
  % endfor
@@ -64,12 +64,6 @@ typedef void (*${class_name}_after_changed_hook)(${class_name} object, const LBP
64
64
  /* notes: 属性变更前回调,返回-1表示阻止值变更,一般用于值合法性校验,只在被远程操作时才会生效,本地变更值不会回调 */
65
65
  typedef gint (*${class_name}_before_change_hook)(${class_name} object, const LBProperty *prop, GVariant *value, gpointer user_data, GError **error);
66
66
 
67
- /* 属性值变更回调钩子 */
68
- typedef struct {
69
- ${class_name}_after_changed_hook after; /* 属性变更(写入对象数据区后)后回调函数 */
70
- ${class_name}_before_change_hook before; /* 属性变更前回调函数,返回0后继续调用,返回非0时中止,所有before都成功时执行属性变更 */
71
- gpointer user_data;
72
- } ${class_name}_property_hook;
73
67
  /* 查询对象 */
74
68
  ${class_name} ${class_name}_get(const gchar *name);
75
69
  /* 创建对象 */
@@ -114,7 +108,8 @@ void ${class_name}_unlock(${class_name} obj);
114
108
  GSList *${class_name}_list(void);
115
109
  /* 监听属性 */
116
110
  % for prop in intf.properties:
117
- void ${class_name}_${prop.name}_hook(const ${class_name}_property_hook *hook);
111
+ void ${class_name}_${prop.name}_hook(${class_name}_before_change_hook before, ${class_name}_after_changed_hook after,
112
+ gpointer user_data);
118
113
  % endfor
119
114
 
120
115
  static inline void ${class_name}_unref_p(${class_name} obj)
@@ -1,7 +1,8 @@
1
1
  """组件公共参数"""
2
2
  import argparse
3
3
  import os
4
- from argparse import RawTextHelpFormatter
4
+ from lbkit.misc import SmartFormatter
5
+ from lbkit.codegen.codegen import codegen_version_arg
5
6
 
6
7
  cwd = os.getcwd()
7
8
  lb_cwd = os.path.split(os.path.realpath(__file__))[0]
@@ -11,7 +12,7 @@ class ArgParser():
11
12
  @staticmethod
12
13
  def new(add_help=True):
13
14
  parser = argparse.ArgumentParser(
14
- description="Build component", add_help=add_help, formatter_class=RawTextHelpFormatter)
15
+ description="Build component", add_help=add_help, formatter_class=SmartFormatter)
15
16
  parser.add_argument("-t", "--build_type", default="Debug",
16
17
  help="Build type(Same as conan's settings.build_type), only Debug,Release can be accepted")
17
18
  parser.add_argument("-pr", "--profile", default="default",
@@ -35,4 +36,6 @@ class ArgParser():
35
36
  parser.add_argument(
36
37
  "-c", "--channel", help='Provide a channel if not specified in mds/package.yml\ndefault value: dev', default="dev")
37
38
  parser.add_argument('-o','--pkg_options', action='append', help='Define options values (host machine), e.g.: -o pkg/*:shared=True', required=False, default=[])
39
+ # 默认的自动生成工具版本号为
40
+ codegen_version_arg(parser, None)
38
41
  return parser
@@ -83,6 +83,8 @@ class BuildComponent():
83
83
  self.base_cmd += f" -o {self.name}/*:test=True"
84
84
  for pkg_option in self.options.pkg_options:
85
85
  self.base_cmd += " -o " + pkg_option
86
+ if self.options.codegen_version:
87
+ self.base_cmd += f" -o */*:codegen_version={self.options.codegen_version}"
86
88
 
87
89
  def get_package_version(self):
88
90
  """
@@ -75,14 +75,17 @@ class TestComponent():
75
75
  res = tool.run(cmd)
76
76
  files = res.stdout.strip().split("\n")
77
77
  ld_library_path = os.environ.get("LD_LIBRARY_PATH", "").strip()
78
- library_path = []
79
- if ld_library_path != "":
80
- library_path = ld_library_path.split(":")
78
+ paths = []
79
+ for path in ld_library_path.split(":"):
80
+ if not path:
81
+ continue
82
+ if not ".temp/rootfs" in path:
83
+ paths.append(path)
81
84
  for file in files:
82
85
  dir = os.path.dirname(file)
83
- if dir not in library_path:
84
- library_path.append(dir)
85
- os.environ["LD_LIBRARY_PATH"] = ":".join(library_path)
86
+ if dir not in paths:
87
+ paths.append(dir)
88
+ os.environ["LD_LIBRARY_PATH"] = ":".join(paths)
86
89
 
87
90
  def run(self):
88
91
  # 构建组件
@@ -9,6 +9,7 @@ from lbkit.log import Logger
9
9
  from lbkit.build_conan_parallel import BuildConanParallel
10
10
  from concurrent.futures import ThreadPoolExecutor
11
11
  from lbkit.errors import LiteBmcException
12
+ from lbkit.codegen.codegen import __version__ as codegen_version
12
13
 
13
14
  log = Logger("product_build")
14
15
 
@@ -35,6 +36,10 @@ class BuildManifest(Task):
35
36
  self.common_args = "-r " + self.config.remote
36
37
  self.common_args += " -pr:b {} -pr:h {}".format(self.config.profile_build, self.config.profile_host)
37
38
  self.common_args += " -o */*:test=False"
39
+ cv = self.get_manifest_config("metadata/codegen_version")
40
+ if cv == "latest":
41
+ cv = codegen_version.str
42
+ self.common_args += " -o */*:codegen_version=" + cv
38
43
 
39
44
  def deploy(self, graph_file):
40
45
  with open(graph_file, "r") as fp:
@@ -85,7 +90,7 @@ class BuildManifest(Task):
85
90
  fp.write(conanfile)
86
91
  fp.close()
87
92
 
88
- self.exec("conan create . " + self.common_args)
93
+ self.exec("conan create . " + self.common_args, verbose=True)
89
94
 
90
95
  def build_litebmc(self):
91
96
  """构建产品conan包"""
@@ -107,11 +112,17 @@ class BuildManifest(Task):
107
112
  fp.close()
108
113
 
109
114
  base_cmd = f"{self.common_args} {self.conan_settings}"
110
- lockfile = os.path.join(self.config.temp_path, "conan.lock")
111
115
  threadPool = ThreadPoolExecutor(max_workers=16)
116
+ if self.config.using_lockfile:
117
+ lockfile = os.path.join(self.config.code_path, "conan.lock")
118
+ else:
119
+ lockfile = os.path.join(self.config.temp_path, "conan.lock")
112
120
  # 创建新的conan.lock文件
113
- lock_cmd = f"conan lock create . {base_cmd} --lockfile-out={lockfile}"
114
- self.exec(lock_cmd)
121
+ if not self.config.using_lockfile or self.config.update_lockfile:
122
+ lock_cmd = f"conan lock create . {base_cmd} --lockfile-out={lockfile}"
123
+ self.exec(lock_cmd, verbose=True)
124
+ if not os.path.isfile(lockfile):
125
+ raise FileNotFoundError("lockfile ./conan.lock was not found")
115
126
  with open(lockfile, "r") as fp:
116
127
  lock = json.load(fp)
117
128
  for key in ["requires", "build_requires", "python_requires", "config_requires"]:
@@ -35,6 +35,10 @@ class Config(object):
35
35
  # 编译目标配置项
36
36
  self.profile_host = args.profile
37
37
 
38
+ # conan.lock options
39
+ self.using_lockfile = args.lockfile
40
+ self.update_lockfile = args.update_lockfile
41
+
38
42
  # 设置并创建构建所需目录
39
43
  log.info("Work dir: %s", self.work_dir)
40
44
  self.code_path = os.getcwd()
@@ -59,12 +63,14 @@ class Config(object):
59
63
  def arg_parser():
60
64
  """返回配置项支持的参数"""
61
65
  parser = argparse.ArgumentParser(description="Build LiteBMC")
62
- parser.add_argument("-m", "--manifest", help="Specify the manifest.yml ", default="./manifest.yml")
66
+ parser.add_argument("-m", "--manifest", help="Specify the manifest.yml, ignored when -l is specified.", default="./manifest.yml")
63
67
  parser.add_argument("-s", "--from_source", help="Build from source", action="store_true")
64
68
  parser.add_argument("-pr", "--profile", help="Apply the specified profile to the host machine", default="litebmc.ini")
65
69
  parser.add_argument("-pr:b", "--profile_build", help="Apply the specified profile to the build machine", default="default")
66
70
  parser.add_argument("-t", "--build_type", type=str, choices=['debug', 'release', 'minsize'], help="Set the build type", default="debug")
67
71
  parser.add_argument("-r", "--remote", help="specified conan server", default="litebmc")
72
+ parser.add_argument("-l", "--lockfile", help="using conan.lock", action="store_true")
73
+ parser.add_argument("-ul", "--update_lockfile", help="update conan.lock", action="store_true")
68
74
  return parser
69
75
 
70
76
  def get_manifest_config(self, key: str, default=None):
@@ -55,6 +55,9 @@ class SmartFormatter(argparse.HelpFormatter):
55
55
  def _split_lines(self, text, width):
56
56
  ret = []
57
57
  for line in text.split("\n"):
58
+ if not line.strip():
59
+ ret.extend(" ")
60
+ continue
58
61
  ret.extend(super()._split_lines(line, width))
59
62
  return ret
60
63
 
@@ -17,9 +17,10 @@ from lbkit.misc import Color
17
17
 
18
18
  class Tools(object):
19
19
  """基础工具类"""
20
- def __init__(self, log_name: str):
21
- os.makedirs(misc.LOG_DIR, exist_ok=True)
22
- self.log_name = os.path.join(misc.LOG_DIR, f"{log_name}.log")
20
+ def __init__(self, log_name: str, log_dir: str=".temp"):
21
+ self.log_dir = os.path.realpath(log_dir)
22
+ os.makedirs(self.log_dir, exist_ok=True)
23
+ self.log_name = os.path.join(self.log_dir, f"{log_name}.log")
23
24
  self.log: Logger = Logger(log_name)
24
25
 
25
26
  @staticmethod
@@ -5,19 +5,16 @@ X_VER = 0x7fff_ffff
5
5
 
6
6
  class Version():
7
7
  def __init__(self, ver_str):
8
- if not re.match("^([0-9]|([1-9][0-9]*))\\.(x|[0-9]|([1-9][0-9]*))$", ver_str):
8
+ if not re.match("^([0-9]|([1-9][0-9]*))\\.([0-9]|([1-9][0-9]*))$", ver_str):
9
9
  raise Exception("Version string {ver_str} not match with regex ^([0-9]|([1-9][0-9]*))\\.([0-9]|([1-9][0-9]*))$")
10
10
  chunks = ver_str.split(".")
11
11
  self.major = int(chunks[0])
12
- if chunks[1] == "x":
13
- self.minor = X_VER
14
- else:
15
- self.minor = int(chunks[1])
16
- self.str = ver_str
12
+ self.minor = int(chunks[1])
13
+ self.str = str(self.major) + "." + str(self.minor)
17
14
 
18
15
  def bt(self, next_ver):
19
16
  next = Version(next_ver)
20
- if self.major > next.major or (self.major == next.major and (self.minor > next.minor and self.minor != X_VER)):
17
+ if self.major > next.major or (self.major == next.major and self.minor > next.minor):
21
18
  return True
22
19
  return False
23
20
 
@@ -29,13 +26,13 @@ class Version():
29
26
 
30
27
  def lt(self, next_ver):
31
28
  next = Version(next_ver)
32
- if self.major < next.major or (self.major == next.major and (self.minor < next.minor and next.minor != X_VER and next.minor != X_VER)):
29
+ if self.major < next.major or (self.major == next.major and self.minor < next.minor):
33
30
  return True
34
31
  return False
35
32
 
36
33
  def le(self, next_ver):
37
34
  next = Version(next_ver)
38
- if self.major < next.major or (self.major == next.major and (self.minor <= next.minor or self.minor == X_VER)):
35
+ if self.major < next.major or (self.major == next.major and self.minor <= next.minor):
39
36
  return True
40
37
  return False
41
38
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: lbkit
3
- Version: 0.7.4
3
+ Version: 0.8.1
4
4
  Summary: Tools provided by litebmc.com
5
5
  Home-page: https://www.litebmc.com
6
6
  Author: xuhj@litebmc.com
@@ -1,12 +1,14 @@
1
1
  import unittest
2
2
  import tempfile
3
3
  import os
4
+ import json
4
5
  import tracemalloc
5
6
 
6
7
  tracemalloc.start()
7
8
  from lbkit.codegen.idf_interface import IdfInterface
8
9
  from lbkit import errors
9
10
  from lbkit.codegen.codegen import __version__ as codegen_version
11
+ from lbkit.codegen.codegen import history_versions as codegen_history
10
12
  from lbkit.utils.version import Version
11
13
 
12
14
  schema_dir = os.path.realpath(os.path.join(os.getcwd(), "..", "schema"))
@@ -28,7 +30,7 @@ class TestCodeGenClass(unittest.TestCase):
28
30
  def mk_interface_with_number_property(self, name, type, max, min, default_val):
29
31
  with open(self.tmp_file, mode="w+") as fp:
30
32
  fp.write(f"# yaml-language-server: $schema={schema_dir}/idf.v1.json\n")
31
- fp.write("version: \"0.1\"\n")
33
+ fp.write("version: 1\n")
32
34
  fp.write("description: 测试接口,用于验证lb_base/lb_core,同时验证自动生成逻辑\n")
33
35
  fp.write("alias: Test\n")
34
36
  fp.write("properties:\n")
@@ -42,7 +44,7 @@ class TestCodeGenClass(unittest.TestCase):
42
44
  def mk_interface_with_string_property(self, name, type, pattern, default_val):
43
45
  with open(self.tmp_file, mode="w+") as fp:
44
46
  fp.write(f"# yaml-language-server: $schema={schema_dir}/idf.v1.json\n")
45
- fp.write("version: \"0.1\"\n")
47
+ fp.write("version: 1\n")
46
48
  fp.write("description: 测试接口,用于验证lb_base/lb_core,同时验证自动生成逻辑\n")
47
49
  fp.write("alias: Test\n")
48
50
  fp.write("properties:\n")
@@ -56,7 +58,7 @@ class TestCodeGenClass(unittest.TestCase):
56
58
  def mk_interface_with_double_property(self, name, type, default_val, max=None, min=None, exclusive_max=None, exclusive_min=None):
57
59
  with open(self.tmp_file, mode="w+") as fp:
58
60
  fp.write(f"# yaml-language-server: $schema={schema_dir}/idf.v1.json\n")
59
- fp.write("version: \"0.1\"\n")
61
+ fp.write("version: 1\n")
60
62
  fp.write("description: 测试接口,用于验证lb_base/lb_core,同时验证自动生成逻辑\n")
61
63
  fp.write("alias: Test\n")
62
64
  fp.write("properties:\n")
@@ -77,7 +79,7 @@ class TestCodeGenClass(unittest.TestCase):
77
79
  def validate_boolean(self, name, type, default):
78
80
  with open(self.tmp_file, mode="w+") as fp:
79
81
  fp.write(f"# yaml-language-server: $schema={schema_dir}/idf.v1.json\n")
80
- fp.write("version: \"0.1\"\n")
82
+ fp.write("version: 1\n")
81
83
  fp.write("description: 测试接口,用于验证lb_base/lb_core,同时验证自动生成逻辑\n")
82
84
  fp.write("alias: Test\n")
83
85
  fp.write("properties:\n")
@@ -283,46 +285,67 @@ class TestCodeGenClass(unittest.TestCase):
283
285
 
284
286
  class TestVersionClass(unittest.TestCase):
285
287
  def test_version_bt(self):
286
- self.assertTrue(Version("5.2").bt("5.1"))
287
- self.assertTrue(Version("6.2").bt("5.1"))
288
+ self.assertTrue(Version("6.3").bt("5.2"))
288
289
  self.assertTrue(Version("6.2").bt("5.2"))
289
- self.assertTrue(Version("6.2").bt("5.3"))
290
- self.assertFalse(Version("5.x").bt("5.1"))
291
- self.assertFalse(Version("5.x").bt("5.x"))
292
- self.assertFalse(Version("5.1").bt("5.2"))
290
+ self.assertTrue(Version("6.1").bt("5.2"))
291
+ self.assertTrue(Version("5.3").bt("5.2"))
293
292
  self.assertFalse(Version("5.2").bt("5.2"))
293
+ self.assertFalse(Version("5.1").bt("5.2"))
294
+ self.assertFalse(Version("4.3").bt("5.2"))
294
295
  self.assertFalse(Version("4.2").bt("5.2"))
295
- self.assertFalse(Version("4.x").bt("5.2"))
296
- self.assertFalse(Version("4.x").bt("5.x"))
296
+ self.assertFalse(Version("4.1").bt("5.2"))
297
297
 
298
298
  def test_version_be(self):
299
+ self.assertTrue(Version("6.3").be("5.2"))
300
+ self.assertTrue(Version("6.2").be("5.2"))
301
+ self.assertTrue(Version("6.1").be("5.2"))
302
+ self.assertTrue(Version("5.3").be("5.2"))
299
303
  self.assertTrue(Version("5.2").be("5.2"))
300
- self.assertTrue(Version("5.x").be("5.3"))
301
- self.assertTrue(Version("5.x").be("5.x"))
302
- self.assertFalse(Version("5.1").be("5.x"))
304
+ self.assertFalse(Version("5.1").be("5.2"))
305
+ self.assertFalse(Version("4.3").be("5.2"))
306
+ self.assertFalse(Version("4.2").be("5.2"))
307
+ self.assertFalse(Version("4.1").be("5.2"))
303
308
 
304
309
  def test_version_le(self):
305
- self.assertFalse(Version("5.2").le("5.1"))
306
- self.assertFalse(Version("6.2").le("5.1"))
310
+ self.assertFalse(Version("6.3").le("5.2"))
307
311
  self.assertFalse(Version("6.2").le("5.2"))
308
- self.assertFalse(Version("6.2").le("5.3"))
309
- self.assertTrue(Version("5.x").le("5.1"))
310
- self.assertTrue(Version("5.x").le("5.x"))
311
- self.assertTrue(Version("5.1").le("5.2"))
312
+ self.assertFalse(Version("6.1").le("5.2"))
313
+ self.assertFalse(Version("5.3").le("5.2"))
312
314
  self.assertTrue(Version("5.2").le("5.2"))
315
+ self.assertTrue(Version("5.1").le("5.2"))
316
+ self.assertTrue(Version("4.3").le("5.2"))
313
317
  self.assertTrue(Version("4.2").le("5.2"))
314
- self.assertTrue(Version("4.x").le("5.2"))
315
- self.assertTrue(Version("4.x").le("5.x"))
318
+ self.assertTrue(Version("4.1").le("5.2"))
316
319
 
317
320
  def test_version_lt(self):
321
+ self.assertFalse(Version("6.3").lt("5.2"))
322
+ self.assertFalse(Version("6.2").lt("5.2"))
323
+ self.assertFalse(Version("6.1").lt("5.2"))
324
+ self.assertFalse(Version("5.3").lt("5.2"))
318
325
  self.assertFalse(Version("5.2").lt("5.2"))
319
- self.assertFalse(Version("5.x").lt("5.3"))
320
- self.assertFalse(Version("5.x").lt("5.x"))
321
- self.assertFalse(Version("5.1").lt("5.x"))
322
326
  self.assertTrue(Version("5.1").lt("5.2"))
323
327
  self.assertTrue(Version("4.3").lt("5.2"))
324
- self.assertTrue(Version("4.3").lt("5.3"))
325
-
328
+ self.assertTrue(Version("4.2").lt("5.2"))
329
+ self.assertTrue(Version("4.1").lt("5.2"))
330
+
331
+ def test_codegen_version_schema(self):
332
+ """
333
+ 测试pdf模式文件的metadata/codegen_version可选值与codegen.py的history_versions是否保持一致
334
+ """
335
+ pdf_file = os.path.join("..", "schema", "pdf.v1.json")
336
+ pdf_file = os.path.realpath(pdf_file)
337
+ with open(pdf_file, "r") as fp:
338
+ data = json.load(fp)
339
+ data = data.get("properties", {}).get("metadata", {})
340
+ data = data.get("properties", {}).get("codegen_version", {})
341
+ data = data.get("enum", [])
342
+ data.sort()
343
+ # latest表示最新的版本生成工具版本号
344
+ versions = ["latest"]
345
+ for ver, _ in codegen_history.items():
346
+ versions.append(ver)
347
+ versions.sort()
348
+ self.assertTrue(data == versions)
326
349
 
327
350
  if __name__ == "__main__":
328
351
  unittest.main()
@@ -1,2 +0,0 @@
1
-
2
- __version__ = '0.7.4'
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes