openubmc-bingo 0.5.242__py3-none-any.whl → 0.5.253__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of openubmc-bingo might be problematic. Click here for more details.

Files changed (68) hide show
  1. bmcgo/__init__.py +1 -1
  2. bmcgo/bmcgo_config.py +82 -1
  3. bmcgo/cli/cli.py +0 -2
  4. bmcgo/cli/config.yaml +9 -0
  5. bmcgo/codegen/lua/Makefile +13 -0
  6. bmcgo/codegen/lua/codegen.py +6 -3
  7. bmcgo/codegen/lua/script/dto/options.py +1 -0
  8. bmcgo/codegen/lua/script/{render_utils/factory.py → factory.py} +1 -1
  9. bmcgo/codegen/lua/script/gen_entry.py +6 -3
  10. bmcgo/codegen/lua/script/gen_intf_rpc_json.py +12 -0
  11. bmcgo/codegen/lua/script/gen_schema.py +2 -0
  12. bmcgo/codegen/lua/script/merge_model.py +10 -3
  13. bmcgo/codegen/lua/script/render_utils/__init__.py +5 -4
  14. bmcgo/codegen/lua/script/render_utils/client_lua.py +2 -2
  15. bmcgo/codegen/lua/script/render_utils/controller_lua.py +2 -2
  16. bmcgo/codegen/lua/script/render_utils/db_lua.py +2 -2
  17. bmcgo/codegen/lua/script/render_utils/error_lua.py +2 -2
  18. bmcgo/codegen/lua/script/render_utils/ipmi_lua.py +2 -2
  19. bmcgo/codegen/lua/script/render_utils/ipmi_message_lua.py +2 -2
  20. bmcgo/codegen/lua/script/render_utils/mdb_lua.py +2 -2
  21. bmcgo/codegen/lua/script/render_utils/message_lua.py +2 -2
  22. bmcgo/codegen/lua/script/render_utils/messages_lua.py +2 -2
  23. bmcgo/codegen/lua/script/render_utils/model_lua.py +2 -2
  24. bmcgo/codegen/lua/script/render_utils/old_model_lua.py +2 -2
  25. bmcgo/codegen/lua/script/render_utils/plugin_lua.py +2 -2
  26. bmcgo/codegen/lua/script/render_utils/redfish_proto.py +2 -2
  27. bmcgo/codegen/lua/script/render_utils/request_lua.py +2 -2
  28. bmcgo/codegen/lua/script/render_utils/service_lua.py +3 -2
  29. bmcgo/codegen/lua/script/template.py +5 -1
  30. bmcgo/codegen/lua/script/utils.py +9 -2
  31. bmcgo/codegen/lua/templates/Makefile +8 -0
  32. bmcgo/codegen/lua/templates/apps/Makefile +27 -1
  33. bmcgo/codegen/lua/templates/apps/controller.lua.mako +20 -4
  34. bmcgo/codegen/lua/v1/script/gen_schema.py +328 -0
  35. bmcgo/codegen/lua/v1/script/render_utils/model_lua.py +458 -0
  36. bmcgo/codegen/lua/v1/templates/apps/model.lua.mako +62 -0
  37. bmcgo/codegen/lua/v1/templates/apps/service.lua.mako +193 -0
  38. bmcgo/component/build.py +16 -42
  39. bmcgo/component/component_helper.py +54 -0
  40. bmcgo/component/coverage/incremental_cov.py +25 -33
  41. bmcgo/component/deploy.py +7 -9
  42. bmcgo/frame.py +9 -6
  43. bmcgo/functional/conan_index_build.py +16 -41
  44. bmcgo/functional/csr_build.py +313 -88
  45. bmcgo/functional/diff.py +3 -3
  46. bmcgo/functional/upgrade.py +31 -1
  47. bmcgo/misc.py +31 -2
  48. bmcgo/target/install_sdk.yml +6 -0
  49. bmcgo/target/personal.yml +5 -0
  50. bmcgo/target/publish.yml +5 -0
  51. bmcgo/tasks/task.py +69 -43
  52. bmcgo/tasks/task_build_conan.py +6 -2
  53. bmcgo/tasks/task_build_wbd_up.py +69 -0
  54. bmcgo/utils/config.py +20 -8
  55. bmcgo/utils/install_manager.py +75 -20
  56. bmcgo/utils/installations/base_installer.py +114 -7
  57. bmcgo/utils/installations/install_consts.py +3 -1
  58. bmcgo/utils/installations/install_plans/bingo.yml +2 -4
  59. bmcgo/utils/installations/install_workflow.py +6 -2
  60. bmcgo/utils/installations/installers/apt_installer.py +58 -136
  61. bmcgo/utils/installations/installers/pip_installer.py +52 -18
  62. bmcgo/utils/installations/version_util.py +1 -1
  63. {openubmc_bingo-0.5.242.dist-info → openubmc_bingo-0.5.253.dist-info}/METADATA +2 -1
  64. {openubmc_bingo-0.5.242.dist-info → openubmc_bingo-0.5.253.dist-info}/RECORD +68 -62
  65. /bmcgo/codegen/lua/script/{render_utils/base.py → base.py} +0 -0
  66. {openubmc_bingo-0.5.242.dist-info → openubmc_bingo-0.5.253.dist-info}/WHEEL +0 -0
  67. {openubmc_bingo-0.5.242.dist-info → openubmc_bingo-0.5.253.dist-info}/entry_points.txt +0 -0
  68. {openubmc_bingo-0.5.242.dist-info → openubmc_bingo-0.5.253.dist-info}/top_level.txt +0 -0
