Skip to content

Commit 1237e03

Browse files
committed
Remove Some Custom Detection
1 parent ab846ff commit 1237e03

File tree

2 files changed

+113
-19
lines changed

2 files changed

+113
-19
lines changed

cppython/plugins/conan/plugin.py

Lines changed: 39 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -113,20 +113,26 @@ def _install_dependencies(self, *, update: bool = False) -> None:
113113

114114
logger.debug('Using profiles: host=%s, build=%s', profile_host, profile_build)
115115

116-
# Build dependency graph
116+
# Build dependency graph - prepare parameters
117+
# According to Conan docs, if profiles not specified, it will use defaults
118+
path = str(conanfile_path)
119+
remotes = all_remotes
120+
update_flag = None if not update else True
121+
check_updates_flag = update
122+
117123
deps_graph = conan_api.graph.load_graph_consumer(
118-
path=str(conanfile_path),
124+
path=path,
119125
name=None,
120126
version=None,
121127
user=None,
122128
channel=None,
123-
profile_host=profile_host,
124-
profile_build=profile_build,
125129
lockfile=None,
126-
remotes=all_remotes,
127-
update=None if not update else True,
128-
check_updates=update,
130+
remotes=remotes,
131+
update=update_flag,
132+
check_updates=check_updates_flag,
129133
is_build_require=False,
134+
profile_host=profile_host,
135+
profile_build=profile_build,
130136
)
131137

132138
logger.debug('Dependency graph loaded with %d nodes', len(deps_graph.nodes))
@@ -249,20 +255,23 @@ def publish(self) -> None:
249255
# Step 2: Get default profiles, handle case when no default profile exists
250256
profile_host, profile_build = self._resolve_profiles(conan_api)
251257

252-
# Step 3: Build dependency graph for the package
258+
# Step 3: Build dependency graph for the package - prepare parameters
259+
path = str(conanfile_path)
260+
remotes = all_remotes # Use all remotes for dependency resolution
261+
253262
deps_graph = conan_api.graph.load_graph_consumer(
254-
path=str(conanfile_path),
263+
path=path,
255264
name=None,
256265
version=None,
257266
user=None,
258267
channel=None,
259-
profile_host=profile_host,
260-
profile_build=profile_build,
261268
lockfile=None,
262-
remotes=all_remotes, # Use all remotes for dependency resolution
269+
remotes=remotes,
263270
update=None,
264271
check_updates=False,
265272
is_build_require=False,
273+
profile_host=profile_host,
274+
profile_build=profile_build,
266275
)
267276

268277
# Step 4: Analyze binaries and install/build them if needed
@@ -301,7 +310,7 @@ def publish(self) -> None:
301310
raise ProviderInstallationError('conan', 'No packages found to upload')
302311

303312
def _resolve_profiles(self, conan_api) -> tuple:
304-
"""Resolve host and build profiles with fallback to detect().
313+
"""Resolve host and build profiles with robust fallback handling.
305314
306315
Args:
307316
conan_api: The Conan API instance
@@ -313,15 +322,14 @@ def _resolve_profiles(self, conan_api) -> tuple:
313322
profile_host_path = conan_api.profiles.get_default_host()
314323
profile_build_path = conan_api.profiles.get_default_build()
315324

316-
# Resolve host profile
325+
# Try to load profiles from paths if they exist
317326
if profile_host_path is None:
318327
profile_host = conan_api.profiles.detect()
319328
else:
320329
profile_host = conan_api.profiles.get_profile([profile_host_path])
321330
if profile_host is None:
322331
profile_host = conan_api.profiles.detect()
323332

324-
# Resolve build profile
325333
if profile_build_path is None:
326334
profile_build = conan_api.profiles.detect()
327335
else:
@@ -332,7 +340,19 @@ def _resolve_profiles(self, conan_api) -> tuple:
332340
return profile_host, profile_build
333341

