Skip to content

Commit 19df473

Browse files
committed
Initial Remote Specification
1 parent 4838f77 commit 19df473

File tree

7 files changed

+54
-34
lines changed

7 files changed

+54
-34
lines changed

cppython/plugins/conan/plugin.py

Lines changed: 28 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,24 @@ def publish(self) -> None:
202202
# Initialize Conan API
203203
conan_api = ConanAPI()
204204

205+
# Get configured remotes from Conan API and filter by our configuration
206+
# TODO: We want to replace the global conan remotes with the ones configured in CPPython.
207+
all_remotes = conan_api.remotes.list()
208+
if not self.data.local_only:
209+
# Filter remotes to only include those specified in configuration
210+
configured_remotes = [remote for remote in all_remotes if remote.name in self.data.remotes]
211+
212+
if not configured_remotes:
213+
available_remotes = [remote.name for remote in all_remotes]
214+
raise ProviderConfigurationError(
215+
'conan',
216+
f'No configured remotes found. Available remotes: {available_remotes}, '
217+
f'Configured remotes: {self.data.remotes}',
218+
'remotes',
219+
)
220+
else:
221+
configured_remotes = []
222+
205223
# Step 1: Export the recipe to the cache
206224
# This is equivalent to the export part of `conan create`
207225
ref, conanfile = conan_api.export.export(
@@ -211,7 +229,7 @@ def publish(self) -> None:
211229
user=None,
212230
channel=None,
213231
lockfile=None,
214-
remotes=conan_api.remotes.list(),
232+
remotes=all_remotes, # Use all remotes for dependency resolution during export
215233
)
216234

217235
# Step 2: Get default profiles
@@ -230,7 +248,7 @@ def publish(self) -> None:
230248
profile_host=profile_host,
231249
profile_build=profile_build,
232250
lockfile=None,
233-
remotes=conan_api.remotes.list(),
251+
remotes=all_remotes, # Use all remotes for dependency resolution
234252
update=None,
235253
check_updates=False,
236254
is_build_require=False,
@@ -240,33 +258,29 @@ def publish(self) -> None:
240258
conan_api.graph.analyze_binaries(
241259
graph=deps_graph,
242260
build_mode=['*'], # Build from source (equivalent to the create behavior)
243-
remotes=conan_api.remotes.list(),
261+
remotes=all_remotes, # Use all remotes for dependency resolution
244262
update=None,
245263
lockfile=None,
246264
)
247265

248266
# Step 5: Install all dependencies and build the package
249-
conan_api.install.install_binaries(deps_graph=deps_graph, remotes=conan_api.remotes.list())
267+
conan_api.install.install_binaries(deps_graph=deps_graph, remotes=all_remotes)
250268

251-
# If not local, upload the package
252-
if not self.data.local:
269+
# If not local only, upload the package
270+
if not self.data.local_only:
253271
# Get all packages matching the created reference
254272
ref_pattern = ListPattern(f'{ref.name}/*', package_id='*', only_recipe=False)
255273
package_list = conan_api.list.select(ref_pattern)
256274

257275
if package_list.recipes:
258-
# Get the first configured remote or raise an error
259-
remotes = conan_api.remotes.list()
260-
if not remotes:
261-
raise ProviderConfigurationError('conan', 'No remotes configured for upload', 'remotes')
262-
263-
remote = remotes[0] # Use first remote
276+
# Use the first configured remote for upload
277+
remote = configured_remotes[0]
264278

