extras-buildsys/utils/pushscript Push.py, 1.35, 1.36 BuildSys.py, 1.2, 1.3 WhatsNew.py, 1.2, 1.3

Michael Schwendt (mschwendt) fedora-extras-commits at redhat.com
Fri Mar 2 16:40:07 UTC 2007


Author: mschwendt

Update of /cvs/fedora/extras-buildsys/utils/pushscript
In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv29585

Modified Files:
	Push.py BuildSys.py WhatsNew.py 
Log Message:
Here come my changes that add %changelog summaries to the build report
for 'development' packages.

- BuildSys.py : move the filedict into the BuildResults class, so the
objects know about the rpms within a plague-results directory

- WhatsNew.py : clean up and add code that deals with rpm changelogs

- Push.py : update for the changes in BuildSys.py and WhatsNew.py,
the build report mail adds a changelog summary for the 'development'
dist only




Index: Push.py
===================================================================
RCS file: /cvs/fedora/extras-buildsys/utils/pushscript/Push.py,v
retrieving revision 1.35
retrieving revision 1.36
diff -u -r1.35 -r1.36
--- Push.py	1 Mar 2007 03:03:09 -0000	1.35
+++ Push.py	2 Mar 2007 16:40:05 -0000	1.36
@@ -145,25 +145,6 @@
 def push_with_rollback(rollback,br,dist,destroot,buildreport):
     print ' ', br
 
-    ## TODO: create and validate in BuildResults class
-    filedict = {}
-    filedict['srpm'] = []
-    filedict['rpm'] = []
-    filedict['debuginfo'] = []
-    filedict['other'] = []
-    # Match the build-results files to what list they should be in.
-    for file in Utils.find_files( br.GetHome() ):
-        if file.endswith('.rpm'):
-            if file.find('debuginfo') != -1:
-                which = 'debuginfo' 
-            elif file.endswith('.src.rpm') or file.endswith('.nosrc.rpm'):
-                which = 'srpm'
-            else:
-                which = 'rpm'
-        else:
-            which = 'other'
-        filedict[which].append(file)
-
     buildreportinfo = None
 
     # In the run-file we store the package NVR ids for the build report.
@@ -178,15 +159,15 @@
     # if it is a noarch package, copy2 it to all arch locations
     # if it is a debuginfo package, move it into the 'debug' dir for that arch
 
-    if len(filedict['srpm']) != 1:
+    if len(br.filedict['srpm']) != 1:
         br.MarkPushed()
         buildreportinfo = '%s : INVALID build results, not published! INV\n' % br
         if buildreport:
             rundirfile.write(buildreportinfo)
         rundirfile.close()
-        raise PushWarning, 'WARNING: %d source rpms in %s' % (len(filedict['srpm']),br.GetHome())
+        raise PushWarning, 'WARNING: %d source rpms in %s' % (len(br.filedict['srpm']),br.GetHome())
     
-    package = filedict['srpm'][0]
+    package = br.filedict['srpm'][0]
     (n,a,e,v,r) = Utils.naevr(package)
     pkg_fn = os.path.basename(package)
     global srpmlocdict  # debug only
@@ -195,7 +176,7 @@
     if not os.path.exists(destloc):
         rollback.append(destloc)
         Utils.install_move(package,destloc)
-        if WhatsNew.get(dist,n):
+        if WhatsNew.queryname(dist,n):
             buildreportinfo = '%s-%s-%s\n' % (n,v,r)
         else:
             buildreportinfo = '%s-%s-%s NEW\n' % (n,v,r)
@@ -207,9 +188,9 @@
         rundirfile.close()
         raise PushWarning, 'WARNING: %s published before' % pkg_fn
 
-    for package in filedict['rpm'] + filedict['debuginfo']:
+    for package in br.filedict['rpm'] + br.filedict['debuginfo']:
         pkg_fn = pkg_destfn = os.path.basename(package)
-        if package in filedict['debuginfo']:
+        if package in br.filedict['debuginfo']:
             pkg_destfn = 'debug/' + pkg_fn
         (n,a,e,v,r) = Utils.naevr(package)
 
@@ -339,6 +320,8 @@
         srpmlocdict = {} # debug only
         for br in results:
             name = br.GetName()
+            clogdiff = WhatsNew.getclogdiff(dist,name,br.GetSourcePkg(),ts)
+            newclog = WhatsNew.readclog(br.GetSourcePkg(),ts)
             if name in cfg.diversion_dict:  # install this elsewhere?
                 buildreport = False
                 targetroot = os.path.join(cfg.diversion_dict[name],dist)
@@ -355,9 +338,12 @@
                 print e
             except rpmUtils.RpmUtilsError, e:
                 print e
-            WhatsNew.set(dist,name)
-        
+            WhatsNew.putname(dist,name)
+            if dist == 'development':
+                WhatsNew.putclog(dist,name,newclog)
+                WhatsNew.putclogdiff(dist,br.__str__(),clogdiff)
         WhatsNew.save(cfg.rundir)
