summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHelmut Grohne <helmut@subdivi.de>2016-08-07 07:08:59 +0200
committerHelmut Grohne <helmut@subdivi.de>2016-08-07 07:08:59 +0200
commitfd88a08733bbf6c380ed5dfd6d07aa1bbb670dc5 (patch)
tree8318b5a4f0ffdd3810eae4dcef7745993420d39a
parent90efeacbc079bb87d44f4ed4bca4d9069ed06eeb (diff)
downloaddebian-dedup-fd88a08733bbf6c380ed5dfd6d07aa1bbb670dc5.tar.gz
multiarchanalyze: make it easily consumable by tracker.d.o
Many thanks to Paul Wise for his detailed feedback on the data format.
-rwxr-xr-xmultiarchanalyze.py80
1 files changed, 70 insertions, 10 deletions
diff --git a/multiarchanalyze.py b/multiarchanalyze.py
index 5cd5de7..201ffc3 100755
--- a/multiarchanalyze.py
+++ b/multiarchanalyze.py
@@ -1,7 +1,11 @@
#!/usr/bin/python
import argparse
+import os.path
import sqlite3
+import sys
+
+import yaml
from dedup.utils import fetchiter
@@ -61,13 +65,16 @@ def show_combinations(combinations):
return "%d bipartitions of %s" % (len(partitions),
show_archset(edges.keys()))
if all(len(outedges) == len(edges) - 1 for outedges in edges.values()):
- return "any two of " + show_archset(edges.keys(), limit=4)
+ return "any two of " + show_archset(edges.keys(), limit=5)
return "%s with %d combinations" % (show_archset(edges.keys()),
len(combinations))
def show_files(filenames):
if len(filenames) == 1:
return next(iter(filenames))
+ prefix = os.path.commonprefix(filenames)
+ if prefix not in ('', '/'):
+ return "%d files starting with %s" % (len(filenames), prefix)
return "%d files" % len(filenames)
def main():
@@ -76,39 +83,92 @@ def main():
default="test.sqlite3",
help="path to the sqlite3 database file")
args = parser.parse_args()
+ hints = []
db = sqlite3.connect(args.database)
cur = db.cursor()
cur.execute("SELECT name1, architecture1, architecture2, filename FROM masame_conflict;")
same_conflicts = {}
for package, arch1, arch2, filename in fetchiter(cur):
+ if filename.startswith("./"):
+ filename = filename[1:]
conflicts = same_conflicts.setdefault(package, {})
conflicts.setdefault(filename, set()).add((arch1, arch2))
for package, conflicts in sorted(same_conflicts.items()):
all_combinations = set()
for combinations in conflicts.values():
all_combinations.update(combinations)
- print("%s conflicts on %s on %s" %
- (package, show_files(conflicts.keys()),
- show_combinations(all_combinations)))
+ desc = "%s conflicts on %s on %s" % \
+ (package, show_files(conflicts.keys()),
+ show_combinations(all_combinations))
+ hints.append(dict(
+ binary=package,
+ description=desc,
+ link="https://wiki.debian.org/MultiArch/Hints#file-conflict",
+ severity="high"))
cur.execute("SELECT name FROM maforeign_candidate ORDER BY name;")
for name, in fetchiter(cur):
- print("%s could be Multi-Arch: foreign" % name)
+ hints.append(dict(
+ binary=name,
+ description="%s could be marked Multi-Arch: foreign" % name,
+ link="https://wiki.debian.org/MultiArch/Hints#ma-foreign",
+ severity="rdeps"))
cur.execute("SELECT name FROM archall_candidate ORDER BY name;")
archall_suggests = set()
for name, in fetchiter(cur):
archall_suggests.add(name)
- print("%s could be converted to Architecture: all + Multi-Arch: foreign" % name)
+ desc = "%s could be converted to Architecture: all and marked Multi-Arch: foreign" % \
+ name
+ hints.append(dict(
+ binary=name,
+ description=desc,
+ link="https://wiki.debian.org/MultiArch/Hints#arch-all",
+ severity="low"))
cur.execute("SELECT name FROM masame_candidate ORDER BY name;")
for name, in fetchiter(cur):
- if name not in archall_suggests:
- print("%s could be Multi-Arch: same" % name)
+ if name in archall_suggests:
+ continue
+ hints.append(dict(
+ binary=name,
+ description="%s could be marked Multi-Arch: same" % name,
+ link="https://wiki.debian.org/MultiArch/Hints#ma-same",
+ severity="normal"))
+
cur.execute("SELECT depender, dependee FROM colonany_candidate ORDER BY depender;")
for depender, dependee in fetchiter(cur):
- print("%s could have its %s dependency annotated with :any" %
- (depender, dependee))
+ desc = "%s could have its dependency on %s annotated with :any" % \
+ (depender, dependee)
+ hints.append(dict(
+ binary=depender,
+ description=desc,
+ link="https://wiki.debian.org/MultiArch/Hints#dep-any",
+ severity="normal"))
+
+ for hint in hints:
+ if "source" not in hint:
+ cur.execute("SELECT distinct(source) FROM package WHERE name = ?;",
+ (hint["binary"],))
+ row = cur.fetchone()
+ if row and row[0] and not cur.fetchone():
+ hint["source"] = row[0]
+
+ if hint.get("severity") == "rdeps":
+ cur.execute("SELECT count(*) FROM depends WHERE dependee = ?;",
+ (hint["binary"],))
+ rdeps = cur.fetchone()[0]
+ if rdeps >= 50:
+ hint["severity"] = "high"
+ elif rdeps:
+ hint["severity"] = "normal"
+ else:
+ hint["severity"] = "low"
+
+ yaml.safe_dump(dict(format="multiarch-hints-1.0", hints=hints),
+ default_flow_style=False,
+ width=1000,
+ stream=sys.stdout)
if __name__ == "__main__":
main()