|
1 | 1 | """Self update Odev by pulling latest changes from the git repository.""" |
2 | 2 |
|
3 | 3 | import contextlib |
| 4 | +import importlib |
4 | 5 | import inspect |
5 | 6 | import os |
6 | 7 | import pkgutil |
|
36 | 37 | from odev.common import progress, string |
37 | 38 | from odev.common.commands import CommandType |
38 | 39 | from odev.common.commands.database import DatabaseType |
39 | | -from odev.common.config import Config |
| 40 | +from odev.common.config import CONFIG_DIR, Config |
40 | 41 | from odev.common.connectors.git import GitConnector, Stash |
41 | 42 | from odev.common.console import Console, console |
42 | 43 | from odev.common.errors import OdevError |
@@ -184,7 +185,7 @@ def tests_path(self) -> Path: |
184 | 185 | @property |
185 | 186 | def plugins_path(self) -> Path: |
186 | 187 | """Local path to the plugins directory.""" |
187 | | - return self.base_path / "plugins" |
| 188 | + return CONFIG_DIR / "plugins" |
188 | 189 |
|
189 | 190 | @property |
190 | 191 | def commands_path(self) -> Path: |
@@ -516,8 +517,12 @@ def import_commands(self, sources: Iterable[Path]) -> list[type[CommandType]]: |
516 | 517 | if not isinstance(module_info.module_finder, FileFinder): |
517 | 518 | raise TypeError("Module finder is not a FileFinder instance") |
518 | 519 |
|
519 | | - module_path = Path(module_info.module_finder.path) / f"{module_info.name}.py" |
520 | | - spec = spec_from_file_location(module_path.stem, module_path.as_posix()) |
| 520 | + if module_info.ispkg: |
| 521 | + module_path = Path(module_info.module_finder.path) / module_info.name / "__init__.py" |
| 522 | + else: |
| 523 | + module_path = Path(module_info.module_finder.path) / f"{module_info.name}.py" |
| 524 | + |
| 525 | + spec = spec_from_file_location(module_info.name, module_path.as_posix()) |
521 | 526 |
|
522 | 527 | if spec is None or spec.loader is None: |
523 | 528 | raise ImportError(f"Cannot load module {module_info.name} from {module_path.as_posix()}") |
@@ -566,11 +571,29 @@ def register_plugin_commands(self) -> None: |
566 | 571 |
|
567 | 572 | def _register_plugin_commands(self) -> None: |
568 | 573 | """Register all commands from the plugins directories.""" |
| 574 | + # Ensure odev.plugins exists as a module so legacy imports work |
| 575 | + odev_module = sys.modules.get("odev") |
| 576 | + if odev_module: |
| 577 | + if not hasattr(odev_module, "plugins"): |
| 578 | + odev_module.plugins = ModuleType("odev.plugins") |
| 579 | + odev_module.plugins.__path__ = [] |
| 580 | + sys.modules["odev.plugins"] = odev_module.plugins |
| 581 | + |
| 582 | + if str(self.plugins_path) not in odev_module.plugins.__path__: |
| 583 | + odev_module.plugins.__path__.append(str(self.plugins_path)) |
| 584 | + |
569 | 585 | for plugin in self.plugins: |
570 | 586 | logger.debug( |
571 | 587 | f"Loading plugin {plugin.name!r} version {string.stylize(plugin.manifest['version'], 'repr.version')}" |
572 | 588 | ) |
573 | 589 |
|
| 590 | + self._install_plugin_requirements(plugin.path) |
| 591 | + |
| 592 | + try: |
| 593 | + importlib.import_module(f"odev.plugins.{plugin.path.name}") |
| 594 | + except ImportError as error: |
| 595 | + logger.debug(f"Could not import plugin module {plugin.path.name}: {error}") |
| 596 | + |
574 | 597 | for command_class in self.import_commands(plugin.path.glob("commands/**")): |
575 | 598 | command_names = [command_class._name] + (list(command_class._aliases) or []) |
576 | 599 | base_command_class = self.commands.get(command_class._name) |
|
0 commit comments