Skip to content

Commit 1e4d549

Browse files
committed
refine structure
1 parent 71d593a commit 1e4d549

4 files changed

Lines changed: 84 additions & 113 deletions

File tree

src/cpp_dev/project/core.py

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,12 @@
66
from pathlib import Path
77
from textwrap import dedent
88

9+
from cpp_dev.common.version import SemanticVersionWithOptionalParts
910
from cpp_dev.dependency.provider import DependencyProvider
11+
from cpp_dev.dependency.specifier import DependencySpecifier
12+
from cpp_dev.dependency.types import DependencySpecifierParts, VersionSpecBound, VersionSpecBoundOperand
1013

11-
from .config import ProjectConfig, create_project_config
14+
from .config import DependencyType, ProjectConfig, create_project_config, load_project_config, update_dependencies
1215
from .lockfile import create_initial_lock_file
1316
from .path_composition import compose_include_file, compose_source_file
1417

@@ -29,6 +32,12 @@ def project_dir(self) -> Path:
2932
"""Return the path to the project directory."""
3033
return self._project_dir
3134

35+
def add_package_dependency(self, deps: list[DependencySpecifier], dep_type: DependencyType) -> None:
36+
"""Add package dependencies to the project for the given type."""
37+
refined_deps = _refine_package_dependencies(self._dependency_provider, deps)
38+
project_config = load_project_config(self.project_dir)
39+
update_dependencies(project_config, refined_deps, dep_type)
40+
3241

3342
def setup_project(
3443
project_config: ProjectConfig,
@@ -124,3 +133,38 @@ def _create_library_test_file(project_dir: Path, name: str) -> None:
124133
def _add_default_cpd_dependencies(project_dir: Path) -> None:
125134
# add_package_dependency(project_dir, [PackageDependency("llvm"), PackageDependency("gtest")], "cpd") # noqa: ERA001
126135
...
136+
137+
138+
DEFAULT_REPOSITORY = "official"
139+
140+
141+
def _refine_package_dependencies(
142+
dep_provider: DependencyProvider, deps: list[DependencySpecifier]
143+
) -> list[DependencySpecifier]:
144+
"""Refine the package dependencies in case of defaults were chosen.
145+
146+
The refinement includes (in order):
147+
o Default repository "official"
148+
o Latest resolved version in case of "latest"
149+
150+
This step is performed to assure that package dependencies with "latest" do not get an older version
151+
than the latest one at the time of resolution. This is important in case a versions gets removed.
152+
"""
153+
updated_deps = []
154+
for dep in deps:
155+
repository = dep.repository if dep.repository is not None else DEFAULT_REPOSITORY
156+
version_spec = dep.version_spec
157+
if dep.version_spec == "latest":
158+
available_versions = dep_provider.fetch_versions(repository, dep.name)
159+
if len(available_versions) == 0:
160+
raise ValueError(f"No available versions for package {dep.name} at repository {dep.repository}.")
161+
version_spec = [
162+
VersionSpecBound(
163+
operand=VersionSpecBoundOperand.GREATER_THAN_OR_EQUAL,
164+
version=SemanticVersionWithOptionalParts.from_semantic_version(available_versions[0]),
165+
)
166+
]
167+
updated_deps.append(
168+
DependencySpecifier.from_parts(DependencySpecifierParts(repository, dep.name, version_spec))
169+
)
170+
return updated_deps

src/cpp_dev/project/dependency/utils.py

Lines changed: 0 additions & 47 deletions
This file was deleted.

src/cpp_dev/project/management.py

Lines changed: 0 additions & 64 deletions
This file was deleted.

src/tests/cpp_dev/project/test_core.py

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,18 @@
44
# For a copy, see <https://opensource.org/license/bsd-3-clause>.
55

66

7+
from collections.abc import Mapping
78
from pathlib import Path
9+
from unittest.mock import patch
810

911
import pytest
1012

1113
from cpp_dev.common.version import SemanticVersion
14+
from cpp_dev.dependency.conan.types import ConanPackageReference
1215
from cpp_dev.dependency.provider import Dependency, DependencyIdentifier, DependencyProvider
16+
from cpp_dev.dependency.specifier import DependencySpecifier
1317
from cpp_dev.project.config import ProjectConfig, load_project_config
14-
from cpp_dev.project.core import setup_project
18+
from cpp_dev.project.core import _refine_package_dependencies, setup_project
1519
from cpp_dev.project.lockfile import load_lock_file
1620
from cpp_dev.project.path_composition import compose_project_config_file, compose_project_lock_file
1721
from tests.cpp_dev.project.utils.artificial_dependency_provider import ArtificialDependencyProvider
@@ -61,3 +65,37 @@ def test_setup_project(tmp_path: Path, dep_provider: DependencyProvider) -> None
6165
assert (project.project_dir / "include" / project_config.name / f"{project_config.name}.hpp").exists()
6266
assert (project.project_dir / "src" / f"{project_config.name}.cpp").exists()
6367
assert (project.project_dir / "src" / f"{project_config.name}.test.cpp").exists()
68+
69+
70+
def conan_list_side_effect(_remote: str, name: str) -> Mapping[ConanPackageReference, dict]:
71+
if name == "cpd":
72+
return {
73+
ConanPackageReference("cpd/1.0.0@official/cppdev"): {},
74+
ConanPackageReference("cpd/2.0.0@official/cppdev"): {},
75+
}
76+
if name == "cpd2":
77+
return {
78+
ConanPackageReference("cpd2/3.0.0@official/cppdev"): {},
79+
ConanPackageReference("cpd2/3.0.0@official/cppdev"): {},
80+
}
81+
if name == "other":
82+
return {
83+
ConanPackageReference("other/2.0.0@custom/cppdev"): {},
84+
}
85+
return {}
86+
87+
88+
def test_refine_package_dependencies(dep_provider: DependencyProvider) -> None:
89+
refined_deps = _refine_package_dependencies(
90+
dep_provider,
91+
[
92+
DependencySpecifier("llvm"),
93+
DependencySpecifier("official/llvm[latest]"),
94+
DependencySpecifier("gtest[3.0.0]"),
95+
],
96+
)
97+
assert refined_deps == [
98+
DependencySpecifier("official/llvm[>=1.0.0]"),
99+
DependencySpecifier("official/llvm[>=1.0.0]"),
100+
DependencySpecifier("official/gtest[3.0.0]"),
101+
]

0 commit comments

Comments
 (0)