From 50b3055275acd3597c421d3e3338f25f2f6010d2 Mon Sep 17 00:00:00 2001 From: Xieyt Date: Tue, 13 Feb 2024 18:23:05 +0530 Subject: [PATCH 1/2] feat: vscode debugger integration --- frappe_manager/__init__.py | 16 ++++--- frappe_manager/commands.py | 9 ++-- frappe_manager/site_manager/SiteManager.py | 50 ++++++++++++++++++---- frappe_manager/site_manager/__init__.py | 29 +++++++++++++ 4 files changed, 84 insertions(+), 20 deletions(-) diff --git a/frappe_manager/__init__.py b/frappe_manager/__init__.py index 14d37fac..21d54d95 100644 --- a/frappe_manager/__init__.py +++ b/frappe_manager/__init__.py @@ -2,24 +2,26 @@ from enum import Enum # TODO configure this using config -#sites_dir = Path().home() / __name__.split(".")[0] -CLI_DIR = Path.home() / 'frappe' -CLI_METADATA_PATH = CLI_DIR / '.fm.toml' -CLI_SITES_ARCHIVE = CLI_DIR / 'archived' +# sites_dir = Path().home() / __name__.split(".")[0] +CLI_DIR = Path.home() / "frappe" +CLI_METADATA_PATH = CLI_DIR / ".fm.toml" +CLI_SITES_ARCHIVE = CLI_DIR / "archived" default_extension = [ "dbaeumer.vscode-eslint", "esbenp.prettier-vscode", "ms-python.python", - "ms-python.black-formatter", + "ms-python.debugpy", "ms-python.flake8", + "ms-python.black-formatter", "visualstudioexptteam.vscodeintellicode", - "VisualStudioExptTeam.intellicode-api-usage-examples" + "VisualStudioExptTeam.intellicode-api-usage-examples", ] + class SiteServicesEnum(str, Enum): - frappe= "frappe" + frappe = "frappe" nginx = "nginx" mailhog = "mailhog" adminer = "adminer" diff --git a/frappe_manager/commands.py b/frappe_manager/commands.py index 130ba8ca..764725c8 100644 --- a/frappe_manager/commands.py +++ b/frappe_manager/commands.py @@ -241,7 +241,7 @@ def stop(sitename: Annotated[str, typer.Argument(help="Name of the site")]): sites.stop_site() -def code_command_callback(extensions: List[str]) -> List[str]: +def code_command_extensions_callback(extensions: List[str]) -> List[str]: extx = extensions + default_extension unique_ext: Set = set(extx) unique_ext_list: List[str] = [x for x in unique_ext] @@ -258,16 +258,17 @@ def code( "--extension", "-e", help="List of extensions to install in vscode at startup.Provide extension id eg: ms-python.python", - callback=code_command_callback, + callback=code_command_extensions_callback, ), ] = default_extension, - force_start: Annotated[bool , typer.Option('--force-start','-f',help="Force start the site before attaching to container.")] = False + force_start: Annotated[bool , typer.Option('--force-start','-f',help="Force start the site before attaching to container.")] = False, + debugger: Annotated[bool , typer.Option('--debugger','-d',help="Sync vscode debugger configuration.")] = False ): """Open site in vscode. """ sites.init(sitename) if force_start: sites.start_site() - sites.attach_to_site(user, extensions) + sites.attach_to_site(user, extensions, debugger) @app.command(no_args_is_help=True) diff --git a/frappe_manager/site_manager/SiteManager.py b/frappe_manager/site_manager/SiteManager.py index 24e88557..d87a4249 100644 --- a/frappe_manager/site_manager/SiteManager.py +++ b/frappe_manager/site_manager/SiteManager.py @@ -7,13 +7,14 @@ from typing import List, Optional from pathlib import Path +from datetime import datetime +from frappe_manager.site_manager import VSCODE_LAUNCH_JSON, VSCODE_TASKS_JSON from frappe_manager.site_manager.site import Site from frappe_manager.display_manager.DisplayManager import richprint from frappe_manager.docker_wrapper import DockerClient, DockerException from frappe_manager import CLI_DIR from rich.table import Table -from frappe_manager.utils.helpers import check_and_display_port_status from frappe_manager.utils.site import generate_services_table @@ -238,7 +239,7 @@ def start_site(self): self.site.frappe_logs_till_start(status_msg="Starting Site") self.site.sync_workers_compose() - def attach_to_site(self, user: str, extensions: List[str]): + def attach_to_site(self, user: str, extensions: List[str], debugger: bool = False): """ Attaches to a running site's container using Visual Studio Code Remote Containers extension. @@ -255,7 +256,7 @@ def attach_to_site(self, user: str, extensions: List[str]): if not vscode_path: richprint.exit( - "Visual Studio Code excutable 'code' nott accessible via cli." + "Visual Studio Code binary i.e 'code' is not accessible via cli." ) container_hex = self.site.get_frappe_container_hex() @@ -271,7 +272,15 @@ def attach_to_site(self, user: str, extensions: List[str]): vscode_config_json = [ { "remoteUser": user, - "customizations": {"vscode": {"extensions": extensions}}, + "remoteEnv": { + "SHELL": "/bin/zsh" + }, + "customizations": {"vscode": { + "settings": { + "python.pythonPath": "/workspace/frappe-bench/env/bin/python" + }, + "extensions": extensions + }}, } ] @@ -299,6 +308,34 @@ def attach_to_site(self, user: str, extensions: List[str]): self.site.start() richprint.print(f"Recreating Containers : Done") + # sync debugger files + if debugger: + richprint.change_head("Sync vscode debugger configuration") + dot_vscode_dir = self.site.path / 'workspace' / '.vscode' + tasks_json_path = dot_vscode_dir / 'tasks' + launch_json_path = dot_vscode_dir / 'launch' + + dot_vscode_config = { + tasks_json_path : VSCODE_TASKS_JSON, + launch_json_path : VSCODE_LAUNCH_JSON, + } + + if not dot_vscode_dir.exists(): + dot_vscode_dir.mkdir(exist_ok=True,parents=True) + + for file_path in [launch_json_path,tasks_json_path]: + file_name = f'{file_path.name}.json' + real_file_path = file_path.parent / file_name + if real_file_path.exists(): + backup_tasks_path = file_path.parent / f"{file_path.name}.{datetime.now().strftime('%d-%b-%y--%H-%M-%S')}.json" + shutil.copy2(real_file_path, backup_tasks_path) + richprint.print(f"Backup previous '{file_name}' : {backup_tasks_path}") + + with open(real_file_path, 'w+') as f: + f.write(json.dumps(dot_vscode_config[file_path])) + + richprint.print("Sync vscode debugger configuration: Done") + richprint.change_head("Attaching to Container") output = subprocess.run(vscode_cmd, shell=True) @@ -424,7 +461,6 @@ def info(self): site_info_table.add_row("Bench Apps", bench_apps_list_table) running_site_services = self.site.get_services_running_status() - running_site_workers = self.site.workers.get_services_running_status() if running_site_services: @@ -436,10 +472,6 @@ def info(self): site_info_table.add_row("Site Workers", site_workers_table) richprint.stdout.print(site_info_table) - # richprint.print( - # f":green_square: -> Active :red_square: -> Inactive", - # emoji_code=":information: ", - # ) def migrate_site(self): """ diff --git a/frappe_manager/site_manager/__init__.py b/frappe_manager/site_manager/__init__.py index e69de29b..c01dea6f 100644 --- a/frappe_manager/site_manager/__init__.py +++ b/frappe_manager/site_manager/__init__.py @@ -0,0 +1,29 @@ +VSCODE_LAUNCH_JSON = { + "version": "0.2.0", + "configurations": [ + { + "name": "fm-frappe-debug", + "type": "debugpy", + "request": "launch", + "program": "/workspace/frappe-bench/apps/frappe/frappe/utils/bench_helper.py", + "args": ["frappe", "serve", "--port", "80", "--noreload", "--nothreading"], + "cwd": "/workspace/frappe-bench/sites", + "env": {"DEV_SERVER": "1"}, + "preLaunchTask": "fm-kill-port-80", + } + ], +} + +VSCODE_TASKS_JSON = { + "version": "2.0.0", + "tasks": [ + { + "label": "fm-kill-port-80", + "type": "shell", + "command": "/bin/bash", + "args": ["-c", "fuser -k 80/tcp || true"], + "presentation": {"reveal": "never", "panel": "dedicated"}, + "options": {"ignoreExitCode": True}, + } + ], +} From a1bc55965a14c1fe0555f6cadb65a8f1bb6dc597 Mon Sep 17 00:00:00 2001 From: Xieyt Date: Tue, 13 Feb 2024 18:41:06 +0530 Subject: [PATCH 2/2] cleanup code and import --- frappe_manager/migration_manager/migration_executor.py | 2 -- .../migration_manager/migrations/migrate_0_10_0.py | 8 -------- 2 files changed, 10 deletions(-) diff --git a/frappe_manager/migration_manager/migration_executor.py b/frappe_manager/migration_manager/migration_executor.py index 953f35e8..84cc4358 100644 --- a/frappe_manager/migration_manager/migration_executor.py +++ b/frappe_manager/migration_manager/migration_executor.py @@ -6,8 +6,6 @@ import pkgutil from pathlib import Path -import rich - from rich import inspect from frappe_manager import CLI_DIR , CLI_SITES_ARCHIVE from frappe_manager.compose_manager.ComposeFile import ComposeFile diff --git a/frappe_manager/migration_manager/migrations/migrate_0_10_0.py b/frappe_manager/migration_manager/migrations/migrate_0_10_0.py index 60e52110..e74cc47d 100644 --- a/frappe_manager/migration_manager/migrations/migrate_0_10_0.py +++ b/frappe_manager/migration_manager/migrations/migrate_0_10_0.py @@ -1,4 +1,3 @@ -from sys import exception from typing import Optional from dataclasses import dataclass import shutil @@ -26,13 +25,6 @@ from frappe_manager.migration_manager.version import Version from pathlib import Path -# from frappe_manager.display_manager.DisplayManager import richprint - -# @dataclass -# class MigrateSite: -# site_name : str -# exception: Optional[Exception] = None - class MigrationV0100(MigrationBase): version = Version("0.10.0")