@@ -46,6 +46,9 @@ def parse_input_args() -> Options:
46
46
  parser.add_argument("-n", "--project_name", dest="project_name",
47
47
  help="project name",
48
48
  default="")
49
+ parser.add_argument("-p", "--major_version", dest="major_version",
50
+ help="major version",
51
+ default="")
49
52
  parser.add_argument("-v", "--version", dest="version",
50
53
  help="version",
51
54
  default=-1)
@@ -122,7 +125,7 @@ def generate(options: Options):
122
125
 
123
126
  header = utils.Utils(data, options).make_header(
124
127
  options.template_name, options.output_file_path)
125
- lookup = TemplateLookup(directories=[os.getcwd() + "/"], input_encoding='utf-8')
128
+ lookup = TemplateLookup(directories=[os.getcwd() + "/", os.getcwd() + "/../../"], input_encoding='utf-8')
126
129
  template = lookup.get_template(options.template_name)
127
130
  if os.path.exists(options.output_file_path):
128
131
  os.remove(options.output_file_path)
@@ -144,6 +147,7 @@ def generate(options: Options):
144
147
  load_import=make_load_import(data, options),
145
148
  project_name=options.project_name,
146
149
  version=options.version,
150
+ major_version=options.major_version,
147
151
  use_frame_log=use_frame_log,
148
152
  ))
149
153
  output_file.write(render_data)
@@ -16,8 +16,8 @@ import re
16
16
  from datetime import datetime, timezone
17
17
  from pathlib import Path
18
18
 
19
- from dto.options import Options
20
- from validate import all_validates
19
+ from bmcgo.codegen.lua.script.dto.options import Options
20
+ from bmcgo.codegen.lua.script.validate import all_validates
21
21
  from bmcgo.codegen import __version__ as codegen_version
22
22
 
23
23
 
@@ -206,6 +206,13 @@ class Utils:
206
206
  return codegen_version
207
207
  return int(env_version)
208
208
 
209
+ @staticmethod
210
+ def get_major_version():
211
+ env_version = os.getenv('MAJOR_VERSION')
212
+ if env_version is None or env_version == "-1" or not env_version.isdigit():
213
+ return 1
214
+ return int(env_version)
215
+
209
216
  @staticmethod
210
217
  def formatter(header, date, filename, lang, draft_info):
211
218
  if draft_info:
@@ -13,10 +13,12 @@ apps:
13
13
  GENERATE_OUT_DIR=${GENERATE_OUT_DIR} \
14
14
  PLUGIN_TEMPLATE_DIR=${TEMP_DIR}/plugin \
15
15
  SCRIPT_DIR=${SCRIPT_DIR} \
16
+ MAJOR_VERIONS_DIR=${MAJOR_VERIONS_DIR} \
16
17
  PROTO_OUT_DIR=${PROTO_OUT_DIR} \
17
18
  PROTO_DIR=${PROTO_DIR} \
18
19
  PROJECT_NAME=${PROJECT_NAME} \
19
20
  VERSION=${VERSION} \
21
+ MAJOR_VERSION=${MAJOR_VERSION} \
20
22
  RESTAPI_DIRS="${RESTAPI_DIRS}" \
21
23
  MDS_DIR=${MDS_DIR} \
22
24
  TEMP_DIR=${TEMP_DIR} \
