Skip to content

Commit 2e737af

Browse files
committed
Handle #!/bin/sh re-director scripts in venvs.
These scripts are used to work around shebang length limitations by Python package installers when they create console scripts in a venv.
1 parent 2140278 commit 2e737af

3 files changed

Lines changed: 31 additions & 6 deletions

File tree

CHANGES.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
# Release Notes
22

3+
## 0.32.2
4+
5+
Fix venv creation to handle `#!/bin/sh` re-director script re-writes. These are Python scripts with
6+
`#!/bin/sh` re-director headers that work around shebang-length limitations.
7+
38
## 0.31.1
49

510
Fix venv creation to use the newest Pip possible given the target python.

dev_cmd/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
# Copyright 2024 John Sirois.
22
# Licensed under the Apache License, Version 2.0 (see LICENSE).
33

4-
__version__ = "0.31.1"
4+
__version__ = "0.31.2"

dev_cmd/venv.py

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -367,15 +367,35 @@ def _extra_requirements_args() -> Iterator[list[str]]:
367367
if candidate_fp.read(2) != b"#!":
368368
continue
369369
shebang = candidate_fp.readline()
370-
if not shebang.startswith(work_dir_path_bytes):
370+
if shebang != b"/bin/sh\n" and not shebang.startswith(work_dir_path_bytes):
371371
continue
372+
372373
rewrite_target = candidate_console_script.with_suffix(".rewrite")
373374
with rewrite_target.open("wb") as rewrite_fp:
374375
rewrite_fp.write(b"#!")
375-
rewrite_fp.write(
376-
shebang.replace(work_dir_path_bytes, venv_dir_path_bytes)
377-
)
378-
shutil.copyfileobj(candidate_fp, rewrite_fp)
376+
if shebang.startswith(work_dir_path_bytes):
377+
rewrite_fp.write(
378+
shebang.replace(work_dir_path_bytes, venv_dir_path_bytes)
379+
)
380+
shutil.copyfileobj(candidate_fp, rewrite_fp)
381+
else:
382+
# N.B.: Scripts with too-long shebangs will use the `#!/bin/sh` trick.
383+
# Like so:
384+
# #!/bin/sh
385+
# # N.B.: This python script executes via a /bin/sh re-exec as a hack to work around a
386+
# # potential maximum shebang length of 128 bytes on this system which
387+
# # the python interpreter `exec`ed below would violate.
388+
# ''''exec /too/long/lead-in/path/.dev-cmd/venvs/Dik2FlYfLsaDdskunQh_vGTlBS1My7KattEsxC0M9-k.work/bin/python2.7 "$0" "$@"
389+
# '''
390+
# # -*- coding: utf-8 -*-
391+
# import importlib
392+
# ...
393+
rewrite_fp.write(shebang)
394+
rewrite_fp.write(
395+
candidate_fp.read().replace(
396+
work_dir_path_bytes, venv_dir_path_bytes, 1
397+
)
398+
)
379399
rewrite_target.replace(candidate_console_script)
380400
_chmod_plus_x(candidate_console_script)
381401

0 commit comments

Comments
 (0)