Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve handling of net versions missmatch #526

Merged
merged 1 commit into from
Dec 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 22 additions & 10 deletions lean/components/docker/lean_runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand All @@ -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)}",
Expand Down Expand Up @@ -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,
Expand All @@ -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"\"<TargetFramework>{net_framework}</TargetFramework>\".")

for package_reference in csproj.iter("PackageReference"):
if not package_reference.get("Include", "").lower().startswith("quantconnect."):
continue
Expand Down
4 changes: 2 additions & 2 deletions lean/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
2 changes: 1 addition & 1 deletion tests/commands/test_backtest.py
Original file line number Diff line number Diff line change
Expand Up @@ -573,7 +573,7 @@ def test_backtest_auto_updates_outdated_csharp_csproj() -> None:
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<TargetFramework>net6.0</TargetFramework>
<TargetFramework>net9.0</TargetFramework>
<OutputPath>bin/$(Configuration)</OutputPath>
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
<NoWarn>CS0618</NoWarn>
Expand Down
4 changes: 2 additions & 2 deletions tests/components/config/test_project_config_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ def test_get_csharp_libraries_returns_all_libraries_in_package_reference_tags_in
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<TargetFramework>net6.0</TargetFramework>
<TargetFramework>net9.0</TargetFramework>
<OutputPath>bin/$(Configuration)</OutputPath>
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
<NoWarn>CS0618</NoWarn>
Expand Down Expand Up @@ -99,7 +99,7 @@ def test_get_csharp_libraries_skips_invalid_package_reference_tags() -> None:
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<TargetFramework>net6.0</TargetFramework>
<TargetFramework>net9.0</TargetFramework>
<OutputPath>bin/$(Configuration)</OutputPath>
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
<NoWarn>CS0618</NoWarn>
Expand Down
7 changes: 6 additions & 1 deletion tests/components/docker/test_lean_runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)

Expand All @@ -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)

Expand Down Expand Up @@ -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)

Expand All @@ -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)

Expand Down Expand Up @@ -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)
Expand Down