@@ -35,10 +37,12 @@ dft_make:
35
37
  GENERATE_OUT_DIR=${GENERATE_OUT_DIR}/dft \
36
38
  PLUGIN_TEMPLATE_DIR=${TEMP_DIR}/dft/plugin \
37
39
  SCRIPT_DIR=${SCRIPT_DIR} \
40
+ MAJOR_VERIONS_DIR=${MAJOR_VERIONS_DIR} \
38
41
  PROTO_OUT_DIR=${PROTO_OUT_DIR}/dft \
39
42
  PROTO_DIR=${PROTO_DIR} \
40
43
  PROJECT_NAME=${DFT_NAME} \
41
44
  VERSION=${VERSION} \
45
+ MAJOR_VERSION=${MAJOR_VERSION} \
42
46
  RESTAPI_DIRS="${RESTAPI_DIRS}" \
43
47
  MDS_DIR=${MDS_DIR}/dft \
44
48
  TEMP_DIR=${TEMP_DIR} \
@@ -60,10 +64,12 @@ debug_make:
60
64
  GENERATE_OUT_DIR=${GENERATE_OUT_DIR}/debug \
61
65
  PLUGIN_TEMPLATE_DIR=${TEMP_DIR}/debug/plugin \
62
66
  SCRIPT_DIR=${SCRIPT_DIR} \
67
+ MAJOR_VERIONS_DIR=${MAJOR_VERIONS_DIR} \
63
68
  PROTO_OUT_DIR=${PROTO_OUT_DIR}/debug \
64
69
  PROTO_DIR=${PROTO_DIR} \
65
70
  PROJECT_NAME=${DEBUG_NAME} \
66
71
  VERSION=${VERSION} \
72
+ MAJOR_VERSION=${MAJOR_VERSION} \
67
73
  RESTAPI_DIRS="${RESTAPI_DIRS}" \
68
74
  MDS_DIR=${MDS_DIR}/debug \
69
75
  TEMP_DIR=${TEMP_DIR} \
@@ -105,10 +111,12 @@ mdb:
105
111
  @cd apps && make \
106
112
  GENERATE_OUT_DIR=${GENERATE_OUT_DIR} \
107
113
  SCRIPT_DIR=${SCRIPT_DIR} \
114
+ MAJOR_VERIONS_DIR=${MAJOR_VERIONS_DIR} \
108
115
  PROTO_OUT_DIR=${PROTO_OUT_DIR} \
109
116
  PROTO_DIR=${PROTO_DIR} \
110
117
  PROJECT_NAME=${PROJECT_NAME} \
111
118
  VERSION=${VERSION} \
119
+ MAJOR_VERSION=${MAJOR_VERSION} \
112
120
  -f Makefile.mdb.mk
113
121
 
114
122
  all: apps errors dft_make debug_make
@@ -5,6 +5,7 @@ LUA_FORMATER = ${SCRIPT_DIR}/lua_format.py
5
5
  MDB_INTF_DIR = ${TEMP_DIR}/opt/bmc/apps/mdb_interface/
6
6
  YAML_TO_JSON_BIN = ${SCRIPT_DIR}/yaml_to_json.py
7
7
  BAK_LOCAL_DB_DIR = ${GEN_BAK_DIR}/${PROJECT_NAME}
8
+ MAJOR_VERSION_EQ_1 := $(shell [ $(MAJOR_VERSION) -eq 1 ] && echo true)
8
9
 
9
10
  define get_proto_files
10
11
  $(wildcard $(1)*.proto) $(foreach e, $(wildcard $(1)*), $(call get_proto_files, $(e)/))
@@ -130,18 +131,38 @@ endif
130
131
  ${PROTO_OUT_DIR}/_model.json: ${SCRIPT_DIR}/merge_model.py
131
132
  python3 ${SCRIPT_DIR}/merge_model.py -i ${MDS_DIR}/model.json -o $@ -d ${MDB_INTF_DIR} -c ${SCRIPT_DIR}/../temp/check_cmd.json
132
133
 
134
+ ifeq ($(MAJOR_VERSION_EQ_1), true)
135
+ $(MDS_DIR)/modelx.json: ${PROTO_OUT_DIR}/_model.json
136
+ mkdir -p $(@D)
137
+ cp $< $@
138
+ modelx:${MDS_DIR}/modelx.json
139
+ else
140
+ modelx:
141
+ endif
142
+
133
143
  ${PROTO_OUT_DIR}/service.json: ${PROTO_OUT_DIR}/_model.json ${SCRIPT_DIR}/gen_intf_rpc_json.py
