2025-01-05 08:37:11 +00:00
|
|
|
import os
|
|
|
|
import shutil
|
2025-01-02 21:26:20 +00:00
|
|
|
import sys
|
2025-01-05 08:37:11 +00:00
|
|
|
import tempfile
|
2025-01-02 21:26:20 +00:00
|
|
|
|
2025-01-05 08:37:11 +00:00
|
|
|
import git
|
2025-01-02 21:26:20 +00:00
|
|
|
import tree_sitter_bash as tsbash
|
|
|
|
from tree_sitter import Language, Parser
|
|
|
|
|
|
|
|
from aides_spec.replacers.arch_replacer import ArchReplacer
|
|
|
|
from aides_spec.replacers.simple_replacer import SimpleReplacer
|
2025-01-05 08:37:11 +00:00
|
|
|
from aides_spec.replacers.sources import SourcesReplacer
|
2025-01-02 21:26:20 +00:00
|
|
|
|
2025-01-07 10:30:50 +00:00
|
|
|
HEADER = """#
|
|
|
|
# WARNING: Automatically converted from PKGBUILD and may contain errors
|
|
|
|
#
|
|
|
|
"""
|
2025-01-02 21:26:20 +00:00
|
|
|
|
|
|
|
|
2025-01-07 10:30:50 +00:00
|
|
|
class PkgbuildDownloader:
|
|
|
|
"""Handles downloading PKGBUILD and associated files."""
|
2025-01-05 08:37:11 +00:00
|
|
|
|
2025-01-07 10:30:50 +00:00
|
|
|
@staticmethod
|
|
|
|
def download_and_extract(pkgname: str) -> bytes:
|
|
|
|
aur_url = f"https://aur.archlinux.org/{pkgname}.git"
|
2025-01-05 08:37:11 +00:00
|
|
|
|
2025-01-07 10:30:50 +00:00
|
|
|
with tempfile.TemporaryDirectory() as tmpdirname:
|
|
|
|
try:
|
|
|
|
print(f"Cloning repository for {pkgname}...")
|
|
|
|
git.Repo.clone_from(aur_url, tmpdirname)
|
|
|
|
print(f"Files for {pkgname} downloaded to {tmpdirname}")
|
2025-01-05 08:37:11 +00:00
|
|
|
|
2025-01-07 10:30:50 +00:00
|
|
|
PkgbuildDownloader._copy_files(tmpdirname)
|
2025-01-05 08:37:11 +00:00
|
|
|
|
2025-01-07 10:30:50 +00:00
|
|
|
with open(os.path.join(tmpdirname, "PKGBUILD"), "rb") as f:
|
|
|
|
return f.read()
|
2025-01-05 08:37:11 +00:00
|
|
|
|
2025-01-07 10:30:50 +00:00
|
|
|
except Exception as e:
|
|
|
|
print(f"Error downloading repository: {e}", file=sys.stderr)
|
|
|
|
sys.exit(1)
|
2025-01-05 08:37:11 +00:00
|
|
|
|
2025-01-07 10:30:50 +00:00
|
|
|
@staticmethod
|
|
|
|
def _copy_files(tmpdirname: str):
|
|
|
|
"""Copies all files to the current directory."""
|
|
|
|
for root, dirs, files in os.walk(tmpdirname):
|
|
|
|
dirs[:] = [d for d in dirs if d not in [".git"]]
|
|
|
|
files = [f for f in files if f not in ["PKGBUILD", ".SRCINFO"]]
|
2025-01-05 08:37:11 +00:00
|
|
|
|
2025-01-07 10:30:50 +00:00
|
|
|
for file in files:
|
|
|
|
file_path = os.path.join(root, file)
|
|
|
|
relative_path = os.path.relpath(file_path, tmpdirname)
|
|
|
|
destination_path = os.path.join(os.getcwd(), relative_path)
|
2025-01-05 08:37:11 +00:00
|
|
|
|
2025-01-07 10:30:50 +00:00
|
|
|
os.makedirs(os.path.dirname(destination_path), exist_ok=True)
|
|
|
|
shutil.copy(file_path, destination_path)
|
2025-01-05 08:37:11 +00:00
|
|
|
|
|
|
|
|
2025-01-07 10:30:50 +00:00
|
|
|
class PkgbuildProcessor:
|
|
|
|
"""Processes PKGBUILD files with replacers."""
|
2025-01-05 08:37:11 +00:00
|
|
|
|
2025-01-07 10:30:50 +00:00
|
|
|
def __init__(self):
|
|
|
|
self.parser = self._initialize_parser()
|
2025-01-02 21:26:20 +00:00
|
|
|
|
2025-01-07 10:30:50 +00:00
|
|
|
@staticmethod
|
|
|
|
def _initialize_parser() -> Parser:
|
|
|
|
bash_language = Language(tsbash.language())
|
|
|
|
return Parser(bash_language)
|
2025-01-02 21:26:20 +00:00
|
|
|
|
2025-01-07 10:30:50 +00:00
|
|
|
def process(self, content: bytes, replacers: list) -> bytes:
|
|
|
|
tree = self.parser.parse(content)
|
2025-01-02 21:26:20 +00:00
|
|
|
|
2025-01-07 10:30:50 +00:00
|
|
|
for replacer_class in replacers:
|
|
|
|
replacer = replacer_class(content, tree)
|
|
|
|
content = replacer.process()
|
|
|
|
tree = self.parser.parse(content, tree)
|
2025-01-02 21:26:20 +00:00
|
|
|
|
2025-01-07 10:30:50 +00:00
|
|
|
return content
|
2025-01-05 08:37:11 +00:00
|
|
|
|
|
|
|
|
2025-01-07 10:30:50 +00:00
|
|
|
def create_from_pkgbuild(content: bytes, output_file: str):
|
|
|
|
"""Creates a new spec file from a PKGBUILD."""
|
|
|
|
processor = PkgbuildProcessor()
|
2025-01-02 21:26:20 +00:00
|
|
|
|
|
|
|
replacers = [
|
|
|
|
SimpleReplacer,
|
|
|
|
ArchReplacer,
|
|
|
|
SourcesReplacer,
|
|
|
|
]
|
|
|
|
|
|
|
|
try:
|
2025-01-07 10:30:50 +00:00
|
|
|
new_content = processor.process(content, replacers)
|
|
|
|
new_content = bytes(HEADER, encoding="utf-8") + new_content
|
|
|
|
|
2025-01-02 21:26:20 +00:00
|
|
|
with open(output_file, "wb") as f:
|
|
|
|
f.write(new_content)
|
2025-01-07 10:30:50 +00:00
|
|
|
|
|
|
|
print(f"File successfully written to {output_file}.")
|
2025-01-02 21:26:20 +00:00
|
|
|
except IOError as e:
|
2025-01-07 10:30:50 +00:00
|
|
|
print(f"Error writing file: {e}", file=sys.stderr)
|
2025-01-02 21:26:20 +00:00
|
|
|
sys.exit(1)
|