265-
# Upload the package
279+
# Upload the package to configured remotes
266280
conan_api.upload.upload_full(
267281
package_list=package_list,
268282
remote=remote,
269-
enabled_remotes=remotes,
283+
enabled_remotes=configured_remotes, # Only upload to configured remotes
270284
check_integrity=False,
271285
force=False,
272286
metadata=None,

cppython/plugins/conan/resolution.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,4 +43,4 @@ def resolve_conan_data(data: dict[str, Any], core_data: CorePluginData) -> Conan
4343
"""
4444
parsed_data = ConanConfiguration(**data)
4545

46-
return ConanData(local=parsed_data.local)
46+
return ConanData(remotes=parsed_data.remotes)

cppython/plugins/conan/schema.py

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,18 @@ def requires(self) -> str:
3030
class ConanData(CPPythonModel):
3131
"""Resolved conan data"""
3232

33-
local: bool
33+
remotes: list[str]
34+
35+
@property
36+
def local_only(self) -> bool:
37+
"""Check if publishing should be local-only."""
38+
return len(self.remotes) == 0
3439

3540

3641
class ConanConfiguration(CPPythonModel):
3742
"""Raw conan data"""
3843

39-
local: Annotated[bool, Field(description='Whether to publish packages locally without uploading to a remote')] = (
40-
False
41-
)
44+
remotes: Annotated[
45+
list[str],
46+
Field(description='List of remotes to upload to. Empty list means the local conan cache will be used.'),
47+
] = ['conancenter']

tests/fixtures/conan.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ def fixture_conan_mock_api_publish(mocker: MockerFixture) -> Mock:
7979

8080
# Mock remotes module
8181
mock_remote = mocker.Mock()
82-
mock_remote.name = 'origin'
82+
mock_remote.name = 'conancenter'
8383
mock_api.remotes.list = mocker.Mock(return_value=[mock_remote])
8484

8585
# Mock upload module

tests/unit/plugins/conan/test_install.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ def fixture_plugin_data() -> dict[str, Any]:
3131
The constructed plugin data
3232
"""
3333
return {
34-
'local': True,
34+
'remotes': [],
3535
}
3636

3737
@staticmethod

tests/unit/plugins/conan/test_publish.py

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ def fixture_plugin_data() -> dict[str, Any]:
2626
The constructed plugin data
2727
"""
2828
return {
29-
'local': False,
29+
'remotes': ['conancenter'],
3030
}
3131

3232
@staticmethod
@@ -42,7 +42,7 @@ def fixture_plugin_type() -> type[ConanProvider]:
4242
def test_publish_local_only(
4343
self, plugin: ConanProvider, conan_mock_api_publish: Mock, conan_temp_conanfile: None, mocker: MockerFixture
4444
) -> None:
45-
"""Test that publish with local=True only exports and builds locally
45+
"""Test that publish with remotes=[] only exports and builds locally
4646
4747
Args:
4848
plugin: The plugin instance
@@ -51,7 +51,7 @@ def test_publish_local_only(
5151
mocker: Pytest mocker fixture
5252
"""
5353
# Set plugin to local mode
54-
plugin.data.local = True
54+
plugin.data.remotes = []
5555

5656
# Mock the necessary imports and API creation
5757
mocker.patch('cppython.plugins.conan.plugin.ConanAPI', return_value=conan_mock_api_publish)
@@ -87,7 +87,7 @@ def test_publish_local_only(
8787
def test_publish_with_upload(
8888
self, plugin: ConanProvider, conan_mock_api_publish: Mock, conan_temp_conanfile: None, mocker: MockerFixture
8989
) -> None:
90-
"""Test that publish with local=False exports, builds, and uploads
90+
"""Test that publish with remotes=['conancenter'] exports, builds, and uploads
9191
9292
Args:
9393
plugin: The plugin instance
@@ -96,7 +96,7 @@ def test_publish_with_upload(
9696
mocker: Pytest mocker fixture
9797
"""
9898
# Set plugin to upload mode
99-
plugin.data.local = False
99+
plugin.data.remotes = ['conancenter']
100100

101101
# Mock the necessary imports and API creation
102102
mocker.patch('cppython.plugins.conan.plugin.ConanAPI', return_value=conan_mock_api_publish)
@@ -130,7 +130,7 @@ def test_publish_no_remotes_configured(
130130
mocker: Pytest mocker fixture
131131
"""
132132
# Set plugin to upload mode
133-
plugin.data.local = False
133+
plugin.data.remotes = ['conancenter']
134134

135135
# Mock the necessary imports and API creation
136136
mocker.patch('cppython.plugins.conan.plugin.ConanAPI', return_value=conan_mock_api_publish)
@@ -143,7 +143,7 @@ def test_publish_no_remotes_configured(
143143
conan_mock_api_publish.remotes.list.return_value = []
144144

145145
# Execute publish and expect ProviderConfigurationError
146-
with pytest.raises(ProviderConfigurationError, match='No remotes configured for upload'):
146+
with pytest.raises(ProviderConfigurationError, match='No configured remotes found'):
147147
plugin.publish()
148148

149149
def test_publish_no_packages_found(
@@ -158,7 +158,7 @@ def test_publish_no_packages_found(
158158
mocker: Pytest mocker fixture
159159
"""
160160
# Set plugin to upload mode
161-
plugin.data.local = False
161+
plugin.data.remotes = ['conancenter']
162162

163163
# Mock the necessary imports and API creation
164164
mocker.patch('cppython.plugins.conan.plugin.ConanAPI', return_value=conan_mock_api_publish)
@@ -188,7 +188,7 @@ def test_publish_uses_default_profiles(
188188
mocker: Pytest mocker fixture
189189
"""
190190
# Set plugin to local mode
191-
plugin.data.local = True
191+
plugin.data.remotes = []
192192

193193
# Mock the necessary imports and API creation
194194
mocker.patch('cppython.plugins.conan.plugin.ConanAPI', return_value=conan_mock_api_publish)
@@ -217,7 +217,7 @@ def test_publish_upload_parameters(
217217
mocker: Pytest mocker fixture
218218
"""
219219
# Set plugin to upload mode
220-
plugin.data.local = False
220+
plugin.data.remotes = ['conancenter']
221221

222222
# Mock the necessary imports and API creation
223223
mocker.patch('cppython.plugins.conan.plugin.ConanAPI', return_value=conan_mock_api_publish)
@@ -228,7 +228,7 @@ def test_publish_upload_parameters(
228228

229229
# Mock remotes and package list
230230
mock_remote = MagicMock()
231-
mock_remote.name = 'origin'
231+
mock_remote.name = 'conancenter'
232232
remotes = [mock_remote]
233233
conan_mock_api_publish.remotes.list.return_value = remotes
234234

@@ -262,7 +262,7 @@ def test_publish_list_pattern_creation(
262262
mocker: Pytest mocker fixture
263263
"""
264264
# Set plugin to upload mode
265-
plugin.data.local = False
265+
plugin.data.remotes = ['conancenter']
266266

267267
# Mock the necessary imports and API creation
268268
mocker.patch('cppython.plugins.conan.plugin.ConanAPI', return_value=conan_mock_api_publish)

tests/unit/plugins/conan/test_update.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ def fixture_plugin_data() -> dict[str, Any]:
2727
The constructed plugin data
2828
"""
2929
return {
30-
'local': True,
30+
'remotes': [],
3131
}
3232

3333
@staticmethod

0 commit comments

Comments
 (0)