ooo-build r13060 - in trunk: . scratch/rcsutil scratch/rcsutil/src



Author: kyoshida
Date: Fri Jul  4 03:56:51 2008
New Revision: 13060
URL: http://svn.gnome.org/viewvc/ooo-build?rev=13060&view=rev

Log:
2008-07-03  Kohei Yoshida  <kyoshida novell com>

	* scratch/rcsutil/src/globals.py: added to store globals.
	
	* scratch/rcsutil/src/revision.py: added a separate file to manage 
	CVS's revision tree.
	
	* scratch/rcsutil/parse_rcs.py: added CWS and author black lists, and
	added a hook to retrieve branch names from revision numbers.


Added:
   trunk/scratch/rcsutil/src/
   trunk/scratch/rcsutil/src/globals.py
   trunk/scratch/rcsutil/src/revision.py
Modified:
   trunk/ChangeLog
   trunk/scratch/rcsutil/parse_rcs.py

Modified: trunk/scratch/rcsutil/parse_rcs.py
==============================================================================
--- trunk/scratch/rcsutil/parse_rcs.py	(original)
+++ trunk/scratch/rcsutil/parse_rcs.py	Fri Jul  4 03:56:51 2008
@@ -5,6 +5,22 @@
 import time, datetime
 import optparse
 