134
144
  python3 ${SCRIPT_DIR}/gen_intf_rpc_json.py -i ${PROTO_OUT_DIR}/_model.json -o $@ -s ${SERVICE_JSON_PATH} -p ${MDS_DIR}/ipmi.json
135
145
 
146
+ ifeq ($(MAJOR_VERSION_EQ_1), true)
147
+ ${GEN_OUT_DIR}/service.lua: ${PROTO_OUT_DIR}/service.json ${TEMPLATE_BIN} \
148
+ ${MAJOR_VERIONS_DIR}/v1/templates/apps/service.lua.mako utils/validate.mako utils/imports.mako service_message message
149
+ python3 ${TEMPLATE_BIN} -d ${PROTO_DIR} -v ${VERSION} -j ${PROTO_OUT_DIR}/json_types/ -n ${PROJECT_NAME} -i ${PROTO_OUT_DIR}/service.json -f ${LUA_FORMATER} -t v1/templates/apps/service.lua.mako -o $@
150
+ else
136
151
  ${GEN_OUT_DIR}/service.lua: ${PROTO_OUT_DIR}/service.json ${TEMPLATE_BIN} \
137
152
  service.lua.mako utils/validate.mako utils/imports.mako service_message message
138
153
  python3 ${TEMPLATE_BIN} -d ${PROTO_DIR} -v ${VERSION} -j ${PROTO_OUT_DIR}/json_types/ -n ${PROJECT_NAME} -i ${PROTO_OUT_DIR}/service.json -f ${LUA_FORMATER} -t service.lua.mako -o $@
154
+ endif
139
155
 
140
156
  service:${GEN_OUT_DIR}/service.lua
141
157
 
142
158
  ifneq ($(wildcard ${MDS_DIR}/model.json),)
159
+ ifeq ($(MAJOR_VERSION_EQ_1), true)
160
+ ${MDS_DIR}/schema.json: ${PROTO_OUT_DIR}/_model.json ${MAJOR_VERIONS_DIR}/v1/script/gen_schema.py
161
+ python3 ${MAJOR_VERIONS_DIR}/v1/script/gen_schema.py -i ${PROTO_OUT_DIR}/_model.json -t ${MDS_DIR}/types.json -n ${PROJECT_NAME} -o $@
162
+ else
143
163
  ${MDS_DIR}/schema.json: ${PROTO_OUT_DIR}/_model.json ${SCRIPT_DIR}/gen_schema.py
144
164
  python3 ${SCRIPT_DIR}/gen_schema.py -i ${PROTO_OUT_DIR}/_model.json -n ${PROJECT_NAME} -o $@
165
+ endif
145
166
 
146
167
  ${PROTO_OUT_DIR}/db_json.json: ${PROTO_OUT_DIR}/_model.json ${SCRIPT_DIR}/gen_db_json.py
147
168
  python3 ${SCRIPT_DIR}/gen_historical_local_db_json.py -i ${BAK_LOCAL_DB_DIR}/local_db.lua -o ${PROTO_OUT_DIR}/historical_local_db.json
@@ -191,8 +212,13 @@ service_message: service_message_json
191
212
  schema: ${MDS_DIR}/schema.json
192
213
  database: ${PROTO_OUT_DIR}/db_json.json
193
214
 
215
+ ifeq ($(MAJOR_VERSION_EQ_1), true)
216
+ ${GENERATE_OUT_DIR}/class/model.lua: ${PROTO_OUT_DIR}/_model.json ${TEMPLATE_BIN} ${MAJOR_VERIONS_DIR}/v1/templates/apps/model.lua.mako
217
+ python3 ${TEMPLATE_BIN} -d ${PROTO_DIR} -v ${VERSION} -j ${PROTO_OUT_DIR} -i ${PROTO_OUT_DIR}/_model.json -f ${LUA_FORMATER} -t v1/templates/apps/model.lua.mako -n ${PROJECT_NAME} -o $@
218
+ else
194
219
  ${GENERATE_OUT_DIR}/class/model.lua: ${PROTO_OUT_DIR}/_model.json ${TEMPLATE_BIN} model.lua.mako
195
220
  python3 ${TEMPLATE_BIN} -d ${PROTO_DIR} -v ${VERSION} -j ${PROTO_OUT_DIR} -i ${PROTO_OUT_DIR}/_model.json -f ${LUA_FORMATER} -t model.lua.mako -n ${PROJECT_NAME} -o $@
