добавила цветной вывод (ANSI-коды)
This commit is contained in:
@@ -1,22 +1,15 @@
|
||||
# mypkg/cli/main.py
|
||||
#!/usr/bin/env python3
|
||||
import argparse
|
||||
import sys
|
||||
from ..core.package_manager import PackageManager
|
||||
from ..utils.colors import print_info, print_package
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(
|
||||
description="My Package Manager - простой менеджер пакетов для Linux",
|
||||
epilog="""
|
||||
Примеры:
|
||||
mypkg install nano Установить пакет nano
|
||||
mypkg list Показать установленные пакеты
|
||||
mypkg --sandbox /tmp/test install nano Установить в песочницу
|
||||
"""
|
||||
description="My Package Manager - менеджер пакетов для Linux"
|
||||
)
|
||||
|
||||
# Глобальный аргумент --sandbox (может быть указан в любом месте)
|
||||
parser.add_argument('--sandbox', type=str, default=None,
|
||||
help='Режим песочницы: установка в изолированную директорию')
|
||||
parser.add_argument('--repo', default='repo',
|
||||
@@ -24,11 +17,9 @@ def main():
|
||||
|
||||
subparsers = parser.add_subparsers(dest='command', help='Команды')
|
||||
|
||||
# команда install
|
||||
install_parser = subparsers.add_parser('install', help='Установить пакет')
|
||||
install_parser.add_argument('package', help='Имя пакета')
|
||||
|
||||
# команда list
|
||||
list_parser = subparsers.add_parser('list', help='Список установленных пакетов')
|
||||
|
||||
args = parser.parse_args()
|
||||
@@ -37,21 +28,16 @@ def main():
|
||||
parser.print_help()
|
||||
sys.exit(1)
|
||||
|
||||
# Создаем менеджер пакетов с учетом песочницы
|
||||
pm = PackageManager(
|
||||
repo_path=args.repo,
|
||||
sandbox=args.sandbox
|
||||
)
|
||||
pm = PackageManager(repo_path=args.repo, sandbox=args.sandbox)
|
||||
|
||||
if args.command == 'install':
|
||||
pm.install(args.package)
|
||||
|
||||
elif args.command == 'list':
|
||||
packages = pm.list_installed()
|
||||
if not packages:
|
||||
print("Нет установленных пакетов")
|
||||
print_info("Нет установленных пакетов")
|
||||
else:
|
||||
print("Установленные пакеты:")
|
||||
print_package(f"Установленные пакеты ({len(packages)}):")
|
||||
for pkg in packages:
|
||||
print(f" {pkg.name} ({pkg.version})")
|
||||
sys.exit(0)
|
||||
|
||||
@@ -2,27 +2,23 @@
|
||||
import json
|
||||
import os
|
||||
import shutil
|
||||
from typing import List, Optional
|
||||
from typing import List
|
||||
from ..models.package import Package
|
||||
from ..database.db_manager import DatabaseManager
|
||||
from ..utils.colors import (
|
||||
print_success, print_error, print_warning,
|
||||
print_info, print_package, print_step, print_sandbox_mode
|
||||
)
|
||||
|
||||
|
||||
class PackageManager:
|
||||
"""Главный класс менеджера пакетов"""
|
||||
|
||||
def __init__(self, repo_path: str = "repo", sandbox: str = None):
|
||||
"""
|
||||
Args:
|
||||
repo_path: путь к репозиторию (папка с пакетами)
|
||||
sandbox: путь к песочнице (если указан, все установки идут туда)
|
||||
"""
|
||||
self.repo_path = repo_path
|
||||
|
||||
# Если указана песочница, используем её как корень
|
||||
if sandbox:
|
||||
self.root = sandbox
|
||||
self.sandbox_mode = True
|
||||
print(f"🏖️ РЕЖИМ ПЕСОЧНИЦЫ: {sandbox}")
|
||||
print_sandbox_mode(self.root)
|
||||
else:
|
||||
self.root = "/"
|
||||
self.sandbox_mode = False
|
||||
@@ -30,14 +26,12 @@ class PackageManager:
|
||||
self.db = DatabaseManager(self.root)
|
||||
|
||||
def install(self, package_name: str) -> bool:
|
||||
"""Устанавливает пакет"""
|
||||
print(f"🔧 Поиск пакета {package_name}...")
|
||||
print_step(f"Поиск пакета {package_name}...")
|
||||
|
||||
# Ищем meta.json пакета
|
||||
meta_path = os.path.join(self.repo_path, "packages", package_name, "meta.json")
|
||||
|
||||
if not os.path.exists(meta_path):
|
||||
print(f"❌ Пакет {package_name} не найден в репозитории")
|
||||
print_error(f"Пакет {package_name} не найден")
|
||||
return False
|
||||
|
||||
with open(meta_path, 'r') as f:
|
||||
@@ -45,40 +39,31 @@ class PackageManager:
|
||||
|
||||
pkg = Package(**pkg_data)
|
||||
|
||||
# Проверяем, не установлен ли уже
|
||||
if self.db.is_installed(package_name):
|
||||
print(f"ℹ️ Пакет {package_name} уже установлен")
|
||||
print_warning(f"Пакет {package_name} уже установлен")
|
||||
return True
|
||||
|
||||
print(f"📦 Установка {pkg.full_name()}...")
|
||||
print_package(f"Установка {pkg.full_name()}...")
|
||||
|
||||
# Копируем файлы
|
||||
source_dir = os.path.join(self.repo_path, "packages", package_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(f"✅ Пакет {package_name} успешно установлен")
|
||||
print_success(f"Пакет {package_name} установлен")
|
||||
|
||||
if self.sandbox_mode:
|
||||
print(f"📁 Файлы установлены в: {self.root}")
|
||||
print_info(f"Файлы в: {self.root}")
|
||||
|
||||
return True
|
||||
|
||||
def list_installed(self) -> List[Package]:
|
||||
"""Возвращает список установленных пакетов"""
|
||||
return list(self.db.installed.values())
|
||||
47
mypkg/utils/colors.py
Normal file
47
mypkg/utils/colors.py
Normal file
@@ -0,0 +1,47 @@
|
||||
# mypkg/utils/colors.py
|
||||
class Colors:
|
||||
"""ANSI-коды для цветов в терминале"""
|
||||
GREEN = '\033[92m'
|
||||
RED = '\033[91m'
|
||||
YELLOW = '\033[93m'
|
||||
BLUE = '\033[94m'
|
||||
CYAN = '\033[96m'
|
||||
MAGENTA = '\033[95m'
|
||||
BOLD = '\033[1m'
|
||||
DIM = '\033[2m'
|
||||
RESET = '\033[0m'
|
||||
|
||||
|
||||
class Emoji:
|
||||
"""Эмодзи для разных ситуаций"""
|
||||
SUCCESS = "✅"
|
||||
ERROR = "❌"
|
||||
WARNING = "⚠️"
|
||||
INFO = "ℹ️"
|
||||
PACKAGE = "📦"
|
||||
INSTALL = "🔧"
|
||||
DELETE = "🗑️"
|
||||
SEARCH = "🔍"
|
||||
SANDBOX = "🏖️"
|
||||
|
||||
|
||||
def print_success(msg: str):
|
||||
print(f"{Colors.GREEN}{Emoji.SUCCESS} {msg}{Colors.RESET}")
|
||||
|
||||
def print_error(msg: str):
|
||||
print(f"{Colors.RED}{Emoji.ERROR} {msg}{Colors.RESET}")
|
||||
|
||||
def print_warning(msg: str):
|
||||
print(f"{Colors.YELLOW}{Emoji.WARNING} {msg}{Colors.RESET}")
|
||||
|
||||
def print_info(msg: str):
|
||||
print(f"{Colors.BLUE}{Emoji.INFO} {msg}{Colors.RESET}")
|
||||
|
||||
def print_package(msg: str):
|
||||
print(f"{Colors.CYAN}{Emoji.PACKAGE} {msg}{Colors.RESET}")
|
||||
|
||||
def print_step(msg: str):
|
||||
print(f"{Colors.BOLD}{Emoji.INSTALL} {msg}{Colors.RESET}")
|
||||
|
||||
def print_sandbox_mode(root: str):
|
||||
print(f"{Colors.YELLOW}{Emoji.SANDBOX} РЕЖИМ ПЕСОЧНИЦЫ: {root}{Colors.RESET}")
|
||||
Reference in New Issue
Block a user