+
     except PushFatal:
         shutil.rmtree(signtmpdir)
         sys.exit(1)
@@ -418,6 +404,12 @@
     if not body:
         return
 
+    try:
+        WhatsNew.load(cfg.rundir)
+        body += '\n'+WhatsNew.getallclogdiffs('development')
+    except:
+        pass
+
     body += cfg.mail_footer
     
     msg = MIMEText(body)
@@ -534,6 +526,8 @@
 
         if cfg.opts.mail:
             email_list(diststopush)
+        for d in diststopush:
+            WhatsNew.clearclogdiffs(cfg.rundir,d)
 
         for cmd in cfg.post_cmds:
             Utils.run_and_check(cmd)


Index: BuildSys.py
===================================================================
RCS file: /cvs/fedora/extras-buildsys/utils/pushscript/BuildSys.py,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- BuildSys.py	27 Feb 2007 23:19:24 -0000	1.2
+++ BuildSys.py	2 Mar 2007 16:40:05 -0000	1.3
@@ -165,10 +165,10 @@
 
     def __init__(self,name,home):
         self.name = name  # src.rpm %{name}
-        self.home = home
         self.origin = home  # original home
-        self.pkgid = self.name+'-'+os.path.basename(self.home)  # plague-results style
-
+        self.pkgid = name+'-'+os.path.basename(home)  # plague-results style
+        self.SetHome(home)
+    
     def __str__(self):
         return self.pkgid
 
@@ -180,12 +180,30 @@
 
     def SetHome(self,home):
         self.home = home
-    
-#    def GetSourcePkg(self):
-#        pass
 
-#    def IsPushed(self):
-#        return False
+        self.filedict = {}
+        self.filedict['srpm'] = []
+        self.filedict['rpm'] = []
+        self.filedict['debuginfo'] = []
+        self.filedict['other'] = []
+        # Match the build-results files to what list they should be in.
+        for file in Utils.find_files( self.home ):
+            if file.endswith('.rpm'):
+                if file.find('debuginfo') != -1:
+                    which = 'debuginfo' 
+                elif file.endswith('.src.rpm') or file.endswith('.nosrc.rpm'):
+                    which = 'srpm'
+                else:
+                    which = 'rpm'
+            else:
+                which = 'other'
+            self.filedict[which].append(file)
+
+    def GetSourcePkg(self):
+        if len(self.filedict['srpm']):
+            return self.filedict['srpm'][0]
+        else:
+            return None
 
     def MarkPushed(self):
         if self.origin:


Index: WhatsNew.py
===================================================================
RCS file: /cvs/fedora/extras-buildsys/utils/pushscript/WhatsNew.py,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- WhatsNew.py	1 Jan 2007 16:00:46 -0000	1.2
+++ WhatsNew.py	2 Mar 2007 16:40:05 -0000	1.3
@@ -16,58 +16,174 @@
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
 import errno, os, sys
-import fnmatch
-import pickle
+import datetime, fnmatch, pickle
 import rpmUtils.transaction, rpmUtils.miscutils
 
 import Utils
 
+# Map of maps: dist -> src.rpm %name -> list of changelog 3-tuples
 names = {}
+# Map of maps: dist -> pkgid -> list of formatted clog lines
+clogdiffs = {}
+
+# The 'names' dict is used to maintain a pickle db of known
+# srcr.rpm %name values and their newest %changelog entries.
+
+# The 'clogdiffs' dict is filled when new packages are published
+# and is cleared after sending a build report.
 
 def rebuild(dist,srcdir):
+    """initialise the pickle files"""
     ts = rpmUtils.transaction.initReadOnlyTransaction()
 
-    # Create map of maps: dist -> src.rpm %name -> True
-    names.setdefault(dist,{})
-   
     for root, dirs, files in os.walk(srcdir):
