Coverage for bugscpp/processor/core/data.py : 100%

Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1"""
2Define data types used within processor module.
4"""
5import json
6from dataclasses import asdict, dataclass, field, fields
7from os import getcwd
8from pathlib import Path, PurePosixPath
9from typing import Tuple, Union
11from config import config
12from errors import DppArgparseConfigCorruptedError, DppArgparseFileNotFoundError, DppArgparseInvalidConfigError
13from taxonomy import MetaData, Taxonomy
15NAMESPACE_ATTR_INDEX = "index"
16NAMESPACE_ATTR_BUGGY = "buggy"
17NAMESPACE_ATTR_WORKSPACE = "workspace"
18NAMESPACE_ATTR_PATH = "path"
19NAMESPACE_ATTR_PATH_CONFIG_NAME = ".defects4cpp.json"
20NAMESPACE_ATTR_METADATA = "metadata"
21NAMESPACE_ATTR_METADATA_BASE = "metadata_base"
24@dataclass
25class Worktree:
26 """
27 Dataclass to manage host and container directory structure.
29 """
31 project_name: str
32 """The name of the defect taxonomy."""
33 index: int
34 """The index number of taxonomy."""
35 buggy: bool = field(default=False)
36 """True if the project is configured as buggy, otherwise False."""
37 workspace: str = field(default=getcwd())
38 """The workspace path string."""
40 @property
41 def base(self) -> Path:
42 """Return base path which will be used to test and build defect taxonomies"""
43 return Path(f"{self.workspace}/{self.project_name}")
45 @property
46 def suffix(self) -> Path:
47 """Return suffix path which is appended to base path"""
48 return Path(f"{'buggy' if self.buggy else 'fixed'}-{self.index}")
50 @property
51 def host(self) -> Path:
52 """Return path from which is mounted"""
53 return self.base / self.suffix
55 @property
56 def container(self) -> PurePosixPath:
57 """Return path to which is mounted inside docker"""
58 return PurePosixPath(config.DPP_DOCKER_HOME)
60 def __post_init__(self):
61 for f in fields(self):
62 value = getattr(self, f.name)
63 if not value:
64 setattr(self, f.name, f.default)
67class Project:
68 """
69 Load and save project from path.
71 """
73 @staticmethod
74 def read_config(project_dir: Union[str, Path]) -> Tuple[MetaData, Worktree]:
75 """
76 Read config file and return parsed options.
78 Parameters
79 ----------
80 project_dir : Union[str, Path]
81 Path to where defect taxonomy is located.
83 Returns
84 -------
85 Tuple[taxonomy.MetaData, docker.Worktree]
86 Return a tuple of metadata and worktree information.
87 """
88 try:
89 with open(Path(project_dir) / NAMESPACE_ATTR_PATH_CONFIG_NAME, "r") as fp:
90 data = json.load(fp)
91 except FileNotFoundError as e:
92 raise DppArgparseFileNotFoundError(e.filename)
93 except json.JSONDecodeError:
94 raise DppArgparseInvalidConfigError()
96 try:
97 worktree = Worktree(**data)
98 except TypeError:
99 raise DppArgparseConfigCorruptedError(data)
101 t = Taxonomy()
102 return t[worktree.project_name], worktree
104 @staticmethod
105 def write_config(worktree: Worktree) -> None:
106 """
107 Write config file to the directory.
109 Parameters
110 ----------
111 worktree : taxonomy.Worktree
112 Worktree
114 Returns
115 -------
116 None
117 """
118 config_file = Path(worktree.host) / NAMESPACE_ATTR_PATH_CONFIG_NAME
119 if config_file.exists():
120 return
122 try:
123 with open(config_file, "w+") as fp:
124 json.dump(asdict(worktree), fp)
125 except FileNotFoundError as e:
126 raise DppArgparseFileNotFoundError(e.filename)