From: Ansgar Burchardt Date: Wed, 26 Nov 2014 21:20:01 +0000 (+0100) Subject: Use new package_list view for "dak ls" command. X-Git-Url: https://git.decadent.org.uk/gitweb/?a=commitdiff_plain;h=6c1639be13ed7c7af1f58b522155953df5a9e94e;p=dak.git Use new package_list view for "dak ls" command. --- diff --git a/dak/ls.py b/dak/ls.py index f4ae00af..5ac4c660 100755 --- a/dak/ls.py +++ b/dak/ls.py @@ -36,7 +36,7 @@ import sys import apt_pkg from daklib.config import Config -from daklib.dbconn import * +from daklib.ls import list_packages from daklib import utils ################################################################################ @@ -89,8 +89,6 @@ def main (): if not packages: utils.fubar("need at least one package name as an argument.") - session = DBConn().session() - # If cron.daily is running; warn the user that our output might seem strange if os.path.exists(os.path.join(cnf["Dir::Lock"], "daily.lock")): utils.warn("Archive maintenance is in progress; database inconsistencies are possible.") @@ -102,117 +100,32 @@ def main (): if not Options["Suite"]: Options["Suite"] = "unstable" - # Parse -a/--architecture, -c/--component and -s/--suite - (con_suites, con_architectures, con_components, check_source) = \ - utils.parse_args(Options) - - if Options["BinaryType"]: - if Options["BinaryType"] != "udeb" and Options["BinaryType"] != "deb": - utils.fubar("Invalid binary type. 'udeb' and 'deb' recognised.") - con_bintype = "AND b.type = '%s'" % (Options["BinaryType"]) - # REMOVE ME TRAMP - if Options["BinaryType"] == "udeb": - check_source = 0 - else: - con_bintype = "" + kwargs = dict() if Options["Regex"]: - comparison_operator = "~" - else: - comparison_operator = "=" - + kwargs['regex'] = True if Options["Source-And-Binary"]: - new_packages = [] - for package in packages: - q = session.execute("SELECT DISTINCT b.package FROM binaries b, bin_associations ba, suite su, source s WHERE b.source = s.id AND su.id = ba.suite AND b.id = ba.bin AND s.source %s :package %s" % (comparison_operator, con_suites), - {'package': package}) - new_packages.extend([ i[0] for i in q.fetchall() ]) - if package not in new_packages: - new_packages.append(package) - packages = new_packages - - results = 0 - for package in packages: - q = session.execute(""" -SELECT b.package, b.version, a.arch_string, su.suite_name, c.name, m.name - FROM binaries b, architecture a, suite su, bin_associations ba, - files f, files_archive_map af, component c, maintainer m - WHERE b.package %s :package AND a.id = b.architecture AND su.id = ba.suite - AND b.id = ba.bin AND b.file = f.id AND af.file_id = f.id AND su.archive_id = af.archive_id - AND af.component_id = c.id AND b.maintainer = m.id %s %s %s -""" % (comparison_operator, con_suites, con_architectures, con_bintype), {'package': package}) - ql = q.fetchall() - if check_source: - q = session.execute(""" -SELECT s.source, s.version, 'source', su.suite_name, c.name, m.name - FROM source s, suite su, src_associations sa, files f, files_archive_map af, - component c, maintainer m - WHERE s.source %s :package AND su.id = sa.suite AND s.id = sa.source - AND s.file = f.id AND af.file_id = f.id AND af.archive_id = su.archive_id AND af.component_id = c.id - AND s.maintainer = m.id %s -""" % (comparison_operator, con_suites), {'package': package}) - if not Options["Architecture"] or con_architectures: - ql.extend(q.fetchall()) - else: - ql = q.fetchall() - d = {} - highver = {} - for i in ql: - results += 1 - (pkg, version, architecture, suite, component, maintainer) = i - if component != "main": - suite = "%s/%s" % (suite, component) - if not d.has_key(pkg): - d[pkg] = {} - highver.setdefault(pkg,"") - if not d[pkg].has_key(version): - d[pkg][version] = {} - if apt_pkg.version_compare(version, highver[pkg]) > 0: - highver[pkg] = version - if not d[pkg][version].has_key(suite): - d[pkg][version][suite] = [] - d[pkg][version][suite].append(architecture) - - packages = d.keys() - packages.sort() - - # Calculate optimal column sizes - sizes = [10, 13, 10] - for pkg in packages: - versions = d[pkg].keys() - for version in versions: - suites = d[pkg][version].keys() - for suite in suites: - sizes[0] = max(sizes[0], len(pkg)) - sizes[1] = max(sizes[1], len(version)) - sizes[2] = max(sizes[2], len(suite)) - fmt = "%%%is | %%%is | %%%is | " % tuple(sizes) - - for pkg in packages: - versions = d[pkg].keys() - versions.sort(apt_pkg.version_compare) - for version in versions: - suites = d[pkg][version].keys() - suites.sort() - for suite in suites: - arches = d[pkg][version][suite] - arches.sort(utils.arch_compare_sw) - if Options["Format"] == "": #normal - sys.stdout.write(fmt % (pkg, version, suite)) - sys.stdout.write(", ".join(arches)) - sys.stdout.write('\n') - elif Options["Format"] in [ "control-suite", "heidi" ]: - for arch in arches: - sys.stdout.write("%s %s %s\n" % (pkg, version, arch)) - if Options["GreaterOrEqual"]: - print "\n%s (>= %s)" % (pkg, highver[pkg]) - if Options["GreaterThan"]: - print "\n%s (>> %s)" % (pkg, highver[pkg]) - - if not results: - sys.exit(1) - -####################################################################################### + kwargs['source_and_binary'] = True + if Options["Suite"]: + kwargs['suites'] = utils.split_args(Options['Suite']) + if Options["Architecture"]: + kwargs['architectures'] = utils.split_args(Options['Architecture']) + if Options['BinaryType']: + kwargs['binary_types'] = utils.split_args(Options['BinaryType']) + if Options['Component']: + kwargs['components'] = utils.split_args(Options['Component']) + + if Options['Format']: + kwargs['format'] = Options['Format'] + if Options['GreaterOrEqual']: + kwargs['highest'] = '>=' + elif Options['GreaterThan']: + kwargs['highest'] = '>>' + + for line in list_packages(packages, **kwargs): + print line + +###################################################################################### if __name__ == '__main__': main() diff --git a/daklib/ls.py b/daklib/ls.py new file mode 100644 index 00000000..aeb8cfcb --- /dev/null +++ b/daklib/ls.py @@ -0,0 +1,84 @@ +"""List packages according to various criteria + +@copyright: 2014, Ansgar Burchardt +@license: GPL-2+ +""" + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +import sqlalchemy.sql as sql +import daklib.daksql as daksql + +from daklib.dbconn import DBConn, session_wrapper + +@session_wrapper +def list_packages(packages, suites=None, components=None, architectures=None, binary_types=None, + source_and_binary=False, regex=False, + format=None, highest=None, + session=None): + t = DBConn().view_package_list + + comparison_operator = "~" if regex else "=" + + where = sql.false() + for package in packages: + where = where | t.c.package.op(comparison_operator)(package) + if source_and_binary: + where = where | t.c.source.op(comparison_operator)(package) + + if suites is not None: + where = where & t.c.suite.in_(suites) + if components is not None: + where = where & t.c.component.in_(components) + if architectures is not None: + where = where & t.c.architecture.in_(architectures) + if binary_types is not None: + where = where & t.c.type.in_(binary_types) + + if format is None: + c_architectures = daksql.string_agg(t.c.architecture, ', ', order_by=[t.c.architecture_is_source.desc(), t.c.architecture]) + query = sql.select([t.c.package, t.c.version, t.c.display_suite, c_architectures]) \ + .where(where) \ + .group_by(t.c.package, t.c.version, t.c.display_suite) \ + .order_by(t.c.package, t.c.version, t.c.display_suite) + result = session.execute(query).fetchall() + + if len(result) == 0: + raise StopIteration + + lengths = { + 'package': max(10, max(len(row[t.c.package]) for row in result)), + 'version': max(13, max(len(row[t.c.version]) for row in result)), + 'suite': max(10, max(len(row[t.c.display_suite]) for row in result)) + } + format = "{0:{lengths[package]}} | {1:{lengths[version]}} | {2:{lengths[suite]}} | {3}" + + for row in result: + yield format.format(row[t.c.package], row[t.c.version], row[t.c.display_suite], row[c_architectures], lengths=lengths) + elif format in ('control-suite', 'heidi'): + query = sql.select([t.c.package, t.c.version, t.c.architecture]).where(where) + result = session.execute(query) + for row in result: + yield "{0} {1} {2}".format(row[t.c.package], row[t.c.version], row[t.c.architecture]) + else: + raise ValueError("Unknown output format requested.") + + if highest is not None: + query = sql.select([t.c.package, sql.func.max(t.c.version)]).where(where) \ + .group_by(t.c.package).order_by(t.c.package) + result = session.execute(query) + yield "" + for row in result: + yield "{0} ({1} {2})".format(row[0], highest, row[1])