diff --git a/.github/workflows/ci-cd.yml b/.github/workflows/ci-cd.yml index 8e47003..4b00693 100644 --- a/.github/workflows/ci-cd.yml +++ b/.github/workflows/ci-cd.yml @@ -31,7 +31,12 @@ jobs: name: Windows steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 + with: + # setuptools-scm uses tags to get the current version, fetch history and tags + # to get correct version + fetch-depth: 0 + fetch-tags: 'true' - name: Set up Python ${{ env.DEV_WORKSPACE_PYTHON_VERSION }} uses: actions/setup-python@v5 @@ -43,7 +48,12 @@ jobs: python -m venv .venvs/dev_workspace source .venvs/dev_workspace/bin/activate python -m pip install --upgrade pip==25.1.1 - python -m pip install --group="dev_workspace" + + # split installation into 2 steps: first internal preset because it is not + # published as pypi package, so pip will fail to resolve it in dev_workspace + # group and only then other dependencies + python -m pip install -e ./finecode_dev_common_preset + python -m pip install --group="dev_workspace" -e . -e ./finecode_extension_runner python -m finecode prepare-envs shell: bash diff --git a/README.md b/README.md index 8e3a471..71767ae 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ With FineCode you can: ```toml [dependency-groups] - dev_workspace = ["finecode==0.2.*"] + dev_workspace = ["finecode==0.3.*"] ``` 1.1.2 Create dev_workspace venv: `python -m venv .venvs/dev_workspace` ([Python Docs](https://docs.python.org/3/library/venv.html#creating-virtual-environments )) @@ -33,12 +33,11 @@ NOTE: `pip install` supports `--group` parameter since pip 25.1. Make sure you h 1.2 Using existing preset -1.2.1 Add `dev_no_runtime` dependency group and put `fine_python_recommended` dependency in it: +1.2.1 Put `fine_python_recommended` dependency in `dev_workspace` dependency group: ```toml [dependency-groups] - dev_workspace = ["finecode==0.2.*"] - dev_no_runtime = ["fine_python_recommended==0.1.*"] + dev_workspace = ["finecode==0.3.*", "fine_python_recommended==0.2.*"] ``` For list of presets from FineCode authors see 'Presets' section below. diff --git a/extensions/fine_python_ast/pyproject.toml b/extensions/fine_python_ast/pyproject.toml index 1e76cf6..ead7e05 100644 --- a/extensions/fine_python_ast/pyproject.toml +++ b/extensions/fine_python_ast/pyproject.toml @@ -1,5 +1,5 @@ [project] -name = "fine-python-ast" +name = "fine_python_ast" version = "0.2.0" description = "" authors = [{ name = "Vladyslav Hnatiuk", email = "aders1234@gmail.com" }] diff --git a/extensions/fine_python_flake8/pyproject.toml b/extensions/fine_python_flake8/pyproject.toml index 4abbac0..50e52c7 100644 --- a/extensions/fine_python_flake8/pyproject.toml +++ b/extensions/fine_python_flake8/pyproject.toml @@ -1,5 +1,5 @@ [project] -name = "fine-python-flake8" +name = "fine_python_flake8" version = "0.2.0" description = "" authors = [{ name = "Vladyslav Hnatiuk", email = "aders1234@gmail.com" }] diff --git a/extensions/fine_python_isort/pyproject.toml b/extensions/fine_python_isort/pyproject.toml index b6ef046..d0c8722 100644 --- a/extensions/fine_python_isort/pyproject.toml +++ b/extensions/fine_python_isort/pyproject.toml @@ -1,5 +1,5 @@ [project] -name = "fine-python-isort" +name = "fine_python_isort" version = "0.2.0" description = "" authors = [{ name = "Vladyslav Hnatiuk", email = "aders1234@gmail.com" }] diff --git a/extensions/fine_python_module_exports/pyproject.toml b/extensions/fine_python_module_exports/pyproject.toml index 0d163c5..85b4348 100644 --- a/extensions/fine_python_module_exports/pyproject.toml +++ b/extensions/fine_python_module_exports/pyproject.toml @@ -1,5 +1,5 @@ [project] -name = "fine-python-module-exports" +name = "fine_python_module_exports" version = "0.2.0" description = "" authors = [{ name = "Vladyslav Hnatiuk", email = "aders1234@gmail.com" }] diff --git a/extensions/fine_python_mypy/pyproject.toml b/extensions/fine_python_mypy/pyproject.toml index 346bb29..19762d0 100644 --- a/extensions/fine_python_mypy/pyproject.toml +++ b/extensions/fine_python_mypy/pyproject.toml @@ -1,5 +1,5 @@ [project] -name = "fine-python-mypy" +name = "fine_python_mypy" version = "0.2.0" description = "" authors = [{ name = "Vladyslav Hnatiuk", email = "aders1234@gmail.com" }] diff --git a/extensions/fine_python_pip/pyproject.toml b/extensions/fine_python_pip/pyproject.toml index 6751b15..ed49dd9 100644 --- a/extensions/fine_python_pip/pyproject.toml +++ b/extensions/fine_python_pip/pyproject.toml @@ -1,5 +1,5 @@ [project] -name = "fine-python-pip" +name = "fine_python_pip" version = "0.1.0" description = "" authors = [{ name = "Vladyslav Hnatiuk", email = "aders1234@gmail.com" }] @@ -8,11 +8,12 @@ requires-python = ">=3.11, < 3.14" dependencies = ["finecode_extension_api==0.3.*"] [dependency-groups] -dev_workspace = ["finecode==0.3.0"] -dev_no_runtime = ["finecode_dev_common_preset==0.2.*"] +dev_workspace = ["finecode==0.3.*", "finecode_dev_common_preset==0.2.*"] [tool.finecode] presets = [{ source = "finecode_dev_common_preset" }] -[tool.finecode.env.dev_no_runtime.dependencies] +[tool.finecode.env.dev_workspace.dependencies] finecode_dev_common_preset = { path = "../../finecode_dev_common_preset", editable = true } +finecode = { path = "../../", editable = true } +finecode_extension_runner = { path = "../../finecode_extension_runner", editable = true } diff --git a/extensions/fine_python_virtualenv/pyproject.toml b/extensions/fine_python_virtualenv/pyproject.toml index a0de105..c8c3ab1 100644 --- a/extensions/fine_python_virtualenv/pyproject.toml +++ b/extensions/fine_python_virtualenv/pyproject.toml @@ -1,5 +1,5 @@ [project] -name = "fine-python-virtualenv" +name = "fine_python_virtualenv" version = "0.1.0" description = "" authors = [{ name = "Vladyslav Hnatiuk", email = "aders1234@gmail.com" }] @@ -11,11 +11,12 @@ dependencies = [ ] [dependency-groups] -dev_workspace = ["finecode==0.3.0"] -dev_no_runtime = ["finecode_dev_common_preset==0.2.*"] +dev_workspace = ["finecode==0.3.*", "finecode_dev_common_preset==0.2.*"] [tool.finecode] presets = [{ source = "finecode_dev_common_preset" }] -[tool.finecode.env.dev_no_runtime.dependencies] +[tool.finecode.env.dev_workspace.dependencies] finecode_dev_common_preset = { path = "../../finecode_dev_common_preset", editable = true } +finecode = { path = "../../", editable = true } +finecode_extension_runner = { path = "../../finecode_extension_runner", editable = true } diff --git a/finecode_dev_common_preset/pyproject.toml b/finecode_dev_common_preset/pyproject.toml index 7424a97..74bdb9f 100644 --- a/finecode_dev_common_preset/pyproject.toml +++ b/finecode_dev_common_preset/pyproject.toml @@ -1,5 +1,5 @@ [project] -name = "finecode-dev-common-preset" +name = "finecode_dev_common_preset" version = "0.2.0" description = "" authors = [{ name = "Vladyslav Hnatiuk", email = "aders1234@gmail.com" }] diff --git a/finecode_dev_common_preset/src/finecode_dev_common_preset/preset.toml b/finecode_dev_common_preset/src/finecode_dev_common_preset/preset.toml index 3790b5f..189e726 100644 --- a/finecode_dev_common_preset/src/finecode_dev_common_preset/preset.toml +++ b/finecode_dev_common_preset/src/finecode_dev_common_preset/preset.toml @@ -8,6 +8,18 @@ presets = [ source = "fine_python_black.BlackFormatHandler" config.preview = true +# in development finecode can only be started with local version of finecode_extension_runner, +# otherwise version conflict occurs, because versions of finecode and +# finecode_extension_runner must match +[tool.finecode.env.runtime.dependencies] +finecode_extension_runner = { path = "../../../finecode_extension_runner", editable = true } + +[tool.finecode.env.dev.dependencies] +finecode_extension_runner = { path = "../../../finecode_extension_runner", editable = true } + +[tool.finecode.env.dev_no_runtime.dependencies] +finecode_extension_runner = { path = "../../../finecode_extension_runner", editable = true } + # currently, all packages in finecode repository are pure python packages, reuse # setuptools build in all of them [build-system] diff --git a/finecode_extension_api/pyproject.toml b/finecode_extension_api/pyproject.toml index 900c6fc..79aa60f 100644 --- a/finecode_extension_api/pyproject.toml +++ b/finecode_extension_api/pyproject.toml @@ -1,5 +1,5 @@ [project] -name = "finecode-extension-api" +name = "finecode_extension_api" version = "0.3.0" description = "" authors = [{ name = "Vladyslav Hnatiuk", email = "aders1234@gmail.com" }] @@ -8,11 +8,12 @@ requires-python = ">=3.11, < 3.14" dependencies = ["typing-extensions (>=4.12.2,<5.0.0)"] [dependency-groups] -dev_workspace = ["finecode==0.3.0"] -dev_no_runtime = ["finecode_dev_common_preset==0.2.*"] +dev_workspace = ["finecode==0.3.*", "finecode_dev_common_preset==0.2.*"] [tool.finecode] presets = [{ source = "finecode_dev_common_preset" }] -[tool.finecode.env.dev_no_runtime.dependencies] +[tool.finecode.env.dev_workspace.dependencies] finecode_dev_common_preset = { path = "../finecode_dev_common_preset", editable = true } +finecode = { path = "../", editable = true } +finecode_extension_runner = { path = "../finecode_extension_runner", editable = true } diff --git a/finecode_extension_runner/pyproject.toml b/finecode_extension_runner/pyproject.toml index 2676c37..7edcaec 100644 --- a/finecode_extension_runner/pyproject.toml +++ b/finecode_extension_runner/pyproject.toml @@ -9,7 +9,7 @@ dependencies = [ "loguru==0.7.*", "tomlkit==0.11.*", "click==8.1.*", - "pydantic==2.10.*", + "pydantic==2.11.*", "platformdirs==4.3.*", "pygls==2.0.0-a2", "finecode_extension_api==0.3.*", @@ -17,16 +17,19 @@ dependencies = [ ] [dependency-groups] -dev_workspace = ["build==1.2.2.post1", "finecode==0.3.0"] -dev = [{ include-group = "runtime" }, "pytest==7.4.*", "debugpy==1.8.*"] -dev_no_runtime = [ +# file_python_import_linter is temporary disabled, because it isn't ported to the new finecode_extension_api yet +# "fine_python_import_linter @ git+https://github.com/finecode-dev/finecode.git#subdirectory=extensions/fine_python_import_linter" +dev_workspace = [ + "build==1.2.2.post1", + "finecode==0.3.*", "finecode_dev_common_preset==0.2.*", - # file_python_import_linter is temporary disabled, because it isn't ported to the new finecode_extension_api yet - # "fine_python_import_linter @ git+https://github.com/finecode-dev/finecode.git#subdirectory=extensions/fine_python_import_linter", ] +dev = [{ include-group = "runtime" }, "pytest==7.4.*", "debugpy==1.8.*"] -[tool.finecode.env.dev_no_runtime.dependencies] +[tool.finecode.env.dev_workspace.dependencies] finecode_dev_common_preset = { path = "../finecode_dev_common_preset", editable = true } +finecode = { path = "../", editable = true } +finecode_extension_runner = { path = "../finecode_extension_runner", editable = true } [build-system] requires = ["setuptools>=64", "setuptools-scm>=8"] diff --git a/finecode_extension_runner/src/finecode_extension_runner/action_handlers/dependency_config_utils.py b/finecode_extension_runner/src/finecode_extension_runner/action_handlers/dependency_config_utils.py index 1a0e93e..f42e874 100644 --- a/finecode_extension_runner/src/finecode_extension_runner/action_handlers/dependency_config_utils.py +++ b/finecode_extension_runner/src/finecode_extension_runner/action_handlers/dependency_config_utils.py @@ -41,6 +41,7 @@ def make_env_deps_pip_compatible( # check all dependencies because it can be duplicated: e.g. as explicit # dependency and as dependency of action handler. dep_indexes_in_group: list[int] = [] + configured_dep_found_in_dep_group = False for idx, dep in enumerate(env_deps_group): if isinstance(dep, dict): if "include-group" in dep: @@ -53,9 +54,7 @@ def make_env_deps_pip_compatible( elif isinstance(dep, str): if get_dependency_name(dep) == dep_name: dep_indexes_in_group.append(idx) - - if len(dep_indexes_in_group) == 0: - continue + configured_dep_found_in_dep_group = True resolved_path_to_dep = pathlib.Path(dep_params["path"]) if not resolved_path_to_dep.is_absolute(): @@ -67,6 +66,12 @@ def make_env_deps_pip_compatible( for idx in dep_indexes_in_group: env_deps_group[idx] = new_dep_str_in_group + if not configured_dep_found_in_dep_group: + # if dependency has configuration, but was not found in dependency + # group of environment, still add it, because it can be deeper in the + # dependency tree and user wants to overwrite it + env_deps_group.append(new_dep_str_in_group) + def get_dependency_name(dependency_str: str) -> str: # simplified way for now: find the first character which is not allowed in package diff --git a/finecode_extension_runner/src/finecode_extension_runner/action_handlers/prepare_runners_install_runner_and_presets.py b/finecode_extension_runner/src/finecode_extension_runner/action_handlers/prepare_runners_install_runner_and_presets.py index f16dbfe..89330a5 100644 --- a/finecode_extension_runner/src/finecode_extension_runner/action_handlers/prepare_runners_install_runner_and_presets.py +++ b/finecode_extension_runner/src/finecode_extension_runner/action_handlers/prepare_runners_install_runner_and_presets.py @@ -54,7 +54,7 @@ async def run( ) except FailedToGetDependencies as exception: raise code_action.ActionFailedException( - f"Failed to get dependencies of env {env.name} in {project_def_path} (install_runner_and_presets handler)" + f"Failed to get dependencies of env {env.name} in {project_def_path}: {exception.message} (install_runner_and_presets handler)" ) dependencies_by_env[env.name] = dependencies @@ -161,10 +161,10 @@ def get_dependencies_in_project_raw_config( and dependency_config_utils.get_dependency_name(dep) == preset_package ) except StopIteration: - if env_name == "dev_no_runtime": - # all preset packages must be in 'dev_no_runtime' env + if env_name == "dev_workspace": + # all preset packages must be in 'dev_workspace' env raise FailedToGetDependencies( - f"'{preset_package}' is used as preset source, but not declared in 'dev_no_runtime' dependency group" + f"'{preset_package}' is used as preset source, but not declared in 'dev_workspace' dependency group" ) else: continue diff --git a/presets/fine_python_format/pyproject.toml b/presets/fine_python_format/pyproject.toml index 5d99042..631796d 100644 --- a/presets/fine_python_format/pyproject.toml +++ b/presets/fine_python_format/pyproject.toml @@ -1,5 +1,5 @@ [project] -name = "fine-python-format" +name = "fine_python_format" version = "0.2.0" description = "" authors = [{ name = "Vladyslav Hnatiuk", email = "aders1234@gmail.com" }] diff --git a/presets/fine_python_lint/pyproject.toml b/presets/fine_python_lint/pyproject.toml index ead7668..fbdf476 100644 --- a/presets/fine_python_lint/pyproject.toml +++ b/presets/fine_python_lint/pyproject.toml @@ -1,5 +1,5 @@ [project] -name = "fine-python-lint" +name = "fine_python_lint" version = "0.2.0" description = "" authors = [{ name = "Vladyslav Hnatiuk", email = "aders1234@gmail.com" }] diff --git a/presets/fine_python_recommended/pyproject.toml b/presets/fine_python_recommended/pyproject.toml index 30cd230..e653876 100644 --- a/presets/fine_python_recommended/pyproject.toml +++ b/presets/fine_python_recommended/pyproject.toml @@ -1,5 +1,5 @@ [project] -name = "fine-python-recommended" +name = "fine_python_recommended" version = "0.2.0" description = "" authors = [{ name = "Vladyslav Hnatiuk", email = "aders1234@gmail.com" }] diff --git a/pyproject.toml b/pyproject.toml index 2230c04..724113d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -10,25 +10,27 @@ dependencies = [ "tomlkit==0.11.*", "watchdog==4.0.*", "click==8.1.*", - "pydantic==2.10.*", + "pydantic==2.11.*", "platformdirs==4.3.*", "pygls==2.0.0-a2", "finecode_extension_api==0.3.*", "finecode_extension_runner==0.3.*", "ordered-set==4.1.*", - "mcp==1.9.*", + "mcp==1.13.*", "fine_python_virtualenv==0.1.*", "fine_python_pip==0.1.*", ] [dependency-groups] -dev_workspace = ["build==1.2.2.post1", "finecode==0.3.0", "debugpy==1.8.*"] -dev = [{ include-group = "runtime" }, "pytest==7.4.*", "debugpy==1.8.*"] -dev_no_runtime = [ +# file_python_import_linter is temporary disabled, because it isn't ported to the new finecode_extension_api yet +# "fine_python_import_linter @ git+https://github.com/finecode-dev/finecode.git#subdirectory=extensions/fine_python_import_linter", +dev_workspace = [ + "build==1.2.2.post1", + "finecode==0.3.*", "finecode_dev_common_preset==0.2.*", - # file_python_import_linter is temporary disabled, because it isn't ported to the new finecode_extension_api yet - # "fine_python_import_linter @ git+https://github.com/finecode-dev/finecode.git#subdirectory=extensions/fine_python_import_linter", + "debugpy==1.8.*", ] +dev = [{ include-group = "runtime" }, "pytest==7.4.*", "debugpy==1.8.*"] [build-system] requires = ["setuptools>=64", "setuptools-scm>=8"] @@ -39,8 +41,9 @@ build-backend = "setuptools.build_meta" [tool.finecode] presets = [{ source = "finecode_dev_common_preset" }] -[tool.finecode.env.dev_no_runtime.dependencies] +[tool.finecode.env.dev_workspace.dependencies] finecode_dev_common_preset = { path = "./finecode_dev_common_preset", editable = true } +finecode_extension_runner = { path = "./finecode_extension_runner", editable = true } [tool.importlinter] root_package = "finecode" diff --git a/src/finecode/cli.py b/src/finecode/cli.py index 3d23742..6175b48 100644 --- a/src/finecode/cli.py +++ b/src/finecode/cli.py @@ -2,8 +2,8 @@ import json import os import pathlib -import typing import sys +import typing import click from loguru import logger @@ -89,7 +89,7 @@ async def show_user_message(message: str, message_type: str) -> None: def deserialize_action_payload(raw_payload: dict[str, str]) -> dict[str, typing.Any]: deserialized_payload = {} for key, value in raw_payload.items(): - if value.startswith('{') and value.endswith('}'): + if value.startswith("{") and value.endswith("}"): try: deserialized_value = json.loads(value) except json.JSONDecodeError: @@ -168,17 +168,21 @@ def run(ctx) -> None: sys.exit(1) else: arg_name, arg_value = arg[2:].split("=") - arg_name = arg_name.replace('-', '_') + arg_name = arg_name.replace("-", "_") action_payload[arg_name] = arg_value.strip('"').strip("'") processed_args_count += 1 user_messages._notification_sender = show_user_message - deserialized_payload= deserialize_action_payload(action_payload) + deserialized_payload = deserialize_action_payload(action_payload) try: output, return_code = asyncio.run( run_cmd.run_actions( - workdir_path, projects, actions_to_run, deserialized_payload, concurrently + workdir_path, + projects, + actions_to_run, + deserialized_payload, + concurrently, ) ) click.echo(output) diff --git a/src/finecode/cli_app/prepare_envs.py b/src/finecode/cli_app/prepare_envs.py index cf62d7c..4b1eb7d 100644 --- a/src/finecode/cli_app/prepare_envs.py +++ b/src/finecode/cli_app/prepare_envs.py @@ -14,7 +14,7 @@ class PrepareEnvsFailed(Exception): ... async def prepare_envs(workdir_path: pathlib.Path, recreate: bool) -> None: # similar to `run_actions`, but with certain differences: - # - prepare_envs doesn't support presets because `dev_no_runtime` env most + # - prepare_envs doesn't support presets because `dev_workspace` env most # probably doesn't exist yet # - we don't need to check missing actions, because prepare_envs is a builtin action # and it exists always @@ -73,11 +73,32 @@ async def prepare_envs(workdir_path: pathlib.Path, recreate: bool) -> None: ws_context=ws_context, ) - # now all 'dev_workspace' envs are valid, run 'prepare_runners' in them to create - # venvs and install runners and presets in them. This is required to be able to - # resolve presets which can contain additional dependency configurations. - # Only then run `prepare_envs` to install dependencies in each subproject. + # reread projects configs, now with resolved presets + # to be able to resolve presets, start runners with presets first + try: + await runner_manager.start_runners_with_presets( + projects=projects, ws_context=ws_context + ) + except runner_manager.RunnerFailedToStart as exception: + raise PrepareEnvsFailed( + f"Starting runners with presets failed: {exception.message}" + ) + + for project in projects: + try: + await read_configs.read_project_config( + project=project, ws_context=ws_context + ) + collect_actions.collect_actions( + project_path=project.dir_path, ws_context=ws_context + ) + except config_models.ConfigurationError as exception: + raise PrepareEnvsFailed( + f"Rereading project config with presets and collecting actions in {project.dir_path} failed: {exception.message}" + ) + # now all 'dev_workspace' envs are valid, run 'prepare_runners' in them to create + # venvs and install runners and presets in them actions_by_projects: dict[pathlib.Path, list[str]] = { project.dir_path: ["prepare_runners"] for project in projects } @@ -107,30 +128,6 @@ async def prepare_envs(workdir_path: pathlib.Path, recreate: bool) -> None: if result_return_code != 0: raise PrepareEnvsFailed(result_output) - # reread projects configs, now with resolved presets - # to be able to resolve presets, start dev_no_runtime runners first - try: - await runner_manager.start_runners_with_presets( - projects=projects, ws_context=ws_context - ) - except runner_manager.RunnerFailedToStart as exception: - raise PrepareEnvsFailed( - f"Starting runners with presets failed: {exception.message}" - ) - - for project in projects: - try: - await read_configs.read_project_config( - project=project, ws_context=ws_context - ) - collect_actions.collect_actions( - project_path=project.dir_path, ws_context=ws_context - ) - except config_models.ConfigurationError as exception: - raise PrepareEnvsFailed( - f"Rereading project config with presets and collecting actions in {project.dir_path} failed: {exception.message}" - ) - actions_by_projects: dict[pathlib.Path, list[str]] = { project.dir_path: ["prepare_envs"] for project in projects } diff --git a/src/finecode/config/read_configs.py b/src/finecode/config/read_configs.py index e5f9302..81455c8 100644 --- a/src/finecode/config/read_configs.py +++ b/src/finecode/config/read_configs.py @@ -132,14 +132,14 @@ async def read_project_config( except config_models.ValidationError as exception: raise config_models.ConfigurationError(str(exception)) - # all presets expected to be in `dev_no_runtime` environment + # all presets expected to be in `dev_workspace` environment project_runners = ws_context.ws_projects_extension_runners[project.dir_path] # TODO: can it be the case that there is no such runner? - dev_no_runtime_runner = project_runners["dev_no_runtime"] + dev_workspace_runner = project_runners["dev_workspace"] new_config = await collect_config_from_py_presets( presets_sources=[preset.source for preset in presets], def_path=project.def_path, - runner=dev_no_runtime_runner, + runner=dev_workspace_runner, ) if new_config is not None: _merge_projects_configs( @@ -269,9 +269,12 @@ async def collect_config_from_py_presets( preset_toml_path = preset_project_path / "preset.toml" preset_toml, preset_config = read_preset_config(preset_toml_path, preset.source) if config is None: - config = preset_toml + # use merge instead of just assigning config, because merge not only merges + # configs, but also adapts relative pathes etc. + config = {} + _merge_projects_configs(config, def_path, preset_toml, preset_toml_path) else: - _merge_projects_configs(config, def_path, preset_toml, preset_project_path) + _merge_projects_configs(config, def_path, preset_toml, preset_toml_path) new_presets_sources = ( set([extend.source for extend in preset_config.extends]) - processed_presets ) @@ -430,22 +433,14 @@ def _merge_projects_configs( env_config1_deps[dependency_name] = dependency else: if "path" in dependency: - new_path = dependency["path"] - if new_path.startswith("."): - abs_path = ( - config2_filepath.parent / new_path - ) - new_rel_path = abs_path.relative_to( - config1_filepath.parent - ) - new_path = new_rel_path.as_posix() - env_config1_deps[dependency_name][ - "path" - ] = new_path + env_config1_deps[dependency_name]["path"] = ( + dependency["path"] + ) if "editable" in dependency: env_config1_deps[dependency_name][ "editable" ] = dependency["editable"] + if "runner" in env_config2: if "runner" not in env_config1: env_config1["runner"] = {} @@ -454,6 +449,29 @@ def _merge_projects_configs( if "debug" in env_config2_runner: env_config1_runner["debug"] = env_config2_runner["debug"] + + for updated_dep_name, updated_dep_config in env_config2.get( + "dependencies", {} + ).items(): + if "path" in updated_dep_config: + # if path is provided in the config2 dependency, + # it overwrites path in config1 and relative path + # must be adjusted + new_path = updated_dep_config["path"] + if new_path.startswith("."): + abs_path = (config2_filepath.parent / new_path).resolve() + new_rel_path = abs_path.relative_to( + config1_filepath.parent, walk_up=True + ) + new_path = new_rel_path.as_posix() + # .relative_to() doesn't add './' for items in the current + # directory, but FineCode needs it to distinguish relative + # path from absolute one + if not new_path.startswith("."): + new_path = "./" + new_path + all_envs_config1[env_name]["dependencies"][ + updated_dep_name + ]["path"] = new_path elif key in config1: tool_finecode_config1[key].update(value) else: diff --git a/src/finecode/lsp_server/endpoints/action_tree.py b/src/finecode/lsp_server/endpoints/action_tree.py index ec0de72..b04fcc5 100644 --- a/src/finecode/lsp_server/endpoints/action_tree.py +++ b/src/finecode/lsp_server/endpoints/action_tree.py @@ -178,9 +178,9 @@ async def __list_actions( # wait for start of all runners, this is required to be able to resolve presets all_started_coros = [] for envs in ws_context.ws_projects_extension_runners.values(): - # all presets are expected to be in `dev_no_runtime` env - dev_no_runtime_runner = envs["dev_no_runtime"] - all_started_coros.append(dev_no_runtime_runner.initialized_event.wait()) + # all presets are expected to be in `dev_workspace` env + dev_workspace_runner = envs["dev_workspace"] + all_started_coros.append(dev_workspace_runner.initialized_event.wait()) await asyncio.gather(*all_started_coros) nodes: list[schemas.ActionTreeNode] = create_node_list_for_ws(ws_context) diff --git a/src/finecode/runner/manager.py b/src/finecode/runner/manager.py index a6c5903..97ecfd5 100644 --- a/src/finecode/runner/manager.py +++ b/src/finecode/runner/manager.py @@ -242,13 +242,13 @@ async def update_runners(ws_context: context.WorkspaceContext) -> None: project_status = project.status if ( ws_context.ws_projects_extension_runners.get(new_dir, {}).get( - "dev_no_runtime", None + "dev_workspace", None ) is not None ): - # start only if dev_no_runtime started successfully + # start only if dev_workspace started successfully for env in project.envs: - if env == "dev_no_runtime": + if env == "dev_workspace": # this env has already started above continue @@ -300,14 +300,14 @@ async def start_runners_with_presets( ) -> None: new_runners_tasks: list[asyncio.Task] = [] try: - # first start runner in 'dev_no_runtime' env to be able to resolve presets for - # other envs (presets can be currently only in `dev_no_runtime` env) + # first start runner in 'dev_workspace' env to be able to resolve presets for + # other envs (presets can be currently only in `dev_workspace` env) async with asyncio.TaskGroup() as tg: for project in projects: project_status = project.status if project_status == domain.ProjectStatus.CONFIG_VALID: task = tg.create_task( - _start_dev_no_runtime_runner( + _start_dev_workspace_runner( project_def=project, ws_context=ws_context ) ) @@ -375,11 +375,11 @@ async def start_runner( return runner -async def _start_dev_no_runtime_runner( +async def _start_dev_workspace_runner( project_def: domain.Project, ws_context: context.WorkspaceContext ) -> runner_info.ExtensionRunnerInfo: return await start_runner( - project_def=project_def, env_name="dev_no_runtime", ws_context=ws_context + project_def=project_def, env_name="dev_workspace", ws_context=ws_context )