Improved workspace and venv handling for uninstall and install command

This commit is contained in:
Sven Heidemann 2021-04-09 20:07:38 +02:00
parent a95d6e7f8a
commit cc9b25356c
4 changed files with 46 additions and 8 deletions

View File

@ -1,6 +1,9 @@
import os
import subprocess import subprocess
import sys import sys
import shlex
from contextlib import suppress from contextlib import suppress
from textwrap import dedent
from typing import Optional from typing import Optional
@ -9,6 +12,8 @@ class Pip:
Executes pip commands Executes pip commands
""" """
_executable = sys.executable _executable = sys.executable
_env = os.environ
_is_venv = False
""" """
Getter Getter
@ -29,8 +34,17 @@ class Pip:
:param executable: :param executable:
:return: :return:
""" """
if executable is not None: if executable is not None and executable != sys.executable:
cls._executable = executable cls._executable = executable
if os.path.islink(cls._executable):
cls._is_venv = True
path = os.path.dirname(os.path.dirname(cls._executable))
cls._env = os.environ
if sys.platform == 'win32':
cls._env['PATH'] = f'{path}\\bin' + os.pathsep + os.environ.get('PATH', '')
else:
cls._env['PATH'] = f'{path}/bin' + os.pathsep + os.environ.get('PATH', '')
cls._env['VIRTUAL_ENV'] = path
@classmethod @classmethod
def reset_executable(cls): def reset_executable(cls):
@ -39,6 +53,7 @@ class Pip:
:return: :return:
""" """
cls._executable = sys.executable cls._executable = sys.executable
cls._is_venv = False
""" """
Public utils functions Public utils functions
@ -53,7 +68,14 @@ class Pip:
""" """
result = None result = None
with suppress(Exception): with suppress(Exception):
result = subprocess.check_output([cls._executable, "-m", "pip", "show", package], stderr=subprocess.DEVNULL) args = [cls._executable, "-m", "pip", "show", package]
if cls._is_venv:
args = ["pip", "show", package]
result = subprocess.check_output(
args,
stderr=subprocess.DEVNULL, env=cls._env
)
if result is None: if result is None:
return None return None
@ -76,7 +98,11 @@ class Pip:
Gets table of outdated packages Gets table of outdated packages
:return: :return:
""" """
return subprocess.check_output([cls._executable, "-m", "pip", "list", "--outdated"]) args = [cls._executable, "-m", "pip", "list", "--outdated"]
if cls._is_venv:
args = ["pip", "list", "--outdated"]
return subprocess.check_output(args, env=cls._env)
@classmethod @classmethod
def install(cls, package: str, *args, source: str = None, stdout=None, stderr=None): def install(cls, package: str, *args, source: str = None, stdout=None, stderr=None):
@ -90,6 +116,8 @@ class Pip:
:return: :return:
""" """
pip_args = [cls._executable, "-m", "pip", "install"] pip_args = [cls._executable, "-m", "pip", "install"]
if cls._is_venv:
pip_args = ["pip", "install"]
for arg in args: for arg in args:
pip_args.append(arg) pip_args.append(arg)
@ -99,7 +127,7 @@ class Pip:
pip_args.append(source) pip_args.append(source)
pip_args.append(package) pip_args.append(package)
subprocess.run(pip_args, stdout=stdout, stderr=stderr) subprocess.run(pip_args, stdout=stdout, stderr=stderr, env=cls._env)
@classmethod @classmethod
def uninstall(cls, package: str, stdout=None, stderr=None): def uninstall(cls, package: str, stdout=None, stderr=None):
@ -110,4 +138,11 @@ class Pip:
:param stderr: :param stderr:
:return: :return:
""" """
subprocess.run([cls._executable, "-m", "pip", "uninstall", "--yes", package], stdout=stdout, stderr=stderr) args = [cls._executable, "-m", "pip", "uninstall", "--yes", package]
if cls._is_venv:
args = ["pip", "uninstall", "--yes", package]
subprocess.run(
args,
stdout=stdout, stderr=stderr, env=cls._env
)

View File

@ -126,6 +126,7 @@ class InstallService(CommandABC):
spinner_foreground_color=ForegroundColorEnum.cyan spinner_foreground_color=ForegroundColorEnum.cyan
) )
new_package = Pip.get_package(name) new_package = Pip.get_package(name)
Console.write_line(new_package)
if new_package is None \ if new_package is None \
or '==' in package and \ or '==' in package and \
version.parse(package.split('==')[1]) != version.parse(new_package.split('==')[1]): version.parse(package.split('==')[1]) != version.parse(new_package.split('==')[1]):

View File

@ -93,11 +93,13 @@ class CommandHandler(ABC):
) )
return return
self._config.add_json_file(project_json, optional=True, output=False) project_json = os.path.join(self._env.working_directory, project_json)
self._env.set_working_directory( self._env.set_working_directory(
os.path.join(self._env.working_directory, os.path.dirname(project_json)) os.path.join(self._env.working_directory, os.path.dirname(project_json))
) )
self._config.add_json_file(project_json, optional=True, output=False)
self._services.get_service(command.command).run(args) self._services.get_service(command.command).run(args)
Console.write('\n') Console.write('\n')

View File

@ -1,6 +1,6 @@
{ {
"ProjectSettings": { "ProjectSettings": {
"Name": "sh_cpl.tests.custom.general", "Name": "general",
"Version": { "Version": {
"Major": "2021", "Major": "2021",
"Minor": "04", "Minor": "04",
@ -20,7 +20,7 @@
], ],
"PythonVersion": ">=3.8", "PythonVersion": ">=3.8",
"PythonPath": { "PythonPath": {
"_linux": "../../../../cpl-env/bin/python3.9", "linux": "../../../../../../cpl-env/bin/python3.9",
"win32": "" "win32": ""
}, },
"Classifiers": [] "Classifiers": []