#!/usr/bin/python # -*- coding: utf-8 -*- import os import sys import argparse import sqlite3 import string import rpm import re import gettext from versutils import * gettext.install('urpm-tools') DB = 'repo.db' def parseargs(args): parser = argparse.ArgumentParser(description=_('Check repository\'s redundancy for a given list of packages.')) parser.add_argument('packages_lst', metavar='packages.lst', help=('path to packages.lst')) parser.add_argument('--repo', action='append', nargs='+', required=True, metavar='REPO', help=_('URL or name of a repository')) opts = parser.parse_args() return opts def main(args): options = parseargs(args) with open(options.packages_lst, 'r') as f: ks_cfg = f.read() section = None in_packages = False sel_packages = [] for line in ks_cfg.split('\n'): ls = line.strip() if ls and not ls.startswith('#'): sel_packages.append(ls) conn = sqlite3.connect(DB) c = conn.cursor() repodirs = [] for repo in options.repo[0]: print repo rid = c.execute(""" SELECT id FROM repodirs WHERE name = ? OR path = ? """, [repo, repo]).fetchall() if rid is None: print 'Repository "%" not found.' % repo exit(1) repodirs.append(rid[0][0]) if not repodirs: print 'No repositories specified.' exit(1) if not sel_packages: print 'No packages specified.' exit(1) in_repodirs = ','.join(str(id) for id in repodirs) package_ids = [] for spackage in sel_packages: packages_found = c.execute(""" SELECT id, nvra, version, release FROM packages WHERE repodir_id IN (%s) AND name = ? """ % in_repodirs, [spackage]).fetchall() if not packages_found: print 'Package "%s" not found!' % spackage continue pid = None if len(packages_found) > 1: chosen_nvra = None chosen_version = None for vpid in packages_found: better_found = pid is None verrel = (vpid[2] if vpid[2] is not None else '') + '-' + \ (vpid[3] if vpid[3] is not None else '') if not better_found: better_found = version_ok(chosen_version, RPMSENSE_GREATER, verrel) if better_found: pid = vpid[0] chosen_nvra = vpid[1] chosen_version = verrel print ('Multiple versions of "%s" found (%s). Choosing latest: %s.' % (spackage, ', '.join(cp[1] for cp in packages_found), chosen_nvra)) else: pid = packages_found[0][0] package_ids.append(pid) package_cnt = 0 while package_cnt < len(package_ids): package_cnt = len(package_ids) in_packages = ','.join(str(id) for id in package_ids) for required_package in c.execute(""" SELECT packages.id, packages.name, nvra FROM packages, requires WHERE packages.id = requires.dep_package_id AND packages.repodir_id IN (%s) AND requires.package_id IN (%s) AND packages.id NOT IN (%s) ORDER BY packages.name """ % (in_repodirs, in_packages, in_packages)): package_ids.append(required_package[0]) in_packages = ','.join(str(id) for id in package_ids) pre_repodir_id = -1 repo_packages_cnt = 0 for reduntant_package in c.execute(""" SELECT repodir_id, repodirs.name, packages.id, packages.nvra FROM packages, repodirs WHERE packages.repodir_id = repodirs.id AND repodirs.id IN (%s) AND packages.id NOT IN (%s) ORDER BY repodir_id, nvra """ % (in_repodirs, in_packages)): (repodir_id, repodir_name, package_nvra) = \ (reduntant_package[0], reduntant_package[1], reduntant_package[3]) if pre_repodir_id != repodir_id: if pre_repodir_id == -1: print 'Redundant packages:' else: print 'Total: %d' % repo_packages_cnt print '' print '%d) %s' % (repodir_id, repodir_name) pre_repodir_id = repodir_id repo_packages_cnt = 0 print '\t%s' % package_nvra repo_packages_cnt += 1 if pre_repodir_id != -1: print 'Total: %d' % repo_packages_cnt print '' conn.rollback() if __name__ == "__main__": main(sys.argv)