mirror of
https://gitflic.ru/project/openide/openide.git
synced 2025-12-16 22:51:17 +07:00
Because we used to call venv.create() function directly in packaging_tool.py when creating environments we ended up using function's own default unconditionally creating copies of executables on all platforms, including those where venv itself creates symlinks (Linux, MacOS). Turned out, it leads to issues with locating dynamic libraries when one attempts to create a virtualenv with MacOS 10.15 system Python 3 interpreter. Now we call venv module directly as we already do with "pip" relying on its default behavior and patching the only command-line flag that we actually need -- "--without-pip". GitOrigin-RevId: d65aaa325817933de7121225038a5cf84fa2c77a
174 lines
4.4 KiB
Python
174 lines
4.4 KiB
Python
import sys
|
|
import traceback
|
|
import getopt
|
|
import os
|
|
|
|
ERROR_WRONG_USAGE = 1
|
|
ERROR_NO_PIP = 2
|
|
ERROR_NO_SETUPTOOLS = 3
|
|
ERROR_EXCEPTION = 4
|
|
|
|
os.putenv("PIP_REQUIRE_VIRTUALENV", "false")
|
|
|
|
def exit(retcode):
|
|
major, minor, micro, release, serial = sys.version_info
|
|
version = major * 10 + minor
|
|
if version < 25:
|
|
import os
|
|
os._exit(retcode)
|
|
else:
|
|
sys.exit(retcode)
|
|
|
|
|
|
def usage():
|
|
sys.stderr.write('Usage: packaging_tool.py <list|install|uninstall|pyvenv>\n')
|
|
sys.stderr.flush()
|
|
exit(ERROR_WRONG_USAGE)
|
|
|
|
|
|
def error(message, retcode):
|
|
sys.stderr.write('Error: %s\n' % message)
|
|
sys.stderr.flush()
|
|
exit(retcode)
|
|
|
|
|
|
def error_no_pip():
|
|
type, value, tb = sys.exc_info()
|
|
if tb is not None and tb.tb_next is None:
|
|
error("Python packaging tool 'pip' not found", ERROR_NO_PIP)
|
|
else:
|
|
error(traceback.format_exc(), ERROR_EXCEPTION)
|
|
|
|
|
|
def do_list():
|
|
try:
|
|
import pkg_resources
|
|
except ImportError:
|
|
error("Python packaging tool 'setuptools' not found", ERROR_NO_SETUPTOOLS)
|
|
for pkg in pkg_resources.working_set:
|
|
try:
|
|
requirements = pkg.requires()
|
|
except Exception:
|
|
requirements = []
|
|
requires = ':'.join([str(x) for x in requirements])
|
|
sys.stdout.write('\t'.join([pkg.project_name, pkg.version, pkg.location, requires])+chr(10))
|
|
sys.stdout.flush()
|
|
|
|
|
|
def do_install(pkgs):
|
|
run_pip(['install'] + pkgs)
|
|
|
|
|
|
def do_uninstall(pkgs):
|
|
run_pip(['uninstall', '-y'] + pkgs)
|
|
|
|
|
|
def run_pip(args):
|
|
import runpy
|
|
sys.argv[1:] = args
|
|
# pip.__main__ has been around since 2010 but support for executing it automatically
|
|
# was added in runpy.run_module only in Python 2.7/3.1
|
|
module_name = 'pip.__main__' if sys.version_info < (2, 7) else 'pip'
|
|
try:
|
|
runpy.run_module(module_name, run_name='__main__', alter_sys=True)
|
|
except ImportError:
|
|
error_no_pip()
|
|
|
|
|
|
def do_pyvenv(args):
|
|
import runpy
|
|
# We cannot rely on automatic installation of setuptools and pip and
|
|
# have to bootstrap these packages ourselves, since some distributions
|
|
# of CPython on Ubuntu and MacOS don't include "ensurepip" module.
|
|
sys.argv[1:] = ['--without-pip'] + args
|
|
try:
|
|
runpy.run_module('venv', run_name='__main__', alter_sys=True)
|
|
except ImportError:
|
|
error("Standard Python 'venv' module not found", ERROR_EXCEPTION)
|
|
|
|
|
|
def do_untar(name):
|
|
import tempfile
|
|
|
|
directory_name = tempfile.mkdtemp("pycharm-management")
|
|
|
|
import tarfile
|
|
|
|
tar = tarfile.open(name)
|
|
for item in tar:
|
|
tar.extract(item, directory_name)
|
|
|
|
sys.stdout.write(directory_name+chr(10))
|
|
sys.stdout.flush()
|
|
|
|
|
|
def mkdtemp_ifneeded():
|
|
try:
|
|
ind = sys.argv.index('--build-dir')
|
|
if not os.path.exists(sys.argv[ind + 1]):
|
|
import tempfile
|
|
|
|
sys.argv[ind + 1] = tempfile.mkdtemp('pycharm-packaging')
|
|
return sys.argv[ind + 1]
|
|
except:
|
|
pass
|
|
|
|
return None
|
|
|
|
|
|
def main():
|
|
try:
|
|
# As a workaround for #885 in setuptools, don't expose other helpers
|
|
# in sys.path so as not no confuse it with possible combination of
|
|
# namespace/ordinary packages
|
|
sys.path.remove(os.path.dirname(__file__))
|
|
except ValueError:
|
|
pass
|
|
|
|
try:
|
|
if len(sys.argv) < 2:
|
|
usage()
|
|
cmd = sys.argv[1]
|
|
if cmd == 'list':
|
|
if len(sys.argv) != 2:
|
|
usage()
|
|
do_list()
|
|
elif cmd == 'install':
|
|
if len(sys.argv) < 2:
|
|
usage()
|
|
|
|
rmdir = mkdtemp_ifneeded()
|
|
|
|
pkgs = sys.argv[2:]
|
|
try:
|
|
do_install(pkgs)
|
|
finally:
|
|
if rmdir is not None:
|
|
import shutil
|
|
shutil.rmtree(rmdir)
|
|
|
|
elif cmd == 'untar':
|
|
if len(sys.argv) < 2:
|
|
usage()
|
|
name = sys.argv[2]
|
|
do_untar(name)
|
|
elif cmd == 'uninstall':
|
|
if len(sys.argv) < 2:
|
|
usage()
|
|
pkgs = sys.argv[2:]
|
|
do_uninstall(pkgs)
|
|
elif cmd == 'pyvenv':
|
|
opts, args = getopt.getopt(sys.argv[2:], '', ['system-site-packages'])
|
|
if len(args) != 1:
|
|
usage()
|
|
do_pyvenv(sys.argv[2:])
|
|
else:
|
|
usage()
|
|
except Exception:
|
|
traceback.print_exc()
|
|
exit(ERROR_EXCEPTION)
|
|
|
|
|
|
if __name__ == '__main__':
|
|
main()
|