]> xenbits.xensource.com Git - people/larsk/xenproject-org-gitdm.git/commitdiff
Add the VirtualEmployer mechanism
authorJonathan Corbet <corbet@lwn.net>
Tue, 10 May 2011 20:32:47 +0000 (14:32 -0600)
committerJonathan Corbet <corbet@lwn.net>
Tue, 10 May 2011 20:32:47 +0000 (14:32 -0600)
A certain obnoxious developer wants his contributions to be split between
two employers.  So add the "VirtualEmployer" mechanism to make that
possible.  A virtual employer is defined with:

VirtualEmployer ve-name
nn% real-name
...
end

(This construct must appear in the main configuration file).  Developers
can be associated with the virtual employer in the usual way; at report
time, any changes credited to that employer will be split among the real
employers according to the percentages provided.

Signed-off-by: Jonathan Corbet <corbet@lwn.net>
ConfigFile.py
README
database.py
gitdm

index 6c351487af4608d87dbf439e8b2f46b16a9d7d8b..32a4aeca4aa3cc2f079da3f94f0604c134ef3af2 100644 (file)
@@ -92,6 +92,36 @@ def ReadGroupMap (fname, employer):
         line = ReadConfigLine (file)
     file.close ()
 
+#
+# Read in a virtual employer description.
+#
+def ReadVirtual (file, name):
+    ve = database.VirtualEmployer (name)
+    line = ReadConfigLine (file)
+    while line:
+        sl = line.split (None, 1)
+        first = sl[0]
+        if first == 'end':
+            ve.store ()
+            return
+        #
+        # Zap the "%" syntactic sugar if it's there
+        #
+        if first[-1] == '%':
+            first = first[:-1]
+        try:
+            percent = int (first)
+        except ValueError:
+            croak ('Bad split value "%s" for virtual empl %s' % (first, name))
+        if not (0 < percent <= 100):
+            croak ('Bad split value "%s" for virtual empl %s' % (first, name))
+        ve.addsplit (' '.join (sl[1:]), percent/100.0)
+        line = ReadConfigLine (file)
+    #
+    # We should never get here
+    #
+    croak ('Missing "end" line for virtual employer %s' % (name))
+
 #
 # Read an overall config file.
 #
@@ -114,6 +144,8 @@ def ConfigFile (name, confdir):
             if len (sline) != 3:
                 croak ('Funky group map line "%s"' % (line))
             ReadGroupMap (os.path.join (confdir, sline[1]), sline[2])
+        elif sline[0] == 'VirtualEmployer':
+            ReadVirtual (file, ' '.join (sline[1:]))
         else:
             croak ('Unrecognized config line: "%s"' % (line))
         line = ReadConfigLine (file)
diff --git a/README b/README
index a5bdf638d1cf5fcf8c6a2dcb3cd8ac3e0024a0f7..7226541e34b051a538792cb9cfecd151c37e63ea 100644 (file)
--- a/README
+++ b/README
@@ -121,6 +121,20 @@ GroupMap file employer
        email addresses only, all of which are associated with the given
        employer.
 
+VirtualEmployer name
+    nn% employer1
+    ...
+end
+
+       This construct (which appears in the main configuration file)
+       allows causes the creation of a fake employer with the given
+       "name".  It directs that any contributions attributed to that
+       employer should be split to other (real) employers using the given
+       percentages.  The functionality works, but is primitive - there is,
+       for example, no check to ensure that the percentages add up to
+       something rational.
+
+
 OTHER TOOLS
 
 A few other tools have been added to this repository:
index e4d533ad965eba96e572880ff1bf730d27a32a07..b5d9382093b004fc042f3d0a633c94c78335c869 100644 (file)
@@ -150,6 +150,52 @@ def GetEmployer (name):
 def AllEmployers ():
     return Employers.values ()
 
+#
+# Certain obnoxious developers, who will remain nameless (because we
+# would never want to run afoul of Thomas) want their work split among
+# multiple companies.  Let's try to cope with that.  Let's also hope
+# this doesn't spread.
+#
+class VirtualEmployer (Employer):
+    def __init__ (self, name):
+        Employer.__init__ (self, name)
+        self.splits = [ ]
+
+    def addsplit (self, name, fraction):
+        self.splits.append ((name, fraction))
+
+    #
+    # Go through and (destructively) apply our credits to the
+    # real employer.  Only one level of weirdness is supported.
+    #
+    def applysplits (self):
+        for name, fraction in self.splits:
+            real = GetEmployer (name)
+            real.added += int (self.added*fraction)
+            real.removed += int (self.removed*fraction)
+            real.changed += int (self.changed*fraction)
+            real.count += int (self.count*fraction)
+        self.__init__ (name) # Reset counts just in case
+
+    def store (self):
+        if Employers.has_key (self.name):
+            print Employers[self.name]
+            sys.stderr.write ('WARNING: Virtual empl %s overwrites another\n'
+                              % (self.name))
+        if len (self.splits) == 0:
+            sys.stderr.write ('WARNING: Virtual empl %s has no splits\n'
+                              % (self.name))
+            # Should check that they add up too, but I'm lazy
+        Employers[self.name] = self
+
+#
+# Mix all the virtual employers into their real destinations.
+#
+def MixVirtuals ():
+    for empl in AllEmployers ():
+        if isinstance (empl, VirtualEmployer):
+            empl.applysplits ()
+
 #
 # The email map.
 #
diff --git a/gitdm b/gitdm
index 5767a88b4677e6760da7811941788880267cd836..8133c2286ec18e50256de11223cc9759cd2cbe74 100755 (executable)
--- a/gitdm
+++ b/gitdm
@@ -379,6 +379,8 @@ print >> sys.stderr, 'Grabbing changesets...done       '
 
 if DumpDB:
     database.DumpDB ()
+database.MixVirtuals ()
+
 #
 # Say something
 #