mirror of
https://abf.rosa.ru/djam/repo-analyzer.git
synced 2025-02-23 04:22:46 +00:00
Add analyze-repo-closure script
This commit is contained in:
parent
c1efad5d72
commit
9e28dd5f8b
1 changed files with 197 additions and 0 deletions
197
analyze-repo-closure.py
Executable file
197
analyze-repo-closure.py
Executable file
|
@ -0,0 +1,197 @@
|
|||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import os
|
||||
import sys
|
||||
import argparse
|
||||
import sqlite3
|
||||
import string
|
||||
import rpm
|
||||
import re
|
||||
import gettext
|
||||
prepare_repodb = __import__("prepare-repodb")
|
||||
|
||||
gettext.install('urpm-tools')
|
||||
|
||||
DB = 'repo.db'
|
||||
|
||||
def parseargs(args):
|
||||
parser = argparse.ArgumentParser(description=_('Find a closed subset of the repository\'s 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:
|
||||
print repo
|
||||
rid = c.execute("""
|
||||
SELECT id FROM repodirs WHERE name = ? OR url = ?
|
||||
""", [repo[0], repo[0]]).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 = prepare_repodb.version_ok(chosen_version,
|
||||
prepare_repodb.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)
|
||||
|
||||
pre_package_cnt = 0
|
||||
src_package_cnt = 0
|
||||
src_package_ids = []
|
||||
while True:
|
||||
src_package_cnt = len(src_package_ids)
|
||||
print >> sys.stderr, "packages processed:", pre_package_cnt, len(package_ids)
|
||||
if pre_package_cnt == len(package_ids):
|
||||
break
|
||||
in_next_packages = ','.join(str(id) for id in package_ids[pre_package_cnt:])
|
||||
pre_package_cnt = len(package_ids)
|
||||
|
||||
for lost_src in c.execute("""
|
||||
SELECT '"' || nvra || '" (' || sourcerpm || ')' FROM packages
|
||||
WHERE id IN (%s) AND
|
||||
sourcerpm IS NOT NULL AND sourcerpm_package IS NULL
|
||||
ORDER BY nvra
|
||||
""" % in_next_packages):
|
||||
print 'Source rpm for package %s not found!' % lost_src
|
||||
|
||||
|
||||
in_packages = ','.join(str(id) for id in package_ids)
|
||||
in_src_packages = ','.join(str(id) for id in src_package_ids) \
|
||||
if len(src_package_ids) > 0 else '-1'
|
||||
for src_package in c.execute("""
|
||||
SELECT sourcerpm_package FROM packages
|
||||
WHERE id IN (%s) AND sourcerpm IS NOT NULL AND sourcerpm_package IS NOT NULL
|
||||
AND sourcerpm_package NOT IN (%s)
|
||||
""" % (in_packages, in_src_packages)):
|
||||
src_package_ids.append(src_package[0])
|
||||
print >> sys.stderr, "src packages processed:", src_package_cnt, len(src_package_ids)
|
||||
if src_package_cnt == len(src_package_ids):
|
||||
break
|
||||
|
||||
while True:
|
||||
package_cnt = len(package_ids)
|
||||
in_packages = ','.join(str(id) for id in package_ids + src_package_ids)
|
||||
for required_package in c.execute("""
|
||||
SELECT packages.id, packages.name, nvra
|
||||
FROM packages, package_requires_res
|
||||
WHERE packages.id = package_requires_res.dep_package_id AND
|
||||
packages.repodir_id IN (%s) AND
|
||||
package_requires_res.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])
|
||||
if package_cnt == len(package_ids):
|
||||
break
|
||||
|
||||
|
||||
in_src_packages = ','.join(str(id) for id in src_package_ids) \
|
||||
if len(src_package_ids) > 0 else '-1'
|
||||
|
||||
repo_packages_cnt = 0
|
||||
pre_repodir_id = -1
|
||||
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
|
||||
packages.id IN (%s)
|
||||
ORDER BY repodir_id, nvra
|
||||
""" % (in_src_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 'Required source 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 ''
|
||||
|
||||
repo_packages_cnt = 0
|
||||
pre_repodir_id = -1
|
||||
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.name IN (SELECT sources FROM repodirs WHERE id IN (%s)) AND
|
||||
packages.id NOT IN (%s)
|
||||
ORDER BY repodir_id, nvra
|
||||
""" % (in_repodirs, in_src_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 source 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)
|
Loading…
Add table
Reference in a new issue