initial commit
This commit is contained in:
78
pythonapp/Decider/ABS.py
Normal file
78
pythonapp/Decider/ABS.py
Normal file
@@ -0,0 +1,78 @@
|
||||
import enum
|
||||
from dataclasses import dataclass
|
||||
from typing import Optional, Set, Dict
|
||||
|
||||
from pythonapp.Instance.ABS import Instance
|
||||
from pythonapp.Libs.pip_api import pip_api
|
||||
from pythonapp.Decider.Loader import Loader
|
||||
from .misc import *
|
||||
|
||||
|
||||
class ConflictSeverity(enum.Enum):
|
||||
FATAL = "Fatal"
|
||||
ERROR = "Error"
|
||||
WARNING = "Warning"
|
||||
|
||||
|
||||
|
||||
@dataclass
|
||||
class ConflictError:
|
||||
"""Класс для хранения информации о конфликте зависимостей."""
|
||||
conflicting_packages: Set[str]
|
||||
sources: Dict[str, str] # package -> source (installed/requested)
|
||||
severity: ConflictSeverity
|
||||
error_message: str
|
||||
resolution_action: str = ""
|
||||
|
||||
def __post_init__(self):
|
||||
# Автоматически определяем источники, если не предоставлены
|
||||
if not self.sources:
|
||||
self.sources = {pkg: "unknown" for pkg in self.conflicting_packages}
|
||||
|
||||
|
||||
|
||||
class DeciderState(enum.Enum):
|
||||
SUCCESS = 0
|
||||
WARN = 30
|
||||
ERROR = 50
|
||||
FATAL = 100
|
||||
|
||||
|
||||
|
||||
class Decider:
|
||||
@classmethod
|
||||
def decide(cls, instance: Instance,
|
||||
packages: list[RequirementInfo] | Path,
|
||||
pip_path: str,
|
||||
index_url: Optional[str] = None,
|
||||
extra_index_urls: Optional[list[str]] = None
|
||||
) -> tuple[list[RequirementInfo], list[ConflictError], DeciderState]:
|
||||
raise NotImplemented
|
||||
|
||||
@classmethod
|
||||
def load(cls, instance: Instance, packages: list[RequirementInfo] | Path, manual=False):
|
||||
if isinstance(packages, Path):
|
||||
opt, req = requirements_separator(packages)
|
||||
packages = requirements_converter(opt, req)
|
||||
p = instance.path
|
||||
c = instance.config
|
||||
installed = Loader.load_existent_requirements(
|
||||
str(p / c.manual_requirements_path), str(p / c.requirements_dir),
|
||||
str(p / c.pinned_packages_path), str(p / c.excluded_packages_path))
|
||||
if not manual:
|
||||
packages = Loader.filter_reqs(packages, str(p / c.pinned_packages_path), str(p / c.excluded_packages_path))
|
||||
installed.extend(packages)
|
||||
return installed, packages
|
||||
|
||||
class SimpleDecider(Decider):
|
||||
@classmethod
|
||||
def decide(cls, instance: Instance,
|
||||
packages: list[RequirementInfo] | Path,
|
||||
pip_path: str,
|
||||
index_url: Optional[str] = None,
|
||||
extra_index_urls: Optional[list[str]] = None,
|
||||
manual=False) -> tuple[list[RequirementInfo] | None, list[ConflictError], DeciderState]:
|
||||
all_packages, packages = cls.load(instance, packages, manual)
|
||||
result = pip_api.run_pip_install(pip_path, [p.requirement_str for p in all_packages], index_url, extra_index_urls, dry_run=True)
|
||||
if result.exit_code != 0: return None, [], DeciderState.FATAL
|
||||
return packages, [], DeciderState.SUCCESS
|
||||
Reference in New Issue
Block a user