summaryrefslogtreecommitdiff
path: root/mesonbuild/cargo
diff options
context:
space:
mode:
authorXavier Claessens <xclaessens@netflix.com>2025-10-16 17:48:02 -0400
committerXavier Claessens <xclaesse@gmail.com>2025-10-17 16:15:14 -0400
commitd6eca52d79f01a9ebe06c78c8577cb65311da043 (patch)
tree0d0bf7ec80afede9f813cf7e02bbf128b15c6539 /mesonbuild/cargo
parent87a367c406e67d38df0946e2d780fbdf715e437a (diff)
downloadmeson-d6eca52d79f01a9ebe06c78c8577cb65311da043.tar.gz
cargo: raw.Manifest can be any Cargo.toml
raw.Manifest represents any Cargo.toml file, a package, a workspace, or both. However, the Manifest dataclass can only be a package, and the Workspace dataclass is a workspace with an optional root package.
Diffstat (limited to 'mesonbuild/cargo')
-rw-r--r--mesonbuild/cargo/interpreter.py20
-rw-r--r--mesonbuild/cargo/manifest.py11
-rw-r--r--mesonbuild/cargo/raw.py13
3 files changed, 12 insertions, 32 deletions
diff --git a/mesonbuild/cargo/interpreter.py b/mesonbuild/cargo/interpreter.py
index c763483dd..818e8640b 100644
--- a/mesonbuild/cargo/interpreter.py
+++ b/mesonbuild/cargo/interpreter.py
@@ -304,23 +304,13 @@ class Interpreter:
path = os.path.join(self.environment.source_dir, subdir)
filename = os.path.join(path, 'Cargo.toml')
self.build_def_files.append(filename)
- toml = load_toml(filename)
- workspace_ = None
- if 'workspace' in toml:
- raw_workspace = T.cast('raw.VirtualManifest', toml)
- workspace_ = Workspace.from_raw(raw_workspace)
- manifest_ = None
- if 'package' in toml:
- raw_manifest = T.cast('raw.Manifest', toml)
+ raw_manifest = T.cast('raw.Manifest', load_toml(filename))
+ if 'workspace' in raw_manifest:
+ manifest_ = Workspace.from_raw(raw_manifest, path)
+ elif 'package' in raw_manifest:
manifest_ = Manifest.from_raw(raw_manifest, path, workspace, member_path)
- if not manifest_ and not workspace_:
+ else:
raise MesonException(f'{subdir}/Cargo.toml does not have [package] or [workspace] section')
-
- if workspace_:
- workspace_.root_package = manifest_
- self.manifests[subdir] = workspace_
- return workspace_
-
self.manifests[subdir] = manifest_
return manifest_
diff --git a/mesonbuild/cargo/manifest.py b/mesonbuild/cargo/manifest.py
index d3d036769..9dadcd8a7 100644
--- a/mesonbuild/cargo/manifest.py
+++ b/mesonbuild/cargo/manifest.py
@@ -481,13 +481,14 @@ class Workspace:
metadata: T.Dict[str, T.Any] = dataclasses.field(default_factory=dict)
# A workspace can also have a root package.
- root_package: T.Optional[Manifest] = dataclasses.field(init=False)
+ root_package: T.Optional[Manifest] = None
@classmethod
- def from_raw(cls, raw: raw.VirtualManifest) -> Workspace:
- ws_raw = raw['workspace']
- fixed = _raw_to_dataclass(ws_raw, cls, 'Workspace')
- return fixed
+ def from_raw(cls, raw: raw.Manifest, path: str) -> Workspace:
+ ws = _raw_to_dataclass(raw['workspace'], cls, 'Workspace')
+ if 'package' in raw:
+ ws.root_package = Manifest.from_raw(raw, path, ws, '.')
+ return ws
@dataclasses.dataclass
diff --git a/mesonbuild/cargo/raw.py b/mesonbuild/cargo/raw.py
index 67dd58a9f..801f9a568 100644
--- a/mesonbuild/cargo/raw.py
+++ b/mesonbuild/cargo/raw.py
@@ -140,7 +140,7 @@ class Workspace(TypedDict):
Manifest = TypedDict(
'Manifest',
{
- 'package': Required[Package],
+ 'package': Package,
'badges': T.Dict[str, Badge],
'dependencies': T.Dict[str, T.Union[FromWorkspace, DependencyV]],
'dev-dependencies': T.Dict[str, T.Union[FromWorkspace, DependencyV]],
@@ -162,17 +162,6 @@ Manifest = TypedDict(
"""The Cargo Manifest format."""
-class VirtualManifest(TypedDict, total=False):
-
- """The Representation of a virtual manifest.
-
- Cargo allows a root manifest that contains only a workspace, this is called
- a virtual manifest. This doesn't really map 1:1 with any meson concept,
- except perhaps the proposed "meta project".
- """
-
- workspace: Workspace
-
class CargoLockPackage(TypedDict, total=False):
"""A description of a package in the Cargo.lock file format."""