|
12 | 12 | import requests |
13 | 13 | from conan.api.conan_api import ConanAPI |
14 | 14 | from conan.api.model import ListPattern |
| 15 | +from conan.internal.model.profile import Profile |
15 | 16 |
|
16 | 17 | from cppython.core.plugin_schema.generator import SyncConsumer |
17 | 18 | from cppython.core.plugin_schema.provider import Provider, ProviderPluginGroupData, SupportedProviderFeatures |
@@ -108,45 +109,27 @@ def _install_dependencies(self, *, update: bool = False) -> None: |
108 | 109 | all_remotes = conan_api.remotes.list() |
109 | 110 | logger.debug('Available remotes: %s', [remote.name for remote in all_remotes]) |
110 | 111 |
|
111 | | - # Get default profiles, handle case when no default profile exists |
112 | | - try: |
113 | | - profile_host_path = conan_api.profiles.get_default_host() |
114 | | - profile_build_path = conan_api.profiles.get_default_build() |
115 | | - |
116 | | - # Ensure we have valid profile paths |
117 | | - if profile_host_path is None: |
118 | | - # Create a minimal default profile if none exists |
119 | | - profile_host = conan_api.profiles.get_profile([]) |
120 | | - else: |
121 | | - profile_host = conan_api.profiles.get_profile([profile_host_path]) |
122 | | - |
123 | | - if profile_build_path is None: |
124 | | - # Create a minimal default profile if none exists |
125 | | - profile_build = conan_api.profiles.get_profile([]) |
126 | | - else: |
127 | | - profile_build = conan_api.profiles.get_profile([profile_build_path]) |
128 | | - |
129 | | - except Exception: |
130 | | - # If profile operations fail, create minimal default profiles |
131 | | - profile_host = conan_api.profiles.get_profile([]) |
132 | | - profile_build = conan_api.profiles.get_profile([]) |
133 | | - |
134 | | - logger.debug('Using profiles: host=%s, build=%s', profile_host, profile_build) |
135 | | - |
136 | | - # Build dependency graph |
| 112 | + # Get profiles with fallback to auto-detection |
| 113 | + profile_host, profile_build = self._get_profiles(conan_api) |
| 114 | + |
| 115 | + path = str(conanfile_path) |
| 116 | + remotes = all_remotes |
| 117 | + update_flag = None if not update else True |
| 118 | + check_updates_flag = update |
| 119 | + |
137 | 120 | deps_graph = conan_api.graph.load_graph_consumer( |
138 | | - path=str(conanfile_path), |
| 121 | + path=path, |
139 | 122 | name=None, |
140 | 123 | version=None, |
141 | 124 | user=None, |
142 | 125 | channel=None, |
143 | | - profile_host=profile_host, |
144 | | - profile_build=profile_build, |
145 | 126 | lockfile=None, |
146 | | - remotes=all_remotes, |
147 | | - update=None if not update else True, |
148 | | - check_updates=update, |
| 127 | + remotes=remotes, |
| 128 | + update=update_flag, |
| 129 | + check_updates=check_updates_flag, |
149 | 130 | is_build_require=False, |
| 131 | + profile_host=profile_host, |
| 132 | + profile_build=profile_build, |
150 | 133 | ) |
151 | 134 |
|
152 | 135 | logger.debug('Dependency graph loaded with %d nodes', len(deps_graph.nodes)) |
@@ -266,43 +249,26 @@ def publish(self) -> None: |
266 | 249 | remotes=all_remotes, # Use all remotes for dependency resolution during export |
267 | 250 | ) |
268 | 251 |
|
269 | | - # Step 2: Get default profiles, handle case when no default profile exists |
270 | | - try: |
271 | | - profile_host_path = conan_api.profiles.get_default_host() |
272 | | - profile_build_path = conan_api.profiles.get_default_build() |
| 252 | + # Step 2: Get profiles with fallback to auto-detection |
| 253 | + profile_host, profile_build = self._get_profiles(conan_api) |
273 | 254 |
|
274 | | - # Ensure we have valid profile paths |
275 | | - if profile_host_path is None: |
276 | | - # Create a minimal default profile if none exists |
277 | | - profile_host = conan_api.profiles.get_profile([]) |
278 | | - else: |
279 | | - profile_host = conan_api.profiles.get_profile([profile_host_path]) |
280 | | - |
281 | | - if profile_build_path is None: |
282 | | - # Create a minimal default profile if none exists |
283 | | - profile_build = conan_api.profiles.get_profile([]) |
284 | | - else: |
285 | | - profile_build = conan_api.profiles.get_profile([profile_build_path]) |
| 255 | + # Step 3: Build dependency graph for the package - prepare parameters |
| 256 | + path = str(conanfile_path) |
| 257 | + remotes = all_remotes # Use all remotes for dependency resolution |
286 | 258 |
|
287 | | - except Exception: |
288 | | - # If profile operations fail, create minimal default profiles |
289 | | - profile_host = conan_api.profiles.get_profile([]) |
290 | | - profile_build = conan_api.profiles.get_profile([]) |
291 | | - |
292 | | - # Step 3: Build dependency graph for the package |
293 | 259 | deps_graph = conan_api.graph.load_graph_consumer( |
294 | | - path=str(conanfile_path), |
| 260 | + path=path, |
295 | 261 | name=None, |
296 | 262 | version=None, |
297 | 263 | user=None, |
298 | 264 | channel=None, |
299 | | - profile_host=profile_host, |
300 | | - profile_build=profile_build, |
301 | 265 | lockfile=None, |
302 | | - remotes=all_remotes, # Use all remotes for dependency resolution |
| 266 | + remotes=remotes, |
303 | 267 | update=None, |
304 | 268 | check_updates=False, |
305 | 269 | is_build_require=False, |
| 270 | + profile_host=profile_host, |
| 271 | + profile_build=profile_build, |
306 | 272 | ) |
307 | 273 |
|
308 | 274 | # Step 4: Analyze binaries and install/build them if needed |
@@ -339,3 +305,68 @@ def publish(self) -> None: |
339 | 305 | ) |
340 | 306 | else: |
341 | 307 | raise ProviderInstallationError('conan', 'No packages found to upload') |
| 308 | + |
| 309 | + def _apply_profile_processing(self, profiles: list[Profile], conan_api: ConanAPI, cache_settings: Any) -> None: |
| 310 | + """Apply profile plugin and settings processing to a list of profiles. |
| 311 | +
|
| 312 | + Args: |
| 313 | + profiles: List of profiles to process |
| 314 | + conan_api: The Conan API instance |
| 315 | + cache_settings: The settings configuration |
| 316 | + """ |
| 317 | + logger = logging.getLogger('cppython.conan') |
| 318 | + |
| 319 | + # Apply profile plugin processing |
| 320 | + try: |
| 321 | + profile_plugin = conan_api.profiles._load_profile_plugin() |
| 322 | + if profile_plugin is not None: |
| 323 | + for profile in profiles: |
| 324 | + try: |
| 325 | + profile_plugin(profile) |
| 326 | + except Exception as plugin_error: |
| 327 | + logger.warning('Profile plugin failed for profile: %s', str(plugin_error)) |
| 328 | + except (AttributeError, Exception): |
| 329 | + logger.debug('Profile plugin not available or failed to load') |
| 330 | + |
| 331 | + # Process settings to initialize processed_settings |
| 332 | + for profile in profiles: |
| 333 | + try: |
| 334 | + profile.process_settings(cache_settings) |
| 335 | + except (AttributeError, Exception) as settings_error: |
| 336 | + logger.debug('Settings processing failed for profile: %s', str(settings_error)) |
| 337 | + |
| 338 | + def _get_profiles(self, conan_api: ConanAPI) -> tuple[Profile, Profile]: |
| 339 | + """Get Conan profiles with fallback to auto-detection. |
| 340 | +
|
| 341 | + Args: |
| 342 | + conan_api: The Conan API instance |
| 343 | +
|
| 344 | + Returns: |
| 345 | + A tuple of (profile_host, profile_build) objects |
| 346 | + """ |
| 347 | + logger = logging.getLogger('cppython.conan') |
| 348 | + |
| 349 | + try: |
| 350 | + # Gather default profile paths, these can raise exceptions if not available |
| 351 | + profile_host_path = conan_api.profiles.get_default_host() |
| 352 | + profile_build_path = conan_api.profiles.get_default_build() |
| 353 | + |
| 354 | + # Load the actual profile objects, can raise if data is invalid |
| 355 | + profile_host = conan_api.profiles.get_profile([profile_host_path]) |
| 356 | + profile_build = conan_api.profiles.get_profile([profile_build_path]) |
| 357 | + |
| 358 | + logger.debug('Using existing default profiles') |
| 359 | + return profile_host, profile_build |
| 360 | + |
| 361 | + except Exception as e: |
| 362 | + logger.warning('Default profiles not available, using auto-detection. Conan message: %s', str(e)) |
| 363 | + |
| 364 | + # Create auto-detected profiles |
| 365 | + profiles = [conan_api.profiles.detect(), conan_api.profiles.detect()] |
| 366 | + cache_settings = conan_api.config.settings_yml |
| 367 | + |
| 368 | + # Apply profile plugin processing to both profiles |
| 369 | + self._apply_profile_processing(profiles, conan_api, cache_settings) |
| 370 | + |
| 371 | + logger.debug('Auto-detected profiles with plugin processing applied') |
| 372 | + return profiles[0], profiles[1] |
0 commit comments