#!/usr/bin/python """ Contains the information about 1 source of spec files """ # 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. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Library General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # Copyright 2004 Dries Verachtert from log4py import Logger from storagefactory import StorageFactory from specrepositoryspecfile import SpecRepositorySpecFile from filterchain import FilterChain from preparespecfilescriptlist import PrepareSpecFileScriptList import posixpath, posix, string # A specrepository has some attributes (a name, the root directory) # and a list of objects which represent 1 spec file within this specrepository # The StoreFactory is used to create a store object so this list of spec files can be saved # within a database if you use the right type of store class SpecRepository: TYPE_SVN = "SVN" TYPE_CVS = "CVS" TYPE_FILES = "FILES" TYPE_UNKNOWN = "UNKNOWN" # name: ascii name, for example 'rpmforge' # type: a constant, can be one of "SVN", "CVS", "FILES" def __init__(self, name, rootdirectory): self.__cat = Logger().get_instance(self) self.__name = name self.__rootdirectory = rootdirectory self._setType(SpecRepository.TYPE_UNKNOWN) self.__cat.debug("initialized") self.__specFiles = []; self.__storage = StorageFactory.getStorage() self.__id = None self.__filterChain = FilterChain() self.__prepareSpecFileScriptList = PrepareSpecFileScriptList() self.__updateSiteScript = None def getSpecRepositorySpecFiles(self): return self.__specFiles def getSpecRepositorySpecFileByFilePath(self,filePath): for i in self.__specFiles: if i.getPathFromRoot() == filePath: return i return None def getSpecRepositorySpecFileById(self,id): self.__cat.debug("id=" + str(id)) for i in self.__specFiles: #self.__cat.debug("comparing with " + str(i.getId())) if i.getId() == id: return i return None # get a unique identifier for the current version of this file # has to be implemented by a subclass # a newer version must always be larger/bigger then an older version: must be able to sort it by number # so newest version: max( versions.. ) def getSpecFileVersion(self,specRepoSpecFile): raise Exception("getSpecFileVersion mus be implemented by a subclass") def appendSpecRepositorySpecFileFilter(self,newFilter): self.__filterChain.appendFilter(newFilter) def appendPrepareSpecFileScript(self,newScript): self.__prepareSpecFileScriptList.appendScript(newScript) def runPrepareSpecFileScripts(self,aCommand,commanddir, brr): self.__prepareSpecFileScriptList.runScripts(aCommand,commanddir, brr) def setUpdateSiteScript(self,newScript): self.__updateSiteScript = newScript def runUpdateSiteScript(self): if self.__updateSiteScript != None: self.__updateSiteScript.runScript(self) def getUpdateCommand(self): return "" def getName(self): return self.__name def getRootDirectory(self): return self.__rootdirectory def getType(self): return self.__type def _setType(self,myType): self.__type = myType # first get the list of files which have to be updated, # then update every file which has been changed def __updateFileListInStorage(self): arr = self.__getListOfModifiedFiles() for modFile in arr: self.__updateFileInStorage(modFile) # the storage class assigns a unique id to each specrepository def getId(self): self.__cat.debug("returnval:" + str(self.__id)) return self.__id def setId(self,newId): self.__cat.debug("id set to: " + str(newId)) self.__id = newId def __updateFileInStorage(self, specfile): self.__cat.debug("start, specfile=" + specfile.getFileName()) specfile.setId(self.__storage.saveSpecRepositorySpecFile(self, specfile)) # normally the checksums are also stored in storage, # this function is only called at the end of updateFileList # so we can compare the checksums of __specFiles with # the contents of the store def __getListOfModifiedFiles(self): self.__cat.debug("start") # we return an array of SpecRepositorySpecFile objects retval = [] myFileNameToCheckSumHash = self.__storage.getSpecRepositoryFileListToChecksum(self) for diskSpecFile in self.__specFiles: if (diskSpecFile.getPathFromRoot() in myFileNameToCheckSumHash.keys()): # this specrepositoryspecfile is already in the storage if (diskSpecFile.getCheckSum() != myFileNameToCheckSumHash[diskSpecFile.getPathFromRoot()]): retval.append(diskSpecFile) else: # new file retval.append(diskSpecFile) return retval def updateFileList(self): self.__cat.debug("start") dirname = self.getRootDirectory() # generate a list of all found spec files in this repository and store it in the database # then the master can accept commands to build one of those spec files self.__specFiles = self.__recursiveFindFiles(dirname, "") self.__assignIdsFromStorage() self.__updateFileListInStorage() return len(self.__specFiles); # storage maybe has unique ids about the spec files: ask the storage for a hash subdir +/+filename => unique id so we can assign them def __assignIdsFromStorage(self): self.__cat.debug("start") myFileNameToIdHash = self.__storage.getSpecRepositoryFileListToIds(self) for diskSpecFile in self.__specFiles: if (diskSpecFile.getPathFromRoot() in myFileNameToIdHash.keys()): # this specrepositoryspecfile is already in the storage pathFromRoot = diskSpecFile.getPathFromRoot() id = myFileNameToIdHash[pathFromRoot] diskSpecFile.setId(id) def __recursiveFindFiles(self,topDir,startDir): #self.cat.debug("start, startDir=" + startDir) arr = [] fullDir = posixpath.join(topDir,startDir) topDirList = posix.listdir(fullDir) for entryInDir in topDirList: #self.cat.debug("entryInDir=" + entryInDir) fullEntryInDir = posixpath.join(fullDir,entryInDir) if posixpath.isdir(fullEntryInDir): #self.cat.debug("it's a dir!") # recurse tmpArr = self.__recursiveFindFiles(topDir,posixpath.join(startDir,entryInDir)) arr = arr + tmpArr else: # it's not a dir rindex = string.rfind(entryInDir,'.spec') if rindex > 0 and rindex == len(entryInDir) - len('.spec'): #self.cat.debug("spec match, entryInDir=" + entryInDir) spf = SpecRepositorySpecFile(self,startDir,entryInDir) if self.__filterChain.accepts(spf): arr.append(spf) return arr