repo-analyzer/analyze-repo-redundancy.py
2014-02-06 20:09:59 +04:00

133 lines
4.5 KiB
Python
Executable file

#!/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 not rid:
print 'Repository "%s" 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)