@@ -86,28 +86,27 @@ def _cargo_config(project_dir: pathlib.Path) -> None:
86
86
tomlkit .dump (cfg , f )
87
87
88
88
89
- def _should_vendor_rust (req : Requirement , project_dir : pathlib .Path ) -> bool :
89
+ def _detect_rust_build_backend (
90
+ req : Requirement , pyproject_toml : dict [str , typing .Any ]
91
+ ) -> str | None :
90
92
"""Detect if project has build requirement on Rust
91
93
92
94
Detects setuptools-rust and maturin.
93
95
"""
94
- pyproject_toml = dependencies .get_pyproject_contents (project_dir )
95
- if not pyproject_toml :
96
- logger .debug (f"{ req .name } : has no pyproject.toml" )
97
- return False
98
-
99
96
build_backend = dependencies .get_build_backend (pyproject_toml )
97
+ if build_backend ["build-backend" ] == "maturin" :
98
+ return "maturin"
100
99
101
100
for reqstring in build_backend ["requires" ]:
102
101
req = Requirement (reqstring )
103
102
if req .name in RUST_BUILD_REQUIRES :
104
103
logger .debug (
105
- f"{ req .name } : build-system requires { req .name } , vendoring crates"
104
+ f"{ req .name } : build-system requires ' { req .name } ' , vendoring crates"
106
105
)
107
- return True
106
+ return req . name
108
107
109
108
logger .debug (f"{ req .name } : no Rust build plugin detected" )
110
- return False
109
+ return None
111
110
112
111
113
112
def vendor_rust (
@@ -119,11 +118,42 @@ def vendor_rust(
119
118
``setuptools-rust`` or ``maturin``, and has a ``Cargo.toml``, otherwise
120
119
``False``.
121
120
"""
122
- if not _should_vendor_rust (req , project_dir ):
121
+ pyproject_toml = dependencies .get_pyproject_contents (project_dir )
122
+ if not pyproject_toml :
123
+ logger .debug (f"{ req .name } : has no pyproject.toml" )
123
124
return False
124
125
125
- # check for Cargo.toml
126
- manifests = list (project_dir .glob ("**/Cargo.toml" ))
126
+ backend = _detect_rust_build_backend (req , pyproject_toml )
127
+ if backend is None :
128
+ return False
129
+
130
+ manifests : list [pathlib .Path ] = []
131
+ # check for Cargo.toml in project root
132
+ root_cargo_toml = project_dir / "Cargo.toml"
133
+ if root_cargo_toml .is_file ():
134
+ manifests .append (root_cargo_toml )
135
+
136
+ # maturin and setuptools-rust can have Cargo.toml in other directories.
137
+ # tool.setuptools-rust and tool.maturin are optional.
138
+ if backend == "maturin" :
139
+ try :
140
+ tool_maturin : dict [str , typing .Any ] = pyproject_toml ["tool" ]["maturin" ]
141
+ except KeyError as e :
142
+ logger .debug (f"{ req .name } : No additional maturin settings: { e } " )
143
+ else :
144
+ if "manifest-path" in tool_maturin :
145
+ manifests .append (project_dir / tool_maturin ["manifest-path" ])
146
+ elif backend == "setuptools-rust" :
147
+ ext_modules : list [dict [str , typing .Any ]]
148
+ try :
149
+ ext_modules = pyproject_toml ["tool" ]["setuptools-rust" ]["ext-modules" ]
150
+ except KeyError as e :
151
+ logger .debug (f"{ req .name } : No additional setuptools-rust settings: { e } " )
152
+ else :
153
+ for ext_module in ext_modules :
154
+ if "path" in ext_module :
155
+ manifests .append (project_dir / ext_module ["path" ])
156
+
127
157
if not manifests :
128
158
logger .debug (f"{ req .name } : has no Cargo.toml files" )
129
159
return False
0 commit comments