def readContentsFile(self): """ Reads the contents.xml file at the beginning of processing. """ contentsFilename = Filename(self.installDir, 'contents.xml') doc = TiXmlDocument(contentsFilename.toOsSpecific()) if not doc.LoadFile(): # Couldn't read file. print("couldn't read %s" % (contentsFilename)) return False xcontents = doc.FirstChildElement('contents') if xcontents: contentsSeq = SeqValue() contentsSeq.loadXml(xcontents) contentsSeq += 1 contentsSeq.storeXml(xcontents) xpackage = xcontents.FirstChildElement('package') while xpackage: solo = xpackage.Attribute('solo') solo = int(solo or '0') filename = xpackage.Attribute('filename') if filename and not solo: filename = Filename(filename) package = self.Package(filename, self, xpackage) package.readDescFile(doProcessing=True) self.packages.append(package) xpackage = xpackage.NextSiblingElement('package') self.contentsDoc = doc return True
def readContentsFile(self): """ Reads the contents.xml file at the beginning of processing. """ contentsFilename = Filename(self.installDir, 'contents.xml') doc = TiXmlDocument(contentsFilename.toOsSpecific()) if not doc.LoadFile(): # Couldn't read file. print "couldn't read %s" % (contentsFilename) return False xcontents = doc.FirstChildElement('contents') if xcontents: contentsSeq = SeqValue() contentsSeq.loadXml(xcontents) contentsSeq += 1 contentsSeq.storeXml(xcontents) xpackage = xcontents.FirstChildElement('package') while xpackage: solo = xpackage.Attribute('solo') solo = int(solo or '0') filename = xpackage.Attribute('filename') if filename and not solo: filename = Filename(filename) package = self.Package(filename, self, xpackage) package.readDescFile(doProcessing = True) self.packages.append(package) xpackage = xpackage.NextSiblingElement('package') self.contentsDoc = doc return True
class PackageEntry: """ This corresponds to a <package> entry in the contents.xml file. """ def __init__(self, xpackage, sourceDir): self.sourceDir = sourceDir self.loadXml(xpackage) def getKey(self): """ Returns a tuple used for sorting the PackageEntry objects uniquely per package. """ return (self.packageName, self.platform, self.version) def isNewer(self, other): return self.descFile.timestamp > other.descFile.timestamp def loadXml(self, xpackage): self.packageName = xpackage.Attribute('name') self.platform = xpackage.Attribute('platform') self.version = xpackage.Attribute('version') solo = xpackage.Attribute('solo') self.solo = int(solo or '0') self.descFile = FileSpec() self.descFile.loadXml(xpackage) self.packageSeq = SeqValue() self.packageSeq.loadXml(xpackage, 'seq') self.packageSetVer = SeqValue() self.packageSetVer.loadXml(xpackage, 'set_ver') self.importDescFile = None ximport = xpackage.FirstChildElement('import') if ximport: self.importDescFile = FileSpec() self.importDescFile.loadXml(ximport) def makeXml(self): """ Returns a new TiXmlElement. """ xpackage = TiXmlElement('package') xpackage.SetAttribute('name', self.packageName) if self.platform: xpackage.SetAttribute('platform', self.platform) if self.version: xpackage.SetAttribute('version', self.version) if self.solo: xpackage.SetAttribute('solo', '1') self.descFile.storeXml(xpackage) self.packageSeq.storeXml(xpackage, 'seq') self.packageSetVer.storeXml(xpackage, 'set_ver') if self.importDescFile: ximport = TiXmlElement('import') self.importDescFile.storeXml(ximport) xpackage.InsertEndChild(ximport) return xpackage
def __readContentsFile(self, sourceDir, packageNames): """ Reads the contents.xml file from the indicated sourceDir, and updates the internal set of packages appropriately. """ assert sourceDir != None, "No source directory was specified!" contentsFilename = Filename(sourceDir, 'contents.xml') doc = TiXmlDocument(contentsFilename.toOsSpecific()) if not doc.LoadFile(): # Couldn't read file. return False xcontents = doc.FirstChildElement('contents') if xcontents: maxAge = xcontents.Attribute('max_age') if maxAge: maxAge = int(maxAge) if self.maxAge is None: self.maxAge = maxAge else: self.maxAge = min(self.maxAge, maxAge) contentsSeq = SeqValue() if contentsSeq.loadXml(xcontents): self.contentsSeq = max(self.contentsSeq, contentsSeq) xhost = xcontents.FirstChildElement('host') if xhost: self.xhost = xhost.Clone() xpackage = xcontents.FirstChildElement('package') while xpackage: pe = self.PackageEntry(xpackage, sourceDir) # Filter out any packages not listed in # packageNames (unless packageNames is None, # in which case don't filter anything). if packageNames is None or pe.packageName in packageNames: other = self.contents.get(pe.getKey(), None) if not other or pe.isNewer(other): # Store this package in the resulting output. self.contents[pe.getKey()] = pe xpackage = xpackage.NextSiblingElement('package') self.contentsDoc = doc return True
def writeDescFile(self): """ Rewrites the desc file with the new patch information. """ if not self.anyChanges: # No need to rewrite. return xpackage = self.doc.FirstChildElement('package') if not xpackage: return packageSeq = SeqValue() packageSeq.loadXml(xpackage, 'seq') packageSeq += 1 packageSeq.storeXml(xpackage, 'seq') # Remove all of the old patch entries from the desc file # we read earlier. xremove = [] for value in ['base_version', 'top_version', 'patch']: xpatch = xpackage.FirstChildElement(value) while xpatch: xremove.append(xpatch) xpatch = xpatch.NextSiblingElement(value) for xelement in xremove: xpackage.RemoveChild(xelement) xpackage.RemoveAttribute('last_patch_version') # Now replace them with the current patch information. xpackage.SetAttribute('patch_version', str(self.patchVersion)) xarchive = TiXmlElement('base_version') self.baseFile.storeXml(xarchive) xpackage.InsertEndChild(xarchive) # The current version is now the top version. xarchive = TiXmlElement('top_version') self.currentFile.storeXml(xarchive) xpackage.InsertEndChild(xarchive) for patchfile in self.patches: xpatch = patchfile.makeXml(self) xpackage.InsertEndChild(xpatch) self.doc.SaveFile() # Also copy the seq to the import desc file, for # documentation purposes. importDescFilename = str(self.packageDesc)[:-3] + 'import.xml' importDescFullpath = Filename(self.patchMaker.installDir, importDescFilename) doc = TiXmlDocument(importDescFullpath.toOsSpecific()) if doc.LoadFile(): xpackage = doc.FirstChildElement('package') if xpackage: packageSeq.storeXml(xpackage, 'seq') doc.SaveFile() else: print("Couldn't read %s" % (importDescFullpath)) if self.contentsDocPackage: # Now that we've rewritten the xml file, we have to # change the contents.xml file that references it to # indicate the new file hash. fileSpec = FileSpec() fileSpec.fromFile(self.patchMaker.installDir, self.packageDesc) fileSpec.storeXml(self.contentsDocPackage) # Also important to update the import.xml hash. ximport = self.contentsDocPackage.FirstChildElement('import') if ximport: fileSpec = FileSpec() fileSpec.fromFile(self.patchMaker.installDir, importDescFilename) fileSpec.storeXml(ximport) # Also copy the package seq value into the # contents.xml file, mainly for documentation purposes # (the authoritative seq value is within the desc # file). packageSeq.storeXml(self.contentsDocPackage, 'seq')
class PackageEntry: """ This corresponds to a <package> entry in the contents.xml file. """ def __init__(self, xpackage, sourceDir): self.sourceDir = sourceDir self.loadXml(xpackage) def getKey(self): """ Returns a tuple used for sorting the PackageEntry objects uniquely per package. """ return (self.packageName, self.platform, self.version) def isNewer(self, other): return self.descFile.timestamp > other.descFile.timestamp def loadXml(self, xpackage): self.packageName = xpackage.Attribute('name') self.platform = xpackage.Attribute('platform') self.version = xpackage.Attribute('version') solo = xpackage.Attribute('solo') self.solo = int(solo or '0') perPlatform = xpackage.Attribute('per_platform') self.perPlatform = int(perPlatform or '0') self.descFile = FileSpec() self.descFile.loadXml(xpackage) self.validatePackageContents() self.descFile.quickVerify(packageDir=self.sourceDir, notify=PackageMerger.notify, correctSelf=True) self.packageSeq = SeqValue() self.packageSeq.loadXml(xpackage, 'seq') self.packageSetVer = SeqValue() self.packageSetVer.loadXml(xpackage, 'set_ver') self.importDescFile = None ximport = xpackage.FirstChildElement('import') if ximport: self.importDescFile = FileSpec() self.importDescFile.loadXml(ximport) self.importDescFile.quickVerify(packageDir=self.sourceDir, notify=PackageMerger.notify, correctSelf=True) def makeXml(self): """ Returns a new TiXmlElement. """ xpackage = TiXmlElement('package') xpackage.SetAttribute('name', self.packageName) if self.platform: xpackage.SetAttribute('platform', self.platform) if self.version: xpackage.SetAttribute('version', self.version) if self.solo: xpackage.SetAttribute('solo', '1') if self.perPlatform: xpackage.SetAttribute('per_platform', '1') self.descFile.storeXml(xpackage) self.packageSeq.storeXml(xpackage, 'seq') self.packageSetVer.storeXml(xpackage, 'set_ver') if self.importDescFile: ximport = TiXmlElement('import') self.importDescFile.storeXml(ximport) xpackage.InsertEndChild(ximport) return xpackage def validatePackageContents(self): """ Validates the contents of the package directory itself against the expected hashes and timestamps. Updates hashes and timestamps where needed. """ if self.solo: return needsChange = False packageDescFullpath = Filename(self.sourceDir, self.descFile.filename) packageDir = Filename(packageDescFullpath.getDirname()) doc = TiXmlDocument(packageDescFullpath.toOsSpecific()) if not doc.LoadFile(): message = "Could not read XML file: %s" % ( self.descFile.filename) raise OSError, message xpackage = doc.FirstChildElement('package') if not xpackage: message = "No package definition: %s" % ( self.descFile.filename) raise OSError, message xcompressed = xpackage.FirstChildElement('compressed_archive') if xcompressed: spec = FileSpec() spec.loadXml(xcompressed) if not spec.quickVerify(packageDir=packageDir, notify=PackageMerger.notify, correctSelf=True): spec.storeXml(xcompressed) needsChange = True xpatch = xpackage.FirstChildElement('patch') while xpatch: spec = FileSpec() spec.loadXml(xpatch) if not spec.quickVerify(packageDir=packageDir, notify=PackageMerger.notify, correctSelf=True): spec.storeXml(xpatch) needsChange = True xpatch = xpatch.NextSiblingElement('patch') if needsChange: PackageMerger.notify.info("Rewriting %s" % (self.descFile.filename)) doc.SaveFile() self.descFile.quickVerify(packageDir=self.sourceDir, notify=PackageMerger.notify, correctSelf=True)
class PackageEntry: """ This corresponds to a <package> entry in the contents.xml file. """ def __init__(self, xpackage, sourceDir): self.sourceDir = sourceDir self.loadXml(xpackage) def getKey(self): """ Returns a tuple used for sorting the PackageEntry objects uniquely per package. """ return (self.packageName, self.platform, self.version) def isNewer(self, other): return self.descFile.timestamp > other.descFile.timestamp def loadXml(self, xpackage): self.packageName = xpackage.Attribute('name') self.platform = xpackage.Attribute('platform') self.version = xpackage.Attribute('version') solo = xpackage.Attribute('solo') self.solo = int(solo or '0') perPlatform = xpackage.Attribute('per_platform') self.perPlatform = int(perPlatform or '0') self.descFile = FileSpec() self.descFile.loadXml(xpackage) self.validatePackageContents() self.descFile.quickVerify(packageDir = self.sourceDir, notify = PackageMerger.notify, correctSelf = True) self.packageSeq = SeqValue() self.packageSeq.loadXml(xpackage, 'seq') self.packageSetVer = SeqValue() self.packageSetVer.loadXml(xpackage, 'set_ver') self.importDescFile = None ximport = xpackage.FirstChildElement('import') if ximport: self.importDescFile = FileSpec() self.importDescFile.loadXml(ximport) self.importDescFile.quickVerify(packageDir = self.sourceDir, notify = PackageMerger.notify, correctSelf = True) def makeXml(self): """ Returns a new TiXmlElement. """ xpackage = TiXmlElement('package') xpackage.SetAttribute('name', self.packageName) if self.platform: xpackage.SetAttribute('platform', self.platform) if self.version: xpackage.SetAttribute('version', self.version) if self.solo: xpackage.SetAttribute('solo', '1') if self.perPlatform: xpackage.SetAttribute('per_platform', '1') self.descFile.storeXml(xpackage) self.packageSeq.storeXml(xpackage, 'seq') self.packageSetVer.storeXml(xpackage, 'set_ver') if self.importDescFile: ximport = TiXmlElement('import') self.importDescFile.storeXml(ximport) xpackage.InsertEndChild(ximport) return xpackage def validatePackageContents(self): """ Validates the contents of the package directory itself against the expected hashes and timestamps. Updates hashes and timestamps where needed. """ if self.solo: return needsChange = False packageDescFullpath = Filename(self.sourceDir, self.descFile.filename) packageDir = Filename(packageDescFullpath.getDirname()) doc = TiXmlDocument(packageDescFullpath.toOsSpecific()) if not doc.LoadFile(): message = "Could not read XML file: %s" % (self.descFile.filename) raise OSError(message) xpackage = doc.FirstChildElement('package') if not xpackage: message = "No package definition: %s" % (self.descFile.filename) raise OSError(message) xcompressed = xpackage.FirstChildElement('compressed_archive') if xcompressed: spec = FileSpec() spec.loadXml(xcompressed) if not spec.quickVerify(packageDir = packageDir, notify = PackageMerger.notify, correctSelf = True): spec.storeXml(xcompressed) needsChange = True xpatch = xpackage.FirstChildElement('patch') while xpatch: spec = FileSpec() spec.loadXml(xpatch) if not spec.quickVerify(packageDir = packageDir, notify = PackageMerger.notify, correctSelf = True): spec.storeXml(xpatch) needsChange = True xpatch = xpatch.NextSiblingElement('patch') if needsChange: PackageMerger.notify.info("Rewriting %s" % (self.descFile.filename)) doc.SaveFile() self.descFile.quickVerify(packageDir = self.sourceDir, notify = PackageMerger.notify, correctSelf = True)
def writeDescFile(self): """ Rewrites the desc file with the new patch information. """ if not self.anyChanges: # No need to rewrite. return xpackage = self.doc.FirstChildElement('package') if not xpackage: return packageSeq = SeqValue() packageSeq.loadXml(xpackage, 'seq') packageSeq += 1 packageSeq.storeXml(xpackage, 'seq') # Remove all of the old patch entries from the desc file # we read earlier. xremove = [] for value in ['base_version', 'top_version', 'patch']: xpatch = xpackage.FirstChildElement(value) while xpatch: xremove.append(xpatch) xpatch = xpatch.NextSiblingElement(value) for xelement in xremove: xpackage.RemoveChild(xelement) xpackage.RemoveAttribute('last_patch_version') # Now replace them with the current patch information. xpackage.SetAttribute('patch_version', str(self.patchVersion)) xarchive = TiXmlElement('base_version') self.baseFile.storeXml(xarchive) xpackage.InsertEndChild(xarchive) # The current version is now the top version. xarchive = TiXmlElement('top_version') self.currentFile.storeXml(xarchive) xpackage.InsertEndChild(xarchive) for patchfile in self.patches: xpatch = patchfile.makeXml(self) xpackage.InsertEndChild(xpatch) self.doc.SaveFile() # Also copy the seq to the import desc file, for # documentation purposes. importDescFilename = self.packageDesc.cStr()[:-3] + 'import.xml' importDescFullpath = Filename(self.patchMaker.installDir, importDescFilename) doc = TiXmlDocument(importDescFullpath.toOsSpecific()) if doc.LoadFile(): xpackage = doc.FirstChildElement('package') if xpackage: packageSeq.storeXml(xpackage, 'seq') doc.SaveFile() else: print "Couldn't read %s" % (importDescFullpath) if self.contentsDocPackage: # Now that we've rewritten the xml file, we have to # change the contents.xml file that references it to # indicate the new file hash. fileSpec = FileSpec() fileSpec.fromFile(self.patchMaker.installDir, self.packageDesc) fileSpec.storeXml(self.contentsDocPackage) # Also important to update the import.xml hash. ximport = self.contentsDocPackage.FirstChildElement('import') if ximport: fileSpec = FileSpec() fileSpec.fromFile(self.patchMaker.installDir, importDescFilename) fileSpec.storeXml(ximport) # Also copy the package seq value into the # contents.xml file, mainly for documentation purposes # (the authoritative seq value is within the desc # file). packageSeq.storeXml(self.contentsDocPackage, 'seq')