221
+ endif
196
222
 
197
223
  model: ${GENERATE_OUT_DIR}/class/model.lua
198
224
 
@@ -258,4 +284,4 @@ client: ${GEN_OUT_DIR}/client.lua
258
284
 
259
285
  endif
260
286
 
261
- all: client service message datas datas_conf restapi restapi_resource schema model types_message model_message database ipmi orm_classes feature impl_feature
287
+ all: client service modelx message datas datas_conf restapi restapi_resource schema model types_message model_message database ipmi orm_classes feature impl_feature
@@ -186,16 +186,28 @@ function C${controller['name']}:on_${method}(req, rsp)
186
186
  local err
187
187
  % if method == 'post':
188
188
  local task_info
189
- err, rsp.body, _, task_info = self.worker_ctrl:process(req.path, '${method}', {body = req.body, query = req.query, user = req.user})
189
+ % if render_utils.get_lua_codegen_version() <= 3:
190
+ err, rsp.body, _, task_info = self.route_mapper:match(req.path, '${method}', {body = req.body, query = req.query, user = req.user})
191
+ % else:
192
+ err, rsp.body, _, task_info = self.worker_ctrl:process(req.path, '${method}', {body = req.body, query = req.query, user = req.user})
193
+ % endif
190
194
  % else:
191
- err, rsp.body = self.worker_ctrl:process(req.path, '${method}', {body = req.body, query = req.query, user = req.user})
195
+ % if render_utils.get_lua_codegen_version() <= 3:
196
+ err, rsp.body = self.route_mapper:match(req.path, '${method}', {body = req.body, query = req.query, user = req.user})
197
+ % else:
198
+ err, rsp.body = self.worker_ctrl:process(req.path, '${method}', {body = req.body, query = req.query, user = req.user})
199
+ % endif
192
200
  % endif
193
201
  if err and #err ~= 0 then
194
202
  local webrest_utils = require 'webrest_utils'
195
203
  return webrest_utils.parse_route_mapper_error(err)
196
204
  end
197
205
  % if method == 'patch':
198
- _, rsp.body = self.worker_ctrl:process(req.path, 'get', {body = req.body, query = req.query, user = req.user})
206
+ % if render_utils.get_lua_codegen_version() <= 3:
207
+ _, rsp.body = self.route_mapper:match(req.path, 'get', {body = req.body, query = req.query, user = req.user})
208
+ % else:
209
+ _, rsp.body = self.worker_ctrl:process(req.path, 'get', {body = req.body, query = req.query, user = req.user})
210
+ % endif
199
211
  % endif
200
212
  % if method == 'post':
201
213
  if task_info then
@@ -213,7 +225,11 @@ function C${controller['name']}:on_${method}(req, rsp)
213
225
  err, rsp.body = redfish_utils.get_rsp_body(self, req)
214
226
  % else:
215
227
  local err, extra_info
216
- err, rsp.body, extra_info = self.worker_ctrl:process(req.path, '${method}', {body = req.body, query = req.query, user = req.user})
228
+ % if render_utils.get_lua_codegen_version() <= 3:
229
+ err, rsp.body, extra_info = self.route_mapper:match(req.path, '${method}', {body = req.body, query = req.query, user = req.user})
230
+ % else:
231
+ err, rsp.body, extra_info = self.worker_ctrl:process(req.path, '${method}', {body = req.body, query = req.query, user = req.user})
232
+ % endif
217
233
  % endif
218
234
  % if method == 'post' or method == 'delete' or method == 'get':
219
235
  if err and #err ~= 0 then
