Skip to content

Commit 120f411

Browse files
committed
Update config in dev_workspace runner after start to provide config with resolved presets. This allows to customize behavior in presets of the most actions executed in dev_workspace. Add current package to runtime env deps. Add 'additional_dirs' config parameter to list_project_files_by_lang_python handler. Fix copying of action subresult.
1 parent 478b73d commit 120f411

File tree

4 files changed

+68
-6
lines changed

4 files changed

+68
-6
lines changed

extensions/fine_python_package_info/fine_python_package_info/list_project_files_by_lang_python.py

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from finecode_extension_api.interfaces import iprojectinfoprovider, ipypackagelayoutinfoprovider
1+
from finecode_extension_api.interfaces import iprojectinfoprovider, ipypackagelayoutinfoprovider, ilogger
22
import dataclasses
33
import pathlib
44

@@ -7,18 +7,28 @@
77

88

99
@dataclasses.dataclass
10-
class ListProjectFilesByLangPythonHandlerConfig(code_action.ActionHandlerConfig): ...
11-
# TODO: parameter for additional dirs
10+
class ListProjectFilesByLangPythonHandlerConfig(code_action.ActionHandlerConfig):
11+
# list of relative pathes relative to project directory with additional python
12+
# sources if they are not in one of default pathes
13+
additional_dirs: list[pathlib.Path] | None = None
1214

1315

1416
class ListProjectFilesByLangPythonHandler(
1517
code_action.ActionHandler[
1618
list_project_files_by_lang_action.ListProjectFilesByLangAction, ListProjectFilesByLangPythonHandlerConfig
1719
]
1820
):
19-
def __init__(self, project_info_provider: iprojectinfoprovider.IProjectInfoProvider, py_package_layout_info_provider: ipypackagelayoutinfoprovider.IPyPackageLayoutInfoProvider) -> None:
21+
def __init__(
22+
self,
23+
config: ListProjectFilesByLangPythonHandlerConfig,
24+
project_info_provider: iprojectinfoprovider.IProjectInfoProvider,
25+
py_package_layout_info_provider: ipypackagelayoutinfoprovider.IPyPackageLayoutInfoProvider,
26+
logger: ilogger.ILogger
27+
) -> None:
28+
self.config = config
2029
self.project_info_provider = project_info_provider
2130
self.py_package_layout_info_provider = py_package_layout_info_provider
31+
self.logger = logger
2232

2333
self.current_project_dir_path = self.project_info_provider.get_current_project_dir_path()
2434
self.tests_dir_path = self.current_project_dir_path / 'tests'
@@ -42,6 +52,15 @@ async def run(
4252

4353
if self.setup_py_path.exists():
4454
py_files.append(self.setup_py_path)
55+
56+
if self.config.additional_dirs is not None:
57+
for dir_path in self.config.additional_dirs:
58+
dir_absolute_path = self.current_project_dir_path / dir_path
59+
if not dir_absolute_path.exists():
60+
self.logger.warning(f"Skip {dir_path} because {dir_absolute_path} doesn't exist")
61+
continue
62+
63+
py_files += list(dir_absolute_path.rglob('*.py'))
4564

4665
return list_project_files_by_lang_action.ListProjectFilesByLangRunResult(
4766
files_by_lang={"python": py_files}

finecode_extension_runner/src/finecode_extension_runner/_services/run_action.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -556,8 +556,11 @@ async def run_subresult_coros_concurrently(
556556
# in it and result from action handler must stay immutable (e.g. it can
557557
# reference to cache)
558558
action_subresult_type = type(coro_result)
559+
# use pydantic dataclass as constructor because it instantiates classes
560+
# recursively, normal dataclass only on the first level
561+
action_subresult_type_pydantic = pydantic_dataclass(action_subresult_type)
559562
action_subresult_dict = dataclasses.asdict(coro_result)
560-
action_subresult = action_subresult_type(**action_subresult_dict)
563+
action_subresult = action_subresult_type_pydantic(**action_subresult_dict)
561564
else:
562565
action_subresult.update(coro_result)
563566

src/finecode/config/read_configs.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -528,6 +528,39 @@ def handler_to_dict(handler: domain.ActionHandler) -> dict[str, str | list[str]]
528528

529529
def add_runtime_dependency_group_if_new(project_config: dict[str, Any]) -> None:
530530
runtime_dependencies = project_config.get("project", {}).get("dependencies", [])
531+
532+
# add root package to runtime env if it is not there yet. It is done here and not
533+
# in package installer, because runtime deps group can be included in other groups
534+
# and root package should be installed in them as well
535+
root_package_name = project_config.get("project", {}).get("name", None)
536+
if root_package_name is None:
537+
raise config_models.ConfigurationError("project.name not found in config")
538+
root_package_in_runtime_deps = any(
539+
dep for dep in runtime_dependencies if get_dependency_name(dep) == root_package_name
540+
)
541+
if not root_package_in_runtime_deps:
542+
runtime_dependencies.insert(0, root_package_name)
543+
544+
# make editable. Example:
545+
# [tool.finecode.env.runtime.dependencies]
546+
# package_name = { path = "./", editable = true }
547+
if 'tool' not in project_config:
548+
project_config['tool'] = {}
549+
tool_config = project_config['tool']
550+
if 'finecode' not in tool_config:
551+
tool_config['finecode'] = {}
552+
finecode_config = tool_config['finecode']
553+
if 'env' not in finecode_config:
554+
finecode_config['env'] = {}
555+
finecode_env_config = finecode_config['env']
556+
if 'runtime' not in finecode_env_config:
557+
finecode_env_config['runtime'] = {}
558+
runtime_env_config = finecode_env_config['runtime']
559+
if 'dependencies' not in runtime_env_config:
560+
runtime_env_config['dependencies'] = {}
561+
runtime_env_deps = runtime_env_config['dependencies']
562+
if root_package_name not in runtime_env_deps:
563+
runtime_env_deps[root_package_name] = { "path": "./", "editable": True}
531564

532565
deps_groups = add_or_get_dict_key_value(project_config, "dependency-groups", {})
533566
if "runtime" not in deps_groups:

src/finecode/runner/manager.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@ def stop_extension_runner_sync(runner: runner_info.ExtensionRunnerInfo) -> None:
185185
logger.debug("Send shutdown to server")
186186
try:
187187
runner_client.shutdown_sync(runner=runner)
188-
except Exception as e:
188+
except Exception:
189189
# currently we get (almost?) always this error. TODO: Investigate why
190190
# mute for now to make output less verbose
191191
# logger.error(f"Failed to shutdown: {e}")
@@ -240,6 +240,9 @@ async def start_runners_with_presets(
240240
)
241241

242242
for project in projects:
243+
if project_status != domain.ProjectStatus.CONFIG_VALID:
244+
continue
245+
243246
try:
244247
await read_configs.read_project_config(
245248
project=project, ws_context=ws_context
@@ -251,6 +254,10 @@ async def start_runners_with_presets(
251254
raise RunnerFailedToStart(
252255
f"Reading project config with presets and collecting actions in {project.dir_path} failed: {exception.message}"
253256
)
257+
258+
# update config of dev_workspace runner, the new config contains resolved presets
259+
dev_workspace_runner = ws_context.ws_projects_extension_runners[project.dir_path]['dev_workspace']
260+
await update_runner_config(runner=dev_workspace_runner, project=project)
254261

255262

256263
async def get_or_start_runners_with_presets(

0 commit comments

Comments
 (0)