sh_cpl/src/cpl_core/utils/pip.py

143 lines
3.7 KiB
Python
Raw Normal View History

import os
2021-03-13 22:53:28 +01:00
import subprocess
import sys
2021-03-14 10:31:45 +01:00
from contextlib import suppress
from typing import Optional
2021-03-13 22:53:28 +01:00
2022-06-27 10:52:26 +02:00
from cpl_core.console import Console
2021-03-13 22:53:28 +01:00
class Pip:
2021-05-17 18:07:08 +02:00
r"""Executes pip commands"""
2021-03-14 13:22:10 +01:00
_executable = sys.executable
_env = os.environ
2021-03-13 22:53:28 +01:00
2021-05-17 18:07:08 +02:00
"""Getter"""
2022-06-27 10:52:26 +02:00
2021-03-14 13:22:10 +01:00
@classmethod
def get_executable(cls) -> str:
return cls._executable
2021-05-17 18:07:08 +02:00
"""Setter"""
2022-06-27 10:52:26 +02:00
2021-03-14 13:22:10 +01:00
@classmethod
def set_executable(cls, executable: str):
2021-05-17 18:07:08 +02:00
r"""Sets the executable
Parameter
---------
executable: :class:`str`
The python command
2021-03-14 16:06:23 +01:00
"""
2022-06-27 10:52:26 +02:00
if executable is None or executable == sys.executable:
return
cls._executable = executable
if not os.path.islink(cls._executable):
return
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
2021-03-14 13:22:10 +01:00
@classmethod
def reset_executable(cls):
2021-05-17 18:07:08 +02:00
r"""Resets the executable to system standard"""
2021-03-14 13:22:10 +01:00
cls._executable = sys.executable
2021-05-17 18:07:08 +02:00
"""Public utils functions"""
2022-06-27 10:52:26 +02:00
2021-03-14 13:22:10 +01:00
@classmethod
def get_package(cls, package: str) -> Optional[str]:
2021-05-17 18:07:08 +02:00
r"""Gets given package py local pip list
Parameter
---------
package: :class:`str`
Returns
-------
The package name as string
2021-03-14 16:06:23 +01:00
"""
2021-03-14 10:31:45 +01:00
result = None
with suppress(Exception):
2022-09-19 21:09:41 +02:00
args = [cls._executable, "-m", "pip", "freeze"]
result = subprocess.check_output(
args,
stderr=subprocess.DEVNULL, env=cls._env
)
2021-03-14 10:31:45 +01:00
if result is None:
return None
2022-09-19 21:09:41 +02:00
for p in str(result.decode()).split('\n'):
if p.startswith(package):
2022-09-19 21:09:41 +02:00
return p
2021-03-13 22:53:28 +01:00
2022-09-19 21:09:41 +02:00
return None
2021-03-13 22:53:28 +01:00
2021-03-14 13:22:10 +01:00
@classmethod
def get_outdated(cls) -> bytes:
2021-05-17 18:07:08 +02:00
r"""Gets table of outdated packages
Returns
-------
Bytes string of the command result
2021-03-14 16:06:23 +01:00
"""
args = [cls._executable, "-m", "pip", "list", "--outdated"]
return subprocess.check_output(args, env=cls._env)
2021-03-14 13:22:10 +01:00
@classmethod
2021-03-14 14:47:53 +01:00
def install(cls, package: str, *args, source: str = None, stdout=None, stderr=None):
2021-05-17 18:07:08 +02:00
r"""Installs given package
Parameter
---------
package: :class:`str`
The name of the package
args: :class:`list`
Arguments for the command
source: :class:`str`
Extra index URL
stdout: :class:`str`
Stdout of subprocess.run
stderr: :class:`str`
Stderr of subprocess.run
2021-03-14 16:06:23 +01:00
"""
2021-03-14 13:22:10 +01:00
pip_args = [cls._executable, "-m", "pip", "install"]
2021-03-13 22:53:28 +01:00
for arg in args:
pip_args.append(arg)
pip_args.append(package)
2021-03-13 22:53:28 +01:00
if source is not None:
pip_args.append(f'--extra-index-url')
pip_args.append(source)
subprocess.run(pip_args, stdout=stdout, stderr=stderr, env=cls._env)
2021-03-14 10:58:59 +01:00
2021-03-14 13:22:10 +01:00
@classmethod
def uninstall(cls, package: str, stdout=None, stderr=None):
2021-05-17 18:07:08 +02:00
r"""Uninstalls given package
Parameter
---------
package: :class:`str`
The name of the package
stdout: :class:`str`
Stdout of subprocess.run
stderr: :class:`str`
Stderr of subprocess.run
2021-03-14 16:06:23 +01:00
"""
args = [cls._executable, "-m", "pip", "uninstall", "--yes", package]
subprocess.run(
args,
stdout=stdout, stderr=stderr, env=cls._env
)