@@ -0,0 +1,328 @@
1
+ #!/usr/bin/env python3
2
+ # coding=utf-8
3
+ # Copyright (c) 2025 Huawei Technologies Co., Ltd.
4
+ # openUBMC is licensed under Mulan PSL v2.
5
+ # You can use this software according to the terms and conditions of the Mulan PSL v2.
6
+ # You may obtain a copy of Mulan PSL v2 at:
7
+ # http://license.coscl.org.cn/MulanPSL2
8
+ # THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
9
+ # EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
10
+ # MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
11
+ # See the Mulan PSL v2 for more details.
12
+
13
+ import json
14
+ import logging
15
+ import getopt
16
+ import sys
17
+ import os
18
+ import stat
19
+ import re
20
+ from collections import OrderedDict
21
+ from bmcgo.codegen.lua.script.utils import Utils
22
+ from bmcgo.utils.tools import Tools
23
+
24
+ tool = Tools()
25
+ log = tool.log
26
+ MDS_REF = "$ref"
27
+ MDS_DEFS = "defs"
28
+ MDS_REF_INTERFACE = "refInterface"
29
+ MDS_PATH = "path"
30
+ MDS_PARENT = "parent"
31
+ MDS_DEFINITIONS = "definitions"
32
+ BASIC_TYPES = ["U8", "U16", "U32", "U64", "S16", "S32", "S64", "String", "Double", "Boolean"]
33
+ RETAIN_ITEMS = ["description", "enum", "minimum", "maximum", "minLength", "maxLength", "pattern", "x-originalName",
34
+ "x-interface"]
35
+
36
+
37
+ def no_need_filter(k):
38
+ filter_list = ["usage", "notAllowNull", "readOnly", "default", "primaryKey", "critical"]
39
+ return k not in filter_list
40
+
41
+
42
+ def is_excluded_intf(intf):
43
+ return intf == "bmc.kepler.Object.Properties"
44
+
45
+
46
+ def is_usage_csr(property_data):
47
+ return "usage" in property_data and "CSR" in property_data["usage"]
48
+
49
+
50
+ def update_dictionary_type(key_data, value_data):
51
+ new_property_data = {}
52
+ if key_data["baseType"] == 'String':
53
+ new_property_data["^.*$"] = update_type(value_data)
54
+ return {"type": "object", "patternProperties": new_property_data}
55
+ else:
56
+ return {"type": "array", "items": {"$ref": "base.json#/definitions/S32"}}
57
+
58
+
59
+ def update_array_type(property_data, base_type):
60
+ new_property_data = property_data.copy()
61
+ new_property_data["type"] = "array"
62
+ if base_type == "Array":
63
+ try:
64
+ new_property_data["items"][MDS_REF] = new_property_data["items"][MDS_REF] \
65
+ .replace(MDS_DEFS, MDS_DEFINITIONS).replace("types.json", "")
66
+ except Exception as e:
67
+ log.error(f"任务状态错误: {e}")
68
+ raise Exception(f"未找到{MDS_REF}") from e
69
+ return new_property_data
70
+
71
+ if "refInterface" in new_property_data:
72
+ ref_interface = new_property_data.pop("refInterface")
73
+ new_property_data["x-refInterface"] = ref_interface
74
+ new_property_data["items"] = {MDS_REF: "base.json#/definitions/" + base_type[:-2]}
75
+ return new_property_data
76
+
77
+
78
+ def update_type(property_data):
79
+ new_property_data = {}
80
+ if not isinstance(property_data, dict):
81
+ return new_property_data
82
+
83
+ if "baseType" in property_data or "$ref" in property_data:
84
+ base_type = property_data.pop("baseType", "")
85
+ match = re.fullmatch(r'^(.+)(\[\])$', base_type)
86
+ if base_type == "Array" or (match and match.group(1) in BASIC_TYPES):
87
+ return update_array_type(property_data, base_type)
88
+
89
+ if MDS_REF_INTERFACE in property_data:
90
+ new_property_data[MDS_REF_INTERFACE] = property_data.pop(MDS_REF_INTERFACE, "")
91
+
92
+ if base_type in BASIC_TYPES:
93
+ new_property_data[MDS_REF] = "base.json#/definitions/" + base_type
94
+ elif MDS_REF in property_data:
95
+ new_property_data[MDS_REF] = property_data[MDS_REF].replace(MDS_DEFS, MDS_DEFINITIONS) \
96
+ .replace("types.json", "")
97
+
98
+ for item in RETAIN_ITEMS:
99
+ if item in property_data:
100
+ new_property_data[item] = property_data[item]
101
+
102
+ return new_property_data
103
+
104
+
105
+ def read_properties(intf_name, properties, out_properties, is_intf_props, usage_csr):
106
+ # properties only mark usage as C should deploy to csr schema
107
+ props = list(p for p, v in properties.items() if is_intf_props or is_usage_csr(v))
108
+ for index, prop in enumerate(props):
109
+ # filter properties which no need for csr
110
+ if is_usage_csr(properties[prop]) != usage_csr:
111
+ continue
112
+ prop_alias = prop
113
+ # if prop have alias, use alias name replace prop name
114
+ if "alias" in properties[prop]:
115
+ prop_alias = properties[prop].pop("alias", "")
116
+ properties[prop]["x-originalName"] = prop
117
+ if intf_name:
118
+ properties[prop]["x-interface"] = intf_name
119
+ out_properties[prop_alias] = {
120
+ k: v
121
+ for k, v in properties[prop].items()
122
+ if no_need_filter(k)
123
+ }
124
+
125
+ if prop_alias != prop:
126
+ out_properties[prop_alias] = update_type(out_properties[prop_alias])
127
+ props[index] = prop_alias
128
+ else:
129
+ out_properties[prop] = update_type(out_properties[prop])
130
+
131
+ return props
132
+
133
+
134
+ def read_defs(structs, data):
135
+ for struct_name, struct_data in data[MDS_DEFS].items():
136
+ if struct_name in structs:
137
+ continue
138
+ properties = {k: v for k, v in struct_data.items()}
139
+ first_value = next(iter(struct_data.values()), None)
140
+ if isinstance(first_value, str) or isinstance(first_value, int):
141
+ structs[struct_name] = {"type": "string" if isinstance(first_value, str) else "integer",
142
+ "enum": list(struct_data.values())}
143
+ continue
144
+ if "key" in properties:
145
+ structs[struct_name] = update_dictionary_type(properties["key"], properties["value"])
146
+ continue
147
+ items = []
148
+ for _, prop_data in properties.items():
149
+ items.append(update_type(prop_data))
150
+ structs[struct_name] = {"type": "array", "items": items}
151
+
152
+
153
+ def read_interfaces(interfaces, out_properties, structs, usage_csr):
154
+ intfs = {}
155
+ for intf_name, intf in interfaces.items():
156
+ # no properties also need interface name , because may be reference Object by other property for Devkit check
157
+ intfs[intf_name] = {}
158
+ if "properties" in intf:
159
+ props = read_properties(intf_name, intf["properties"], out_properties, not is_excluded_intf(intf_name),
160
+ usage_csr)
161
+ intfs[intf_name] = props
162
+ if MDS_DEFS in intf:
163
+ read_defs(structs, intf)
164
+ return intfs
165
+
166
+
167
+ def save_csr_schema(of_name, csr_schema):
168
+ if os.path.exists(of_name):
169
+ with os.fdopen(os.open(of_name, os.O_RDONLY, stat.S_IRUSR), "r") as load_f:
170
+ if json.load(load_f) == csr_schema:
171
+ logging.info("schema 文件内容没有变更")
172
+ return
173
+
174
+ with os.fdopen(
175
+ os.open(
176
+ of_name, os.O_WRONLY | os.O_CREAT | os.O_TRUNC, stat.S_IWUSR | stat.S_IRUSR
177
+ ),
178
+ "w", encoding="utf-8"
179
+ ) as load_f:
180
+ json.dump(csr_schema, load_f, ensure_ascii=False, indent=4)
181
+ logging.info("schema 已经发生改变")
182
+
183
+
184
+ csr_schema_template = {
185
+ "$id": "CSR",
186
+ "$schema": "https://json-schema.org/draft/2019-09/schema#",
187
+ "x-version": "1.0",
188
+ "title": "CSR",
189
+ "description": "支持对CSR对象配置进行检查和校验",
190
+ "type": "object",
191
+ "patternProperties": {}
192
+ }
193
+
194
+
195
+ def replace_colon(path):
196
+ path = os.path.realpath(path) if (path[0:1] == "/") else path
197
+ paths = path.split("/")
198
+ maps = {}
199
+ for var in paths:
200
+ if var.startswith(":"):
201
+ maps[var] = var.replace(":", "${") + "}"
202
+ for old, new in maps.items():
203
+ path = path.replace(old, new)
204
+ return path
205
+
206
+
207
+ def create_schema_class(interfaces, properties, non_csr_properties, class_data):
208
+ class_def = {"type": "object", "properties": properties, "x-publicProperties": non_csr_properties}
209
+ if MDS_PATH in class_data:
210
+ class_def["x-" + MDS_PATH] = replace_colon(class_data[MDS_PATH])
211
+ if MDS_PARENT in class_data:
212
+ class_def["x-" + MDS_PARENT] = class_data[MDS_PARENT]
213
+ class_def["additionalProperties"] = True
214
+ return class_def
215
+
216
+
217
+ def count_dir_level(path):
218
+ level = 0
219
+ while True:
220
+ path = os.path.dirname(path)
221
+ if path == '/':
222
+ break
223
+ level += 1
224
+ return level
225
+
226
+
227
+ def filling_material(load_dict, csr_schema):
228
+ for class_name, class_data in load_dict.items():
229
+ properties = {}
230
+ non_csr_properties = {}
231
+ interfaces = {}
232
+ if "interfaces" in class_data:
233
+ interfaces = read_interfaces(
234
+ class_data["interfaces"], properties, csr_schema[MDS_DEFINITIONS], True
235
+ )
236
+ _ = read_interfaces(
237
+ class_data["interfaces"], non_csr_properties, csr_schema[MDS_DEFINITIONS], False
238
+ )
239
+ if "properties" in class_data:
240
+ _ = read_properties(None, class_data["properties"], properties, False, True)
241
+ _ = read_properties(None, class_data["properties"], non_csr_properties, False, False)
242
+ if MDS_DEFS in class_data:
243
+ read_defs(csr_schema[MDS_DEFINITIONS], class_data)
244
+ # no properties means no properties mark usage C ,no need generic csr schema class
245
+ if properties:
246
+ csr_schema["patternProperties"]["^" + class_name + "_.+$"] = create_schema_class(
247
+ interfaces, properties, non_csr_properties, class_data
248
+ )
249
+ if MDS_DEFS in load_dict:
250
+ read_defs(csr_schema[MDS_DEFINITIONS], load_dict)
251
+
252
+
253
+ def generate_schema(types_path, root, file, csr_schema):
254
+ file_path = os.path.join(root, file)
255
+ load_f = os.fdopen(os.open(file_path, os.O_RDONLY, stat.S_IRUSR), "r")
256
+ load_dict = json.load(load_f)
257
+ if os.path.exists(types_path):
258
+ load_f2 = os.fdopen(os.open(types_path, os.O_RDONLY, stat.S_IRUSR), "r")
259
+ load_dict2 = json.load(load_f2)
260
+ types_defs = {}
261
+ read_defs(types_defs, load_dict2)
262
+ csr_schema[MDS_DEFINITIONS].update(types_defs)
263
+
264
+ filling_material(load_dict, csr_schema)
265
+ load_f.close()
266
+
267
+
268
+ def generate(types_path, if_name, of_name, project_name):
269
+ if not os.path.exists(if_name):
270
+ return
271
+
272
+ # APP的目录层级是3,组件层级是4
273
+ pattern = re.compile(f'.*(/[^/]+/temp/{project_name}/.*)')
274
+ match = re.search(pattern, if_name)
275
+ path_level = 0
276
+ if match:
277
+ temp_model_path = match.group(1)
278
+ path_level = count_dir_level(temp_model_path)
279
+ dir_path = os.path.dirname(if_name)
280
+
281
+ if not (dir_path.endswith('test_gen_schema') or path_level == 3):
282
+ return
283
+
284
+ csr_schema = OrderedDict(csr_schema_template.copy())
285
+ csr_schema[MDS_DEFINITIONS] = {}
286
+ for root, _, files in os.walk(dir_path):
287
+ for file in files:
288
+ if file.endswith('_model.json'):
289
+ generate_schema(types_path, root, file, csr_schema)
290
+
291
+ save_csr_schema(of_name, csr_schema)
292
+
293
+
294
+
295
+ def usage():
296
+ logging.info("gen_schema.py -i <inputfile> -o <outfile> -n <project_name>")
297
+
298
+
299
+ def main(argv):
300
+ m_input = ""
301
+ output = ""
302
+ try:
303
+ opts, _ = getopt.getopt(argv, "ht:i:o:n:", ["help", "types_path=", "input=", "out=", "project_name="])
304
+ except getopt.GetoptError:
305
+ help()
306
+ return
307
+ for opt, arg in opts:
308
+ if opt in ("-h", "--help"):
309
+ usage()
310
+ return
311
+ elif opt in ("-t", "--types_path"):
312
+ m_types_path = arg
313
+ elif opt in ("-i", "--input"):
314
+ m_input = arg
315
+ elif opt in ("-o", "--out"):
316
+ output = arg
317
+ elif opt in ("-n", "--project_name"):
318
+ project_name = arg
319
+ else:
320
+ raise RuntimeError("不支持的选项: {}".format(opt))
321
+ if not m_input or not output:
322
+ usage()
323
+ return
324
+ generate(m_types_path, m_input, output, project_name)
325
+
326
+
327
+ if __name__ == "__main__":
328
+ main(sys.argv[1:])