+# import local modules.
+sys.path.append(sys.path[0]+"/src")
+import revision, globals
+
+
+# all commits that were made to the following branches are ignored.
+ignoredBranches = [
+    'SRX643_TF_BINFILTER',
+    'cws_dev300_changefileheader', 
+    'cws_src680_hedaburemove01',
+    'cws_src680_ooo19126']
+
+# all commmits done by the following authors are ignored.
+ignoredAuthors = [
+    'gh', 'ihi', 'rt', 'vg']
+
 currentAffiliations = {
     'ab': 'Sun', # Andreas Bregas       
     'abi': 'Sun', # Andreas Bille        
@@ -340,19 +356,9 @@
     return affil
 
 
-class Debuggable(object):
-
-    def __init__ (self):
-        self.debug = True
-
-    def debugPrint (self, msg, abortAfter=False):
-        if self.debug:
-            sys.stderr.write(msg + "\n")
-            if abortAfter:
-                sys.exit(1)
 
 
-class RCSFile(Debuggable):
+class RCSFile(globals.Debuggable):
 
     # alpha numeric letter
     alphnum = '([a-z]|[A-Z]|[0-9])'
@@ -365,17 +371,17 @@
 
 
     def __init__ (self, lines, ext):
-        Debuggable.__init__(self)
+        globals.Debuggable.__init__(self)
 
         self.lines = lines
-        self.lineLength = len(self.lines)
+        self.lineCount = len(self.lines)
         self.ext = ext
         self.reset()
 
 
     def reset (self):
         self.headers = {}
-        self.branchSymbols = {}
+        self.revTree = revision.RevisionTree()
         self.commitLogs = []
         self.descError = False
         self.symbolicNamesError = False
@@ -386,7 +392,7 @@
 
         rePattern = re.compile(RCSFile.reCategory)
         i = 0
-        while i < self.lineLength:
+        while i < self.lineCount:
             line = self.lines[i].rstrip()
             res = rePattern.search(line)
             if res == None:
@@ -407,15 +413,16 @@
             i += 1
 
 
+    def outputRevTree (self):
+        self.revTree.output()
+
+    def getBranchName (self, revision):
+        return self.revTree.getBranchName(revision)
+
     def output (self):
         for key in self.headers.keys():
             print key + " -> '" + self.headers[key] + "'"
 
-        keys = self.branchSymbols.keys()
-        keys.sort()
-        for key in keys:
-            print key + " -> " + self.branchSymbols[key]
-
         for commitLog in self.commitLogs:
             print ('-'*45)
             keys = commitLog.keys()
@@ -432,7 +439,7 @@
 
         # [tab]symbol name: branch number
 
-        while i < self.lineLength:
+        while i < self.lineCount:
             line = self.__getLine(i)
             if len(line) == 0:
                 break
@@ -445,7 +452,7 @@
             name = name.strip()
             number = number.strip()
 
-            self.branchSymbols[number] = name
+            self.revTree.addSymbol(name, number)
             i += 1
 
         self.symbolicNamesError = True
@@ -499,7 +506,7 @@
         self.debugPrint(self.__getLine(i))
         i += 1
 
-        while i < self.lineLength:
+        while i < self.lineCount:
             self.debugPrint(self.__getLine(i))
             commitLog = {}
     
@@ -512,7 +519,12 @@
     
             revnum = line.split()[1].strip()
             commitLog['revision'] = revnum
-    
+            try:
+                branch = self.revTree.getBranchName(revnum)
+                commitLog['branch'] = branch
+            except revision.RevisionError:
+                pass
+
             i += 1
             self.debugPrint(self.__getLine(i))
 
@@ -526,7 +538,7 @@
     
             # the rest is a commit message.
             msg = []
-            while i < self.lineLength:
+            while i < self.lineCount:
                 self.debugPrint(self.__getLine(i))
                 if self.__isRevSeparator(i):
                     break
@@ -626,6 +638,7 @@
     * date - commit date and time (datetime object).
     * author - who made the commit (string).
     * revision - revision number (string)
+    * branch - name of the branch to which the commit was made (string).
     * state - state of the file ??? (string)
     * message - commit message (string list).
 
@@ -674,11 +687,22 @@
                 if isIssueNumber:
                     statObj.patchCommitCount += 1
 
+            # branch
+            if log.has_key('branch') and log['branch'] in ignoredBranches:
+                self.debugPrint ("commit made to branch %s is ignored (%s)"%(log['branch'], log['revision']))
+                statObj.ignoredByBranchCount += 1
+                continue
+
             # author
             if not log.has_key('author'):
                 self.debugPrint("author record is absent")
                 return False
             author = log['author']
+            if author in ignoredAuthors:
+                self.debugPrint("commit made by %s is ignored"%author)
+                statObj.ignoredByAuthorCount += 1
+                continue
+
 
             # date
             if not log.has_key('date'):
@@ -729,6 +753,8 @@
         self.totalCommitCount = 0
         self.resyncCommitCount = 0
         self.integrationCommitCount = 0
+        self.ignoredByBranchCount = 0
+        self.ignoredByAuthorCount = 0
         self.patchCommitCount = 0
 
     def add (self, author, date, ext, added, removed):
@@ -898,7 +924,9 @@
             sys.stderr.write("error parsing " + filepath + "\n")
             self.isError = True
 
+#       obj.outputRevTree()
 #       obj.output()
+
         if not obj.writeCommitStats(self.stats):
             sys.stderr.write("failed to write commit stats\n")
             sys.exit(1)
@@ -939,6 +967,8 @@
         fd.write("total commit count\t%d\n"%self.stats.totalCommitCount)
         fd.write("cws integration commits ignored\t%d\n"%self.stats.integrationCommitCount)
         fd.write("resync commits ignored\t%d\n"%self.stats.resyncCommitCount)
+        fd.write("commits ignored by branch name\t%d\n"%self.stats.ignoredByBranchCount)
+        fd.write("commits ignored by author name\t%d\n"%self.stats.ignoredByAuthorCount)
         fd.write("issue numbers found\t%d\n"%self.stats.patchCommitCount)
 
 

Added: trunk/scratch/rcsutil/src/globals.py
==============================================================================
--- (empty file)
+++ trunk/scratch/rcsutil/src/globals.py	Fri Jul  4 03:56:51 2008
@@ -0,0 +1,13 @@
+
+import sys
+
+class Debuggable(object):
+
+    def __init__ (self):
+        self.debug = True
+
+    def debugPrint (self, msg, abortAfter=False):
+        if self.debug:
+            sys.stderr.write(msg + "\n")
+            if abortAfter:
+                sys.exit(1)

Added: trunk/scratch/rcsutil/src/revision.py
==============================================================================
--- (empty file)
+++ trunk/scratch/rcsutil/src/revision.py	Fri Jul  4 03:56:51 2008
@@ -0,0 +1,129 @@
+
+import sys
+import globals
+
+class RevisionError(Exception):
+    def __init__ (self, msg='RevisionFormatError Exception'):
+        self.message = msg
+
+class Node(object):
+
+    def __init__ (self, num, parent):
+        self.num = num
+        self.children = {}
+        self.tags = []
+        self.branchName = ''
+        self.parent = parent
+
+    def output (self, level=0):
+        isRoot = (self.parent == None)
+        if isRoot:
+            childKeys = self.children.keys()
+            childKeys.sort()
+            for key in childKeys:
+                self.children[key].output(level)
+            return
+
+        sys.stdout.write("  "*level)
+        node = self
+        revText = ''
+        while node != None:
+            if len(revText) == 0:
+                revText = "%d"%node.num
+            else:
+                revText = "%d"%node.num + '.' + revText
+            node = node.parent
+
+        revText += ' ' + self.branchName
+        sys.stdout.write(revText + "\n")
+
+        childKeys = self.children.keys()
+        childKeys.sort()
+        for key in childKeys:
+            self.children[key].output(level+1)
+
+
+class RevisionTree(globals.Debuggable):
+    """Manage revision tree.
+
+CVS's revision number has the following characteristics:
+
+    * The first number is always 1 (for root node).
+    * The second number is the revision in HEAD.
+    * When the 2nd to the last number is 0, that node is a branch 
+      node whose number is the original revision with theat 0 removed 
+      e.g. if the original number is 1.34.0.4, then that's the branch 
+      node for 1.34.4.
+"""
+
+    def __init__ (self):
+        globals.Debuggable.__init__(self)
+
+        self.root = Node(1, None)
+
+
+    def __revisionStr2NumList (self, revision):
+        numStrs = revision.split('.')
+        nums = []
+        for s in numStrs:
+            nums.append(int(s))
+        return nums
+
+    def addSymbol (self, name, revision):
+        nums = self.__revisionStr2NumList(revision)
+        n = len(nums)
+
+        isBranchName = False
+        if n >= 4 and nums[-2] == 0:
+            # special case for branch name
+            nums2 = nums[:-2]
+            nums2.append(nums[-1])
+            isBranchName = True
+            nums = nums2
+            n -= 1
+
+        currentNode = self.root
+        for i in xrange(1, n):
+            num = nums[i]
+            if not currentNode.children.has_key(num):
+                currentNode.children[num] = Node(num, currentNode)
+            currentNode = currentNode.children[num]
+            if i == n - 1:
+                # last node
+                if isBranchName:
+                    currentNode.branchName = name
+                else:
+                    currentNode.tags.append(name)
+
+
+    def output (self):
+        self.root.output()
+
+
+    def getBranchName (self, revision):
+        """Get the branch name for a give revision number.
+
+The revision number must be given as a string (e.g. '1.23.2.1').
+"""
+        if type(revision) != type(''):
+            raise ValueError
+
+        nums = self.__revisionStr2NumList(revision)
+        node = self.root
+        if nums[0] != node.num:
+            raise RevisionError('first number is not 1')
+
+        for num in nums[1:]:
+            if len(node.children.keys()) == 0:
+                return node.branchName
+
+            if not node.children.has_key(num):
+                raise RevisionError("revision " + revision + " doesn't have any associated branch name")
+
+            node = node.children[num]
+
+
+
+
+
+



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]