Files
Hotel-Booking/Backend/venv/lib/python3.12/site-packages/safety/tool/pip/main.py
Iliyan Angelov 62c1fe5951 updates
2025-12-01 06:50:10 +02:00

151 lines
4.4 KiB
Python

import logging
import re
import shutil
import subprocess
from pathlib import Path
from typing import Optional
import typer
from rich.console import Console
from safety.tool.constants import (
PYPI_PUBLIC_REPOSITORY_URL,
PYPI_ORGANIZATION_REPOSITORY_URL,
PYPI_PROJECT_REPOSITORY_URL,
)
from safety.tool.resolver import get_unwrapped_command
from safety.utils.pyapp_utils import get_path, get_env
from safety.console import main_console
from safety.tool.auth import build_index_url
from ...encoding import detect_encoding
logger = logging.getLogger(__name__)
class Pip:
@classmethod
def is_installed(cls) -> bool:
"""
Checks if the PIP program is installed
Returns:
True if PIP is installed on system, or false otherwise
"""
return shutil.which("pip", path=get_path()) is not None
@classmethod
def configure_requirements(
cls,
file: Path,
org_slug: Optional[str],
project_id: Optional[str],
console: Console = main_console,
) -> Optional[Path]:
"""
Configures Safety index url for specified requirements file.
Args:
file (Path): Path to requirements.txt file.
org_slug (str): Organization slug.
project_id (str): Project identifier.
console (Console): Console instance.
"""
with open(file, "r+", encoding=detect_encoding(file)) as f:
content = f.read()
repository_url = (
PYPI_PROJECT_REPOSITORY_URL.format(org_slug, project_id)
if project_id and org_slug
else (
PYPI_ORGANIZATION_REPOSITORY_URL.format(org_slug)
if org_slug
else PYPI_PUBLIC_REPOSITORY_URL
)
)
index_config = f"-i {repository_url}\n"
if content.find(index_config) == -1:
f.seek(0)
f.write(index_config + content)
logger.info(f"Configured {file} file")
return file
else:
logger.info(f"{file} is already configured. Skipping.")
return None
@classmethod
def configure_system(
cls, org_slug: Optional[str], console: Console = main_console
) -> Optional[Path]:
"""
Configures PIP system to use to Safety index url.
"""
try:
repository_url = (
PYPI_ORGANIZATION_REPOSITORY_URL.format(org_slug)
if org_slug
else PYPI_PUBLIC_REPOSITORY_URL
)
result = subprocess.run(
[
get_unwrapped_command(name="pip"),
"config",
"--user",
"set",
"global.index-url",
repository_url,
],
capture_output=True,
env=get_env(),
)
if result.returncode != 0:
logger.error(
f"Failed to configure PIP global settings: {result.stderr.decode('utf-8')}"
)
return None
output = result.stdout.decode("utf-8")
match = re.search(r"Writing to (.+)", output)
if match:
config_file_path = match.group(1).strip()
return Path(config_file_path)
logger.error("Failed to match the config file path written by pip.")
return Path()
except Exception:
logger.exception("Failed to configure PIP global settings.")
return None
@classmethod
def reset_system(cls, console: Console = main_console):
# TODO: Move this logic and implement it in a more robust way
try:
subprocess.run(
[
get_unwrapped_command(name="pip"),
"config",
"--user",
"unset",
"global.index-url",
],
capture_output=True,
env=get_env(),
)
except Exception:
console.print("Failed to reset PIP global settings.")
@classmethod
def default_index_url(cls) -> str:
return "https://pypi.org/simple/"
@classmethod
def build_index_url(cls, ctx: typer.Context, index_url: Optional[str]) -> str:
return build_index_url(ctx, index_url, "pypi")