Example #1
0
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
Example #2
0
    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)
Example #3
0
    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)
Example #4
0
def build_next_node(*args):
    """Relay function call to static method."""
    return Nodes.build_next_node(*args)