Skip to content

Commit 6556997

Browse files
committed
Vcpkg Dependency Resolution
1 parent db0eb32 commit 6556997

File tree

3 files changed

+88
-8
lines changed

3 files changed

+88
-8
lines changed

cppython/plugins/vcpkg/resolution.py

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22

33
from typing import Any
44

5+
from packaging.requirements import Requirement
6+
7+
from cppython.core.exception import ConfigException
58
from cppython.core.schema import CorePluginData
69
from cppython.plugins.vcpkg.schema import (
710
Manifest,
@@ -54,11 +57,44 @@ def resolve_vcpkg_data(data: dict[str, Any], core_data: CorePluginData) -> Vcpkg
5457
modified_install_directory.mkdir(parents=True, exist_ok=True)
5558

5659
vcpkg_dependencies: list[VcpkgDependency] = []
57-
for dependency in parsed_data.dependencies:
58-
vcpkg_dependency = VcpkgDependency(name=dependency.name)
59-
vcpkg_dependencies.append(vcpkg_dependency)
60+
for requirement in core_data.cppython_data.dependencies:
61+
resolved_dependency = resolve_vcpkg_dependency(requirement)
62+
vcpkg_dependencies.append(resolved_dependency)
6063

6164
return VcpkgData(
6265
install_directory=modified_install_directory,
6366
dependencies=vcpkg_dependencies,
6467
)
68+
69+
70+
def resolve_vcpkg_dependency(requirement: Requirement) -> VcpkgDependency:
71+
"""Resolve a VcpkgDependency from a packaging requirement.
72+
73+
Args:
74+
requirement: A packaging requirement object.
75+
76+
Returns:
77+
A resolved VcpkgDependency object.
78+
"""
79+
specifiers = requirement.specifier
80+
81+
# If the length of specifiers is greater than one, raise a configuration error
82+
if len(specifiers) > 1:
83+
raise ConfigException('Multiple specifiers are not supported. Please provide a single specifier.', [])
84+
85+
# Extract the version from the single specifier
86+
version = None
87+
if len(specifiers) == 1:
88+
specifier = next(iter(specifiers))
89+
if specifier.operator != '>=':
90+
raise ConfigException(f"Unsupported specifier '{specifier.operator}'. Only '>=' is supported.", [])
91+
version = specifier.version
92+
93+
return VcpkgDependency(
94+
name=requirement.name,
95+
default_features=True,
96+
features=[],
97+
version=version,
98+
platform=None,
99+
host=False,
100+
)

cppython/plugins/vcpkg/schema.py

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,32 @@
1111
class VcpkgDependency(CPPythonModel):
1212
"""Vcpkg dependency type"""
1313

14-
name: str
14+
name: Annotated[str, Field(description='The name of the dependency.')]
15+
default_features: Annotated[
16+
bool,
17+
Field(
18+
alias='default-features',
19+
description='Whether to use the default features of the dependency. Defaults to true.',
20+
),
21+
] = True
22+
features: Annotated[
23+
list[str],
24+
Field(description='A list of additional features to require for the dependency.'),
25+
] = []
26+
version: Annotated[
27+
str | None,
28+
Field(
29+
description='The minimum required version of the dependency, optionally with a port-version suffix.',
30+
),
31+
] = None
32+
platform: Annotated[
33+
str | None,
34+
Field(description='A platform expression specifying the platforms where the dependency applies.'),
35+
] = None
36+
host: Annotated[
37+
bool,
38+
Field(description='Whether the dependency is required for the host machine instead of the target.'),
39+
] = False
1540

1641

1742
class VcpkgData(CPPythonModel):
@@ -32,10 +57,6 @@ class VcpkgConfiguration(CPPythonModel):
3257
),
3358
] = Path('build')
3459

35-
dependencies: Annotated[
36-
list[VcpkgDependency], Field(description='The directory to store the manifest file, vcpkg.json')
37-
] = []
38-
3960

4061
class Manifest(CPPythonModel):
4162
"""The manifest schema"""
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
"""Unit tests for the Vcpkg resolution plugin."""
2+
3+
from packaging.requirements import Requirement
4+
5+
from cppython.plugins.vcpkg.resolution import resolve_vcpkg_dependency
6+
7+
8+
class TestVcpkgResolution:
9+
"""Test the resolution of Vcpkg dependencies"""
10+
11+
@staticmethod
12+
def test_resolve_vcpkg_dependency() -> None:
13+
"""Test resolving a VcpkgDependency from a packaging requirement."""
14+
requirement = Requirement('example-package>=1.2.3')
15+
16+
dependency = resolve_vcpkg_dependency(requirement)
17+
18+
assert dependency.name == 'example-package'
19+
assert dependency.version == '1.2.3'
20+
assert dependency.default_features is True
21+
assert dependency.features == []
22+
assert dependency.platform is None
23+
assert dependency.host is False

0 commit comments

Comments
 (0)