Skip to content

Commit adcc1d1

Browse files
authored
Update Nested Exceptions (#118)
1 parent 178d65f commit adcc1d1

File tree

2 files changed

+60
-78
lines changed

2 files changed

+60
-78
lines changed

cppython/plugins/conan/plugin.py

Lines changed: 58 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -76,52 +76,54 @@ def _install_dependencies(self, *, update: bool = False) -> None:
7676
update: If True, check remotes for newer versions/revisions and install those.
7777
If False, use cached versions when available.
7878
"""
79+
operation = 'update' if update else 'install'
80+
7981
try:
8082
# Setup environment and generate conanfile
8183
conan_api, conanfile_path = self._prepare_installation()
84+
except Exception as e:
85+
raise ProviderInstallationError('conan', f'Failed to prepare {operation} environment: {e}', e) from e
8286

87+
try:
8388
# Load dependency graph
8489
deps_graph = self._load_dependency_graph(conan_api, conanfile_path, update)
90+
except Exception as e:
91+
raise ProviderInstallationError('conan', f'Failed to load dependency graph: {e}', e) from e
8592

93+
try:
8694
# Install dependencies
8795
self._install_binaries(conan_api, deps_graph, update)
96+
except Exception as e:
97+
raise ProviderInstallationError('conan', f'Failed to install binary dependencies: {e}', e) from e
8898

99+
try:
89100
# Generate consumer files
90101
self._generate_consumer_files(conan_api, deps_graph)
91-
92102
except Exception as e:
93-
operation = 'update' if update else 'install'
94-
raise ProviderInstallationError('conan', f'Failed to {operation} dependencies: {e}', e) from e
103+
raise ProviderInstallationError('conan', f'Failed to generate consumer files: {e}', e) from e
95104

96105
def _prepare_installation(self) -> tuple[ConanAPI, Path]:
97106
"""Prepare the installation environment and generate conanfile.
98107
99108
Returns:
100109
Tuple of (ConanAPI instance, conanfile path)
101-
102-
Raises:
103-
ProviderInstallationError: If conanfile generation or setup fails
104110
"""
105-
try:
106-
# Resolve dependencies and generate conanfile.py
107-
resolved_dependencies = [resolve_conan_dependency(req) for req in self.core_data.cppython_data.dependencies]
108-
self.builder.generate_conanfile(self.core_data.project_data.project_root, resolved_dependencies)
109-
110-
# Ensure build directory exists
111-
self.core_data.cppython_data.build_path.mkdir(parents=True, exist_ok=True)
111+
# Resolve dependencies and generate conanfile.py
112+
resolved_dependencies = [resolve_conan_dependency(req) for req in self.core_data.cppython_data.dependencies]
113+
self.builder.generate_conanfile(self.core_data.project_data.project_root, resolved_dependencies)
112114

113-
# Setup paths and API
114-
conan_api = ConanAPI()
115-
project_root = self.core_data.project_data.project_root
116-
conanfile_path = project_root / 'conanfile.py'
115+
# Ensure build directory exists
116+
self.core_data.cppython_data.build_path.mkdir(parents=True, exist_ok=True)
117117

118-
if not conanfile_path.exists():
119-
raise ProviderInstallationError('conan', 'Generated conanfile.py not found')
118+
# Setup paths and API
119+
conan_api = ConanAPI()
120+
project_root = self.core_data.project_data.project_root
121+
conanfile_path = project_root / 'conanfile.py'
120122

121-
return conan_api, conanfile_path
123+
if not conanfile_path.exists():
124+
raise FileNotFoundError('Generated conanfile.py not found')
122125

123-
except Exception as e:
124-
raise ProviderInstallationError('conan', f'Failed to prepare installation environment: {e}', e) from e
126+
return conan_api, conanfile_path
125127

126128
def _load_dependency_graph(self, conan_api: ConanAPI, conanfile_path: Path, update: bool):
127129
"""Load and build the dependency graph.
@@ -133,31 +135,24 @@ def _load_dependency_graph(self, conan_api: ConanAPI, conanfile_path: Path, upda
133135
134136
Returns:
135137
The loaded dependency graph
136-
137-
Raises:
138-
ProviderInstallationError: If dependency graph loading fails
139138
"""
140-
try:
141-
all_remotes = conan_api.remotes.list()
142-
profile_host, profile_build = self.data.host_profile, self.data.build_profile
143-
144-
return conan_api.graph.load_graph_consumer(
145-
path=str(conanfile_path),
146-
name=None,
147-
version=None,
148-
user=None,
149-
channel=None,
150-
lockfile=None,
151-
remotes=all_remotes,
152-
update=update or None,
153-
check_updates=update,
154-
is_build_require=False,
155-
profile_host=profile_host,
156-
profile_build=profile_build,
157-
)
139+
all_remotes = conan_api.remotes.list()
140+
profile_host, profile_build = self.data.host_profile, self.data.build_profile
158141

159-
except Exception as e:
160-
raise ProviderInstallationError('conan', f'Failed to load dependency graph: {e}', e) from e
142+
return conan_api.graph.load_graph_consumer(
143+
path=str(conanfile_path),
144+
name=None,
145+
version=None,
146+
user=None,
147+
channel=None,
148+
lockfile=None,
149+
remotes=all_remotes,
150+
update=update or None,
151+
check_updates=update,
152+
is_build_require=False,
153+
profile_host=profile_host,
154+
profile_build=profile_build,
155+
)
161156

162157
def _install_binaries(self, conan_api: ConanAPI, deps_graph, update: bool) -> None:
163158
"""Analyze and install binary dependencies.
@@ -166,50 +161,36 @@ def _install_binaries(self, conan_api: ConanAPI, deps_graph, update: bool) -> No
166161
conan_api: The Conan API instance
167162
deps_graph: The dependency graph
168163
update: Whether to check for updates
169-
170-
Raises:
171-
ProviderInstallationError: If binary analysis or installation fails
172164
"""
173-
try:
174-
all_remotes = conan_api.remotes.list()
175-
176-
# Analyze binaries to determine what needs to be built/downloaded
177-
conan_api.graph.analyze_binaries(
178-
graph=deps_graph,
179-
build_mode=['missing'],
180-
remotes=all_remotes,
181-
update=update or None,
182-
lockfile=None,
183-
)
165+
all_remotes = conan_api.remotes.list()
184166

185-
# Install all dependencies
186-
conan_api.install.install_binaries(deps_graph=deps_graph, remotes=all_remotes)
167+
# Analyze binaries to determine what needs to be built/downloaded
168+
conan_api.graph.analyze_binaries(
169+
graph=deps_graph,
170+
build_mode=['missing'],
171+
remotes=all_remotes,
172+
update=update or None,
173+
lockfile=None,
174+
)
187175

188-
except Exception as e:
189-
raise ProviderInstallationError('conan', f'Failed to install binary dependencies: {e}', e) from e
176+
# Install all dependencies
177+
conan_api.install.install_binaries(deps_graph=deps_graph, remotes=all_remotes)
190178

191179
def _generate_consumer_files(self, conan_api: ConanAPI, deps_graph) -> None:
192180
"""Generate consumer files (CMake toolchain, deps, etc.).
193181
194182
Args:
195183
conan_api: The Conan API instance
196184
deps_graph: The dependency graph
197-
198-
Raises:
199-
ProviderInstallationError: If consumer file generation fails
200185
"""
201-
try:
202-
project_root = self.core_data.project_data.project_root
203-
204-
conan_api.install.install_consumer(
205-
deps_graph=deps_graph,
206-
generators=['CMakeToolchain', 'CMakeDeps'],
207-
source_folder=str(project_root),
208-
output_folder=str(self.core_data.cppython_data.build_path),
209-
)
186+
project_root = self.core_data.project_data.project_root
210187

211-
except Exception as e:
212-
raise ProviderInstallationError('conan', f'Failed to generate consumer files: {e}', e) from e
188+
conan_api.install.install_consumer(
189+
deps_graph=deps_graph,
190+
generators=['CMakeToolchain', 'CMakeDeps'],
191+
source_folder=str(project_root),
192+
output_folder=str(self.core_data.cppython_data.build_path),
193+
)
213194

214195
def install(self) -> None:
215196
"""Installs the provider"""

tests/unit/plugins/conan/test_install.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,8 @@ def mock_resolve(requirement: Requirement) -> ConanDependency:
126126

127127
# Execute and verify exception is raised
128128
with pytest.raises(
129-
ProviderInstallationError, match='Failed to install dependencies: Conan API error: package not found'
129+
ProviderInstallationError,
130+
match='Failed to load dependency graph: Conan API error: package not found',
130131
):
131132
plugin.install()
132133

0 commit comments

Comments
 (0)