Encapsulate the logic for a single component line in [components].
| 38 | |
| 39 | @dataclass |
| 40 | class ConfiguredComponent: |
| 41 | """ |
| 42 | Encapsulate the logic for a single component line in [components]. |
| 43 | """ |
| 44 | |
| 45 | env: TracEnvironment |
| 46 | pathstr: str |
| 47 | boolstr: str |
| 48 | |
| 49 | @property |
| 50 | def is_installed(self): |
| 51 | """ |
| 52 | Recursively navigate the environment's installed components to figure out if |
| 53 | this one matches one (or more) of them. |
| 54 | """ |
| 55 | branch = self.env.registered_component_tree |
| 56 | for node in self.pathstr.split("."): |
| 57 | if node == "*": |
| 58 | return bool(branch) |
| 59 | if node not in branch: |
| 60 | return False |
| 61 | branch = branch[node] |
| 62 | |
| 63 | assert not branch, f"Final node in installation tree is not empty: {branch!r}" |
| 64 | return True |
| 65 | |
| 66 | @property |
| 67 | def is_valid_boolstr(self): |
| 68 | """ |
| 69 | Only accept either `enabled` or `disabled`, this is to prevent issues with trailing |
| 70 | comments. For example the line `someplugin.* = enabled # we need this` would not |
| 71 | enable the plugin because of the comment. |
| 72 | """ |
| 73 | return self.boolstr in {"enabled", "disabled"} |
| 74 | |
| 75 | def __str__(self): |
| 76 | return f"{self.pathstr} = {self.boolstr}" |
| 77 | |
| 78 | def get_lint_errors(self): |
| 79 | errors = [] |
| 80 | |
| 81 | if not self.is_valid_boolstr: |
| 82 | errors.append("Invalid boolean value") |
| 83 | if not self.is_installed: |
| 84 | errors.append("Component is not installed") |
| 85 | |
| 86 | return errors |
| 87 | |
| 88 | |
| 89 | class CommandEnvironment(TracEnvironment): |
no outgoing calls