334342
except Exception:
335-
# If profile operations fail, create minimal default profiles with basic settings
336-
profile_host = conan_api.profiles.detect()
337-
profile_build = conan_api.profiles.detect()
338-
return profile_host, profile_build
343+
# If profile operations fail with other exceptions, let's try detect() as fallback
344+
logger = logging.getLogger('cppython.conan')
345+
logger.warning('Profile resolution failed, attempting detect() fallback')
346+
347+
try:
348+
# Try to use detect() as fallback
349+
profile_host = conan_api.profiles.detect()
350+
profile_build = conan_api.profiles.detect()
351+
352+
# If detect returns None, that's okay - we'll let Conan handle None gracefully
353+
return profile_host, profile_build
354+
355+
except Exception as detect_error:
356+
logger.warning('Profile detect() also failed: %s', str(detect_error))
357+
# Return None for both profiles - Conan should handle this according to docs
358+
return None, None

tests/unit/plugins/conan/test_install.py

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -302,3 +302,77 @@ def test_install_with_get_profile_returning_none_fallback(
302302
conan_mock_api.graph.load_graph_consumer.assert_called_once()
303303
conan_mock_api.install.install_binaries.assert_called_once()
304304
conan_mock_api.install.install_consumer.assert_called_once()
305+
306+
def test_install_with_detect_returning_none_graceful_handling(
307+
self,
308+
plugin: ConanProvider,
309+
conan_temp_conanfile: Path,
310+
conan_mock_dependencies: list[Requirement],
311+
conan_setup_mocks: dict[str, Mock],
312+
conan_mock_api: Mock,
313+
) -> None:
314+
"""Test install method when detect() returns None (graceful handling)
315+
316+
Args:
317+
plugin: The plugin instance
318+
conan_temp_conanfile: Path to temporary conanfile.py
319+
conan_mock_dependencies: List of mock dependencies
320+
conan_setup_mocks: Dictionary containing all mocks
321+
conan_mock_api: Mock ConanAPI instance
322+
"""
323+
# Configure profiles to not exist and detect to return None
324+
conan_mock_api.profiles.get_default_host.return_value = None
325+
conan_mock_api.profiles.get_default_build.return_value = None
326+
conan_mock_api.profiles.detect.return_value = None # This should be handled gracefully
327+
328+
# Setup dependencies
329+
plugin.core_data.cppython_data.dependencies = conan_mock_dependencies
330+
331+
# Execute - should succeed gracefully by letting Conan handle None profiles
332+
plugin.install()
333+
334+
# Verify that detect was called (fallback was attempted)
335+
conan_mock_api.profiles.detect.assert_called()
336+
337+
# Verify the rest of the process continued (profiles were omitted from API call)
338+
conan_mock_api.graph.load_graph_consumer.assert_called_once()
339+
conan_mock_api.install.install_binaries.assert_called_once()
340+
conan_mock_api.install.install_consumer.assert_called_once()
341+
342+
def test_install_with_profile_exception_fallback_to_detect_works(
343+
self,
344+
plugin: ConanProvider,
345+
conan_temp_conanfile: Path,
346+
conan_mock_dependencies: list[Requirement],
347+
conan_setup_mocks: dict[str, Mock],
348+
conan_mock_api: Mock,
349+
) -> None:
350+
"""Test install method when profile operations throw exceptions but detect() works
351+
352+
Args:
353+
plugin: The plugin instance
354+
conan_temp_conanfile: Path to temporary conanfile.py
355+
conan_mock_dependencies: List of mock dependencies
356+
conan_setup_mocks: Dictionary containing all mocks
357+
conan_mock_api: Mock ConanAPI instance
358+
"""
359+
# Configure the API mock to throw exception on profile calls but detect() works
360+
conan_mock_api.profiles.get_default_host.side_effect = Exception('Profile not found')
361+
362+
# Setup dependencies
363+
plugin.core_data.cppython_data.dependencies = conan_mock_dependencies
364+
365+
# Execute - should succeed using fallback detect profiles
366+
plugin.install()
367+
368+
# Verify that the fallback was used
369+
conan_setup_mocks['conan_api_constructor'].assert_called_once()
370+
conan_mock_api.profiles.get_default_host.assert_called_once()
371+
372+
# Verify detect was called for fallback (should be called twice for fallback)
373+
assert conan_mock_api.profiles.detect.call_count >= EXPECTED_PROFILE_CALLS
374+
375+
# Verify the rest of the process continued
376+
conan_mock_api.graph.load_graph_consumer.assert_called_once()
377+
conan_mock_api.install.install_binaries.assert_called_once()
378+
conan_mock_api.install.install_consumer.assert_called_once()

0 commit comments

Comments
 (0)