# """
# This is the old yaml hook. Perhaps later it can be inspiration for a yaml hook that
# updates files in place? Could be useful to just point to a yaml file and combine the
# read and write in one operation with a swiss army knife of different filters...
# Maybe...
# """
#
# """YAML hook."""
# import logging
# import yaml
# import re
# import os
# from pydantic import Field
#
# from typing import Union, Dict, List, Any
#
# from tackle.models import BaseHook
# from tackle.utils import merge_configs
#
# logger = logging.getLogger(__name__)
#
#
# class YamlHook(BaseHook):
#     """
#     Hook for modifying a yaml in place (ie read, transform, and write back to the file
#     in one operation).
#     """
#     hook_type: str = 'yaml_in_place'
#
#     path: str = Field(..., description="The file path to put read or write to.")
#     remove: Union[List, str] = Field(
#         None, description="Parameter or regex to remove from list or dict."
#     )
#     contents: Union[Dict, List] = Field(
#         None, description="Supplied dictionary or list to write."
#     )
#     update: Dict = Field(
#         None,
#         description="Use the python `update` dict method on `contents` before writing",
#     )
#     filter: List = Field(None, description="List or string to values to.")
#     merge_dict: dict = Field(
#         None, description="Dict input that recursively overwrites the `contents`."
#     )
#     in_place: bool = Field(
#         False,
#         description="Boolean to read the contents of the `path` and then write after modifications.",
#     )
#     append_items: Union[Dict, str, List[Any]] = Field(
#         None, description="List to append to `append_key` key."
#     )
#     append_keys: Union[Dict, str, List[Any]] = Field(
#         None,
#         description="String or list of hierarchical keys to append item to. Defaults",
#     )
#     mode: str = Field(
#         None,
#         description="The mode that the file should write. Defaults to write 'w'. See https://docs.python.org/3/library/functions.html#open",
#     )
#     write: bool = Field(None, description="")
#
#     args: list = ['path', 'contents']
#
#     def __init__(self, **data: Any):
#         super().__init__(**data)
#         self.path = os.path.expanduser(os.path.expandvars(self.path))
#
#     def _load_contents(self):
#         if self.contents:
#             # We are writing. Context is provided
#             self.write = True
#             pass
#         if self.in_place:
#             # We are modifying in place. Context is read from path
#             self.write = True
#             with open(self.path, 'r') as f:
#                 self.contents = yaml.safe_load(f)
#         elif not self.contents:
#             # We are reading. Contents is read from path
#             self.write = False
#             mode = self.mode or 'r'
#             with open(self.path, mode) as f:
#                 self.contents = yaml.safe_load(f)
#
#     def _append_each_item(self, append_item):
#         if isinstance(self.append_keys, str):
#             self.contents[self.append_keys].append(append_item)
#         elif isinstance(self.append_keys, list):
#             for k in self.append_keys[:-1]:
#                 self.contents = self.contents.setdefault(k, {})
#             self.contents[self.append_keys[-1]].append(append_item)
#         else:
#             self.contents.append(append_item)
#
#     def _remove_from_contents(self, regex):
#         if isinstance(self.contents, list):
#             self.contents = [i for i in self.contents if not re.search(regex, i)]
#         if isinstance(self.contents, dict):
#             for k in list(self.contents.keys()):
#                 if re.search(regex, k):
#                     self.contents.pop(k)
#
#     def _modify_dicts(self):
#         if self.remove:
#             if isinstance(self.remove, str):
#                 self._remove_from_contents(self.remove)
#
#             if isinstance(self.remove, list):
#                 for i in self.remove:
#                     self._remove_from_contents(i)
#
#         if self.filter:
#             if isinstance(self.contents, dict):
#                 self.contents = {
#                     k: v for (k, v) in self.contents.items() if k in self.filter
#                 }
#
#         if self.update:
#             self.contents.update(self.update)
#
#         if self.merge_dict:
#             self.contents = merge_configs(self.contents, self.merge_dict)
#
#         if self.append_items:
#             if isinstance(self.append_items, str) or isinstance(
#                 self.append_items, dict
#             ):
#                 self._append_each_item(self.append_items)
#             elif isinstance(self.append_items, list):
#                 for i in self.append_items:
#                     self._append_each_item(i)
#
#     def exec(self) -> Union[str, dict]:
#         # Load the path into contents unless it already exists
#         self._load_contents()
#         # Run all the modifiers
#         self._modify_dicts()
#
#         if self.write:
#             mode = self.mode or 'w'
#             with open(self.path, mode) as f:
#                 yaml.dump(self.contents, f)
#                 return self.contents
#         else:
#             # Read operation, just return contents
#             return self.contents
