in src/aaz_dev/command/controller/workspace_cfg_editor.py [0:0]
def merge(self, plus_cfg_editor):
"""
create conditions according to the path
expand all http-operations with merged path in the main cfg using condition for switching
"""
if not self._can_merge(plus_cfg_editor):
return None
plus_operations_by_method = {}
plus_ops_required_args = {}
plus_resources_arg_groups = []
for method in ['get', 'put', 'post', 'delete', 'patch']:
for _, command in plus_cfg_editor.iter_commands_by_operations(method):
if command.subresource_selector:
continue
if method not in plus_operations_by_method:
plus_operations_by_method[method] = {}
for operation in command.operations:
if isinstance(operation, CMDHttpOperation) and operation.http.request.method.lower() == method:
plus_operations_by_method[method][operation.operation_id] = operation
plus_op_required_args, plus_op_optional_args = self._parse_command_http_op_url_args(command)
plus_ops_required_args.update(plus_op_required_args)
if not plus_resources_arg_groups:
# merge args
new_args = set()
for args in plus_op_required_args.values():
new_args.update(args)
for args in plus_op_optional_args.values():
new_args.update(args)
for arg_group in command.arg_groups:
arg_group = plus_cfg_editor._filter_args_in_arg_group(arg_group, new_args, copy=True)
if arg_group:
plus_resources_arg_groups.append(arg_group)
if method in plus_operations_by_method:
assert len(plus_operations_by_method[method]) == len(plus_cfg_editor.resources)
main_editor = WorkspaceCfgEditor(self.cfg.__class__(self.cfg.to_primitive())) # generate a copy of main cfg
for _, main_command in main_editor.iter_commands():
# create plus http operations by replace the path and query args
merged_operations = []
plus_operations = []
plus_op_required_args = {}
for operation in main_command.operations:
if not isinstance(operation, CMDHttpOperation):
if plus_operations:
merged_operations.extend(plus_operations)
plus_operations = []
merged_operations.append(operation)
continue
if plus_operations and operation.http.request.method.lower() == plus_operations[0].http.request.method.lower():
merged_operations.append(operation)
continue
if plus_operations:
merged_operations.extend(plus_operations)
plus_operations = []
merged_operations.append(operation)
for operation_id, plus_operation in plus_operations_by_method[operation.http.request.method.lower()].items():
plus_operation = plus_operation.__class__(plus_operation.to_primitive())
plus_operation.http.request.header = operation.http.request.header
plus_operation.http.request.body = operation.http.request.body
plus_operation.http.responses = operation.http.responses
if plus_operation.http.request.method.lower() == 'get' and plus_operation.http.request.query.params:
# the get method in generate update command will ignore the optional query params if it's not exist in the put or patch operations.
# here we need to exclude them if those query params has args in the main command
params = []
for param in plus_operation.http.request.query.params:
arg, _ = main_editor.find_arg_in_command_by_var(main_command, arg_var=param.arg)
if not param.required and not arg:
continue
params.append(param)
plus_operation.http.request.query.params = params
plus_operation = plus_operation.__class__(plus_operation.to_primitive())
plus_operations.append(plus_operation)
if operation_id not in plus_op_required_args:
plus_op_required_args[operation_id] = plus_ops_required_args[operation_id]
if plus_operations:
merged_operations.extend(plus_operations)
plus_operations = []
# merge args
for arg_group in plus_resources_arg_groups:
try:
main_editor._command_merge_arg_group(main_command, arg_group)
except exceptions.InvalidAPIUsage as ex:
logger.error(ex)
return None
# create conditions
main_op_required_args, _ = main_editor._parse_command_http_op_url_args(main_command)
op_required_args = {**plus_op_required_args, **main_op_required_args}
merged_required_args, merged_optional_args, main_command.conditions, main_command.operations = main_editor._merge_command_operations(
op_required_args,
*merged_operations
)
# update arg required of command
for arg_group in main_command.arg_groups:
for arg in arg_group.args:
if arg.var in merged_required_args:
arg.required = True
elif arg.var in merged_optional_args:
arg.required = False
for resource in plus_cfg_editor.resources:
resource = resource.__class__(resource.to_primitive())
resource.subresource = main_command.resources[0].subresource # follow the main command's subresource
main_command.resources.append(resource)
# relink main_command
main_command.link()
for resource in plus_cfg_editor.resources:
main_editor.cfg.resources.append(
resource.__class__(resource.to_primitive())
)
main_editor.reformat()
return main_editor