Erminig/erminig/core/package.py

106 lines
3.6 KiB
Python
Raw Normal View History

#
# Erminig - Fonctions de base pour les paquets
# Copyright (C) 2025 L0m1g
# Sous licence DOUARN - Voir le fichier LICENCE pour les détails
#
# Ce fichier fait partie du projet Erminig.
# Libre comme lair, stable comme un menhir, et salé comme le beurre.
#
2025-05-05 16:16:24 +02:00
import hashlib
import tarfile
import tempfile
import shutil
import pwd
import grp
from pathlib import Path
from erminig.core.config import Config
class Package:
def __init__(self, name, version, tmp_dir):
self.name = name
self.version = version
self.tmp_dir = Path(tmp_dir)
self.manifest = []
def generate_manifest(self):
install_root = self.tmp_dir / "tmp"
for path in install_root.rglob("*"):
rel_path = Path("/") / path.relative_to(install_root)
stat = path.lstat()
user = pwd.getpwuid(stat.st_uid).pw_name
group = grp.getgrgid(stat.st_gid).gr_name
2025-05-05 16:16:24 +02:00
if path.is_file():
md5 = hashlib.md5(path.read_bytes()).hexdigest()
self.manifest.append(
{
"path": str(rel_path),
"md5": md5,
"mode": oct(stat.st_mode & 0o777),
"user": user,
"group": group,
"type": "file",
}
)
elif path.is_dir():
self.manifest.append(
{
"path": str(rel_path),
"md5": "-", # pas de hash pour les dossiers
"mode": oct(stat.st_mode & 0o777),
"user": user,
"group": group,
"type": "dir",
2025-05-05 16:16:24 +02:00
}
)
def write_manifest(self):
manifest_path = self.tmp_dir / "MANIFEST"
with open(manifest_path, "w") as f:
for entry in self.manifest:
f.write(
f"{entry['type']} {entry['path']} {entry['md5']} {entry['mode']} {entry['user']} {entry['group']}\n"
2025-05-05 16:16:24 +02:00
)
def copy_pakva(self, pakva_path):
dest = self.tmp_dir / "Pakva"
content = Path(pakva_path).read_text()
dest.write_text(content)
# Dans ta classe Package
def build_archive(self):
temp_dir = tempfile.mkdtemp()
temp_path = Path(temp_dir)
# Copie les fichiers Pakva et MANIFEST dans le répertoire temporaire
shutil.copy(self.tmp_dir / "Pakva", temp_path / "Pakva")
shutil.copy(self.tmp_dir / "MANIFEST", temp_path / "MANIFEST")
# Crée le dossier Files et copie dedans UNIQUEMENT le contenu de $TMP
files_dir = temp_path / "Files"
files_dir.mkdir()
for item in (self.tmp_dir).iterdir():
if item.name in ["Pakva", "MANIFEST"]:
continue
install_dir = self.tmp_dir / "tmp"
if install_dir.exists():
for item in install_dir.iterdir():
dest = files_dir / item.name
if item.is_dir():
shutil.copytree(item, dest)
else:
shutil.copy2(item, dest)
# Crée l'archive .bzh sans inclure les dossiers de travail
archive_path = Config.BUILD_DIR / f"{self.name}-{self.version}.bzh"
with tarfile.open(archive_path, "w|xz") as tar:
tar.add(temp_path / "Pakva", arcname="Pakva")
tar.add(temp_path / "MANIFEST", arcname="MANIFEST")
tar.add(files_dir, arcname="Files")
shutil.rmtree(temp_path)
return archive_path