From cc9b25356c51f9cbce0dd2e11bf51ff577659a2a Mon Sep 17 00:00:00 2001 From: Sven Heidemann Date: Fri, 9 Apr 2021 20:07:38 +0200 Subject: [PATCH] Improved workspace and venv handling for uninstall and install command --- src/cpl/utils/pip.py | 45 ++++++++++++++++--- src/cpl_cli/command/install_service.py | 1 + src/cpl_cli/command_handler_service.py | 4 +- .../custom/general/src/general/general.json | 4 +- 4 files changed, 46 insertions(+), 8 deletions(-) diff --git a/src/cpl/utils/pip.py b/src/cpl/utils/pip.py index b0035a0c..5ed0f617 100644 --- a/src/cpl/utils/pip.py +++ b/src/cpl/utils/pip.py @@ -1,6 +1,9 @@ +import os import subprocess import sys +import shlex from contextlib import suppress +from textwrap import dedent from typing import Optional @@ -9,6 +12,8 @@ class Pip: Executes pip commands """ _executable = sys.executable + _env = os.environ + _is_venv = False """ Getter @@ -29,8 +34,17 @@ class Pip: :param executable: :return: """ - if executable is not None: + if executable is not None and executable != sys.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 def reset_executable(cls): @@ -39,6 +53,7 @@ class Pip: :return: """ cls._executable = sys.executable + cls._is_venv = False """ Public utils functions @@ -53,7 +68,14 @@ class Pip: """ result = None 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: return None @@ -76,7 +98,11 @@ class Pip: Gets table of outdated packages :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 def install(cls, package: str, *args, source: str = None, stdout=None, stderr=None): @@ -90,6 +116,8 @@ class Pip: :return: """ pip_args = [cls._executable, "-m", "pip", "install"] + if cls._is_venv: + pip_args = ["pip", "install"] for arg in args: pip_args.append(arg) @@ -99,7 +127,7 @@ class Pip: pip_args.append(source) pip_args.append(package) - subprocess.run(pip_args, stdout=stdout, stderr=stderr) + subprocess.run(pip_args, stdout=stdout, stderr=stderr, env=cls._env) @classmethod def uninstall(cls, package: str, stdout=None, stderr=None): @@ -110,4 +138,11 @@ class Pip: :param stderr: :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 + ) diff --git a/src/cpl_cli/command/install_service.py b/src/cpl_cli/command/install_service.py index bf2a58fe..2178e735 100644 --- a/src/cpl_cli/command/install_service.py +++ b/src/cpl_cli/command/install_service.py @@ -126,6 +126,7 @@ class InstallService(CommandABC): spinner_foreground_color=ForegroundColorEnum.cyan ) new_package = Pip.get_package(name) + Console.write_line(new_package) if new_package is None \ or '==' in package and \ version.parse(package.split('==')[1]) != version.parse(new_package.split('==')[1]): diff --git a/src/cpl_cli/command_handler_service.py b/src/cpl_cli/command_handler_service.py index 32bd0228..70a6eefd 100644 --- a/src/cpl_cli/command_handler_service.py +++ b/src/cpl_cli/command_handler_service.py @@ -93,11 +93,13 @@ class CommandHandler(ABC): ) 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( 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) Console.write('\n') diff --git a/src/tests/custom/general/src/general/general.json b/src/tests/custom/general/src/general/general.json index e3ebdf79..8c2aee2a 100644 --- a/src/tests/custom/general/src/general/general.json +++ b/src/tests/custom/general/src/general/general.json @@ -1,6 +1,6 @@ { "ProjectSettings": { - "Name": "sh_cpl.tests.custom.general", + "Name": "general", "Version": { "Major": "2021", "Minor": "04", @@ -20,7 +20,7 @@ ], "PythonVersion": ">=3.8", "PythonPath": { - "_linux": "../../../../cpl-env/bin/python3.9", + "linux": "../../../../../../cpl-env/bin/python3.9", "win32": "" }, "Classifiers": []