|
6 | 6 | import hashlib |
7 | 7 | import io |
8 | 8 | import os |
| 9 | +import shutil |
9 | 10 | from argparse import ArgumentParser |
10 | 11 |
|
11 | 12 | from pex import scie, specifier_sets |
|
26 | 27 | from pex.util import CacheHelper |
27 | 28 |
|
28 | 29 | if TYPE_CHECKING: |
29 | | - from typing import Optional, Union |
| 30 | + from typing import Optional, Tuple, Union |
30 | 31 |
|
31 | 32 | import attr # vendor:skip |
32 | 33 | else: |
@@ -188,6 +189,30 @@ def _fetch( |
188 | 189 | return dest |
189 | 190 |
|
190 | 191 |
|
| 192 | +def _extract_pex_info(path): |
| 193 | + # type: (str) -> Union[Tuple[str, PexInfo], Error] |
| 194 | + |
| 195 | + pex_info_or_error = catch(PexInfo.from_pex, path) |
| 196 | + if isinstance(pex_info_or_error, Error): |
| 197 | + return Error( |
| 198 | + "The path {path} does not appear to be a PEX: {err}".format( |
| 199 | + path=path, err=pex_info_or_error |
| 200 | + ) |
| 201 | + ) |
| 202 | + |
| 203 | + raw_pex_version = pex_info_or_error.build_properties.get("pex_version") |
| 204 | + if raw_pex_version and Version(raw_pex_version) < Version("2.1.25"): |
| 205 | + return Error( |
| 206 | + "Can only create scies from PEXes built by Pex 2.1.25 (which was released on " |
| 207 | + "January 21st, 2021) or newer.\n" |
| 208 | + "The PEX at {path} was built by Pex {pex_version}.".format( |
| 209 | + path=path, pex_version=raw_pex_version |
| 210 | + ) |
| 211 | + ) |
| 212 | + |
| 213 | + return path, pex_info_or_error |
| 214 | + |
| 215 | + |
191 | 216 | class Scie(OutputMixin, BuildTimeCommand): |
192 | 217 | """Manipulate scies.""" |
193 | 218 |
|
@@ -240,40 +265,38 @@ def _create(self): |
240 | 265 |
|
241 | 266 | resolver_configuration = resolver_options.configure(self.options) |
242 | 267 | if os.path.exists(self.options.pex[0]): |
243 | | - pex_file = self.options.pex[0] |
244 | | - else: |
245 | | - pex_file = try_( |
246 | | - _fetch( |
247 | | - url=ArtifactURL.parse(self.options.pex[0]), |
248 | | - fetcher=URLFetcher( |
249 | | - network_configuration=resolver_configuration.network_configuration, |
250 | | - handle_file_urls=True, |
251 | | - password_entries=resolver_configuration.repos_configuration.password_entries, |
252 | | - ), |
253 | | - dest_dir=self.options.dest_dir, |
254 | | - ) |
255 | | - ) |
256 | | - |
257 | | - pex_info_or_error = catch(PexInfo.from_pex, pex_file) |
258 | | - if isinstance(pex_info_or_error, Error): |
259 | | - return Error( |
260 | | - "The path {pex_file} does not appear to be a PEX: {err}".format( |
261 | | - pex_file=pex_file, err=pex_info_or_error |
| 268 | + pex_file, pex_info = try_(_extract_pex_info(self.options.pex[0])) |
| 269 | + if self.options.dest_dir and os.path.realpath( |
| 270 | + self.options.dest_dir |
| 271 | + ) != os.path.realpath(os.path.dirname(pex_file)): |
| 272 | + pex_dest = os.path.join( |
| 273 | + safe_mkdir(self.options.dest_dir), os.path.basename(pex_file) |
262 | 274 | ) |
263 | | - ) |
264 | | - raw_pex_version = pex_info_or_error.build_properties.get("pex_version") |
265 | | - if raw_pex_version and Version(raw_pex_version) < Version("2.1.25"): |
266 | | - return Error( |
267 | | - "Can only create scies from PEXes built by Pex 2.1.25 (which was released on " |
268 | | - "January 21st, 2021) or newer.\n" |
269 | | - "The PEX at {pex_file} was built by Pex {pex_version}.".format( |
270 | | - pex_file=pex_file, pex_version=raw_pex_version |
| 275 | + if os.path.isfile(pex_file): |
| 276 | + shutil.copy(pex_file, pex_dest) |
| 277 | + else: |
| 278 | + shutil.copytree(pex_file, pex_dest) |
| 279 | + pex_file = pex_dest |
| 280 | + else: |
| 281 | + pex_file, pex_info = try_( |
| 282 | + _extract_pex_info( |
| 283 | + try_( |
| 284 | + _fetch( |
| 285 | + url=ArtifactURL.parse(self.options.pex[0]), |
| 286 | + fetcher=URLFetcher( |
| 287 | + network_configuration=resolver_configuration.network_configuration, |
| 288 | + handle_file_urls=True, |
| 289 | + password_entries=resolver_configuration.repos_configuration.password_entries, |
| 290 | + ), |
| 291 | + dest_dir=self.options.dest_dir, |
| 292 | + ) |
| 293 | + ) |
271 | 294 | ) |
272 | 295 | ) |
273 | 296 |
|
274 | 297 | targets = try_( |
275 | 298 | _resolve_targets( |
276 | | - pex_interpreter_constraints=pex_info_or_error.interpreter_constraints, |
| 299 | + pex_interpreter_constraints=pex_info.interpreter_constraints, |
277 | 300 | target_configuration=target_options.configure( |
278 | 301 | self.options, pip_configuration=resolver_configuration.pip_configuration |
279 | 302 | ), |
@@ -313,6 +336,9 @@ def _create(self): |
313 | 336 | if scie_configuration.options.scie_only and os.path.realpath( |
314 | 337 | pex_file |
315 | 338 | ) != os.path.realpath(scie_info.file): |
316 | | - os.unlink(pex_file) |
| 339 | + if os.path.isfile(pex_file): |
| 340 | + os.unlink(pex_file) |
| 341 | + else: |
| 342 | + shutil.rmtree(pex_file) |
317 | 343 |
|
318 | 344 | return Ok() |
0 commit comments