|
4 | 4 | import subprocess
|
5 | 5 | from distutils.errors import DistutilsSetupError
|
6 | 6 | from enum import IntEnum, auto
|
7 |
| -from typing import Dict, List, Optional, Union |
| 7 | +from typing import Any, Dict, List, NewType, Optional, Union |
8 | 8 |
|
9 | 9 | from semantic_version import SimpleSpec
|
10 | 10 | from typing_extensions import Literal
|
@@ -145,22 +145,13 @@ def __init__(
|
145 | 145 | path = os.path.relpath(path)
|
146 | 146 | self.path = path
|
147 | 147 |
|
| 148 | + self._cargo_metadata: Optional[_CargoMetadata] = None |
| 149 | + |
148 | 150 | def get_lib_name(self) -> str:
|
149 | 151 | """Parse Cargo.toml to get the name of the shared library."""
|
150 |
| - data = json.loads( |
151 |
| - subprocess.check_output( |
152 |
| - [ |
153 |
| - "cargo", |
154 |
| - "metadata", |
155 |
| - "--manifest-path", |
156 |
| - self.path, |
157 |
| - "--format-version", |
158 |
| - "1", |
159 |
| - ] |
160 |
| - ) |
161 |
| - ) |
162 |
| - root_key = data["resolve"]["root"] |
163 |
| - [pkg] = [p for p in data["packages"] if p["id"] == root_key] |
| 152 | + metadata = self._metadata() |
| 153 | + root_key = metadata["resolve"]["root"] |
| 154 | + [pkg] = [p for p in metadata["packages"] if p["id"] == root_key] |
164 | 155 | name = pkg["targets"][0]["name"]
|
165 | 156 | assert isinstance(name, str)
|
166 | 157 | return re.sub(r"[./\\-]", "_", name)
|
@@ -190,13 +181,33 @@ def install_script(self, module_name: str, exe_path: str) -> None:
|
190 | 181 | dirname, executable = os.path.split(exe_path)
|
191 | 182 | file = os.path.join(dirname, "_gen_%s.py" % module_name)
|
192 | 183 | with open(file, "w") as f:
|
193 |
| - f.write(TMPL.format(executable=repr(executable))) |
| 184 | + f.write(_TMPL.format(executable=repr(executable))) |
| 185 | + |
| 186 | + def _metadata(self) -> "_CargoMetadata": |
| 187 | + """Returns cargo metedata for this extension package. |
| 188 | +
|
| 189 | + Cached - will only execute cargo on first invocation. |
| 190 | + """ |
| 191 | + if self._cargo_metadata is None: |
| 192 | + metadata_command = [ |
| 193 | + "cargo", |
| 194 | + "metadata", |
| 195 | + "--manifest-path", |
| 196 | + self.path, |
| 197 | + "--format-version", |
| 198 | + "1", |
| 199 | + ] |
| 200 | + self._cargo_metadata = json.loads(subprocess.check_output(metadata_command)) |
| 201 | + return self._cargo_metadata |
194 | 202 |
|
195 | 203 | def _uses_exec_binding(self) -> bool:
|
196 | 204 | return self.binding == Binding.Exec
|
197 | 205 |
|
198 | 206 |
|
199 |
| -TMPL = """ |
| 207 | +_CargoMetadata = NewType("_CargoMetadata", Dict[str, Any]) |
| 208 | + |
| 209 | + |
| 210 | +_TMPL = """ |
200 | 211 | import os
|
201 | 212 | import sys
|
202 | 213 |
|
|
0 commit comments