Skip to content
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
24 changes: 17 additions & 7 deletions cppython/plugins/conan/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ def _install_dependencies(self, *, update: bool = False) -> None:
If False, use cached versions when available.
"""
operation = 'update' if update else 'install'

try:
# Setup environment and generate conanfile
conan_api, conanfile_path = self._prepare_installation()
Expand Down Expand Up @@ -247,6 +247,7 @@ def publish(self) -> None:
raise FileNotFoundError(f'conanfile.py not found at {conanfile_path}')

conan_api = ConanAPI()

all_remotes = conan_api.remotes.list()

# Configure remotes for upload
Expand All @@ -272,7 +273,7 @@ def publish(self) -> None:
user=None,
channel=None,
lockfile=None,
remotes=all_remotes,
remotes=all_remotes, # Use all remotes for dependency resolution
update=None,
check_updates=False,
is_build_require=False,
Expand All @@ -284,22 +285,31 @@ def publish(self) -> None:
conan_api.graph.analyze_binaries(
graph=deps_graph,
build_mode=['*'],
remotes=all_remotes,
remotes=all_remotes, # Use all remotes for dependency resolution
update=None,
lockfile=None,
)

conan_api.install.install_binaries(deps_graph=deps_graph, remotes=all_remotes)

# Upload if not local only
if not self.data.local_only:
if not self.data.skip_upload:
self._upload_package(conan_api, ref, configured_remotes)

def _get_configured_remotes(self, all_remotes):
"""Get and validate configured remotes for upload."""
if self.data.local_only:
"""Get and validate configured remotes for upload.

Note: This only affects upload behavior. For dependency resolution,
we always use all available system remotes regardless of this config.
"""
# If skip_upload is True, don't upload anywhere
if self.data.skip_upload:
return []

# If no remotes specified, upload to all available remotes
if not self.data.remotes:
return all_remotes

# Otherwise, upload only to specified remotes
configured_remotes = [remote for remote in all_remotes if remote.name in self.data.remotes]

if not configured_remotes:
Expand Down
1 change: 1 addition & 0 deletions cppython/plugins/conan/resolution.py
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,7 @@ def resolve_conan_data(data: dict[str, Any], core_data: CorePluginData) -> Conan

return ConanData(
remotes=parsed_data.remotes,
skip_upload=parsed_data.skip_upload,
host_profile=host_profile,
build_profile=build_profile,
)
12 changes: 6 additions & 6 deletions cppython/plugins/conan/schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -293,22 +293,22 @@ class ConanData(CPPythonModel):
"""Resolved conan data"""

remotes: list[str]
skip_upload: bool
host_profile: Profile
build_profile: Profile

@property
def local_only(self) -> bool:
"""Check if publishing should be local-only."""
return len(self.remotes) == 0


class ConanConfiguration(CPPythonModel):
"""Raw conan data"""

remotes: Annotated[
list[str],
Field(description='List of remotes to upload to. Empty list means the local conan cache will be used.'),
Field(description='List of remotes to upload to. If empty, uploads to all available remotes.'),
] = ['conancenter']
skip_upload: Annotated[
bool,
Field(description='If true, skip uploading packages during publish (local-only mode).'),
] = False
host_profile: Annotated[
str | None,
Field(
Expand Down
81 changes: 48 additions & 33 deletions pdm.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

33 changes: 26 additions & 7 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,23 @@ dependencies = [
]

[project.optional-dependencies]
pytest = ["pytest>=8.4.1", "pytest-mock>=3.14.1"]
git = ["dulwich>=0.23.2"]
pdm = ["pdm>=2.25.4"]
cmake = ["cmake>=4.0.3"]
conan = ["conan>=2.18.1", "libcst>=1.8.2"]
pytest = [
"pytest>=8.4.1",
"pytest-mock>=3.14.1",
]
git = [
"dulwich>=0.23.2",
]
pdm = [
"pdm>=2.25.4",
]
cmake = [
"cmake>=4.0.3",
]
conan = [
"conan>=2.18.1",
"libcst>=1.8.2",
]

[project.urls]
homepage = "https://github.com/Synodic-Software/CPPython"
Expand All @@ -47,8 +59,15 @@ cppython = "cppython.plugins.pdm.plugin:CPPythonPlugin"
cppython = "cppython.test.pytest.fixtures"

[dependency-groups]
lint = ["ruff>=0.12.3", "pyrefly>=0.23.1"]
test = ["pytest>=8.4.1", "pytest-cov>=6.2.1", "pytest-mock>=3.14.1"]
lint = [
"ruff>=0.12.4",
"pyrefly>=0.24.2",
]
test = [
"pytest>=8.4.1",
"pytest-cov>=6.2.1",
"pytest-mock>=3.14.1",
]

[project.scripts]
cppython = "cppython.console.entry:app"
Expand Down
19 changes: 19 additions & 0 deletions tests/fixtures/conan.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""Shared fixtures for Conan plugin tests"""

from pathlib import Path
from typing import Any
from unittest.mock import Mock

import pytest
Expand All @@ -10,6 +11,24 @@
from cppython.plugins.conan.plugin import ConanProvider
from cppython.plugins.conan.schema import ConanDependency

# Shared parameterization for plugin data across all conan tests
CONAN_PLUGIN_DATA_PARAMS = [
{'remotes': ['conancenter'], 'skip_upload': False}, # Default behavior
{'remotes': [], 'skip_upload': False}, # Empty remotes (upload to all)
{'remotes': ['conancenter'], 'skip_upload': True}, # Skip upload with specific remotes
{'remotes': [], 'skip_upload': True}, # Skip upload with empty remotes
]


@pytest.fixture(name='conan_plugin_data', scope='session', params=CONAN_PLUGIN_DATA_PARAMS)
def fixture_conan_plugin_data(request) -> dict[str, Any]:
"""Shared parameterized plugin data for conan tests

Returns:
The constructed plugin data with different combinations of remotes and skip_upload
"""
return request.param


@pytest.fixture(autouse=True)
def clean_conan_cache(tmp_path: Path, monkeypatch: pytest.MonkeyPatch):
Expand Down
2 changes: 1 addition & 1 deletion tests/integration/examples/test_conan_cmake.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ def test_simple(example_runner: CliRunner) -> None:

# --- Setup for Publish with modified config ---
# Modify the in-memory representation of the pyproject data
pyproject_data['tool']['cppython']['providers']['conan']['remotes'] = []
pyproject_data['tool']['cppython']['providers']['conan']['skip_upload'] = True

# Create a new project instance with the modified configuration for the 'publish' step
publish_project = Project(project_configuration, interface, pyproject_data)
Expand Down
6 changes: 2 additions & 4 deletions tests/unit/plugins/conan/test_install.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,13 @@ class TestConanInstall(ProviderPluginTestMixin[ConanProvider]):

@staticmethod
@pytest.fixture(name='plugin_data', scope='session')
def fixture_plugin_data() -> dict[str, Any]:
def fixture_plugin_data(conan_plugin_data: dict[str, Any]) -> dict[str, Any]:
"""A required testing hook that allows data generation

Returns:
The constructed plugin data
"""
return {
'remotes': [],
}
return conan_plugin_data

@staticmethod
@pytest.fixture(name='plugin_type', scope='session')
Expand Down
Loading
Loading