diff --git a/__manifest__.py b/__manifest__.py index c4fb61a..87adef2 100644 --- a/__manifest__.py +++ b/__manifest__.py @@ -22,7 +22,7 @@ # or merged change. # ------------------------------------------------------------------------------ -__version__ = "1.2.0" +__version__ = "1.2.1" # --- Dependencies ------------------------------------------------------------- # List other odev plugins from which this current plugin depends. diff --git a/common/editor_vscode.py b/common/editor_vscode.py index 69accfb..b69823e 100644 --- a/common/editor_vscode.py +++ b/common/editor_vscode.py @@ -2,11 +2,9 @@ from pathlib import Path from odev.common import bash, progress, string -from odev.common.console import console from odev.common.databases import LocalDatabase from odev.common.logging import logging from odev.common.odoobin import OdoobinProcess -from odev.common.python import PythonEnv from odev.plugins.odev_plugin_editor_base.common.editor import Editor logger = logging.getLogger(__name__) @@ -65,69 +63,84 @@ def configure(self): f"skipping {self.display_name} configuration" ) - if self.workspace_path.is_file(): - return logger.debug("Workspace file already exists") + # We always want to update the configuration to ensure the Python environment is correct + # even if the workspace file already exists. with progress.spinner(f"Configuring {self.display_name} for project {self.git.name!r}"): self.workspace_directory.mkdir(parents=True, exist_ok=True) - missing_files = filter( - lambda path: not path.is_file(), - [self.workspace_path, self.launch_path, self.tasks_path], - ) - - if not list(missing_files): - return logger.debug(f"{self.display_name} config files already exist") - created_files_list = [] if self._create_workspace(): created_files_list.append(f"Workspace: {self.workspace_path}") - if not self.version: - self._create_launch() - self._create_tasks() - created_files_list.extend([ - f"Debugging: {self.launch_path}", - f"Tasks: {self.tasks_path}", - ]) + self._create_launch() + self._create_tasks() + created_files_list.extend([ + f"Debugging: {self.launch_path}", + f"Tasks: {self.tasks_path}", + ]) created_files = string.join_bullet(created_files_list) logger.info(f"Created {self.display_name} config for project {self.git.name!r}\n{created_files}") def _create_workspace(self) -> bool: """Create a workspace file for the project.""" + workspace_config = {} if self.workspace_path.is_file(): - logger.debug("Workspace file already exists") - return False - - workspace_config = { - "folders": [], - "settings": { - "terminal.integrated.cwd": self.path.as_posix(), - }, - } + try: + workspace_config = json.loads(self.workspace_path.read_text()) + except Exception: + logger.warning(f"Could not load existing workspace file {self.workspace_path}") + + if not workspace_config: + workspace_config = { + "folders": [], + "settings": {}, + } + + workspace_config["settings"]["terminal.integrated.cwd"] = self.path.as_posix() process = ( self.database.process if isinstance(self.database, LocalDatabase) and self.database.process - else OdoobinProcess(self.database, self.version).with_edition("enterprise") + else OdoobinProcess(self.database, version=self.version).with_edition("enterprise") ) if isinstance(self.database, LocalDatabase): - workspace_config["folders"].append({"path": ".."}) - workspace_config["settings"]["python.defaultInterpreterPath"] = self.database.venv.python.as_posix() + if {"path": ".."} not in workspace_config["folders"]: + workspace_config["folders"].append({"path": ".."}) + + python_path = process.venv.python.as_posix() + workspace_config["settings"]["python.defaultInterpreterPath"] = python_path + # Set interpreterPath as well for better compatibility with different editor versions + workspace_config["settings"]["python.interpreterPath"] = python_path + + # Add extra paths for better autocompletion + extra_paths = [p.as_posix() for p in process.addons_paths if p.exists()] + workspace_config["settings"]["python.analysis.extraPaths"] = extra_paths + workspace_config["settings"]["python.autoComplete.extraPaths"] = extra_paths + + # Force Ruff extension to use the binary from the venv + ruff_bin = (process.venv.path / "bin" / "ruff").as_posix() + workspace_config["settings"]["ruff.path"] = [ruff_bin] + workspace_config["settings"]["ruff.importStrategy"] = "fromEnvironment" for worktree in process.odoo_worktrees: - workspace_config["folders"].append({"path": worktree.path.as_posix()}) + worktree_path = {"path": worktree.path.as_posix()} + if worktree_path not in workspace_config["folders"]: + workspace_config["folders"].append(worktree_path) - console.print(json.dumps(workspace_config, indent=4), file=self.workspace_path) + self.workspace_path.write_text(json.dumps(workspace_config, indent=4)) return True def _create_launch(self): """Create a launch file for the project.""" - if self.launch_path.is_file(): - return logger.debug("Launch file already exists") + process = ( + self.database.process + if isinstance(self.database, LocalDatabase) and self.database.process + else OdoobinProcess(self.database, version=self.version).with_edition("enterprise") + ) def run_config(shell: bool = False): title = "Shell" if shell else "Run" @@ -141,7 +154,7 @@ def run_config(shell: bool = False): "consoleName": f"Odev {title} ({self.database.name})", "cwd": self.path.as_posix(), "program": self.database.odev.executable.as_posix(), - "python": PythonEnv().python.as_posix(), + "python": process.venv.python.as_posix(), "args": [ title.lower(), self.database.name, @@ -165,16 +178,14 @@ def run_config(shell: bool = False): ], } - console.print(json.dumps(launch_config, indent=4), file=self.launch_path) + self.launch_path.write_text(json.dumps(launch_config, indent=4)) def _create_tasks(self): """Create a tasks file for the project.""" - if self.tasks_path.is_file(): - return logger.debug("Tasks file already exists") tasks_config = { "version": "2.0.0", "tasks": [], } - console.print(json.dumps(tasks_config, indent=4), file=self.tasks_path) + self.tasks_path.write_text(json.dumps(tasks_config, indent=4))