def _try_load_input_file(args, log, yaml, change_path, new_value): """Attempt to load the input data file or abend on error.""" (yaml_data, doc_loaded) = Parsers.get_yaml_data(yaml, log, args.yaml_file) if not doc_loaded: # An error message has already been logged sys.exit(1) elif yaml_data is None: yaml_data = Nodes.build_next_node(change_path, 0, new_value) return yaml_data
def merge_with(self, rhs: Any) -> None: """ Merge this document with another. Parameters: 1. rhs (Any) The document to merge into this one. Returns: N/A Raises: - `MergeException` when a clean merge is impossible. """ # Do nothing when RHS is None (empty document) if rhs is None: return # Remove all comments (no sensible way to merge them) Parsers.delete_all_comments(rhs) # When LHS is None (empty document), just dump all of RHS into it, # honoring any --mergeat|-m location as best as possible. insert_at = self.config.get_insertion_point() if self.data is None: self.logger.debug("Replacing None data with:", prefix="Merger::merge_with: ", data=rhs, data_header=" *****") self.data = Nodes.build_next_node(insert_at, 0, rhs) self.logger.debug("Merged document is now:", prefix="Merger::merge_with: ", data=self.data, footer=" ***** ***** *****") if isinstance(rhs, (dict, list)): # Only Scalar values need further processing return # Resolve any anchor conflicts self._resolve_anchor_conflicts(rhs) # Prepare the merge rules self.config.prepare(rhs) # Identify a reasonable default should a DOM need to be built up to # receive the RHS data. default_val = rhs if isinstance(rhs, CommentedMap): default_val = {} elif isinstance(rhs, CommentedSeq): default_val = [] # Loop through all insertion points and the elements in RHS merge_performed = False nodes: List[NodeCoords] = [] lhs_proc = Processor(self.logger, self.data) for node_coord in lhs_proc.get_nodes(insert_at, default_value=default_val): nodes.append(node_coord) for node_coord in nodes: target_node = (node_coord.node if isinstance( node_coord.node, (CommentedMap, CommentedSeq)) else node_coord.parent) Parsers.set_flow_style(rhs, (target_node.fa.flow_style() if hasattr( target_node, "fa") else None)) if isinstance(rhs, CommentedMap): # The RHS document root is a map if isinstance(target_node, CommentedSeq): # But the destination is a list self._merge_lists(target_node, CommentedSeq([rhs]), insert_at) else: self._merge_dicts(target_node, rhs, insert_at) # Synchronize YAML Tags self.logger.debug( "Merger::merge_with: Setting LHS tag from {} to {}.". format(target_node.tag.value, rhs.tag.value)) target_node.yaml_set_tag(rhs.tag.value) merge_performed = True elif isinstance(rhs, CommentedSeq): # The RHS document root is a list self._merge_lists(target_node, rhs, insert_at) merge_performed = True # Synchronize any YAML Tag self.logger.debug( "Merger::merge_with: Setting LHS tag from {} to {}.". format(target_node.tag.value, rhs.tag.value)) target_node.yaml_set_tag(rhs.tag.value) else: # The RHS document root is a Scalar value target_node = node_coord.node if isinstance(target_node, CommentedSeq): Nodes.append_list_element(target_node, rhs) merge_performed = True elif isinstance(target_node, CommentedMap): raise MergeException( "Impossible to add Scalar value, {}, to a Hash without" " a key. Change the value to a 'key: value' pair, a" " '{{key: value}}' Hash, or change the merge target to" " an Array or other Scalar value.".format(rhs), insert_at) else: lhs_proc.set_value(insert_at, rhs) merge_performed = True self.logger.debug("Completed merge operation, resulting in document:", prefix="Merger::merge_with: ", data=self.data) if not merge_performed: raise MergeException( "A merge was not performed. Ensure your target path matches" " at least one node in the left document(s).", insert_at)
def merge_with(self, rhs: Any) -> None: """ Merge this document with another. Parameters: 1. rhs (Any) The document to merge into this one. Returns: N/A Raises: - `MergeException` when a clean merge is impossible. """ # Do nothing when RHS is None (empty document) if rhs is None: return # Remove all comments (no sensible way to merge them) Parsers.delete_all_comments(rhs) # When LHS is None (empty document), just dump all of RHS into it, # honoring any --mergeat|-m location as best as possible. insert_at = self.config.get_insertion_point() if self.data is None: self.logger.debug( "Replacing None data with:", prefix="Merger::merge_with: ", data=rhs, data_header=" *****") self.data = Nodes.build_next_node(insert_at, 0, rhs) self.logger.debug( "Merged document is now:", prefix="Merger::merge_with: ", data=self.data, footer=" ***** ***** *****") if isinstance(rhs, (dict, list, CommentedSet, set)): # Only Scalar values need further processing return # Resolve any anchor conflicts self._resolve_anchor_conflicts(rhs) # Prepare the merge rules self.config.prepare(rhs) # Merge into each insertion point merge_performed = False lhs_proc = Processor(self.logger, self.data) for node_coord in self._get_merge_target_nodes( insert_at, lhs_proc, rhs ): target_node = node_coord.node Parsers.set_flow_style( rhs, (target_node.fa.flow_style() if hasattr(target_node, "fa") else None)) if isinstance(rhs, CommentedMap): # The RHS document root is a dict merge_performed = self._insert_dict( insert_at, target_node, rhs) elif isinstance(rhs, CommentedSeq): # The RHS document root is a list merge_performed = self._insert_list( insert_at, target_node, rhs) elif isinstance(rhs, CommentedSet): # The RHS document is a set merge_performed = self._insert_set( insert_at, target_node, rhs) else: # The RHS document root is a Scalar value merge_performed = self._insert_scalar( insert_at, target_node, lhs_proc, rhs) self.logger.debug( "Completed merge operation, resulting in document:", prefix="Merger::merge_with: ", data=self.data) if not merge_performed: raise MergeException( "A merge was not performed. Ensure your target path matches" " at least one node in the left document(s).", insert_at)
def build_next_node(*args): """Relay function call to static method.""" return Nodes.build_next_node(*args)