Skip to content

Commit 7d3aff4

Browse files
committed
Fix failing dump-config . Improve prepare-envs: distinguish empty list and missing value for envs to run discovery only on missing value. Fix adding finecode_extension_runner to env not declared in dependency-groups
1 parent d8a81a5 commit 7d3aff4

9 files changed

Lines changed: 45 additions & 26 deletions

File tree

finecode_builtin_handlers/src/finecode_builtin_handlers/create_envs_discover_envs.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ class CreateEnvsDiscoverEnvsHandler(
2121
):
2222
"""Discover and populate run_context.envs from the current project's config.
2323
24-
If payload.envs is already non-empty (explicit caller), those envs are
24+
If payload.envs is provided (explicit caller), those envs are
2525
used as-is — the caller is responsible for any filtering.
2626
Otherwise all envs defined in ``dependency-groups`` are discovered.
2727
"""
@@ -41,7 +41,7 @@ async def run(
4141
payload: create_envs_action.CreateEnvsRunPayload,
4242
run_context: create_envs_action.CreateEnvsRunContext,
4343
) -> create_envs_action.CreateEnvsRunResult:
44-
if payload.envs:
44+
if payload.envs is not None:
4545
envs = list(payload.envs)
4646
else:
4747
project_def_path = self.project_info_provider.get_current_project_def_path()

finecode_builtin_handlers/src/finecode_builtin_handlers/dump_config_save.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
from finecode_extension_api import code_action
77
from finecode_extension_api.actions.system import dump_config_action
88
from finecode_extension_api.interfaces import ifilemanager, ifileeditor
9+
from finecode_extension_api.resource_uri import resource_uri_to_path
910

1011

1112
@dataclasses.dataclass
@@ -35,14 +36,15 @@ async def run(
3536
run_context: dump_config_action.DumpConfigRunContext,
3637
) -> dump_config_action.DumpConfigRunResult:
3738
raw_config_str = tomlkit.dumps(run_context.raw_config_dump)
38-
target_file_dir_path = payload.target_file_path.parent
39+
target_file_path = resource_uri_to_path(payload.target_file_path)
40+
target_file_dir_path = target_file_path.parent
3941

4042
await self.file_manager.create_dir(dir_path=target_file_dir_path)
4143
async with self.file_editor.session(
4244
author=self.FILE_OPERATION_AUTHOR
4345
) as session:
4446
await session.save_file(
45-
file_path=payload.target_file_path, file_content=raw_config_str
47+
file_path=target_file_path, file_content=raw_config_str
4648
)
4749

