#!/usr/bin/env python3 """Parses pacstall packages into JSON.""" import sys from json import dumps from pathlib import Path from shutil import rmtree from subprocess import PIPE, Popen, run def extract_var(line: str, var: str) -> str: """ Strips off ``var=`` and quotes from a line and returns the variable. Parameters ---------- line (str): The pacscript line. var (str): The variable to extract. Returns ------- Extracted variable. """ return line.replace(var, "").strip('"') def query_data(pacscript_reader_process: "Popen[bytes]", query_command: str) -> str: """ Queries data off of the pacscript reading subprocess. Parameters ---------- pacscript_reader_process (Popen[bytes]): The pacscript reading subprocess. query_command (str): The command to execute in the ``pacscript_reader_process``. Returns ------- The output of ``query_command`` in the subprocess. """ if pacscript_reader_process.stdin is None: sys.exit("FATAL ERROR: Can't send commands to the pacscript reader!") if pacscript_reader_process.stdout is None: sys.exit("FATAL ERROR: Can't read output from the pacscript reader!") pacscript_reader_process.stdin.write(f"{query_command}\n".encode()) pacscript_reader_process.stdin.flush() return pacscript_reader_process.stdout.readline().decode("utf-8").strip() def main() -> None: """Main function.""" CLONED_PACKAGES_DIR = Path("/tmp/pacparse") JSON = Path("pacstall.json") PACKAGE_LIST = CLONED_PACKAGES_DIR / "packagelist" if CLONED_PACKAGES_DIR.exists(): rmtree(CLONED_PACKAGES_DIR) REPOSITORY_URL = "https://github.com/pacstall/pacstall-programs" # Clone the repo run( [ "git", "clone", "--depth", "1", f"{REPOSITORY_URL}.git", CLONED_PACKAGES_DIR, ], check=True, ) # Changed changed_pacscripts = all packages if none are specified # Otherwise changed_pacscripts = specified packages + all git packages changed_pacscripts = all_pacscripts = PACKAGE_LIST.read_text().splitlines() try: if sys.argv[1] in ["-p", "--packages"]: # Get the pacscript files supplied changed_pacscripts = [ changed_package.split("/")[-1].replace(".pacscript", "") for changed_package in sys.argv[2:] if changed_package.endswith(".pacscript") ] for pacscript in all_pacscripts: if "-git" in pacscript: changed_pacscripts.append(pacscript) except IndexError: pass print(f"\nComputing: {changed_pacscripts}\n") NAME = "name=" VERSION = "version=" URL = "url=" DESCRIPTION = "description=" DEPENDS = "depends=" BUILD_DEPENDS = "build_depends=" MAINTAINER = "maintainer=" repology_data = {} for package in changed_pacscripts: print(f"Current Package: {package}") pacscript_data = {} pacscript_file = CLONED_PACKAGES_DIR / f"packages/{package}/{package}.pacscript" pacscript_reader = Popen(["/bin/bash"], stdin=PIPE, stdout=PIPE) if pacscript_reader.stdin is None: sys.exit("FATAL ERROR: Can't send commands to the pacscript reader!") pacscript_reader.stdin.write(f"source {pacscript_file}\n".encode()) pacscript_reader.stdin.flush() try: pacscript_lines = pacscript_file.read_text().splitlines() except FileNotFoundError: print(f"Warning: '{pacscript_file}' not found") continue name = "" for line in pacscript_lines: if line.startswith(NAME): name = extract_var(line, NAME) elif line.startswith(VERSION): if any( char in (version := extract_var(line, VERSION)) for char in ["$", "\\"] ): version = query_data(pacscript_reader, "echo ${version}") pacscript_data["version"] = version elif line.startswith(URL): if any(char in (url := extract_var(line, URL)) for char in ["$", "\\"]): url = query_data(pacscript_reader, "echo ${url}") pacscript_data["url"] = url elif line.startswith(DESCRIPTION): if any( char in (description := extract_var(line, DESCRIPTION)) for char in ["$", "\\"] ): description = query_data(pacscript_reader, "echo ${description}") pacscript_data["summary"] = description elif line.startswith(DEPENDS): if any( char in (depends := extract_var(line, DEPENDS)) for char in ["$", "\\"] ): depends = query_data(pacscript_reader, "echo ${depends}") try: pacscript_data["dependencies"] += f" {depends}" except KeyError: pacscript_data["dependencies"] = depends elif line.startswith(BUILD_DEPENDS): if any( char in (build_depends := extract_var(line, BUILD_DEPENDS)) for char in ["$", "\\"] ): build_depends = query_data( pacscript_reader, "echo ${build_depends}" ) build_depends = query_data(pacscript_reader, "echo ${build_depends}") try: pacscript_data["dependencies"] += f" {build_depends}" except KeyError: pacscript_data["dependencies"] = build_depends elif line.startswith(MAINTAINER): if any( char in (maintainer := extract_var(line, MAINTAINER)) for char in ["$", "\\"] ): maintainer = query_data(pacscript_reader, "echo ${maintainer}") pacscript_data["maintainer"] = maintainer pacscript_data[ "recipe" ] = f"{REPOSITORY_URL}/blob/master/packages/{name}/{name}.pacscript" repology_data[name] = pacscript_data pacscript_reader.stdin.close() pacscript_reader.wait() with open(JSON, "w") as file: print(f"Writing file: {JSON}") file.write(dumps(repology_data, indent="\t")) if __name__ == "__main__": main()