From dbdd5cd26dc8527afd4d64da68b5d4279947503e Mon Sep 17 00:00:00 2001 From: 24_ChernovaSS <24_ChernovaSS@iux.local> Date: Mon, 25 May 2026 22:54:23 +0300 Subject: [PATCH] =?UTF-8?q?=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8=D0=BB?= =?UTF-8?q?=D0=B0=20=D0=B0=D0=B2=D1=82=D0=BE=D0=BC=D0=B0=D1=82=D0=B8=D1=87?= =?UTF-8?q?=D0=B5=D1=81=D0=BA=D0=BE=D0=B5=20=D1=80=D0=B0=D0=B7=D1=80=D0=B5?= =?UTF-8?q?=D1=88=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=B7=D0=B0=D0=B2=D0=B8=D1=81?= =?UTF-8?q?=D0=B8=D0=BC=D0=BE=D1=81=D1=82=D0=B5=D0=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- mypkg/core/dependency_resolver.py | 45 ++++++++++ mypkg/core/package_manager.py | 82 ++++++++++--------- .../libncurses/files/usr/lib/libncurses.so.6 | 0 repo/packages/libncurses/meta.json | 13 +++ 4 files changed, 100 insertions(+), 40 deletions(-) create mode 100644 mypkg/core/dependency_resolver.py create mode 100644 repo/packages/libncurses/files/usr/lib/libncurses.so.6 create mode 100644 repo/packages/libncurses/meta.json diff --git a/mypkg/core/dependency_resolver.py b/mypkg/core/dependency_resolver.py new file mode 100644 index 0000000..73ae1f7 --- /dev/null +++ b/mypkg/core/dependency_resolver.py @@ -0,0 +1,45 @@ +# mypkg/core/dependency_resolver.py +import os +import json +from typing import List, Set, Dict +from ..models.package import Package + + +class DependencyResolver: + def __init__(self, repo_path: str, installed: Dict[str, Package]): + self.repo_path = repo_path + self.installed = installed + self.visited = set() + + def resolve(self, target_name: str) -> List[Package]: + """Возвращает список пакетов для установки в правильном порядке""" + self.visited.clear() + to_install = [] # используем список вместо множества + self._resolve_recursive(target_name, to_install) + return to_install + + def _resolve_recursive(self, pkg_name: str, to_install: List[Package]): + if pkg_name in self.visited: + return + self.visited.add(pkg_name) + + if pkg_name in self.installed: + return + + # Читаем meta.json пакета + meta_path = os.path.join(self.repo_path, "packages", pkg_name, "meta.json") + if not os.path.exists(meta_path): + raise Exception(f"Зависимость '{pkg_name}' не найдена в репозитории") + + with open(meta_path, 'r') as f: + pkg_data = json.load(f) + + pkg = Package(**pkg_data) + + # Сначала обрабатываем зависимости + for dep in pkg.depends: + self._resolve_recursive(dep, to_install) + + # Добавляем текущий пакет (если ещё не добавлен) + if pkg not in to_install: + to_install.append(pkg) \ No newline at end of file diff --git a/mypkg/core/package_manager.py b/mypkg/core/package_manager.py index 72e8115..24961a7 100644 --- a/mypkg/core/package_manager.py +++ b/mypkg/core/package_manager.py @@ -1,4 +1,5 @@ # mypkg/core/package_manager.py +from .dependency_resolver import DependencyResolver import json import os import shutil @@ -24,62 +25,63 @@ class PackageManager: self.sandbox_mode = False self.db = DatabaseManager(self.root) + self.resolver = DependencyResolver(repo_path, self.db.installed) def install(self, package_name: str, dry_run: bool = False) -> bool: - print_step(f"Поиск пакета {package_name}...") - - meta_path = os.path.join(self.repo_path, "packages", package_name, "meta.json") - - if not os.path.exists(meta_path): - print_error(f"Пакет {package_name} не найден") - return False - - with open(meta_path, 'r') as f: - pkg_data = json.load(f) - - pkg = Package(**pkg_data) - - if self.db.is_installed(package_name): - print_warning(f"Пакет {package_name} уже установлен") - return True - - # DRY-RUN: только показываем, ничего не делаем + # DRY-RUN: показываем, что будет if dry_run: print("🔍 РЕЖИМ DRY-RUN (ничего не устанавливается)") - print(f"\n📦 Будет установлен: {pkg.full_name()}") - if pkg.depends: - print(f" Зависимости: {', '.join(pkg.depends)}") - else: - print(f" Зависимости: нет") - print(f" Файлы ({len(pkg.files)}):") - for f in pkg.files: - print(f" {f['destination']}") - if self.sandbox_mode: - print(f"\n🏖️ Установка будет выполнена в песочницу: {self.root}") + try: + to_install = self.resolver.resolve(package_name) + except Exception as e: + print_error(f"Ошибка: {e}") + return False + + print(f"\n📦 Будет установлено:") + for pkg in to_install: + print(f" {pkg.full_name()}") + if pkg.depends: + print(f" Зависимости: {', '.join(pkg.depends)}") print(f"\n✅ Установка не произведена (dry-run)") return True # РЕАЛЬНАЯ УСТАНОВКА - print_package(f"Установка {pkg.full_name()}...") + print_step(f"Поиск пакета {package_name}...") - source_dir = os.path.join(self.repo_path, "packages", package_name, "files") + # 1. Разрешаем зависимости + try: + to_install = self.resolver.resolve(package_name) + except Exception as e: + print_error(f"Ошибка разрешения зависимостей: {e}") + return False - for file_info in pkg.files: - src = os.path.join(source_dir, file_info["source"]) - dst = os.path.join(self.root, file_info["destination"].lstrip("/")) + # 2. Устанавливаем всё по порядку + for pkg in to_install: + if self.db.is_installed(pkg.name): + print_info(f"{pkg.name} уже установлен") + continue - os.makedirs(os.path.dirname(dst), exist_ok=True) - shutil.copy2(src, dst) + print_step(f"Установка {pkg.full_name()}...") - if "permissions" in file_info: - os.chmod(dst, file_info["permissions"]) - - self.db.add_package(pkg) - print_success(f"Пакет {package_name} установлен") + source_dir = os.path.join(self.repo_path, "packages", pkg.name, "files") + + for file_info in pkg.files: + src = os.path.join(source_dir, file_info["source"]) + dst = os.path.join(self.root, file_info["destination"].lstrip("/")) + + os.makedirs(os.path.dirname(dst), exist_ok=True) + shutil.copy2(src, dst) + + if "permissions" in file_info: + os.chmod(dst, file_info["permissions"]) + + self.db.add_package(pkg) + print_success(f"{pkg.name} установлен") if self.sandbox_mode: print_info(f"Файлы в: {self.root}") + print_success(f"Пакет {package_name} и его зависимости установлены") return True def remove(self, package_name: str, force: bool = False, dry_run: bool = False) -> bool: diff --git a/repo/packages/libncurses/files/usr/lib/libncurses.so.6 b/repo/packages/libncurses/files/usr/lib/libncurses.so.6 new file mode 100644 index 0000000..e69de29 diff --git a/repo/packages/libncurses/meta.json b/repo/packages/libncurses/meta.json new file mode 100644 index 0000000..13828e0 --- /dev/null +++ b/repo/packages/libncurses/meta.json @@ -0,0 +1,13 @@ +{ + "name": "libncurses", + "version": "6.2", + "description": "Библиотека для работы с терминалом", + "depends": [], + "files": [ + { + "source": "usr/lib/libncurses.so.6", + "destination": "/usr/lib/libncurses.so.6", + "permissions": 644 + } + ] +}