@@ -43,9 +43,10 @@ def fixup_meson_varname(name: str) -> str:
43
43
return name .replace ('-' , '_' )
44
44
45
45
46
- def _raw_to_dataclass (raw : T .Dict [str , T .Any ], cls : T .Type [_DI ], msg : str , ** kwargs : T .Callable [[T .Any ], object ]) -> _DI :
46
+ def _raw_to_dataclass (raw : T .Dict [str , T .Any ], cls : T .Type [_DI ], msg : str , raw_from_workspace : T . Optional [ T . Dict [ str , T . Any ]] = None , ** kwargs : T .Callable [[T .Any ], object ]) -> _DI :
47
47
"""Convert and validate raw cargo mappings to a Python dataclass.
48
48
49
+ * Inherit values from the workspace.
49
50
* Replaces any `-` with `_` in the keys.
50
51
* Remove and warn on keys that are coming from cargo, but are unknown to
51
52
our representations.
@@ -59,7 +60,13 @@ def _raw_to_dataclass(raw: T.Dict[str, T.Any], cls: T.Type[_DI], msg: str, **kwa
59
60
unexpected : T .Set [str ] = set ()
60
61
known = {x .name for x in dataclasses .fields (cls )}
61
62
result : T .Dict [str , T .Any ] = {}
63
+ if raw .get ('workspace' , False ):
64
+ del raw ['workspace' ]
65
+ for k , v in raw_from_workspace .items ():
66
+ raw .setdefault (k , v )
62
67
for k , v in raw .items ():
68
+ if isinstance (v , dict ) and v .get ('workspace' , False ):
69
+ v = raw_from_workspace [k ]
63
70
k = fixup_meson_varname (k )
64
71
if k not in known :
65
72
unexpected .add (k )
@@ -113,8 +120,9 @@ def api(self) -> str:
113
120
return version .api (self .version )
114
121
115
122
@classmethod
116
- def from_raw (cls , raw : T .Dict [str , T .Any ]) -> Self :
117
- return _raw_to_dataclass (raw , cls , f'Package entry { raw ["name" ]} ' )
123
+ def from_raw (cls , raw : T .Dict [str , T .Any ], workspace : T .Optional [Workspace ] = None ) -> Self :
124
+ raw_from_workspace = workspace .package if workspace else None
125
+ return _raw_to_dataclass (raw , cls , f'Package entry { raw ["name" ]} ' , raw_from_workspace )
118
126
119
127
@dataclasses .dataclass
120
128
class SystemDependency :
@@ -195,12 +203,20 @@ def meson_version(self) -> T.List[str]:
195
203
return version .convert (self .version ) if self .version else []
196
204
197
205
@classmethod
198
- def from_raw (cls , name : str , raw : T .Union [T .Dict [str , T .Any ], str ]) -> Dependency :
206
+ def from_raw (cls , name : str , raw : T .Union [T .Dict [str , T .Any ], str ], workspace : T . Optional [ Workspace ] = None , member_path : str = '' ) -> Dependency :
199
207
"""Create a dependency from a raw cargo dictionary"""
200
208
if isinstance (raw , str ):
201
209
return cls (name , raw )
210
+ raw_from_workspace = workspace .dependencies .get (name ) if workspace else None
211
+ if raw_from_workspace is not None :
212
+ name = raw_from_workspace .get ('package' , name )
213
+ if 'features' in raw :
214
+ raw ['features' ] += raw_from_workspace .get ('features' , [])
215
+ if 'path' in raw_from_workspace :
216
+ raw_from_workspace = raw_from_workspace .copy ()
217
+ raw_from_workspace ['path' ] = os .path .relpath (raw_from_workspace ['path' ], member_path )
202
218
raw .setdefault ('package' , name )
203
- return _raw_to_dataclass (raw , cls , f'Dependency entry { name } ' )
219
+ return _raw_to_dataclass (raw , cls , f'Dependency entry { name } ' , raw_from_workspace )
204
220
205
221
206
222
@dataclasses .dataclass
@@ -322,13 +338,15 @@ def system_dependencies(self) -> T.Dict[str, SystemDependency]:
322
338
return {k : SystemDependency .from_raw (k , v ) for k , v in self .package .metadata .get ('system-deps' , {}).items ()}
323
339
324
340
@classmethod
325
- def from_raw (cls , raw : T .Dict [str , T .Any ]) -> Manifest :
341
+ def from_raw (cls , raw : T .Dict [str , T .Any ], workspace : T . Optional [ Workspace ] = None , member_path : str = '' ) -> Manifest :
326
342
name = raw ['package' ]['name' ]
327
343
raw .setdefault ('lib' , {'name' : name })
344
+
328
345
def dependencies_from_raw (x : T .Dict [str , T .Any ]) -> T .Dict [str , Dependency ]:
329
- return {k : Dependency .from_raw (k , v ) for k , v in x .items ()}
346
+ return {k : Dependency .from_raw (k , v , workspace , member_path ) for k , v in x .items ()}
347
+
330
348
return _raw_to_dataclass (raw , cls , f'Manifest { name } ' ,
331
- package = lambda x : Package .from_raw (x ),
349
+ package = lambda x : Package .from_raw (x , workspace ),
332
350
dependencies = dependencies_from_raw ,
333
351
dev_dependencies = dependencies_from_raw ,
334
352
build_dependencies = dependencies_from_raw ,
@@ -340,6 +358,46 @@ def dependencies_from_raw(x: T.Dict[str, T.Any]) -> T.Dict[str, Dependency]:
340
358
target = lambda x : {k : dependencies_from_raw (v .get ('dependencies' , {})) for k , v in x .items ()})
341
359
342
360
361
+ @dataclasses .dataclass
362
+ class Workspace :
363
+
364
+ """Cargo Workspace definition.
365
+ """
366
+
367
+ resolver : str = '2'
368
+ members : T .List [str ] = dataclasses .field (default_factory = list )
369
+ exclude : T .List [str ] = dataclasses .field (default_factory = list )
370
+ default_members : T .List [str ] = dataclasses .field (default_factory = list )
371
+ package : T .Dict [str , T .Any ] = dataclasses .field (default_factory = dict )
372
+ dependencies : T .Dict [str , T .Dict [str , T .Any ]] = dataclasses .field (default_factory = dict )
373
+ lints : T .Dict [str , T .Any ] = dataclasses .field (default_factory = dict )
374
+ metadata : T .Dict [str , T .Any ] = dataclasses .field (default_factory = dict )
375
+
376
+ root_package : T .Optional [Manifest ] = None
377
+
378
+ @classmethod
379
+ def from_raw (cls , raw : T .Dict [str , T .Any ]) -> Workspace :
380
+ extra_members : T .List [str ] = []
381
+
382
+ def dependency_from_raw (x : T .Dict [str , T .Any ]) -> T .Dict [str , T .Any ]:
383
+ if isinstance (x , str ):
384
+ return {'version' : x }
385
+ path = x .get ('path' )
386
+ if path :
387
+ extra_members .append (path )
388
+ return x
389
+
390
+ ws = _raw_to_dataclass (raw ['workspace' ], cls , 'Workspace' ,
391
+ dependencies = lambda x : {k : dependency_from_raw (v ) for k , v in x .items ()})
392
+ ws .members .extend (extra_members )
393
+
394
+ if 'package' in raw :
395
+ del raw ['workspace' ]
396
+ ws .root_package = Manifest .from_raw (raw , ws , member_path = '.' )
397
+
398
+ return ws
399
+
400
+
343
401
@dataclasses .dataclass
344
402
class CargoLockPackage :
345
403
0 commit comments