def link_project(self, mproject): """ Loads in the commits from a project and then attempts to place new entires in the user_corporation_project table (aka ProjectInvolvement) table. @param mproject: a dbobjects.MasterProject element to load the data for """ # FIXME: this currently has no support for hierarchical master projects projects = Project.select(Project.q.masterProjectID == mproject.id) # pylint: disable-msg=E1101 # we'll need this for building SQL queries projarr = [x.id for x in projects] # get the first commit on the project so we know what month to start pumping data at firstcommit = CVSCommit.select(AND(CVSCommit.q.startDate > datetime.datetime(1997, 11, 01), # pylint: disable-msg=E1101 IN(CVSCommit.q.projectID, projarr))).min(CVSCommit.q.startDate) # pylint: disable-msg=E1101 lastcommit = CVSCommit.select(AND(CVSCommit.q.startDate > datetime.datetime(1997, 11, 01), # pylint: disable-msg=E1101 IN(CVSCommit.q.projectID, projarr))).max(CVSCommit.q.startDate) # pylint: disable-msg=E1101 if firstcommit == None: # do something here to indicate that it couldn't process this time period self.log.info("Project %s (id=%s) does not appear to have any commits in the window", mproject.name, mproject.id) return self.log.info("%s - %s %s", mproject.name, firstcommit, lastcommit) # iterate on a monthly basis across the data so we have monthly snapshots, just as we do for Eclipse currentdate = datetime.datetime(firstcommit.year, firstcommit.month, 1) nextdate = add_month(currentdate) while currentdate < lastcommit: self.link_project_month(mproject, projarr, currentdate, nextdate) currentdate = nextdate nextdate = add_month(currentdate)
def link_project_month(self, mproject, projarr, currentdate, nextdate): """ Does the "heavy" lifting for linking individuals to projects over a time period @param mproject: master project to link to @param projarr: the array of child projects @param currendate: the date to start looking @param nextdate: the date to stop looking """ # get the developers who committed during that period people = Person.select(AND(Person.q.id == PersonUser.q.personID, # pylint: disable-msg=E1101 PersonUser.q.userID == CVSCommit.q.userID, # pylint: disable-msg=E1101 CVSCommit.q.startDate >= currentdate, # pylint: disable-msg=E1101 CVSCommit.q.startDate < nextdate, # pylint: disable-msg=E1101 IN(CVSCommit.q.projectID, projarr)), distinct=True) # pylint: disable-msg=E1101 count = 0 numcorp = 0 numunknown = 0 # iterate over each of the people for person in people: user = User.select(AND(User.q.id == PersonUser.q.userID, # pylint: disable-msg=E1101 PersonUser.q.personID == person.id))[0] # pylint: disable-msg=E1101 # first get their company. cache it if possible if self.corpmap.has_key(person.id): corporation = self.corpmap[person.id] else: corporations = person.corporations if len(corporations) == 0: corporation = self.unknowncorp else: corporation = corporations[0] self.corpmap[person.id] = corporation # increment some tracking counters if corporation == self.unknowncorp: numunknown = numunknown + 1 else: numcorp = numcorp + 1 # now, get their commits, we need the number of commits and the number of lines added/removed commits = CVSCommit.select(AND(CVSCommit.q.userID == PersonUser.q.userID, # pylint: disable-msg=E1101 PersonUser.q.personID == person.id, # pylint: disable-msg=E1101 CVSCommit.q.startDate >= currentdate, # pylint: disable-msg=E1101 CVSCommit.q.startDate < nextdate, # pylint: disable-msg=E1101 IN(CVSCommit.q.projectID, projarr)), distinct=True) # pylint: disable-msg=E1101 commitids = [x.id for x in commits] numcommits = len(commitids) # in some cases, we don't have complete information, we just set those to empty here linesadded = FileCommit.select(IN(FileCommit.q.cvsCommitID, commitids)).sum(FileCommit.q.linesAdded) or 0 # pylint: disable-msg=E1101 linesremoved = FileCommit.select(IN(FileCommit.q.cvsCommitID, commitids)).sum(FileCommit.q.linesRemoved) or 0 # pylint: disable-msg=E1101 linesdelta = linesadded - linesremoved # commit the object newpi = ProjectInvolvement(user=user, corporation=corporation, project=mproject, year=currentdate.year, month=currentdate.month, date=currentdate, numCommits=numcommits, linesAdded=linesadded, linesRemoved=linesremoved, linesDelta=linesdelta) count = count + 1 self.log.info("%s-%s Added %d links (%d corp, %d unknown)...", currentdate, nextdate, count, numcorp, numunknown) return count