Coverage for src / dotbot / context.py: 96%

27 statements  

« prev     ^ index     » next       coverage.py v7.12.0, created at 2025-11-29 10:55 -0800

1import copy 

2import os 

3from argparse import Namespace 

4from typing import TYPE_CHECKING, Any, Dict, List, Optional, Type 

5 

6if TYPE_CHECKING: 

7 from dotbot.plugin import Plugin 

8 

9 

10class Context: 

11 """ 

12 Contextual data and information for plugins. 

13 """ 

14 

15 def __init__( 

16 self, base_directory: str, options: Optional[Namespace] = None, plugins: "Optional[List[Type[Plugin]]]" = None 

17 ): 

18 self._base_directory = base_directory 

19 self._defaults: Dict[str, Any] = {} 

20 self._options = options if options is not None else Namespace() 

21 self._plugins = plugins 

22 

23 def set_base_directory(self, base_directory: str) -> None: 

24 self._base_directory = base_directory 

25 

26 def base_directory(self, canonical_path: bool = True) -> str: # noqa: FBT001, FBT002 # part of established public API 

27 base_directory = self._base_directory 

28 if canonical_path: 

29 base_directory = os.path.realpath(base_directory) 

30 return base_directory 

31 

32 def set_defaults(self, defaults: Dict[str, Any]) -> None: 

33 self._defaults = defaults 

34 

35 def defaults(self) -> Dict[str, Any]: 

36 return copy.deepcopy(self._defaults) 

37 

38 def options(self) -> Namespace: 

39 return copy.deepcopy(self._options) 

40 

41 def plugins(self) -> "Optional[List[Type[Plugin]]]": 

42 # shallow copy is ok here 

43 return copy.copy(self._plugins) 

44 

45 def dry_run(self) -> bool: 

46 return bool(self._options.dry_run)