#!/usr/bin/python3 """Upload a gist containing packages installed on the system. Dependencies ============ * pacman * gist """ import argparse import configparser import re import subprocess import sys # ========== Constants ========== # Paths CONFIG_FILE = "/etc/packaging-scripts.conf" DEFAULT_FILENAME = "pacman-packages.txt" # Config file options CONFIG_SECTION = "pug2" CONFIG_OPTION_DESCRIPTION = "GIST_DESCRIPTION" CONFIG_OPTION_ENABLE = "RUN_ON_PACMAN_HOOK" CONFIG_OPTION_FILENAME = "GIST_FILENAME" CONFIG_OPTION_ID = "GIST_ID" # ========== Functions ========== def extract_gist_id(url): """Extract the gist id from a gist URL. Normalizes URLs from * http(s)?://..// * / * to one of * / * both of which are valid for use with gist :param url: a valid URL containing the gist id :type url: str :returns: the valid gist ID :rtype: str """ return re.sub("^http(s)?://[\\w]*.[\\w]*.[\\w]/", "", url) def retrieve_gist_info(gist_id): """Retrieve info from gist ID that is specified in the config file. :param gist_id: string id to read gist info :returns: data read from gist :rtype: bytes """ return subprocess.run(f"gist --read {gist_id}", capture_output=True).stdout def package_lists_match(gist_id): """Compare local package list to that of pacman and gist, return if they match.""" local_packages = subprocess.run(["pacman", "-Qqen"], capture_output=True).stdout gist_packages = subprocess.run( ["gist", "--read", gist_id], capture_output=True ).stdout return local_packages == gist_packages # ========== Main Script ========== if __name__ == "__main__": parser = argparse.ArgumentParser() parser.add_argument( "-c", "--check-if-enabled", dest="check_enabled", help="check if enabled in config file", action="store_true", ) args = parser.parse_args() config = configparser.ConfigParser() config.read(CONFIG_FILE) # Check if script is enabled to run; if not, exit silently if args.check_enabled and not config.getboolean( CONFIG_SECTION, CONFIG_OPTION_ENABLE ): sys.exit(0) gist_description = config.get(CONFIG_SECTION, CONFIG_OPTION_DESCRIPTION) gist_filename = config.get(CONFIG_SECTION, CONFIG_OPTION_FILENAME) gist_id = config.get(CONFIG_SECTION, CONFIG_OPTION_ID) if gist_id == "": try: print("No gist ID detected, creating new.") gist_process = subprocess.run( f"pacman -Qqen | gist --filename {gist_filename} --description {gist_description}", capture_output=True, text=True, shell=True, check=True, ) except subprocess.CalledProcessError as e: print(e.stdout.strip(), file=sys.stderr) sys.exit(e.returncode) else: config[CONFIG_SECTION][CONFIG_OPTION_ID] = extract_gist_id( gist_process.stdout ) print("Gist creation complete.") elif package_lists_match(gist_id): print("Package lists match, no update necessary.") sys.exit(0) else: try: print("Package lists differ, updating.") subprocess.run( f"pacman -Qqen | gist --update {gist_id} --filename {gist_filename} --description {gist_description}", capture_output=True, text=True, shell=True, check=True, ) except subprocess.CalledProcessError as e: print(e.stdout.strip(), file=sys.stderr) sys.exit(e.returncode) else: print("Update complete.")