| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106 |
- '''Hooks for isloating the AppImage Python and making it relocatable
- '''
- import atexit
- import os
- import sys
- def clean_path():
- '''Remove system locations from the packages search path
- '''
- site_packages = '/usr/local/lib/python{:}.{:}/site-packages'.format(
- *sys.version_info[:2])
- binaries_path = '/usr/local/bin'
- env_path = os.getenv("PYTHONPATH")
- if env_path is None:
- env_path = []
- else:
- env_path = [os.path.realpath(path) for path in env_path.split(':')]
- if ((os.path.dirname(sys.executable) != binaries_path) and
- (site_packages not in env_path)):
- # Remove the builtin site-packages from the path
- try:
- sys.path.remove(site_packages)
- except ValueError:
- pass
- clean_path()
- _bin_at_start = os.listdir(sys.prefix + '/bin')
- '''Initial content of the bin/ directory
- '''
- def patch_pip_install():
- '''Change absolute shebangs to relative ones following a `pip` install
- '''
- if not 'pip' in sys.modules:
- return
- args = sys.argv[1:]
- if 'install' in args:
- for exe in os.listdir(sys.prefix + '/bin'):
- path = os.path.join(sys.prefix, 'bin', exe)
- if (not os.path.isfile(path)) or (not os.access(path, os.X_OK)) or \
- exe.startswith('python') or os.path.islink(path) or \
- exe.endswith('.pyc') or exe.endswith('.pyo'):
- continue
- try:
- with open(path, 'r') as f:
- header = f.read(2)
- if header != '#!':
- continue
- content = f.read()
- except:
- continue
- shebang, body = content.split(os.linesep, 1)
- shebang = shebang.split()
- python_x_y = os.path.basename(shebang.pop(0))
- if not python_x_y.startswith('python'):
- continue
- relpath = os.path.relpath(
- sys.prefix + '/../../usr/bin/' + python_x_y,
- sys.prefix + '/bin')
- shebang.append('"$@"')
- cmd = (
- '"exec"',
- '"$(dirname $(readlink -f ${0}))/' + relpath + '"',
- '"$0"',
- ' '.join(shebang)
- )
- try:
- with open(path, 'w') as f:
- f.write('#! /bin/sh\n')
- f.write(' '.join(cmd) + '\n')
- f.write(body)
- except IOError:
- continue
- if exe in _bin_at_start:
- continue
- usr_dir = os.path.join(sys.prefix, '../../usr/bin')
- usr_exe = os.path.join(usr_dir, exe)
- if not os.path.exists(usr_exe):
- relpath = os.path.relpath(path, usr_dir)
- os.symlink(relpath, usr_exe)
- elif 'uninstall' in args:
- usr_dir = os.path.join(sys.prefix, '../../usr/bin')
- for exe in os.listdir(usr_dir):
- path = os.path.join(usr_dir, exe)
- if (not os.path.islink(path)) or \
- os.path.exists(os.path.realpath(path)):
- continue
- os.remove(path)
- atexit.register(patch_pip_install)
|