[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