[Pkg-haskell-commits] darcs: tools: Visualize status of experimental uploads
Joachim Breitner
mail at joachim-breitner.de
Fri Oct 19 15:53:33 UTC 2012
Wed Oct 17 17:54:38 UTC 2012 Joachim Breitner <mail at joachim-breitner.de>
* Visualize status of experimental uploads
Ignore-this: c18d8e00924b864ca345f7f6c276c8c1
A ./haskell-pkg-graph-experimental.py
Wed Oct 17 17:54:38 UTC 2012 Joachim Breitner <mail at joachim-breitner.de>
* Visualize status of experimental uploads
Ignore-this: c18d8e00924b864ca345f7f6c276c8c1
diff -rN -u old-tools//haskell-pkg-graph-experimental.py new-tools//haskell-pkg-graph-experimental.py
--- old-tools//haskell-pkg-graph-experimental.py 1970-01-01 00:00:00.000000000 +0000
+++ new-tools//haskell-pkg-graph-experimental.py 2012-10-19 15:53:33.843966101 +0000
@@ -0,0 +1,246 @@
+#!/usr/bin/python
+# encoding:utf8
+#
+# Copyright (C) 2009, Joachim Breitner <nomeata at debian.org>
+#
+# Inspired by debian-ocaml-status.py written by Stefano Zacchiroli <zack at debian.org>
+#
+# 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.
+#
+# Suggested usage: ./haskell-pkg-graph.py | tred | unflatten | dot -Tpdf -o haskell-pkg-graph.pdf
+
+# Select which arches file to use
+arch = "amd64"
+
+import bz2
+import gzip
+import datetime
+import gzip
+import os
+import re
+import string
+import sys
+from itertools import *
+from subprocess import *
+from xml.dom.minidom import *
+
+from debian_bundle import debian_support
+from debian_bundle.debian_support import version_compare
+from debian_bundle.deb822 import PkgRelation, Deb822
+#from genshi.template import TemplateLoader
+
+def patch_pkg_dict(entry):
+ if not isinstance(entry, dict): # backward compatibility for debian_support
+ entry = dict(map(lambda (x, y): (x.lower(), y), entry))
+ return entry
+
+def smart_open(fname):
+ """Transparently open a compressed (or not) file."""
+
+ f = None
+ if fname.endswith('.gz'):
+ f = gzip.GzipFile(fname)
+ elif fname.endswith('.bz2'):
+ f = bz2.BZ2File(fname)
+ else:
+ f = open(fname)
+ return f
+
+def debcheck(binary_src_map):
+ f = smart_open("data/unstable-main-binary-%s-Packages.gz" % arch)
+ f2 = smart_open("data/experimental-main-binary-%s-Packages.gz" % arch)
+ p = Popen(['edos-debcheck','-quiet','-xml','-failures','-checkonly', ','.join(binary_src_map.keys())], stdin=PIPE,stdout=PIPE)
+ (out, err) = p.communicate(f.read() + "\n" + f2.read())
+
+ parsed = parseString(out)
+
+ uninstallable_srcs = set()
+
+ for package in parsed.getElementsByTagName('package'):
+ package_name = package.attributes['package'].nodeValue
+
+ src = binary_src_map[package_name]
+ uninstallable_srcs.add(src['package'])
+
+ return uninstallable_srcs
+
+class HaskellInfo:
+ def is_interesting_source(self, src):
+ return (src['package'] == 'ghc' or self.is_haskell_lib_src(src))
+
+ def is_haskell_lib_src(self,src):
+ if 'build-depends' in src:
+ for rel in PkgRelation.parse_relations(src['build-depends']):
+ for opt in rel:
+ if opt['name'] == 'ghc':
+ return True
+ if opt['name'] == 'ghc6':
+ return True
+ return False
+
+ def is_haskell_lib(self,src):
+ if 'build-depends' in src:
+ for rel in PkgRelation.parse_relations(src['build-depends']):
+ for opt in rel:
+ if opt['name'] == 'ghc':
+ return True
+ return False
+
+ def is_buildable(self,src):
+ rels = PkgRelation.parse_relations(src['build-depends'])
+ for rel in rels:
+ ok = False
+ for opt in rel:
+ if opt['name'] == 'ghc':
+ if opt['version']:
+ (relop,v) = opt['version']
+ #print "Comparing %s %s %s" % (self.ghcversion, relop, v)
+ cmp = version_compare(self.ghcversion, v)
+ if relop == ">=":
+ ok = cmp >= 0
+ elif relop == "<<":
+ ok = cmp < 0
+ elif relop == "=":
+ ok = cmp == 0
+ else:
+ print "Do not handle %s yet" % relop
+ else:
+ #print "%s has an unversioned build-dependency on ghc." % src['package']
+ ok = True
+ else:
+ # we only consider ghc depenencies here
+ ok = True
+ if not ok: return False
+ return True
+
+
+ def add_incoming_info(status):
+ # TODO
+ return status
+
+ def main(self):
+ # sources will contian haskell libraries + ghc
+ self.sources = {}
+ f = smart_open("data/unstable-main-Sources.gz")
+ srcfile = debian_support.PackageFile('', file_obj=f)
+ try:
+ for src in filter(self.is_interesting_source, imap(patch_pkg_dict,srcfile)):
+ self.sources[src['package']] = src
+ self.sources[src['package']]['experimental'] = False
+ except Exception, e:
+ print "E: error while parsing %s, ignoring it." % "data/unstable-main-Sources.gz"
+ print " exception: %s" % e
+ f.close()
+
+ # overwrite with experimental
+ f = smart_open("data/experimental-main-Sources.gz")
+ srcfile = debian_support.PackageFile('', file_obj=f)
+ try:
+ for src in filter(self.is_interesting_source, imap(patch_pkg_dict,srcfile)):
+ self.sources[src['package']] = src
+ self.sources[src['package']]['experimental'] = True
+ except Exception, e:
+ print "E: error while parsing %s, ignoring it." % "data/experimental-main-Sources.gz"
+ print " exception: %s" % e
+ f.close()
+
+ # Create dict of all binaries
+ self.packages = {}
+ f = smart_open("data/unstable-main-binary-%s-Packages.gz" % arch)
+ binfile = debian_support.PackageFile('', file_obj=f)
+ try:
+ for pkg in imap(patch_pkg_dict, binfile):
+ self.packages[pkg['package']] = pkg
+ except Exception, e:
+ print "E: error while parsing %s, ignoring it." % ("data/unstable-main-binary-%s-Packages.gz" % arch)
+ print " exception: %s" % e
+ f.close()
+
+ f = smart_open("data/experimental-main-binary-%s-Packages.gz" % arch)
+ binfile = debian_support.PackageFile('', file_obj=f)
+ try:
+ for pkg in imap(patch_pkg_dict, binfile):
+ self.packages[pkg['package']] = pkg
+ except Exception, e:
+ print "E: error while parsing %s, ignoring it." % ("data/experimental-main-binary-%s-Packages.gz" % arch)
+ print " exception: %s" % e
+ f.close()
+
+ self.haskell_lib_to_source = {}
+ self.exp_haskell_lib_to_source = {}
+
+ # Go through all buildable sources and collect the names of the binaries
+ for srcname in self.sources.keys():
+ src = self.sources[srcname]
+ for binary_name in src['binary'].split(", "):
+ # Ignore missing packages
+ if binary_name not in self.packages: continue
+ binary = self.packages[binary_name]
+ # Ignore arch-independent packages
+ #if binary['architecture'] == 'all': continue
+
+ self.haskell_lib_to_source[binary_name] = src
+ if src['experimental']:
+ self.exp_haskell_lib_to_source[binary_name] = src
+ #print "Source %s has binary %s" % (src['package'],binary_name)
+
+ broken = debcheck(self.exp_haskell_lib_to_source)
+
+ print "digraph DebianHaskellPackages {"
+ print "ranksep=1.5;mclimit=300;"
+ print "rankdir=LR;"
+ seen_edges = set()
+ for src in self.sources.itervalues():
+ if src['experimental']:
+ if src['package'] in broken:
+ colour="red"
+ else:
+ colour="green"
+ else:
+ colour="gray"
+ name = src['package'].replace("haskell-","-")
+ style = "filled"
+ if "pkg-haskell-maintainers at lists.alioth.debian.org" not in src['maintainer']:
+ style += ",dashed"
+ print '%s [label="%s",style="%s",color=black,fillcolor="%s"]' % (hash(src['package']), name, style, colour)
+ # check recursively the build-dependencies if something already
+ # needs to be rebuild
+ rels = PkgRelation.parse_relations(src['build-depends'])
+ for rel in rels:
+ if len(rel) != 1:
+ continue # the dependencies we care about are not optional
+ opt = rel[0]
+ depname = opt['name']
+ if depname not in self.haskell_lib_to_source:
+ # try transition
+ depname = depname.replace("libghc6-","libghc-")
+ if depname not in self.haskell_lib_to_source:
+ continue
+
+ # avoid loops
+ if hash(self.haskell_lib_to_source[depname]['package']) == hash(src['package']):
+ continue
+
+ # avoid cpphs, haddock etc.
+ if depname in ('alex','c2hs','cpphs','happy','hscolour','haddock'):
+ continue
+
+
+ # avoid cpphs, haddock etc.
+ #if opt['name'] in ('ghc','ghc-doc','ghc-prof'):
+ # continue
+
+ edge = (hash(self.haskell_lib_to_source[depname]['package']), hash(src['package']))
+ if edge not in seen_edges:
+ print '%s -> %s;' % edge
+ seen_edges.add(edge)
+ print "}"
+
+
+
+if __name__ == '__main__':
+ HaskellInfo().main()
+
More information about the Pkg-haskell-commits
mailing list