initial commit

This commit is contained in:
Bacruru Sakaguchi
2025-09-12 17:10:13 +07:00
commit 9e5e214944
57 changed files with 1538 additions and 0 deletions

78
pythonapp/Decider/ABS.py Normal file
View 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