Mercurial > treepkg > treepkg
view treepkg/info/status.py @ 579:97a5e09c84dc tip
Fix: pass url to command expand to be able to checkout a new git repository
author | Bjoern Ricks <bricks@intevation.de> |
---|---|
date | Sat, 03 Sep 2011 12:32:32 +0000 |
parents | 6d65aa725f99 |
children |
line wrap: on
line source
# Copyright (C) 2010 by Intevation GmbH # Authors: # Bjoern Ricks <bjoern.ricks@intevation.de> # # This program is free software under the GPL (>=v2) # Read the file COPYING coming with the software for details. """Build treepkg status information""" import os.path import xml.dom.minidom from treepkg.report import get_packager_group from treepkg.util import md5sum from treepkg.info.package import BinaryPackage TREEPKG_NAMESPACE_URI = "http://wald.intevation.org/projects/treepkg/" TREEPKG_NAMESPACE_PREFIX = "tpkg" def createTpkgElement(doc, name): return doc.createElementNS(TREEPKG_NAMESPACE_URI, name) def createTpkgRoot(name): domimpl = xml.dom.minidom.getDOMImplementation() doc = domimpl.createDocument(TREEPKG_NAMESPACE_URI, name, None) root = doc.documentElement return (doc, root) def getTextFromNode(node): if not node: return None textnode = node.firstChild if not textnode or textnode.nodeType != node.TEXT_NODE: return None return textnode.data def getChild(node, name, required=False): childs = getChilds(node, name, required) if not childs or len(childs) == 0: return None else: return childs[0] def getChilds(node, name, required=False): if not node: if required: raise TreepkgInfoException("Element %s is required as child. But" "parent element is not available.") return None childs = node.getElementsByTagName(name) if not childs: if required: raise TreepkgInfoException("Element %s is required as child for %s." "The XML file must be invalid." % (name, node.nodeName)) return None return childs class TreepkgInfoException(Exception): """ Exception class for TreepkgInfo """ class TreepkgInfo: def __init__(self, config, numnewestrev=-1, success=False): self.numnewestrev = numnewestrev self.success = success group = get_packager_group(config) treepkgrootinfo = TreepkgRootInfo(group.name, group.treepkg_dir, group.tracks_dir) version = "1.0" self.tpkgroot = TreepkgRoot(version, treepkgrootinfo) tracks = group.get_package_tracks() for track in tracks: trackinfo = TreepkgTrackInfo(track.name) self.tpkgroot.add_track(trackinfo) self.add_revisions(track, trackinfo) def toxml(self): return self.tpkgroot.toxml() @staticmethod def fromxml(xmlstr): doc = xml.dom.minidom.parseString(xmlstr) root = doc.documentElement if not root.tagName == "treepkg": raise TreepkgInfoException("XML is not valid for treepkginfo") return TreepkgRoot.fromxml(root) def add_revisions(self, track, trackinfo): revisions = track.get_revisions() for r in revisions: # Builds without status are no candidates if not r.status.start: revisions.remove(r) revisions = sorted(revisions, key=lambda r: r.status.start, reverse=True) candidates = revisions if self.success: # skip not successful builds candidates = [rev for rev in revisions if rev.status.status.finished and not rev.status.status.error] if self.numnewestrev > 0: candidates = candidates[:self.numnewestrev] arch = None for rev in candidates: revision = rev.revision rules_revision = rev.rules_revision status = rev.status.status.description # extend status sources = rev.list_source_files() binaries = rev.list_binary_files() revinfo = TreepkgTrackRevisionInfo(revision, rules_revision, status) logs = rev.get_log_files() for (title, filename) in logs: loginfo = TreepkgLogInfo(title, filename) revinfo.add_log(loginfo) for source in sources: self.add_package(revinfo, source, "source") for binary in binaries: binpackage = BinaryPackage(binary) arch = binpackage.get_architecture() self.add_package(revinfo, binary, "binary", arch) trackinfo.add_revision(revinfo) def add_package(self, revision, file, type, arch=None): name = os.path.basename(file) checksum = md5sum(file) checksuminfo = TreepkgChecksumInfo(checksum, "md5") pkginfo = TreepkgPackageInfo(name, file, type, arch) pkginfo.add_checksum(checksuminfo) revision.add_package(pkginfo) class TreepkgRoot: def __init__(self, version, info): self.version = version self.info = info self.tracks = [] def add_track(self, track): self.tracks.append(track) def toxml(self): (doc, root) = createTpkgRoot("treepkg") root.setAttributeNS(TREEPKG_NAMESPACE_URI, "version", self.version) if len(self.tracks) > 0: tracksele = createTpkgElement(doc, "tracks") for track in self.tracks: tracksele.appendChild(track.toxml()) root.appendChild(tracksele) root.appendChild(self.info.toxml()) return root @staticmethod def fromxml(node): version = node.getAttribute("version") tracksele = getChild(node, "tracks") trackeles = getChilds(tracksele, "track") infoele = getChild(node, "info") treepkgrootinfo = TreepkgRootInfo.fromxml(infoele) treepkgroot = TreepkgRoot(version, treepkgrootinfo) tracks = [] for trackele in trackeles: tracks.append(TreepkgTrackInfo.fromxml(trackele)) treepkgroot.tracks = tracks return treepkgroot class TreepkgRootInfo: def __init__(self, name, treepkgpath=None, trackspath=None, version=None): self.name = name self.treepkgpath = treepkgpath self.trackspath = trackspath self.version = version def toxml(self): (doc, root) = createTpkgRoot("info") # add <name> nameele = createTpkgElement(doc, "name") text = doc.createTextNode(self.name) nameele.appendChild(text) root.appendChild(nameele) # add <treepkgpath> if self.treepkgpath: treepkgpathele = createTpkgElement(doc, "treepkgpath") text = doc.createTextNode(self.treepkgpath) treepkgpathele.appendChild(text) root.appendChild(treepkgpathele) # add <trackspath> if self.trackspath: trackspathele = createTpkgElement(doc, "trackspath") text = doc.createTextNode(self.trackspath) trackspathele.appendChild(text) root.appendChild(trackspathele) # add <version> if self.version: versionele = createTpkgElement(doc, "version") text = doc.createTextNode(self.version) versionele.appendChild(text) root.appendChild(versionele) return root @staticmethod def fromxml(node): version = node.getAttribute("version") nameele = getChild(node, "name", True) name = getTextFromNode(nameele) treepkgpathele = getChild(node, "treepkgpath") treepkgpath = getTextFromNode(treepkgpathele) trackspathele = getChild(node, "trackspath") trackspath = getTextFromNode(trackspathele) return TreepkgRootInfo(name, treepkgpath, trackspath, version) class TreepkgTrackInfo: def __init__(self, name, os=None): self.name = name self.os = os self.revisions = [] def add_revision(self, revision): self.revisions.append(revision) def toxml(self): (doc, root) = createTpkgRoot("track") nameele = createTpkgElement(doc, "name") text = doc.createTextNode(self.name) nameele.appendChild(text) root.appendChild(nameele) for rev in self.revisions: root.appendChild(rev.toxml()) if not self.os is None: osele = createTpkgElement(doc, "os") text = doc.createTextNode(self.os) osele.appendChild(text) root.appendChild(osele) return root @staticmethod def fromxml(node): nameele = getChild(node, "name", True) name = getTextFromNode(nameele) osele = getChild(node, "os") os = getTextFromNode(osele) treepkgtrackinfo = TreepkgTrackInfo(name, os) treepkgtrackinfo.revisions = [] revisioneles = node.getElementsByTagName("revision") for revele in revisioneles: treepkgrevision = TreepkgTrackRevisionInfo.fromxml(revele) treepkgtrackinfo.revisions.append(treepkgrevision) return treepkgtrackinfo class TreepkgTrackRevisionInfo: def __init__(self, number, rules, status): self.number = number self.rules = rules self.status = status self.packages = [] self.logs = [] def add_package(self, package): self.packages.append(package) def add_log(self, log): self.logs.append(log) def toxml(self): (doc, root) = createTpkgRoot("revision") # add <number> numberele = createTpkgElement(doc, "number") text = doc.createTextNode(self.number) numberele.appendChild(text) root.appendChild(numberele) # add <rules> rulesele = createTpkgElement(doc, "rules") text = doc.createTextNode(self.rules) rulesele.appendChild(text) root.appendChild(rulesele) # add <status><message></message></status> statusele = createTpkgElement(doc, "status") messageele = createTpkgElement(doc, "message") text = doc.createTextNode(self.status) messageele.appendChild(text) statusele.appendChild(messageele) root.appendChild(statusele) # add <packages> packagesele = createTpkgElement(doc, "packages") for package in self.packages: packagesele.appendChild(package.toxml()) root.appendChild(packagesele) # add <logs> logsele = createTpkgElement(doc, "logs") for log in self.logs: logsele.appendChild(log.toxml()) root.appendChild(logsele) return root @staticmethod def fromxml(node): numberele = getChild(node, "number", True) number = getTextFromNode(numberele) rulesele = getChild(node, "rules", True) rules = getTextFromNode(rulesele) statusele = getChild(node, "status", True) messageele = getChild(statusele, "message") message = getTextFromNode(messageele) treepkgrevisioninfo = TreepkgTrackRevisionInfo(number, rules, message) packagesele = getChild(node, "packages") packageeles = getChilds(packagesele, "package") for packageele in packageeles: treepkgrevisioninfo.packages.append( TreepkgPackageInfo.fromxml(packageele)) logsele = getChild(node, "logs") logeles = getChilds(logsele, "log") for logele in logeles: treepkgrevisioninfo.logs.append(TreepkgLogInfo.fromxml(logele)) return treepkgrevisioninfo class TreepkgLogInfo: def __init__(self, name, path): self.name = name self.path = path def toxml(self): (doc, root) = createTpkgRoot("log") # add <name> nameele = createTpkgElement(doc, "name") text = doc.createTextNode(self.name) nameele.appendChild(text) root.appendChild(nameele) # add path pathele = createTpkgElement(doc, "path") text = doc.createTextNode(self.path) pathele.appendChild(text) root.appendChild(pathele) return root @staticmethod def fromxml(node): nameele = getChild(node, "name", True) name = getTextFromNode(nameele) pathele = getChild(node, "path", True) path = getTextFromNode(pathele) return TreepkgLogInfo(name, path) class TreepkgPackageInfo: def __init__(self, name, path, type, arch): self.name = name self.path = path self.type = type self.arch = arch self.checksums = [] def toxml(self): (doc, root) = createTpkgRoot("package") # add <name> nameele = createTpkgElement(doc, "name") text = doc.createTextNode(self.name) nameele.appendChild(text) root.appendChild(nameele) # add <path> pathele = createTpkgElement(doc, "path") text = doc.createTextNode(self.path) pathele.appendChild(text) root.appendChild(pathele) # add <checksum> for checksum in self.checksums: root.appendChild(checksum.toxml()) # add <type> root.setAttributeNS(TREEPKG_NAMESPACE_URI, "type", self.type) if not self.arch is None: root.setAttributeNS(TREEPKG_NAMESPACE_URI, "arch", self.arch) return root def add_checksum(self, checksum): self.checksums.append(checksum) @staticmethod def fromxml(node): nameele = getChild(node, "name", True) name = getTextFromNode(nameele) pathele = getChild(node, "path", True) path = getTextFromNode(pathele) ptype = node.getAttribute("type") arch = node.getAttribute("arch") if not arch: arch = None packageinfo = TreepkgPackageInfo(name, path, ptype, arch) checksumeles = node.getElementsByTagName("checksum") for checksumele in checksumeles: packageinfo.checksums.append( TreepkgChecksumInfo.fromxml(checksumele)) return packageinfo class TreepkgChecksumInfo: def __init__(self, checksum, type="md5"): self.checksum = checksum self.type = type def toxml(self): (doc, root) = createTpkgRoot("checksum") text = doc.createTextNode(self.checksum) root.appendChild(text) # add attribute type if type: root.setAttributeNS(TREEPKG_NAMESPACE_URI, "type", self.type) return root @staticmethod def fromxml(node): checksum = getTextFromNode(node) ctype = node.getAttribute("type") if not ctype: return TreepkgChecksumInfo(checksum) return TreepkgChecksumInfo(checksum, ctype)