Skip to content

Commit 245a32b

Browse files
committed
Restore accidentally removed python-venv-stubber.sh
1 parent 2def657 commit 245a32b

File tree

1 file changed

+72
-0
lines changed

1 file changed

+72
-0
lines changed

libexec/python-venv-stubber.sh

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
#!/usr/bin/env -S pkgx bash
2+
# shellcheck shell=bash
3+
4+
# python virtual-envs are not relocatable
5+
# our only working choice is to rewrite these files and symlinks every time
6+
# because we promise that pkgx is relocatable *at any time*
7+
#FIXME requiring sed is a bit lame
8+
9+
if test -z "$VIRTUAL_ENV"; then
10+
echo "error: VIRTUAL_ENV not set" >&2
11+
exit 1
12+
fi
13+
14+
mkdir -p "$VIRTUAL_ENV/../bin"
15+
16+
CMD_NAME="$1"
17+
18+
cat <<EOF > "$VIRTUAL_ENV"/../bin/"$CMD_NAME"
19+
#!/usr/bin/env python
20+
21+
import os
22+
import sys
23+
import glob
24+
import shutil
25+
from pathlib import Path
26+
27+
# Determine directories and paths
28+
script_dir = os.path.dirname(os.path.realpath(__file__))
29+
virtual_env = os.path.normpath(os.path.join(script_dir, '..', 'venv'))
30+
arg0 = os.path.basename(sys.argv[0])
31+
python_path = shutil.which('python')
32+
python_home = os.path.dirname(python_path)
33+
34+
# Write pyvenv.cfg file
35+
pyvenv_cfg_path = os.path.join(virtual_env, 'pyvenv.cfg')
36+
with open(pyvenv_cfg_path, 'w') as f:
37+
f.write(f"home = {python_home}\ninclude-system-site-packages = false\nexecutable = {python_path}\n")
38+
39+
new_first_line = b"#!" + os.path.join(virtual_env, 'bin', 'python').encode('utf-8') + b"\n"
40+
41+
# Go through files in the bin directory
42+
for filepath in glob.glob(os.path.join(virtual_env, 'bin', '*')):
43+
if os.path.isfile(filepath) and not os.path.islink(filepath):
44+
with open(filepath, 'rb+') as f:
45+
first_two_chars = f.read(2)
46+
47+
if first_two_chars == b'#!':
48+
old_first_line = first_two_chars + f.readline() # Read the rest of the first line
49+
50+
if old_first_line.strip().endswith(b"python") and old_first_line != new_first_line:
51+
rest_of_file = f.read()
52+
f.seek(0)
53+
f.write(new_first_line + rest_of_file)
54+
f.truncate()
55+
56+
# Create symlink to the specified Python version in the virtual environment
57+
python_symlink = os.path.join(virtual_env, 'bin', 'python')
58+
59+
# Remove the symbolic link if it already exists
60+
if os.path.islink(python_symlink) or os.path.exists(python_symlink):
61+
os.remove(python_symlink)
62+
63+
os.symlink(python_path, python_symlink)
64+
65+
# Execute the corresponding script in the virtual environment
66+
arg0 = os.path.join(virtual_env, 'bin', arg0)
67+
args = sys.argv[1:]
68+
args.insert(0, arg0)
69+
os.execv(arg0, args)
70+
EOF
71+
72+
chmod +x "$VIRTUAL_ENV/../bin/$CMD_NAME"

0 commit comments

Comments
 (0)