124 lines
4.1 KiB
Python
124 lines
4.1 KiB
Python
"""
|
|
Debian package manager for Blue-Build CLI
|
|
|
|
Handles APT-based package management and repository configuration.
|
|
"""
|
|
|
|
import subprocess
|
|
import tempfile
|
|
from typing import List, Dict, Any, Optional
|
|
from pathlib import Path
|
|
|
|
class DebianPackageManager:
|
|
"""Debian package management using APT"""
|
|
|
|
def __init__(self, work_dir: Optional[Path] = None):
|
|
self.work_dir = work_dir or Path.cwd()
|
|
self.repositories = []
|
|
self.packages = []
|
|
|
|
def add_repository(self, repo_line: str) -> bool:
|
|
"""Add Debian repository"""
|
|
try:
|
|
# Parse repository line (deb http://deb.debian.org/debian bookworm main)
|
|
parts = repo_line.split()
|
|
if len(parts) >= 4 and parts[0] == "deb":
|
|
self.repositories.append(repo_line)
|
|
return True
|
|
return False
|
|
except Exception:
|
|
return False
|
|
|
|
def add_package(self, package_name: str) -> bool:
|
|
"""Add package to install list"""
|
|
if package_name and package_name not in self.packages:
|
|
self.packages.append(package_name)
|
|
return True
|
|
return False
|
|
|
|
def resolve_dependencies(self, package_name: str) -> List[str]:
|
|
"""Resolve package dependencies"""
|
|
try:
|
|
result = subprocess.run(
|
|
["apt-cache", "depends", package_name],
|
|
capture_output=True,
|
|
text=True,
|
|
cwd=self.work_dir
|
|
)
|
|
|
|
if result.returncode == 0:
|
|
dependencies = []
|
|
for line in result.stdout.split('\n'):
|
|
if line.strip().startswith('Depends:'):
|
|
deps = line.replace('Depends:', '').strip()
|
|
dependencies.extend([d.strip() for d in deps.split(',')])
|
|
return dependencies
|
|
return []
|
|
except Exception:
|
|
return []
|
|
|
|
def create_sources_list(self, output_path: Path) -> bool:
|
|
"""Create sources.list file"""
|
|
try:
|
|
with open(output_path, 'w') as f:
|
|
for repo in self.repositories:
|
|
f.write(f"{repo}\n")
|
|
return True
|
|
except Exception:
|
|
return False
|
|
|
|
def generate_apt_commands(self) -> List[str]:
|
|
"""Generate APT commands for package installation"""
|
|
commands = [
|
|
"apt-get update",
|
|
f"apt-get install -y {' '.join(self.packages)}",
|
|
"apt-get clean",
|
|
"rm -rf /var/lib/apt/lists/*"
|
|
]
|
|
return commands
|
|
|
|
def validate_packages(self) -> Dict[str, List[str]]:
|
|
"""Validate package availability"""
|
|
results = {
|
|
"available": [],
|
|
"unavailable": [],
|
|
"dependencies": []
|
|
}
|
|
|
|
for package in self.packages:
|
|
try:
|
|
result = subprocess.run(
|
|
["apt-cache", "show", package],
|
|
capture_output=True,
|
|
text=True,
|
|
cwd=self.work_dir
|
|
)
|
|
|
|
if result.returncode == 0:
|
|
results["available"].append(package)
|
|
deps = self.resolve_dependencies(package)
|
|
results["dependencies"].extend(deps)
|
|
else:
|
|
results["unavailable"].append(package)
|
|
except Exception:
|
|
results["unavailable"].append(package)
|
|
|
|
return results
|
|
|
|
def create_package_script(self, output_path: Path) -> bool:
|
|
"""Create package installation script"""
|
|
try:
|
|
with open(output_path, 'w') as f:
|
|
f.write("#!/bin/bash\n")
|
|
f.write("set -e\n\n")
|
|
f.write("# Package installation script\n")
|
|
f.write("# Generated by Debian Blue-Build CLI\n\n")
|
|
|
|
for cmd in self.generate_apt_commands():
|
|
f.write(f"{cmd}\n")
|
|
|
|
# Make executable
|
|
output_path.chmod(0o755)
|
|
return True
|
|
except Exception:
|
|
return False
|