from typing import List, Optional, Union, Dict from pathlib import Path import yaml import json from .enums import NamingScheme from .generic_text import GenericText from .formatterif import Config from .git_version_info import GitVersionInfo from .constants import * from .enums import TeXType, TeXFlavour class VersionInfo: def __init__(self): self._repo_version: Optional[GitVersionInfo] = None self._pytex_version: Optional[GitVersionInfo] = None @property def pytex_version(self) -> Optional[GitVersionInfo]: if self._pytex_version is None: return None else: return self._pytex_version @property def repo_version(self) -> Optional[GitVersionInfo]: if self._repo_version is None: return None else: return self._repo_version def clean_dict(dictionary: Dict) -> Optional[Dict]: aux = { k: clean_dict(v) for k, v in dictionary.items() if type(v) == dict } | { k: v for k, v in dictionary.items() if type(v) != dict } aux2 = { k: v for k, v in aux.items() if v is not None } return aux2 if aux2 != {} else None class FormattingConfig(Config): def __init__(self): self._naming_scheme: Optional[Union[NamingScheme, str]] = None self._license: Optional[GenericText] = None self._description: Optional[str] = None self._include_extra_header: Optional[bool] = None self._include_pytex_version: Optional[bool] = None self._include_pytex_info_text: Optional[bool] = None self._include_repo_version: Optional[bool] = None self._include_repo_info_text: Optional[bool] = None self._include_time: Optional[bool] = None self._include_license: Optional[bool] = None self._extra_header: Optional[GenericText] = None self._author: Optional[str] = None self._version: Optional[str] = None self._pytex_info_text: Optional[GenericText] = None self._repo_info_text: Optional[GenericText] = None self._include_drv: Optional[bool] = None self._include_ins: Optional[bool] = None self._docstrip_guards: Optional[List[str]] = None self._doc_dependencies: Optional[List[str]] = None self._tex_dependencies: Optional[List[str]] = None self._tex_type: Optional[TeXType] = None self._tex_flavour: Optional[TeXFlavour] = None def set_from_json(self, content: Dict): content = FormattingConfig().to_json() | content # Fill with none values info = content[YAML_INFO] self._author = info[YAML_AUTHOR] self._naming_scheme = info[YAML_NAMING_SCHEME] self._tex_flavour = info[YAML_TEX_FLAVOUR] self._tex_type = info[YAML_TEX_TYPE] self._description = info[YAML_DESCRIPTION] header = content[YAML_HEADER] extra = header[YAML_EXTRA] self._include_extra_header = extra[YAML_INCLUDE_EXTRA_HEADER] self._extra_header = GenericText( extra[YAML_PATH] if extra[YAML_PATH] else extra[YAML_TEXT] ) @classmethod def from_yaml(cls, content: Path): with open(content, 'r') as config: content: Dict = yaml.safe_load(config) return cls.from_json(content) @classmethod def from_json(cls, content: Union[Path, Dict]): if isinstance(content, Path): with open(content, 'r') as config: content: Dict = json.load(config) config = FormattingConfig() config.set_from_json(content) return config def dump_as_yaml(self, filename: Path): with filename.open('w') as file: simple_dict = clean_dict(self.to_json()) if simple_dict is not None: yaml.dump(simple_dict, file) else: pass # TODO def to_json(self) -> Dict: return { YAML_INFO: { YAML_AUTHOR: self._author, YAML_NAMING_SCHEME: self._naming_scheme, YAML_TEX_FLAVOUR: self._tex_flavour, YAML_TEX_TYPE: self._tex_type, YAML_VERSION: self._version, YAML_DESCRIPTION: self._description }, YAML_HEADER: { YAML_EXTRA: { YAML_INCLUDE_EXTRA_HEADER: self._include_extra_header, YAML_PATH: self._extra_header.pathname if self._extra_header else None, YAML_TEXT: self._extra_header.real_text if self._extra_header else None }, YAML_REPO: { YAML_INCLUDE_INFO_TEXT: self._include_repo_info_text, YAML_INCLUDE_VERSION: self._include_repo_version, YAML_PATH: self._repo_info_text.pathname if self._repo_info_text else None, YAML_TEXT: self._repo_info_text.real_text if self._repo_info_text else None }, YAML_PYTEX: { YAML_INCLUDE_INFO_TEXT: self._include_pytex_info_text, YAML_INCLUDE_VERSION: self._include_pytex_version, YAML_PATH: self._pytex_info_text.path if self._pytex_info_text else None, YAML_TEXT: self._pytex_info_text.real_text if self._pytex_info_text else None }, YAML_INCLUDE_TIME: self._include_time, YAML_LICENSE: { YAML_INCLUDE_LICENSE: self._include_license, YAML_PATH: self._license.path if self._license else None, YAML_TEXT: self._license.real_text if self._license else None }, }, YAML_DOCSTRIP: { YAML_INCLUDE_DRV: self._include_drv, YAML_INCLUDE_INS: self._include_ins, YAML_DOCSTRIP_GUARDS: self._docstrip_guards }, YAML_DEPENDENCIES: { YAML_DOC_DEPENDENCIES: self._doc_dependencies, YAML_TEX_DEPENDENCIES: self._tex_dependencies } } @property def naming_scheme(self) -> NamingScheme: if self._naming_scheme is None: return NamingScheme.prepend_author else: return self._naming_scheme @naming_scheme.setter def naming_scheme(self, naming_scheme: NamingScheme): self._naming_scheme = naming_scheme @property def license(self) -> GenericText: if self._license is None: return GenericText() else: return self._license @license.setter def license(self, license: GenericText): self._license = license @property def include_extra_header(self) -> bool: if self._include_extra_header is None: return False else: return self._include_extra_header @include_extra_header.setter def include_extra_header(self, include: bool): self._include_extra_header = include @property def include_pytex_version(self) -> bool: if self._include_pytex_version is None: return False else: return self._include_pytex_version @include_pytex_version.setter def include_pytex_version(self, include: bool): self._include_pytex_version = include @property def include_pytex_info_text(self) -> bool: if self._include_pytex_info_text is None: return False else: return self._include_pytex_info_text @include_pytex_info_text.setter def include_pytex_info_text(self, include: bool): self._include_pytex_info_text = include @property def include_repo_version(self) -> bool: if self._include_repo_version is None: return False else: return self._include_repo_version @include_repo_version.setter def include_repo_version(self, include: bool): self._include_repo_version = include @property def include_repo_info_text(self) -> bool: if self._include_repo_info_text is None: return False else: return self._include_repo_info_text @include_repo_info_text.setter def include_repo_info_text(self, include: bool): self._include_repo_info_text = include @property def extra_header(self) -> GenericText: if self._extra_header is None: return GenericText() else: return self._extra_header @extra_header.setter def extra_header(self, extra_header: GenericText): self._extra_header = extra_header @property def author(self) -> str: if self._author is None: return "MISSING AUTHOR" else: return self._author @author.setter def author(self, author: str): self._author = author @property def version(self) -> str: if self._version is None: return "0.0.0" else: return self._version @version.setter def version(self, version: str): self._version = version @property def pytex_info_text(self) -> GenericText: if self._pytex_info_text is None: return GenericText() else: return self._pytex_info_text @pytex_info_text.setter def pytex_info_text(self, info_text: GenericText): self._pytex_info_text = info_text @property def repo_info_text(self) -> GenericText: if self._repo_info_text is None: return GenericText() else: return self._repo_info_text @repo_info_text.setter def repo_info_text(self, info_text: GenericText): self._repo_info_text = info_text @property def include_drv(self) -> bool: if self._include_drv is None: return False else: return self._include_drv @include_drv.setter def include_drv(self, include: bool): self._include_drv = include @property def include_ins(self) -> bool: if self._include_ins is None: return False else: return self._include_ins @include_ins.setter def include_ins(self, include): self._include_ins = include @property def docstrip_guards(self) -> List[str]: if self._docstrip_guards is None: return [] else: return self._docstrip_guards @docstrip_guards.setter def docstrip_guards(self, guards: List[str]): self._docstrip_guards = guards @property def description(self) -> str: if self._description is None: return '' else: return self._description @description.setter def description(self, description: str): self._description = description @property def include_time(self) -> bool: if self._include_time is None: return False else: return self._include_time @include_time.setter def include_time(self, include: bool): self._include_time = include @property def doc_dependencies(self) -> List[str]: if self._doc_dependencies is None: return [] else: return self._doc_dependencies @doc_dependencies.setter def doc_dependencies(self, dependencies: List[str]): self._doc_dependencies = dependencies @property def tex_dependencies(self) -> List[str]: if self._tex_dependencies is None: return [] else: return self._tex_dependencies @tex_dependencies.setter def tex_dependencies(self, dependencies: List[str]): self._tex_dependencies = dependencies class DocFormattingConfig: def __init__(self): self._documents: Optional[List[str]] = None self._dependencies: Optional[List[str]] = None