83 lines
3 KiB
Python
83 lines
3 KiB
Python
|
#!/usr/bin/env python3
|
|||
|
# -*- coding: utf-8 -*-
|
|||
|
|
|||
|
|
|||
|
import argparse
|
|||
|
import os
|
|||
|
import subprocess
|
|||
|
|
|||
|
from arch import ArchDatabase, ArchPackage
|
|||
|
from aur import AURPackage
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
class Styling:
|
|||
|
"""Output styling constants."""
|
|||
|
ENDC = '\033[0m'
|
|||
|
BOLD = '\033[1m'
|
|||
|
UPTODATE = '\033[32m'
|
|||
|
NEEDS_UPDATE = '\033[31m'
|
|||
|
FLAGGED = '\033[33m'
|
|||
|
NEEDS_DOWNGRADE = '\033[34m'
|
|||
|
URL = '\033[37m'
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
class AURChecker:
|
|||
|
"""
|
|||
|
Read local Arch Linux package databases/repositories and compare the
|
|||
|
version of each containing package against the AUR package with the same
|
|||
|
name to determine and print a status for each package.
|
|||
|
"""
|
|||
|
STATUS_UPTODATE = "uptodate"
|
|||
|
STATUS_NEEDS_UPDATE = "needs update"
|
|||
|
STATUS_NEEDS_DOWNGRADE = "needs downgrade"
|
|||
|
|
|||
|
|
|||
|
def check(directory):
|
|||
|
"""Check all databases/repositories in a directory."""
|
|||
|
databases = ArchDatabase.find_databases(directory)
|
|||
|
for database in databases:
|
|||
|
AURChecker.check_database(database)
|
|||
|
|
|||
|
|
|||
|
def check_database(database):
|
|||
|
"""Check a database/repository."""
|
|||
|
print(Styling.BOLD + "# repository {}".format(database.get_name()) + Styling.ENDC)
|
|||
|
for package in database.get_packages():
|
|||
|
aur_package = AURPackage(package.get_name())
|
|||
|
status = AURChecker.compare(package, aur_package)
|
|||
|
|
|||
|
status_messages = {}
|
|||
|
status_messages[AURChecker.STATUS_UPTODATE] = Styling.UPTODATE + "up-do-date" + Styling.ENDC
|
|||
|
status_messages[AURChecker.STATUS_NEEDS_UPDATE] = Styling.NEEDS_UPDATE + "needs update to {}\n".format(aur_package.get_version()) + Styling.URL + " {}{}".format(AURPackage.AUR_URL, aur_package.get_url_path()) + Styling.ENDC
|
|||
|
status_messages[AURChecker.STATUS_NEEDS_DOWNGRADE] = Styling.NEEDS_DOWNGRADE + "local is newer" + Styling.ENDC
|
|||
|
|
|||
|
message = " – {} {}: {}".format(package.get_name(), package.get_version(), status_messages[status])
|
|||
|
if aur_package.get_out_of_date():
|
|||
|
message = Styling.FLAGGED + "{} (flagged)".format(message) + Styling.ENDC
|
|||
|
print(message)
|
|||
|
|
|||
|
|
|||
|
def compare(package, aur_package):
|
|||
|
"""Compare package two versions and return status."""
|
|||
|
result = subprocess.check_output(["vercmp", package.get_version(), aur_package.get_version()])
|
|||
|
result = int(result)
|
|||
|
if result < 0:
|
|||
|
return AURChecker.STATUS_NEEDS_UPDATE
|
|||
|
elif result > 0:
|
|||
|
return AURChecker.STATUS_NEEDS_DOWNGRADE
|
|||
|
else:
|
|||
|
return AURChecker.STATUS_UPTODATE
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
if __name__ == "__main__":
|
|||
|
parser = argparse.ArgumentParser("Read local Arch Linux package databases/repositories and compare the version of each containing package against the AUR package with the same name to determine and print a status for each package.")
|
|||
|
parser.add_argument('folder', help="source folder containing one or several databases/repositories (subdirectories possible)")
|
|||
|
args = parser.parse_args()
|
|||
|
AURChecker.check(args.folder)
|