4850
return dump_config_action.DumpConfigRunResult(

finecode_builtin_handlers/src/finecode_builtin_handlers/install_envs_discover_envs.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ class InstallEnvsDiscoverEnvsHandler(
2323
):
2424
"""Discover and populate run_context.envs from the current project's config.
2525
26-
If payload.envs is already non-empty (explicit caller), those envs are
26+
If payload.envs is provided (explicit caller), those envs are
2727
used as-is — the caller is responsible for any filtering.
2828
Otherwise envs are discovered from dependency-groups: every dependency group
2929
defined in the project definition is included as an env.
@@ -44,7 +44,7 @@ async def run(
4444
payload: install_envs_action.InstallEnvsRunPayload,
4545
run_context: install_envs_action.InstallEnvsRunContext,
4646
) -> install_envs_action.InstallEnvsRunResult:
47-
if payload.envs:
47+
if payload.envs is not None:
4848
envs = list(payload.envs)
4949
else:
5050
project_def_path = self.project_info_provider.get_current_project_def_path()

finecode_extension_api/src/finecode_extension_api/actions/environments/create_envs_action.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ class EnvInfo:
1919

2020
@dataclasses.dataclass
2121
class CreateEnvsRunPayload(code_action.RunActionPayload):
22-
envs: list[EnvInfo] = dataclasses.field(default_factory=list)
23-
"""Explicit list of environments to create. Empty means handlers discover envs."""
22+
envs: list[EnvInfo] | None = None
23+
"""Explicit list of environments to create. ``None`` means handlers discover envs, empty list means explicit no-op."""
2424
recreate: bool = False
2525
"""Remove and recreate existing environments from scratch even if they are already valid."""
2626

@@ -43,7 +43,7 @@ def __init__(
4343
self.envs: list[EnvInfo] | None = None
4444

4545
async def init(self) -> None:
46-
if self.initial_payload.envs:
46+
if self.initial_payload.envs is not None:
4747
self.envs = list(self.initial_payload.envs)
4848

4949

finecode_extension_api/src/finecode_extension_api/actions/environments/install_envs_action.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@
1414

1515
@dataclasses.dataclass
1616
class InstallEnvsRunPayload(code_action.RunActionPayload):
17-
envs: list[EnvInfo] = dataclasses.field(default_factory=list)
18-
"""Explicit list of environments to install dependencies in. Empty means handlers discover envs at run time."""
17+
envs: list[EnvInfo] | None = None
18+
"""Explicit list of environments to install dependencies in. ``None`` means handlers discover envs, empty list means explicit no-op."""
1919
env_names: list[str] | None = None
2020
"""Filter: when set, only in environments whose name is in this list dependencies will be installed. Applied during discovery only."""
2121

@@ -40,6 +40,9 @@ def __init__(
4040
self.project_def_by_venv_dir_path: dict[ResourceUri, dict[str, typing.Any]] = {}
4141

4242
async def init(self) -> None:
43+
if self.initial_payload.envs is None:
44+
return
45+
4346
self.envs = list(self.initial_payload.envs)
4447
for env_info in self.initial_payload.envs:
4548
self.project_def_path_by_venv_dir_path[env_info.venv_dir_path] = (

src/finecode/cli_app/commands/dump_config_cmd.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import pathlib
33

44
from finecode.wm_client import ApiClient, ApiError
5+
from finecode_extension_api.resource_uri import path_to_resource_uri
56
from finecode.wm_server import wm_lifecycle
67

78

@@ -50,9 +51,13 @@ async def dump_config(
5051
action="dump_config",
5152
project=project_path,
5253
params={
53-
"source_file_path": str(source_file_path),
54+
"source_file_path": str(
55+
path_to_resource_uri(source_file_path)
56+
),
5457
"project_raw_config": project_raw_config,
55-
"target_file_path": str(target_file_path),
58+
"target_file_path": str(
59+
path_to_resource_uri(target_file_path)
60+
),
5661
},
5762
options={
5863
"resultFormats": ["string"],

src/finecode/cli_app/commands/prepare_envs_cmd.py

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -170,15 +170,18 @@ async def _check_or_remove_dw(project: dict) -> None:
170170

171171
# Steps 3a + 3b — create virtualenvs and install deps via shared helper.
172172
# ('recreate' for dev_workspace envs is handled above via remove_env, no need to pass here)
173-
try:
174-
await create_and_install_envs(
175-
client=client,
176-
project_path=current_project["path"],
177-
envs=dw_envs,
178-
dev_env=dev_env,
179-
)
180-
except EnvSetupFailed as exc:
181-
raise PrepareEnvsFailed(f"dev_workspace setup failed: {exc.message}") from exc
173+
if dw_envs:
174+
try:
175+
await create_and_install_envs(
176+
client=client,
177+
project_path=current_project["path"],
178+
envs=dw_envs,
179+
dev_env=dev_env,
180+
)
181+
except EnvSetupFailed as exc:
182+
raise PrepareEnvsFailed(f"dev_workspace setup failed: {exc.message}") from exc
183+
else:
184+
logger.info("No dev_workspace environments selected for bootstrap, skipping")
182185

183186
# Step 4 — start dev_workspace runners (resolves preset-defined actions).
184187
logger.info("Starting dev_workspace runners...")

src/finecode/mcp_server.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
from finecode.wm_client import ApiClient
1717
from finecode.wm_server import wm_lifecycle
18+
from finecode_extension_api.resource_uri import path_to_resource_uri
1819
from loguru import logger
1920
from mcp.server import Server
2021
from mcp.server.stdio import stdio_server
@@ -268,10 +269,14 @@ async def call_tool(name: str, arguments: dict) -> list[TextContent]:
268269
"dump_config",
269270
project,
270271
params={
271-
"source_file_path": str(project_path / "pyproject.toml"),
272+
"source_file_path": str(
273+
path_to_resource_uri(project_path / "pyproject.toml")
274+
),
272275
"project_raw_config": raw_config,
273276
"target_file_path": str(
274-
project_path / "finecode_config_dump" / "pyproject.toml"
277+
path_to_resource_uri(
278+
project_path / "finecode_config_dump" / "pyproject.toml"
279+
)
275280
),
276281
},
277282
options={"resultFormats": ["json"], "trigger": "user", "devEnv": "ai"},

src/finecode/wm_server/config/read_configs.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -170,10 +170,11 @@ async def read_project_config(
170170
# add runtime dependency group if it's not explicitly declared
171171
add_runtime_dependency_group_if_new(project_config)
172172

173-
add_extension_runner_to_dependencies(project_config)
174-
175173
merge_handlers_dependencies_into_groups(project_config)
176174
merge_services_dependencies_into_groups(project_config)
175+
# add extension runner after mergin handlers dependencies into groups
176+
# because env may be missing in dependency-groups and be used in handlers
177+
add_extension_runner_to_dependencies(project_config)
177178

178179
ws_context.ws_projects_raw_configs[project.dir_path] = project_config
179180
else:

0 commit comments

Comments
 (0)