-            srpms = []
-            srpms.extend(fnmatch.filter(files,'*.src.rpm'))
-            srpms.extend(fnmatch.filter(files,'*.nosrc.rpm'))
-            for f in srpms:
-                srcfile = os.path.join(root,f)
-                hdr = rpmUtils.miscutils.hdrFromPackage(ts,srcfile)
-                set(dist,hdr['name'])
+        srpms = []
+        srpms.extend(fnmatch.filter(files,'*.src.rpm'))
+        srpms.extend(fnmatch.filter(files,'*.nosrc.rpm'))
+        for f in srpms:
+            srcfile = os.path.join(root,f)
+            hdr = rpmUtils.miscutils.hdrFromPackage(ts,srcfile)
+            put(dist,srcfile,ts)
 
 
-def set(dist,name):
-    names[dist].setdefault(name,True)
+def putname(dist,name):
+    """mark the name of this source rpm as seen before"""
+    names.setdefault(dist,{})
+    names[dist].setdefault(name,[])
 
 
-def get(dist,name):
-    return names[dist].has_key(name)
+def queryname(dist,name):
+    """query whether source rpm name is known, returns True or False"""
+    return names.has_key(dist) and names[dist].has_key(name)
+
+
+def put(dist,srcrpm,ts):
+    """mark the name of this source rpm as seen before and collect most recent changelog data"""
+    hdr = rpmUtils.miscutils.hdrFromPackage(ts,srcrpm)
+    name = hdr['name']
+    putclog(dist,name,readclog(srcrpm,ts))
+
+
+def putclog(dist,name,clogtuples):
+    """update a package's changelog data
+    input: zipped RPM changelog tuples"""
+    tosave = []  # changelog tuples to store
+    if len(clogtuples):
+        reftime = clogtuples[0][1]  # only save entries with highest timestamp
+        for (clogname, clogtime, clogtext) in clogtuples:
+            if clogtime >= reftime:
+                tosave.append( (clogname,clogtime,clogtext) )
+            else:
+                break
+    putname(dist,name)
+    names[dist][name] = tosave
+
+
+def getclog(dist,name):
+    """get the list of most recent changelog 3-tuples for this package, if any have been stored in the WhatsNew db before"""
+    if not names.has_key(dist):
+        return []
+    return names[dist].get(name,[])
+
+
+def formatclog(clogtuples):
+    """format a list of changelog 3-tuples to a printable string"""
+    clog = []
+    if len(clogtuples):
+        for (clogname, clogtime, clogtext) in clogtuples:
+            datestr = datetime.date.fromtimestamp(clogtime).strftime("%a %b %d %Y")
+            line = '* %s %s\n%s\n\n' % (datestr,clogname,clogtext)
+            clog.append(line)
+    return ''.join(clog)
+
+
+def readclog(srcrpm,ts):
+    """return a list of low-level changelog 3-tuples"""
+    if not srcrpm:
+        return []
+    hdr = rpmUtils.miscutils.hdrFromPackage(ts,srcrpm)
+    if not len(hdr['changelogname']):
+        return []
+    ctimes = hdr['changelogtime']
+    if isinstance(ctimes,int):  # pitfall in RPM
+        ctimes = [ctimes]
+    return zip(hdr['changelogname'],ctimes,hdr['changelogtext'])
+
+
+def getclogdiff(dist,name,rpm,ts):
+    """compares the changelog entries in a given rpm with what is stored in the WhatsNew db and returns new entries in printable form"""
+    oldclog = getclog(dist,name)
+    newclog = readclog(rpm,ts)
+    if len(oldclog):
+        reftime = datetime.date.fromtimestamp(oldclog[0][1])  # only get entries at least as new as this
+        haveold = True
+    else:
+        reftime = datetime.date.today()-datetime.timedelta( days = 30 )
+        haveold = False
+    # TODO: limit max.number of entries?
+    tosave = []
+    if len(newclog):
+        for clogtup in newclog:
+            if haveold and (clogtup == oldclog[0]):
+                break
+            (clogname, clogtime, clogtext) = clogtup
+            if datetime.date.fromtimestamp(clogtime) > reftime:
+                tosave.append( (clogname,clogtime,clogtext) )
+            else:
+                break
+    return formatclog(tosave)
+
+
+def putclogdiff(dist,pkgid,clogdiff):
+    """store a pair of package id and printable changelog entries"""
+    clogdiffs.setdefault(dist,{})
+    clogdiffs[dist].setdefault(pkgid,clogdiff)
+
+
+def getallclogdiffs(dist):
+    rv = ''
+    if not clogdiffs.has_key(dist):
+        return rv
+    pkgids = clogdiffs[dist].keys()
+    pkgids.sort()
+    for pkgid in pkgids:
+        rv += '%s\n' % pkgid +'-'*len(pkgid)+'\n%s' % clogdiffs[dist][pkgid]
+    return rv
+
+
+def clearclogdiffs(workdir,dist):
+    load(workdir)
+    clogdiffs.setdefault(dist,{})
+    clogdiffs[dist] = {}
+    save(workdir)
 
 
 def save(workdir):
-    f = file(os.path.join(workdir,'pkgnamesdict.pickle'),'w')
+    """save WhatNew run-time data to disk"""
+    f = file(os.path.join(workdir,'whatsnewdict.pickle'),'w')
     pickle.dump(names,f)
+    pickle.dump(clogdiffs,f)
     f.close()
 
 
 def load(workdir):
-    global names
+    """load WhatsNew run-time data from disk"""
+    global names, clogdiffs
     names = {}
+    clogdiffs = {}
     try:
-        f = file(os.path.join(workdir,'pkgnamesdict.pickle'),'r')
+        f = file(os.path.join(workdir,'whatsnewdict.pickle'),'r')
     except:
         return
     names = pickle.load(f)
+    clogdiffs = pickle.load(f)
     f.close()
 
 
 def main(cfg):
-    global names
+    global names, clogdiffs
     names = {}
+    clogdiffs = {}
     for dist in cfg.alldists:
         srcdir = os.path.join(cfg.treedir,dist,'SRPMS')
         rebuild(dist,srcdir)




More information about the fedora-extras-commits mailing list