| #!/usr/bin/env python | 
|   | 
| # This script generates a report on the packaging status of X.org | 
| # releases in Buildroot. It does so by downloading the list of | 
| # tarballs that are part of a given X.org release, and compare that | 
| # with the packages that are available in Buildroot. | 
|   | 
| import BeautifulSoup | 
| import re | 
| import os | 
| import urllib | 
| from distutils.version import LooseVersion | 
|   | 
| # This can be customized | 
| XORG_VERSION = "X11R7.7" | 
|   | 
| # Key names in dictionaries | 
| XORG_VERSION_KEY = "xorg-version" | 
| BR_VERSION_KEY = "br-version" | 
| BR_NAME_KEY = "br-name" | 
|   | 
| # Packages part of X.org releases that we do not want to package in | 
| # Buildroot (old drivers for hardware unlikely to be used in embedded | 
| # contexts). | 
| XORG_EXCEPTIONS = [ | 
|     'xf86-video-suncg6', | 
|     'xf86-video-sunffb', | 
| ] | 
|   | 
| # Get the list of tarballs of a X.org release, parse it, and return a | 
| # dictionary of dictionaries, of the form: | 
| # | 
| #   { <name_of_package> : { XORG_VERSION_KEY: <version_of_package> }, | 
| #     <name_of_package2> : { XORG_VERSION_KEY: <version_of_package2> }} | 
| # | 
| def get_xorg_release_pkgs(): | 
|     u = urllib.URLopener().open("http://www.x.org/releases/%s/src/everything/" % XORG_VERSION) | 
|     b = BeautifulSoup.BeautifulSoup() | 
|     b.feed(u.read()) | 
|     links = b.findAll("a") | 
|     packages = {} | 
|     r = re.compile("(.*)-([0-9\.]*).tar.bz2") | 
|     # We now have a list of all links. | 
|     for link in links: | 
|         href = link.get("href") | 
|         # Skip everything but tarballs | 
|         if not href.endswith(".tar.bz2"): | 
|             continue | 
|         # Separate the name and the version | 
|         groups = r.match(href) | 
|         if not groups: | 
|             continue | 
|         name = groups.group(1) | 
|         version = groups.group(2) | 
|         # Skip packages we don't want to hear about | 
|         if name in XORG_EXCEPTIONS: | 
|             continue | 
|         packages[name] = { XORG_VERSION_KEY : version } | 
|     return packages | 
|   | 
| # Files and directories in package/x11r7/ that should be ignored in | 
| # our processing. | 
| BUILDROOT_EXCEPTIONS = [ | 
|     "mcookie", # Code is directly in package directory | 
|     "x11r7.mk", | 
|     "Config.in", | 
|     "xdriver_xf86-input-tslib", # From Pengutronix, not part of X.org releases | 
| ] | 
|   | 
| # Prefixes of directories in package/x11r7/ that must be stripped | 
| # before trying to match Buildroot package names with X.org tarball | 
| # names. | 
| BUILDROOT_PREFIXES = [ | 
|     "xapp", | 
|     "xdriver", | 
|     "xfont", | 
|     "xlib", | 
|     "xserver", | 
|     "xutil", | 
|     "xproto", | 
| ] | 
|   | 
| # From a Buildroot package name, try to see if a prefix should be | 
| # stripped from it. For example, passing "xapp_xlsfonts" as argument | 
| # to this function will return "xlsfonts". | 
| def buildroot_strip_prefix(dirname): | 
|     for prefix in BUILDROOT_PREFIXES: | 
|         if dirname.startswith(prefix + "_"): | 
|             return dirname[len(prefix) + 1:] | 
|     return dirname | 
|   | 
| # From a Buildroot package name, parse its .mk file to find the | 
| # Buildroot version of the package by looking at the <foo>_VERSION | 
| # line. | 
| def buildroot_get_version(dirname): | 
|     f = open(os.path.join("package", "x11r7", dirname, dirname + ".mk")) | 
|     r = re.compile("^([A-Z0-9_]*)_VERSION = ([0-9\.]*)$") | 
|     for l in f.readlines(): | 
|         m = r.match(l) | 
|         if m: | 
|             return m.group(2) | 
|     return None | 
|   | 
| # Augment the information of the X.org list of packages (given as | 
| # argument) by details about their packaging in Buildroot. Those | 
| # details are found by looking at the contents of package/x11r7/. | 
| def get_buildroot_pkgs(packages): | 
|     dirs = os.listdir(os.path.join(os.getcwd(), "package", "x11r7")) | 
|     for d in dirs: | 
|         # Skip exceptions | 
|         if d in BUILDROOT_EXCEPTIONS: | 
|             continue | 
|         pkgname = buildroot_strip_prefix(d) | 
|         version = buildroot_get_version(d) | 
|         if packages.has_key(pkgname): | 
|             # There is a X.org package of the same name, so we just | 
|             # add information to the existing dict entry. | 
|             packages[pkgname]['br-version'] = version | 
|             packages[pkgname]['br-name'] = d | 
|         else: | 
|             # There is no X.org package with this name, so we add a | 
|             # new dict entry. | 
|             packages[pkgname] = { BR_VERSION_KEY: version, | 
|                                   BR_NAME_KEY : d } | 
|     return packages | 
|   | 
| def show_summary(packages): | 
|     FORMAT_STRING = "%40s | %15s | %15s | %-30s" | 
|     print FORMAT_STRING % ("Package name", "Vers in BR", "Vers in X.org", "Action") | 
|     print FORMAT_STRING % ("-" * 40, "-" * 15, "-" * 15, "-" * 30) | 
|     pkgs = packages.keys() | 
|     pkgs.sort() | 
|     total_pkgs = 0 | 
|     upgrade_pkgs = 0 | 
|     add_pkgs = 0 | 
|     remove_pkgs = 0 | 
|     nothing_todo_pkgs = 0 | 
|     for pkgname in pkgs: | 
|         pkg = packages[pkgname] | 
|         total_pkgs += 1 | 
|         if pkg.has_key(XORG_VERSION_KEY) and not pkg.has_key(BR_VERSION_KEY): | 
|             xorg_version = pkg[XORG_VERSION_KEY] | 
|             br_version = "N/A" | 
|             action = "Add to Buildroot" | 
|             add_pkgs += 1 | 
|         elif not pkg.has_key(XORG_VERSION_KEY) and pkg.has_key(BR_VERSION_KEY): | 
|             br_version = pkg[BR_VERSION_KEY] | 
|             xorg_version = "N/A" | 
|             action = "Remove from Buildroot" | 
|             remove_pkgs += 1 | 
|         elif LooseVersion(pkg[XORG_VERSION_KEY]) > LooseVersion(pkg[BR_VERSION_KEY]): | 
|             br_version = pkg[BR_VERSION_KEY] | 
|             xorg_version = pkg[XORG_VERSION_KEY] | 
|             action = "Upgrade" | 
|             upgrade_pkgs += 1 | 
|         elif LooseVersion(pkg[XORG_VERSION_KEY]) < LooseVersion(pkg[BR_VERSION_KEY]): | 
|             br_version = pkg[BR_VERSION_KEY] | 
|             xorg_version = pkg[XORG_VERSION_KEY] | 
|             action = "More recent" | 
|             nothing_todo_pkgs += 1 | 
|         else: | 
|             br_version = pkg[BR_VERSION_KEY] | 
|             xorg_version = pkg[XORG_VERSION_KEY] | 
|             action = "" | 
|             nothing_todo_pkgs += 1 | 
|   | 
|         print FORMAT_STRING % (pkgname, br_version.center(15), xorg_version.center(15), action) | 
|     print FORMAT_STRING % ("-" * 40, "-" * 15, "-" * 15, "-" * 30) | 
|     STAT_FORMAT_STRING = "%40s : %3d" | 
|     print STAT_FORMAT_STRING % ("Total number of packages", total_pkgs) | 
|     print STAT_FORMAT_STRING % ("Packages to upgrade", upgrade_pkgs) | 
|     print STAT_FORMAT_STRING % ("Packages to add", add_pkgs) | 
|     print STAT_FORMAT_STRING % ("Packages to remove", remove_pkgs) | 
|     print STAT_FORMAT_STRING % ("Packages with nothing to do", nothing_todo_pkgs) | 
|   | 
| packages = get_xorg_release_pkgs() | 
| packages = get_buildroot_pkgs(packages) | 
| # print packages | 
| show_summary(packages) |