def _build_developer_branch_rel(self, branch): '''Build the relationship between developer and branch DeveloperBranch is the core relationship between developer and branch, and also a core concept to GitView to query and generate report. Developers will created for you if they does not exist in GitView already. ''' branch_name = branch.name remote_branch_name = git.build_remote_branch_name(branch_name) contributors = self.git_repo.get_contributors(remote_branch_name) qs = DeveloperBranch.objects.filter( branch__project=self.project).values('developer__full_name', 'branch__name') existing_rels = set((key_generator(rel['developer__full_name'], rel['branch__name']) for rel in qs.iterator())) get_developer = Developer.objects.get create_developer = Developer.objects.create create_rel = DeveloperBranch.objects.create add_developer_to_project = self.project.developers.add for contributor in contributors: new_rel_key = key_generator(contributor.full_name, branch_name) if new_rel_key in existing_rels: continue try: developer = get_developer(full_name=contributor.full_name, email=contributor.email) except Developer.DoesNotExist: kerb_name = contributor.email.split('@')[0] developer = create_developer(kerb_name=kerb_name, email=contributor.email, full_name=contributor.full_name) add_developer_to_project(developer) # Finally, we have enough things, developer and branch, to # build the relationship. That's great! create_rel(developer=developer, branch=branch) # Remember this newly added relationship, next iterations would # check the existence of relationship between developer and branch existing_rels.add(new_rel_key)
def _sync_branch_commits(self, branch): '''Synchronize commits against remote branch :param branch: from which branch to synchronize commits :type branch: Branch ''' # Determine rev range commits = Commit.objects.filter(project=self.project, branch=branch) commits = commits.only('commit_hash').order_by('-submit_date')[:1] if len(commits) == 0: rev_range = 'HEAD' else: rev_range = '{0}...HEAD'.format(commits[0].commit_hash) logger.info( 'Commits within {0} on branch {1} will be synchronized'.format( rev_range, branch.name)) # Get logs (commits) within the rev range logs = self.git_repo.logs(rev_range, git.build_remote_branch_name(branch.name)) # Sync commits create_developer = Developer.objects.create filter_developer = Developer.objects.filter create_commit = Commit.objects.create qs = Commit.objects.filter(project=self.project, branch=branch).values_list('commit_hash', flat=True) existings = set(qs.iterator()) for log in logs: if log.commit_hash in existings: continue logger.debug('Synchronize commit {0}'.format(log.commit_hash)) # I know, I know, developers are already synchronized in a separate # step, but still add here if necessary as a supplementary. qs = filter_developer(email=log.author_email).only('pk') if len(qs) == 0: logger.debug('Add new developer {0}'.format(log.author_email)) kerb_name = log.author_email.split('@')[0] developer = create_developer(kerb_name=kerb_name, email=log.author_email, full_name=log.author_name) else: developer = qs[0] # Shrink summary to length 100 character summary = log.summary summary_too_long = len(summary) > COMMIT_SUMMARY_MAX_LENGTH if summary_too_long: logger.warning(u'Summary "{0}" of commit {1} is too long to ' u'store in database. Truncate to 100 to fit ' u'the length of Commit.summary field.'.format( summary, log.abbreviated_commit_hash)) summary = summary[0:100] create_commit(commit_hash=log.commit_hash, submit_date=log.submit_date, summary=summary, classification='', total_files=log.files_changed, lines_inserted=log.lines_inserted, lines_deleted=log.lines_deleted, project=self.project, branch=branch, developer=developer)