From 317d5381ffd5bed0e4200bbc9405ce450a328dcb Mon Sep 17 00:00:00 2001 From: Martin-Molinero Date: Wed, 18 Dec 2024 12:48:11 -0300 Subject: [PATCH] Improve handling of net versions missmatch (#526) --- lean/components/docker/lean_runner.py | 32 +++++++++++++------ lean/constants.py | 4 +-- tests/commands/test_backtest.py | 2 +- .../config/test_project_config_manager.py | 4 +-- tests/components/docker/test_lean_runner.py | 7 +++- 5 files changed, 33 insertions(+), 16 deletions(-) diff --git a/lean/components/docker/lean_runner.py b/lean/components/docker/lean_runner.py index 4c2260ff..3d704b17 100644 --- a/lean/components/docker/lean_runner.py +++ b/lean/components/docker/lean_runner.py @@ -585,13 +585,14 @@ def set_up_csharp_options(self, project_dir: Path, run_options: Dict[str, Any], "mode": "rw" } + framework_ver = self._docker_manager.get_image_label(image, 'target_framework', + DEFAULT_LEAN_DOTNET_FRAMEWORK) + # Ensure all .csproj files refer to the version of LEAN in the Docker container csproj_temp_dir = self._temp_manager.create_temporary_directory() for path in compile_root.rglob("*.csproj"): - self._ensure_csproj_uses_correct_lean(compile_root, path, csproj_temp_dir, run_options) + self._ensure_csproj_is_valid(compile_root, path, csproj_temp_dir, run_options, framework_ver) - framework_ver = self._docker_manager.get_image_label(image, 'target_framework', - DEFAULT_LEAN_DOTNET_FRAMEWORK) # Set up the MSBuild properties msbuild_properties = { "Configuration": "Release" if release else "Debug", @@ -601,8 +602,6 @@ def set_up_csharp_options(self, project_dir: Path, run_options: Dict[str, Any], "GenerateAssemblyInfo": "false", "GenerateTargetFrameworkAttribute": "false", "AppendTargetFrameworkToOutputPath": "false", - "AutoGenerateBindingRedirects": "true", - "GenerateBindingRedirectsOutputType": "true", "AutomaticallyUseReferenceAssemblyPackages": "false", "CopyLocalLockFileAssemblies": "true", "PathMap": f"/LeanCLI={str(compile_root)}", @@ -770,11 +769,12 @@ def _get_csharp_compile_root(self, project_dir: Path) -> Path: return project_dir - def _ensure_csproj_uses_correct_lean(self, - compile_root: Path, - csproj_path: Path, - temp_dir: Path, - run_options: Dict[str, Any]) -> None: + def _ensure_csproj_is_valid(self, + compile_root: Path, + csproj_path: Path, + temp_dir: Path, + run_options: Dict[str, Any], + net_framework: str) -> None: """Ensures a C# project is compiled using the version of LEAN in the Docker container. When a .csproj file refers to the NuGet version of LEAN, @@ -791,6 +791,18 @@ def _ensure_csproj_uses_correct_lean(self, csproj = self._xml_manager.parse(csproj_path.read_text(encoding="utf-8")) include_added = False + if net_framework: + target_framework_iter = csproj.iter("TargetFramework") + if target_framework_iter: + target_frameworks = [framework.text for framework in target_framework_iter] + if target_frameworks: + if net_framework not in target_frameworks: + raise RuntimeError(f"This project is targeting {target_frameworks[0].replace('net', 'Net ')}" + f" and {net_framework.replace('net', 'Net ')} is required. Please" + f" update the \"Target Framework\" project setting in VSCode to" + f" the new SDK or modify the csproj file directly to " + f"\"{net_framework}\".") + for package_reference in csproj.iter("PackageReference"): if not package_reference.get("Include", "").lower().startswith("quantconnect."): continue diff --git a/lean/constants.py b/lean/constants.py index 3e24b66f..fdb553e7 100644 --- a/lean/constants.py +++ b/lean/constants.py @@ -23,8 +23,8 @@ # we get these values from the image labels, but we still have defaults just in case DEFAULT_LEAN_PYTHON_VERSION = "3.11" -DEFAULT_LEAN_STRICT_PYTHON_VERSION = f"{DEFAULT_LEAN_PYTHON_VERSION}.7" -DEFAULT_LEAN_DOTNET_FRAMEWORK = "net6.0" +DEFAULT_LEAN_STRICT_PYTHON_VERSION = f"{DEFAULT_LEAN_PYTHON_VERSION}.11" +DEFAULT_LEAN_DOTNET_FRAMEWORK = "net9.0" # Label name used in Docker containers to specify the version of Lean being used CONTAINER_LABEL_LEAN_VERSION_NAME = "lean_version" diff --git a/tests/commands/test_backtest.py b/tests/commands/test_backtest.py index 80d48260..3752adf8 100644 --- a/tests/commands/test_backtest.py +++ b/tests/commands/test_backtest.py @@ -573,7 +573,7 @@ def test_backtest_auto_updates_outdated_csharp_csproj() -> None: Debug AnyCPU - net6.0 + net9.0 bin/$(Configuration) false CS0618 diff --git a/tests/components/config/test_project_config_manager.py b/tests/components/config/test_project_config_manager.py index 9bfe80b9..48bd26ec 100644 --- a/tests/components/config/test_project_config_manager.py +++ b/tests/components/config/test_project_config_manager.py @@ -60,7 +60,7 @@ def test_get_csharp_libraries_returns_all_libraries_in_package_reference_tags_in Debug AnyCPU - net6.0 + net9.0 bin/$(Configuration) false CS0618 @@ -99,7 +99,7 @@ def test_get_csharp_libraries_skips_invalid_package_reference_tags() -> None: Debug AnyCPU - net6.0 + net9.0 bin/$(Configuration) false CS0618 diff --git a/tests/components/docker/test_lean_runner.py b/tests/components/docker/test_lean_runner.py index ff2e7138..de5ba8fd 100644 --- a/tests/components/docker/test_lean_runner.py +++ b/tests/components/docker/test_lean_runner.py @@ -27,7 +27,7 @@ from lean.components.util.project_manager import ProjectManager from lean.components.util.temp_manager import TempManager from lean.components.util.xml_manager import XMLManager -from lean.constants import DEFAULT_ENGINE_IMAGE, LEAN_ROOT_PATH, DEFAULT_DATA_DIRECTORY_NAME +from lean.constants import DEFAULT_ENGINE_IMAGE, LEAN_ROOT_PATH, DEFAULT_DATA_DIRECTORY_NAME, DEFAULT_LEAN_DOTNET_FRAMEWORK from lean.models.utils import DebuggingMethod from lean.models.docker import DockerImage from lean.models.modules import NuGetPackage @@ -97,6 +97,7 @@ def test_run_lean_compiles_csharp_project_in_correct_configuration(release: bool docker_manager = mock.Mock() docker_manager.run_image.return_value = True + docker_manager.get_image_label.return_value = DEFAULT_LEAN_DOTNET_FRAMEWORK lean_runner = create_lean_runner(docker_manager) @@ -123,6 +124,7 @@ def test_run_lean_runs_lean_container_detached() -> None: docker_manager = mock.Mock() docker_manager.run_image.return_value = True + docker_manager.get_image_label.return_value = DEFAULT_LEAN_DOTNET_FRAMEWORK lean_runner = create_lean_runner(docker_manager) @@ -384,6 +386,7 @@ def test_run_lean_sets_image_name_when_debugging_with_vsdbg() -> None: docker_manager = mock.Mock() docker_manager.run_image.return_value = True + docker_manager.get_image_label.return_value = DEFAULT_LEAN_DOTNET_FRAMEWORK lean_runner = create_lean_runner(docker_manager) @@ -407,6 +410,7 @@ def test_run_lean_exposes_ssh_when_debugging_with_rider() -> None: docker_manager = mock.Mock() docker_manager.run_image.return_value = True + docker_manager.get_image_label.return_value = DEFAULT_LEAN_DOTNET_FRAMEWORK lean_runner = create_lean_runner(docker_manager) @@ -556,6 +560,7 @@ def test_run_lean_compiles_csharp_project_that_is_part_of_a_solution(in_solution docker_manager = mock.Mock() docker_manager.run_image.return_value = True + docker_manager.get_image_label.return_value = DEFAULT_LEAN_DOTNET_FRAMEWORK root_dir = Path.cwd() lean_runner = create_lean_runner(docker_manager)