1
1
"""Defines the data and routines for building a CPPython project type"""
2
2
3
3
import logging
4
- from importlib import metadata
4
+ from importlib . metadata import entry_points
5
5
from inspect import getmodule
6
6
from logging import Logger
7
7
from typing import Any
8
8
9
- from cppython_core .exceptions import PluginError
10
- from cppython_core .plugin_schema .generator import Generator
11
- from cppython_core .plugin_schema .provider import Provider
12
- from cppython_core .plugin_schema .scm import SCM
13
- from cppython_core .resolution import (
9
+ from cppython .core .plugin_schema .generator import Generator
10
+ from cppython .core .plugin_schema .provider import Provider
11
+ from cppython .core .plugin_schema .scm import SCM
12
+ from cppython .core .resolution import (
14
13
PluginBuildData ,
15
14
PluginCPPythonData ,
16
15
resolve_cppython ,
21
20
resolve_provider ,
22
21
resolve_scm ,
23
22
)
24
- from cppython_core .schema import (
23
+ from cppython . core .schema import (
25
24
CoreData ,
26
25
CorePluginData ,
27
26
CPPythonGlobalConfiguration ,
32
31
ProjectConfiguration ,
33
32
ProjectData ,
34
33
)
35
-
36
34
from cppython .data import Data , Plugins
35
+ from cppython .defaults import DefaultSCM
36
+ from cppython .utility .exception import PluginError
37
37
38
38
39
39
class Resolver :
40
40
"""The resolution of data sources for the builder"""
41
41
42
42
def __init__ (self , project_configuration : ProjectConfiguration , logger : Logger ) -> None :
43
-
43
+ """Initializes the resolver"""
44
44
self ._project_configuration = project_configuration
45
45
self ._logger = logger
46
46
@@ -56,19 +56,18 @@ def generate_plugins(
56
56
Returns:
57
57
The resolved plugin data
58
58
"""
59
-
60
59
raw_generator_plugins = self .find_generators ()
61
60
generator_plugins = self .filter_plugins (
62
61
raw_generator_plugins ,
63
62
cppython_local_configuration .generator_name ,
64
- " Generator" ,
63
+ ' Generator' ,
65
64
)
66
65
67
66
raw_provider_plugins = self .find_providers ()
68
67
provider_plugins = self .filter_plugins (
69
68
raw_provider_plugins ,
70
69
cppython_local_configuration .provider_name ,
71
- " Provider" ,
70
+ ' Provider' ,
72
71
)
73
72
74
73
scm_plugins = self .find_source_managers ()
@@ -80,7 +79,8 @@ def generate_plugins(
80
79
81
80
return PluginBuildData (generator_type = generator_type , provider_type = provider_type , scm_type = scm_type )
82
81
83
- def generate_cppython_plugin_data (self , plugin_build_data : PluginBuildData ) -> PluginCPPythonData :
82
+ @staticmethod
83
+ def generate_cppython_plugin_data (plugin_build_data : PluginBuildData ) -> PluginCPPythonData :
84
84
"""Generates the CPPython plugin data from the resolved plugins
85
85
86
86
Args:
@@ -89,15 +89,15 @@ def generate_cppython_plugin_data(self, plugin_build_data: PluginBuildData) -> P
89
89
Returns:
90
90
The plugin data used by CPPython
91
91
"""
92
-
93
92
return PluginCPPythonData (
94
93
generator_name = plugin_build_data .generator_type .name (),
95
94
provider_name = plugin_build_data .provider_type .name (),
96
95
scm_name = plugin_build_data .scm_type .name (),
97
96
)
98
97
98
+ @staticmethod
99
99
def generate_pep621_data (
100
- self , pep621_configuration : PEP621Configuration , project_configuration : ProjectConfiguration , scm : SCM | None
100
+ pep621_configuration : PEP621Configuration , project_configuration : ProjectConfiguration , scm : SCM | None
101
101
) -> PEP621Data :
102
102
"""Generates the PEP621 data from configuration sources
103
103
@@ -111,13 +111,13 @@ def generate_pep621_data(
111
111
"""
112
112
return resolve_pep621 (pep621_configuration , project_configuration , scm )
113
113
114
- def resolve_global_config (self ) -> CPPythonGlobalConfiguration :
114
+ @staticmethod
115
+ def resolve_global_config () -> CPPythonGlobalConfiguration :
115
116
"""Generates the global configuration object
116
117
117
118
Returns:
118
119
The global configuration object
119
120
"""
120
-
121
121
return CPPythonGlobalConfiguration ()
122
122
123
123
def find_generators (self ) -> list [type [Generator ]]:
@@ -129,24 +129,23 @@ def find_generators(self) -> list[type[Generator]]:
129
129
Returns:
130
130
The list of generator plugin types
131
131
"""
132
-
133
- group_name = "generator"
132
+ group_name = 'generator'
134
133
plugin_types : list [type [Generator ]] = []
135
134
136
135
# Filter entries by type
137
- for entry_point in list (metadata . entry_points (group = f" cppython.{ group_name } " )):
136
+ for entry_point in list (entry_points (group = f' cppython.{ group_name } ' )):
138
137
loaded_type = entry_point .load ()
139
138
if not issubclass (loaded_type , Generator ):
140
139
self ._logger .warning (
141
140
f"Found incompatible plugin. The '{ loaded_type .name ()} ' plugin must be an instance of"
142
141
f" '{ group_name } '"
143
142
)
144
143
else :
145
- self ._logger .warning (f" { group_name } plugin found: { loaded_type .name ()} from { getmodule (loaded_type )} " )
144
+ self ._logger .warning (f' { group_name } plugin found: { loaded_type .name ()} from { getmodule (loaded_type )} ' )
146
145
plugin_types .append (loaded_type )
147
146
148
147
if not plugin_types :
149
- raise PluginError (f" No { group_name } plugin was found" )
148
+ raise PluginError (f' No { group_name } plugin was found' )
150
149
151
150
return plugin_types
152
151
@@ -159,24 +158,23 @@ def find_providers(self) -> list[type[Provider]]:
159
158
Returns:
160
159
The list of provider plugin types
161
160
"""
162
-
163
- group_name = "provider"
161
+ group_name = 'provider'
164
162
plugin_types : list [type [Provider ]] = []
165
163
166
164
# Filter entries by type
167
- for entry_point in list (metadata . entry_points (group = f" cppython.{ group_name } " )):
165
+ for entry_point in list (entry_points (group = f' cppython.{ group_name } ' )):
168
166
loaded_type = entry_point .load ()
169
167
if not issubclass (loaded_type , Provider ):
170
168
self ._logger .warning (
171
169
f"Found incompatible plugin. The '{ loaded_type .name ()} ' plugin must be an instance of"
172
170
f" '{ group_name } '"
173
171
)
174
172
else :
175
- self ._logger .warning (f" { group_name } plugin found: { loaded_type .name ()} from { getmodule (loaded_type )} " )
173
+ self ._logger .warning (f' { group_name } plugin found: { loaded_type .name ()} from { getmodule (loaded_type )} ' )
176
174
plugin_types .append (loaded_type )
177
175
178
176
if not plugin_types :
179
- raise PluginError (f" No { group_name } plugin was found" )
177
+ raise PluginError (f' No { group_name } plugin was found' )
180
178
181
179
return plugin_types
182
180
@@ -189,30 +187,29 @@ def find_source_managers(self) -> list[type[SCM]]:
189
187
Returns:
190
188
The list of source control manager plugin types
191
189
"""
192
-
193
- group_name = "scm"
190
+ group_name = 'scm'
194
191
plugin_types : list [type [SCM ]] = []
195
192
196
193
# Filter entries by type
197
- for entry_point in list (metadata . entry_points (group = f" cppython.{ group_name } " )):
194
+ for entry_point in list (entry_points (group = f' cppython.{ group_name } ' )):
198
195
loaded_type = entry_point .load ()
199
196
if not issubclass (loaded_type , SCM ):
200
197
self ._logger .warning (
201
198
f"Found incompatible plugin. The '{ loaded_type .name ()} ' plugin must be an instance of"
202
199
f" '{ group_name } '"
203
200
)
204
201
else :
205
- self ._logger .warning (f" { group_name } plugin found: { loaded_type .name ()} from { getmodule (loaded_type )} " )
202
+ self ._logger .warning (f' { group_name } plugin found: { loaded_type .name ()} from { getmodule (loaded_type )} ' )
206
203
plugin_types .append (loaded_type )
207
204
208
205
if not plugin_types :
209
- raise PluginError (f" No { group_name } plugin was found" )
206
+ raise PluginError (f' No { group_name } plugin was found' )
210
207
211
208
return plugin_types
212
209
213
- def filter_plugins [
214
- T : DataPlugin
215
- ]( self , plugin_types : list [ type [ T ]], pinned_name : str | None , group_name : str ) -> list [type [T ]]:
210
+ def filter_plugins [T : DataPlugin ](
211
+ self , plugin_types : list [ type [ T ]], pinned_name : str | None , group_name : str
212
+ ) -> list [type [T ]]:
216
213
"""Finds and filters data plugins
217
214
218
215
Args:
@@ -226,13 +223,12 @@ def filter_plugins[
226
223
Returns:
227
224
The list of applicable plugins
228
225
"""
229
-
230
226
# Lookup the requested plugin if given
231
227
if pinned_name is not None :
232
228
for loaded_type in plugin_types :
233
229
if loaded_type .name () == pinned_name :
234
230
self ._logger .warning (
235
- f" Using { group_name } plugin: { loaded_type .name ()} from { getmodule (loaded_type )} "
231
+ f' Using { group_name } plugin: { loaded_type .name ()} from { getmodule (loaded_type )} '
236
232
)
237
233
return [loaded_type ]
238
234
@@ -243,13 +239,13 @@ def filter_plugins[
243
239
# Deduce types
244
240
for loaded_type in plugin_types :
245
241
self ._logger .warning (
246
- f" A { group_name } plugin is supported: { loaded_type .name ()} from { getmodule (loaded_type )} "
242
+ f' A { group_name } plugin is supported: { loaded_type .name ()} from { getmodule (loaded_type )} '
247
243
)
248
244
supported_types .append (loaded_type )
249
245
250
246
# Fail
251
247
if supported_types is None :
252
- raise PluginError (f" No { group_name } could be deduced from the root directory." )
248
+ raise PluginError (f' No { group_name } could be deduced from the root directory.' )
253
249
254
250
return supported_types
255
251
@@ -260,21 +256,20 @@ def select_scm(self, scm_plugins: list[type[SCM]], project_data: ProjectData) ->
260
256
scm_plugins: The list of SCM plugin types
261
257
project_data: The project data
262
258
263
- Raises:
264
- PluginError: Raised if no SCM plugin was found that supports the given data
265
-
266
259
Returns:
267
260
The selected SCM plugin type
268
261
"""
269
-
270
262
for scm_type in scm_plugins :
271
263
if scm_type .features (project_data .pyproject_file .parent ).repository :
272
264
return scm_type
273
265
274
- raise PluginError ("No SCM plugin was found that supports the given path" )
266
+ self ._logger .info ('No SCM plugin was found that supports the given path' )
267
+
268
+ return DefaultSCM
275
269
270
+ @staticmethod
276
271
def solve (
277
- self , generator_types : list [type [Generator ]], provider_types : list [type [Provider ]]
272
+ generator_types : list [type [Generator ]], provider_types : list [type [Provider ]]
278
273
) -> tuple [type [Generator ], type [Provider ]]:
279
274
"""Selects the first generator and provider that can work together
280
275
@@ -288,7 +283,6 @@ def solve(
288
283
Returns:
289
284
A tuple of the selected generator and provider plugin types
290
285
"""
291
-
292
286
combos : list [tuple [type [Generator ], type [Provider ]]] = []
293
287
294
288
for generator_type in generator_types :
@@ -300,12 +294,12 @@ def solve(
300
294
break
301
295
302
296
if not combos :
303
- raise PluginError (" No provider that supports a given generator could be deduced" )
297
+ raise PluginError (' No provider that supports a given generator could be deduced' )
304
298
305
299
return combos [0 ]
306
300
301
+ @staticmethod
307
302
def create_scm (
308
- self ,
309
303
core_data : CoreData ,
310
304
scm_type : type [SCM ],
311
305
) -> SCM :
@@ -318,7 +312,6 @@ def create_scm(
318
312
Returns:
319
313
The constructed source control manager
320
314
"""
321
-
322
315
cppython_plugin_data = resolve_cppython_plugin (core_data .cppython_data , scm_type )
323
316
scm_data = resolve_scm (core_data .project_data , cppython_plugin_data )
324
317
@@ -344,7 +337,6 @@ def create_generator(
344
337
Returns:
345
338
The constructed generator
346
339
"""
347
-
348
340
cppython_plugin_data = resolve_cppython_plugin (core_data .cppython_data , generator_type )
349
341
350
342
generator_data = resolve_generator (core_data .project_data , cppython_plugin_data )
@@ -380,7 +372,6 @@ def create_provider(
380
372
Returns:
381
373
A constructed provider plugins
382
374
"""
383
-
384
375
cppython_plugin_data = resolve_cppython_plugin (core_data .cppython_data , provider_type )
385
376
386
377
provider_data = resolve_provider (core_data .project_data , cppython_plugin_data )
@@ -403,6 +394,7 @@ class Builder:
403
394
"""Helper class for building CPPython projects"""
404
395
405
396
def __init__ (self , project_configuration : ProjectConfiguration , logger : Logger ) -> None :
397
+ """Initializes the builder"""
406
398
self ._project_configuration = project_configuration
407
399
self ._logger = logger
408
400
@@ -413,7 +405,7 @@ def __init__(self, project_configuration: ProjectConfiguration, logger: Logger)
413
405
self ._logger .addHandler (logging .StreamHandler ())
414
406
self ._logger .setLevel (levels [project_configuration .verbosity ])
415
407
416
- self ._logger .info (" Logging setup complete" )
408
+ self ._logger .info (' Logging setup complete' )
417
409
418
410
self ._resolver = Resolver (self ._project_configuration , self ._logger )
419
411
@@ -428,12 +420,12 @@ def build(
428
420
Args:
429
421
pep621_configuration: The PEP621 configuration
430
422
cppython_local_configuration: The local configuration
431
- plugin_build_data: Plugin override data. If it exists, the build will use the given types instead of resolving them
423
+ plugin_build_data: Plugin override data. If it exists, the build will use the given types
424
+ instead of resolving them
432
425
433
426
Returns:
434
427
The built data object
435
428
"""
436
-
437
429
project_data = resolve_project_configuration (self ._project_configuration )
438
430
439
431
if plugin_build_data is None :
0 commit comments