Exemple #1
0
        public async Task Execute(string token, string agenName, string owner, string repo, string branch)
        {
            using (var dbContext = new GitRepositoryDbContext(true))
            {
                dbContext.Database.ExecuteSqlCommand($"TRUNCATE TABLE PullRequests");
                var githubExtractor = new GithubDataFetcher(token, agenName, _logger);
                var pullRequests    = await githubExtractor.FetchAllPullRequests(owner, repo).ConfigureAwait(false);

                _logger.LogInformation("{datetime}: trying to save {count} pull requests.", DateTime.Now, pullRequests.Length);
                foreach (PullRequest pullrequest in pullRequests)
                {
                    var startdate = pullrequest.CreatedAtDateTime;
                    var enddate   = pullrequest.ClosedAtDateTime;
                    var overlap   = pullRequests.Where(a => a.ClosedAtDateTime > startdate && a.CreatedAtDateTime < enddate && a.Number != pullrequest.Number).ToList();
                    foreach (PullRequest item in overlap)
                    {
                        if (item.Number < pullrequest.Number)
                        {
                            pullrequest.OverlapPullRequest = string.Concat(pullrequest.OverlapPullRequest, item.Number.ToString() + ",");
                        }
                    }
                }
                dbContext.AddRange(pullRequests);
                dbContext.SaveChanges();
                _logger.LogInformation("{datetime}: pull requests has been saved successfully.", DateTime.Now);
            }
        }
Exemple #2
0
 private static void InitDatabase()
 {
     using (var client = new GitRepositoryDbContext())
     {
         client.Database.EnsureCreated();
     }
 }
        public async Task Execute(string token, string agenName, string owner, string repo)
        {
            using (var dbContext = new GitRepositoryDbContext())
            {
                var commitAuthors = await dbContext.Commits
                                    .FromSql(@"select c1.* from Commits as c1
                INNER JOIN (select NormalizedAuthorName,AuthorName,max(AuthorDateTime) as AuthorDateTime from Commits
                group by NormalizedAuthorName,AuthorName) as c2 on c1.AuthorDateTime=c2.AuthorDateTime
                and c1.NormalizedAuthorName=c2.NormalizedAuthorName
                and c1.AuthorName=c2.AuthorName")
                                    .ToArrayAsync().ConfigureAwait(false);

                _logger.LogInformation("{datetime}: fetching corresponding GitHub user of {count} git authors.", DateTime.Now, commitAuthors.Length);

                var github = new GithubDataFetcher(token, agenName, _logger);

                foreach (var commitAuthor in commitAuthors)
                {
                    var commit = await github.GetCommit(owner, repo, commitAuthor.Sha).ConfigureAwait(false);

                    // Github does not return the author for some of the old Commits
                    dbContext.Add(new GitHubGitUser
                    {
                        GitUsername           = commitAuthor.AuthorName,
                        GitHubUsername        = commit.Author?.Login,
                        GitNormalizedUsername = commitAuthor.NormalizedAuthorName
                    });
                }

                await dbContext.SaveChangesAsync().ConfigureAwait(false);

                _logger.LogInformation("{datetime}: corresponding GitHub users have been saved successfully.", DateTime.Now);
            }
        }
Exemple #4
0
        public async Task Execute()
        {
            using (var dbContext = new GitRepositoryDbContext(false))
            {
                _logger.LogInformation("{datetime}: applying normalization on commits.", DateTime.Now);

                await dbContext
                .Database
                .ExecuteSqlCommandAsync(
                    @"UPDATE Commits SET NormalizedAuthorName=AliasedDeveloperNames.NormalizedName
                    from AliasedDeveloperNames
                    where AliasedDeveloperNames.Email=Commits.AuthorEmail").ConfigureAwait(false);

                _logger.LogInformation("{datetime}: applying normalization on committed blob blames.", DateTime.Now);

                await dbContext
                .Database
                .ExecuteSqlCommandAsync(
                    @"UPDATE CommitBlobBlames SET NormalizedDeveloperIdentity=Commits.NormalizedAuthorName
                    from Commits
                    where  CommitBlobBlames.AuthorCommitSha=Sha").ConfigureAwait(false);


                _logger.LogInformation("{datetime}: applying normalization on committed changes blames.", DateTime.Now);

                await dbContext
                .Database
                .ExecuteSqlCommandAsync(
                    @"update CommittedChangeBlames SET NormalizedDeveloperIdentity=Commits.NormalizedAuthorName
                    from Commits 
                    where CommittedChangeBlames.CommitSha=Sha").ConfigureAwait(false);
            }
        }
Exemple #5
0
 public OwnerShipKnowledgeShareStrategy(string knowledgeSaveReviewerReplacementType, ILogger logger, string pullRequestReviewerSelectionStrategy, bool?addOnlyToUnsafePullrequests, string recommenderOption, bool changePast) : base(knowledgeSaveReviewerReplacementType, logger, pullRequestReviewerSelectionStrategy, addOnlyToUnsafePullrequests, recommenderOption, changePast)
 {
     this.knowledgeSaveReviewerReplacementType = knowledgeSaveReviewerReplacementType;
     this.logger = logger;
     this.pullRequestReviewerSelectionStrategy = pullRequestReviewerSelectionStrategy;
     this.addOnlyToUnsafePullrequests          = addOnlyToUnsafePullrequests;
     this.recommenderOption = recommenderOption;
     this.changePast        = changePast;
     _dbContext             = new GitRepositoryDbContext(false);
 }
Exemple #6
0
        public async Task Execute(string periodType, int periodLength)
        {
            var commitPeriods = new List <CommitPeriod>();

            using (var dbContext = new GitRepositoryDbContext())
            {
                var commits = dbContext.Commits.OrderBy(m => m.AuthorDateTime).ToArray();

                _logger.LogInformation("{datetime}: trying to periodize all the {count} commits. Period Type: {type}, Period Length: {length}",
                                       DateTime.Now, commits.Count(), periodType, periodLength);

                var beginDatetime = commits.Min(m => m.AuthorDateTime);
                beginDatetime = new DateTime(beginDatetime.Year, beginDatetime.Month, 1);
                var endDatetime = commits.Max(m => m.AuthorDateTime);

                var periods            = GetPeriods(periodType, periodLength, beginDatetime, endDatetime);
                var currentPeriodIndex = 0;

                periods[currentPeriodIndex].FirstCommitSha = commits[0].Sha;
                for (int i = 0; i < commits.Length; i++)
                {
                    if (periods[currentPeriodIndex].ToDateTime < commits[i].AuthorDateTime)
                    {
                        var candidateCommits = commits.Where(q => !q.Ignore && q.AuthorDateTime <= commits[i - 1].AuthorDateTime);

                        if (candidateCommits.Count() > 0) // the problem happens (rarely) in the first period.
                        {
                            periods[currentPeriodIndex].LastCommitSha = candidateCommits.Last().Sha;
                        }
                        else
                        {
                            periods[currentPeriodIndex].LastCommitSha = periods[currentPeriodIndex].FirstCommitSha;
                        }

                        currentPeriodIndex++;

                        periods[currentPeriodIndex].FirstCommitSha = commits
                                                                     .First(q => !q.Ignore && q.AuthorDateTime >= commits[i].AuthorDateTime)
                                                                     .Sha;
                    }

                    commits[i].PeriodId = periods[currentPeriodIndex].Id;
                }

                periods[currentPeriodIndex].LastCommitSha = commits[commits.Length - 1].Sha;

                _logger.LogInformation("{datetime}: trying to save {count} periods.", DateTime.Now, periods.Count());
                dbContext.Periods.AddRange(periods);
                await dbContext.SaveChangesAsync().ConfigureAwait(false);

                _logger.LogInformation("{datetime}: periods has been saved successfully.", DateTime.Now);
            }
        }
        public async Task Execute(string token, string agenName, string owner, string repo, string[] labels, string state = "All")
        {
            using (var dbContext = new GitRepositoryDbContext())
            {
                dbContext.Database.ExecuteSqlCommand($"TRUNCATE TABLE Issue");
                var githubExtractor = new GithubDataFetcher(token, agenName, _logger);
                var issues          = await githubExtractor.GetIssues(owner, repo, labels, state).ConfigureAwait(false);

                dbContext.AddRange(issues);
                dbContext.SaveChanges();
            }
        }
        public async Task Execute(string token, string agenName, string owner, string repo)
        {
            using (var dbContext = new GitRepositoryDbContext())
            {
                var loadedIssues    = dbContext.Issue.ToArray();
                var githubExtractor = new GithubDataFetcher(token, agenName, _logger);
                var issueEvents     = await githubExtractor.GetIssueEvents(owner, repo, loadedIssues).ConfigureAwait(false);

                dbContext.AddRange(issueEvents);
                dbContext.SaveChanges();
            }
        }
        public async Task Execute(string token, string agenName, string owner, string repo, string branch)
        {
            using (var dbContext = new GitRepositoryDbContext(true))
            {
                dbContext.Database.ExecuteSqlCommand($"TRUNCATE TABLE PullRequests");
                var githubExtractor = new GithubDataFetcher(token, agenName, _logger);
                var pullRequests    = await githubExtractor.FetchAllPullRequests(owner, repo).ConfigureAwait(false);

                _logger.LogInformation("{datetime}: trying to save {count} pull requests.", DateTime.Now, pullRequests.Length);
                dbContext.AddRange(pullRequests);
                dbContext.SaveChanges();
                _logger.LogInformation("{datetime}: pull requests has been saved successfully.", DateTime.Now);
            }
        }
Exemple #10
0
        public async Task Execute(string repoPath, string branchName)
        {
            using (var dbContext = new GitRepositoryDbContext(false))
            {
                var gitRepository  = new GitRepository(repoPath, _logger);
                var orderedCommits = gitRepository.ExtractCommitsFromBranch(branchName);
                var relationships  = orderedCommits.SelectMany(q => q.CommitRelationship).ToArray();
                _logger.LogInformation("{datetime}: trying to save {count} commits into database.", DateTime.Now, orderedCommits.Count());
                await dbContext.BulkInsertAsync(orderedCommits).ConfigureAwait(false);

                await dbContext.BulkInsertAsync(relationships).ConfigureAwait(false);

                _logger.LogInformation("{datetime}: commits has been saved successfully.", DateTime.Now);
            }
        }
        public async Task Execute(string repoPath, string branchName, string[] validExtensions, string[] excludedBlamePaths)
        {
            using (var dbContext = new GitRepositoryDbContext(false))
            {
                var gitRepository    = new GitRepository(repoPath, _logger);
                var committedChanges = dbContext.CommittedChanges.ToArray();

                _logger.LogInformation("{datetime}: just started to extract blames.", DateTime.Now);
                var blames = gitRepository.GetBlameOfChanges(branchName, validExtensions, excludedBlamePaths, committedChanges);
                _logger.LogInformation("{datetime}: trying to save {count} blames into database.", DateTime.Now, blames.Count());
                await dbContext.BulkInsertAsync(blames).ConfigureAwait(false);

                _logger.LogInformation("{datetime}: blames has been saved successfully.", DateTime.Now);
            }
        }
Exemple #12
0
        public async Task Execute(double coreDeveloperThreshold, string coreDeveloperCalculationType)
        {
            using (var dbContext = new GitRepositoryDbContext(false))
            {
                _logger.LogInformation("{datetime}: extracting developer statistics for each period.", DateTime.Now);

                var reviewersPeriodsDic       = dbContext.GetPeriodReviewerCounts();
                var reviewersParticipationDic = dbContext.GetReviewersParticipationDates();
                await ExtractDevelopersInformation(reviewersPeriodsDic, reviewersParticipationDic, dbContext).ConfigureAwait(false);
                await ExctractContributionsPerPeriod(coreDeveloperThreshold, coreDeveloperCalculationType, reviewersPeriodsDic, dbContext).ConfigureAwait(false);

                await dbContext.SaveChangesAsync().ConfigureAwait(false);

                _logger.LogInformation("{datetime}: developer information has been extracted and saved.", DateTime.Now);
            }
        }
        public async Task Execute(string token, string agenName, string owner, string repo, string branch)
        {
            using (var dbContext = new GitRepositoryDbContext(false))
            {
                dbContext.Database.ExecuteSqlCommand($"TRUNCATE TABLE PullRequestReviewerComments");
                var githubExtractor             = new GithubDataFetcher(token, agenName, _logger);
                var pullRequestReviewerComments = await githubExtractor.FetchPullRequestReviewerCommentsFromRepository(owner, repo).ConfigureAwait(false);

                _logger.LogInformation("{datetime}: saving {count} review comments  into database.", DateTime.Now, pullRequestReviewerComments.Length);

                dbContext.BulkInsert(pullRequestReviewerComments, new BulkConfig {
                    BatchSize = 50000, BulkCopyTimeout = 0
                });

                _logger.LogInformation("{datetime}: {count} review comments have been saved into database.", DateTime.Now, pullRequestReviewerComments.Length);
            }
        }
Exemple #14
0
        public async Task Execute(string token, string agenName, string owner, string repo, string branch)
        {
            using (var dbContext = new GitRepositoryDbContext(true))
            {
                var loadedPullRequests = await dbContext.PullRequests.FromSql(@"select * from PullRequests WHERE Merged=1 and MergeCommitSha not in (select Sha from Commits)")
                                         .ToArrayAsync().ConfigureAwait(false);

                _logger.LogInformation("{datetime}: there are {count} pull requests with no corresponding merged commit", DateTime.Now, loadedPullRequests.Length);

                var githubExtractor = new GithubDataFetcher(token, agenName, _logger);
                await githubExtractor.MergeEvents(owner, repo, loadedPullRequests).ConfigureAwait(false);

                await dbContext.SaveChangesAsync().ConfigureAwait(false);

                _logger.LogInformation("{datetime}: corresponding merged commits has been resolved and saved.", DateTime.Now);
            }
        }
Exemple #15
0
        public async Task Execute(string repoPath, string branchName)
        {
            using (var dbContext = new GitRepositoryDbContext(false))
            {
                var gitRepository  = new GitRepository(repoPath, _logger);
                var orderedCommits = gitRepository.ExtractCommitsFromBranch(branchName);
                gitRepository.LoadChangesOfCommits(orderedCommits);

                _logger.LogInformation("{dateTime}: saving committed changes", DateTime.Now);

                dbContext.BulkInsert(orderedCommits.SelectMany(q => q.CommittedChanges).ToArray(), new BulkConfig {
                    BatchSize = 50000, BulkCopyTimeout = 0
                });

                _logger.LogInformation("{dateTime}: committed changes have been saved successfully", DateTime.Now);
            }
        }
        private async Task ExtractBlamesofCommit(Commit commit, Dictionary <string, string> canonicalDic, string[] validExtensions, string[] excludePath, GitRepository gitRepository, string branch, bool extractBlames)
        {
            using (var dbContext = new GitRepositoryDbContext(false))
            {
                _logger.LogInformation("{datetime}: extracting blames out of commit {Commitsha}", DateTime.Now, commit.Sha);

                gitRepository.LoadBlobsAndTheirBlamesOfCommit(commit, validExtensions, excludePath, canonicalDic, extractBlames, branch);

                var blames = commit.Blobs.SelectMany(m => m.CommitBlobBlames);
                _logger.LogInformation("{datetime}: saving {count} blames of {blobCount} from commit {Commitsha} into database.", DateTime.Now, blames.Count(), commit.Blobs.Count(), commit.Sha);

                await dbContext.BulkInsertAsync(commit.Blobs.ToArray()).ConfigureAwait(false);

                await dbContext.BulkInsertAsync(blames.ToArray()).ConfigureAwait(false);

                _logger.LogInformation("{datetime}: blames of {Commitsha} have been saved.", DateTime.Now, commit.Sha);
            }
        }
        public async Task Execute(string token, string agenName, string owner, string repo, string branch)
        {
            using (var dbContext = new GitRepositoryDbContext(false))
            {
                var loadedPullRequests = await dbContext.PullRequests.ToArrayAsync().ConfigureAwait(false);

                var githubExtractor = new GithubDataFetcher(token, agenName, _logger);
                var files           = await githubExtractor.FetchFilesOfPullRequests(owner, repo, loadedPullRequests).ConfigureAwait(false);

                _logger.LogInformation("{datetime}: saving {count} pull request files into database.", DateTime.Now, files.Length);

                dbContext.BulkInsert(files, new BulkConfig {
                    BatchSize = 50000, BulkCopyTimeout = 0
                });


                _logger.LogInformation("{datetime}: pull request files have been saved successfully.", DateTime.Now, loadedPullRequests.Length);
            }
        }
Exemple #18
0
        internal Task Execute(LossSimulationOption lossSimulationOption)
        {
            _dbContext = new GitRepositoryDbContext(false);

            var lossSimulation = CreateLossSimulation(lossSimulationOption);

            var timeMachine = CreateTimeMachine(lossSimulation);

            var knowledgeDistributioneMap = timeMachine.FlyInTime();

            var leavers = GetLeavers(lossSimulation);

            using (var transaction = _dbContext.Database.BeginTransaction())
            {
                SavePullRequestReviewes(knowledgeDistributioneMap, lossSimulation);
                _logger.LogInformation("{datetime}: RecommendedPullRequestReviewes are saved successfully.", DateTime.Now);
                SaveOwnershipDistribution(knowledgeDistributioneMap, lossSimulation, leavers);
                _logger.LogInformation("{datetime}: Ownership Distribution is saved Successfully.", DateTime.Now);

                SavePullRequestSimulatedRecommendationResults(knowledgeDistributioneMap, lossSimulation);
                _logger.LogInformation("{datetime}: Pull Requests Recommendation Results are saved Successfully.", DateTime.Now);

                SaveOpenReviews(knowledgeDistributioneMap, lossSimulation);
                _logger.LogInformation("{datetime}: Developer OpenReviews are saved successfully.", DateTime.Now);

                transaction.Commit();
                _logger.LogInformation("{datetime}: Transaction is committed.", DateTime.Now);
            }

            _logger.LogInformation("{datetime}: trying to save results into database", DateTime.Now);
            _dbContext.SaveChanges();

            lossSimulation.EndDateTime             = DateTime.Now;
            _dbContext.Entry(lossSimulation).State = EntityState.Modified;

            _dbContext.SaveChanges();
            _logger.LogInformation("{datetime}: results have been saved", DateTime.Now);
            _dbContext.Dispose();

            return(Task.CompletedTask);
        }
        public async Task Execute(string token, string agentName)
        {
            using (var dbContext = new GitRepositoryDbContext())
            {
                dbContext.Database.ExecuteSqlCommand($"TRUNCATE TABLE Users");
                var unknownUsers = dbContext.Users
                                   .FromSql(@"Select UserLogin,null AS Name, NULL as Email from (
                            select distinct(UserLogin) AS UserLogin from PullRequests  WHERE UserLogin IS NOT null
                            union   
                            select distinct(UserLogin) AS UserLogin from PullRequestReviewers  WHERE UserLogin IS NOT null
                            union   
                            select distinct(UserLogin) from PullRequestReviewerComments WHERE UserLogin IS NOT null) AS Temp")
                                   .ToArray();

                var githubExtractor = new GithubDataFetcher(token, agentName, _logger);
                await githubExtractor.GetUsers(unknownUsers).ConfigureAwait(false);

                dbContext.AddRange(unknownUsers);
                await dbContext.SaveChangesAsync().ConfigureAwait(false);
            }
        }
        public async Task Execute(ExtractBlameForEachPeriodOption options)
        {
            var dbContext = new GitRepositoryDbContext();

            var extractedCommits = await dbContext.CommitBlobBlames.Select(m => m.CommitSha).Distinct().ToArrayAsync().ConfigureAwait(false);

            var periods = await GetPeriods(options, dbContext, extractedCommits).ConfigureAwait(false);

            var canonicalDic = dbContext.GetCanonicalPaths();

            var gitRepository  = new GitRepository(options.RepositoryPath, _logger);
            var orderedCommits = gitRepository.ExtractCommitsFromBranch(options.GitBranch).ToDictionary(q => q.Sha);

            dbContext.Dispose();

            _logger.LogInformation("{datetime}: extracting blames for {count} periods.", DateTime.Now, periods.Count());

            foreach (var period in periods)
            {
                await ExtractBlamesofCommit(orderedCommits[period.LastCommitSha], canonicalDic, options.Extensions, options.ExcludedBlamePaths, gitRepository, options.GitBranch, options.ExtractBlames).ConfigureAwait(false);
            }
        }
Exemple #21
0
        public async Task Execute(string token, string agenName, string owner, string repo, string branch)
        {
            using (var dbContext = new GitRepositoryDbContext(false))
            {
                dbContext.Database.ExecuteSqlCommand($"TRUNCATE TABLE PullRequestReviewers");

                var pullRequests = await dbContext.PullRequests.AsNoTracking()
                                   .OrderBy(q => q.Number)
                                   .ToArrayAsync().ConfigureAwait(false);

                _logger.LogInformation("{datetime}: trying to fetch all the assigned reviewers for all {count} pull requests.", DateTime.Now, pullRequests.Length);

                var githubExtractor    = new GithubDataFetcher(token, agenName, _logger);
                var pullRequestReviews = await githubExtractor.FetchReviewersOfPullRequests(owner, repo, pullRequests).ConfigureAwait(false);

                _logger.LogInformation("{datetime}: trying to save {count} reviewers into database.", DateTime.Now, pullRequestReviews.Length);

                dbContext.BulkInsert(pullRequestReviews, new BulkConfig {
                    BatchSize = 50000, BulkCopyTimeout = 0
                });

                _logger.LogInformation("{datetime}: reviewers has been save successfully.", DateTime.Now, pullRequestReviews.Length);
            }
        }
Exemple #22
0
        public async Task Execute(int megaCommitSize, IEnumerable <string> developerNames)
        {
            var developerNamesSet = "( " + developerNames
                                    .Select(q => $"'{q}'")
                                    .Aggregate((a, b) => $"{a},{b}") + " )";

            using (var dbContext = new GitRepositoryDbContext(false))
            {
                var query = $@"
                UPDATE Commits set Ignore=0;
                UPDATE Commits set Ignore=1
                WHERE NormalizedAuthorName in {developerNamesSet}
                OR Sha in (select CommitSha from CommittedChanges group by CommitSha having count(*)>={megaCommitSize});
                UPDATE CommitBlobBlames set Ignore=0;
                UPDATE CommitBlobBlames set Ignore=1
                WHERE NormalizedDeveloperIdentity in {developerNamesSet};
                UPDATE CommitBlobBlames set Ignore=1
                FROM CommitBlobBlames
                INNER JOIN (select CommitSha from CommittedChanges group by CommitSha having count(*)>={megaCommitSize}) as t
                On AuthorCommitSha=t.CommitSha";

                await dbContext.Database.ExecuteSqlCommandAsync(query).ConfigureAwait(false);
            }
        }
Exemple #23
0
        private async Task ExctractContributionsPerPeriod(double coreDeveloperThreshold, string coreDeveloperCalculationType, Dictionary <string, Dictionary <long, int> > reviewersInPeriods, GitRepositoryDbContext dbContext)
        {
            var commits = await dbContext.Commits
                          .Where(q => !q.Ignore)
                          .GroupBy(q => new { q.NormalizedAuthorName, q.PeriodId })
                          .Select(q => new
            {
                DeveloperName = q.Key.NormalizedAuthorName,
                PeriodId      = q.Key.PeriodId,
                TotalCommits  = q.Count(),
            })
                          .ToArrayAsync().ConfigureAwait(false);

            foreach (var period in dbContext.Periods.ToArray())
            {
                var commitSha = period.LastCommitSha;

                var blames = await dbContext.CommitBlobBlames
                             .Where(q => q.CommitSha == commitSha && !q.Ignore)
                             .GroupBy(q => q.NormalizedDeveloperIdentity)
                             .Select(q => new
                {
                    DeveloperName      = q.Key,
                    DeveloperKnowledge = q.Sum(l => l.AuditedLines)
                })
                             .OrderByDescending(q => q.DeveloperKnowledge)
                             .ToArrayAsync().ConfigureAwait(false);

                var totalKnowledge = (double)blames.Sum(q => q.DeveloperKnowledge);

                var knowledgePortions = 0.0;

                foreach (var dev in blames)
                {
                    var ownershipPercentage = dev.DeveloperKnowledge / totalKnowledge;
                    knowledgePortions += ownershipPercentage;

                    var totalReviews = reviewersInPeriods.ContainsKey(dev.DeveloperName)
                    ? reviewersInPeriods[dev.DeveloperName].ContainsKey(period.Id)
                    ? reviewersInPeriods[dev.DeveloperName][period.Id]
                    : 0
                    : 0;

                    dbContext.Add(new DeveloperContribution()
                    {
                        IsCore          = IsCore(knowledgePortions, ownershipPercentage, dev.DeveloperKnowledge, coreDeveloperThreshold, coreDeveloperCalculationType),
                        NormalizedName  = dev.DeveloperName,
                        TotalLines      = dev.DeveloperKnowledge,
                        PeriodId        = period.Id,
                        LinesPercentage = ownershipPercentage,
                        TotalCommits    = commits.SingleOrDefault(q => q.PeriodId == period.Id && q.DeveloperName == dev.DeveloperName)?.TotalCommits ?? 0,
                        TotalReviews    = totalReviews
                    });
                }

                var reviewersOfPeriod = reviewersInPeriods.Keys.Where(q => reviewersInPeriods[q].ContainsKey(period.Id));
                foreach (var soleReviewer in reviewersOfPeriod.Where(q => !blames.Any(d => d.DeveloperName == q)))
                {
                    var totalReviews = reviewersInPeriods[soleReviewer][period.Id];

                    dbContext.Add(new DeveloperContribution()
                    {
                        IsCore          = false,
                        NormalizedName  = soleReviewer,
                        TotalLines      = 0,
                        PeriodId        = period.Id,
                        LinesPercentage = 0,
                        TotalCommits    = 0,
                        TotalReviews    = totalReviews
                    });
                }
            }
        }
Exemple #24
0
        public async Task Execute()
        {
            using (var dbContext = new GitRepositoryDbContext(false))
            {
                var normalizedDevelopers = new List <AliasedDeveloperName>();

                var authorsPlace = new Dictionary <string, string>();

                var authors = dbContext.Commits
                              .Select(m => new { m.AuthorEmail, m.AuthorName })
                              .Distinct()
                              .ToArray();

                _logger.LogInformation("{datetime}: there are {count} authors submitted all the commits.", DateTime.Now, authors.Count());

                foreach (var author in authors)
                {
                    var normalizedEmail = author.AuthorEmail
                                          .Replace(" ", string.Empty)
                                          .Replace(".", string.Empty)
                                          .Replace("[", string.Empty)
                                          .Replace("]", string.Empty)
                                          .Replace("_", string.Empty)
                                          .Replace("-", string.Empty)
                                          .Replace("(", string.Empty)
                                          .Replace(")", string.Empty)
                                          .ToLower()
                                          .Trim()
                                          .RemoveDiacritics();

                    var normalizedName = author.AuthorName
                                         .Replace(" ", string.Empty)
                                         .Replace(".", string.Empty)
                                         .Replace("[", string.Empty)
                                         .Replace("]", string.Empty)
                                         .Replace("_", string.Empty)
                                         .Replace("-", string.Empty)
                                         .Replace("(", string.Empty)
                                         .Replace(")", string.Empty)
                                         .Trim()
                                         .ToLower()
                                         .RemoveDiacritics();

                    if (authorsPlace.ContainsKey(normalizedName))
                    {
                        var uniqueId = authorsPlace[normalizedName];

                        if (authorsPlace.ContainsKey(normalizedEmail) &&
                            authorsPlace[normalizedEmail] != uniqueId)
                        {
                            /* it supports following edge case:
                             * Occurence 1 ehsan,[email protected]
                             * Occurence 2 ali,[email protected]
                             * Occurence 3 ehsan,[email protected]
                             */

                            var oldUniqueId = authorsPlace[normalizedEmail];

                            foreach (var dev in normalizedDevelopers.Where(q => q.NormalizedName == oldUniqueId))
                            {
                                dev.NormalizedName = uniqueId;
                            }
                        }

                        authorsPlace[normalizedEmail] = uniqueId;
                    }
                    else if (authorsPlace.ContainsKey(normalizedEmail))
                    {
                        authorsPlace[normalizedName] = authorsPlace[normalizedEmail];
                    }
                    else
                    {
                        authorsPlace[normalizedName]  = normalizedName;
                        authorsPlace[normalizedEmail] = normalizedName;
                    }

                    normalizedDevelopers.Add(new AliasedDeveloperName()
                    {
                        Email          = author.AuthorEmail,
                        Name           = author.AuthorName,
                        NormalizedName = authorsPlace[normalizedName]
                    });
                }

                var damerauDistanceAlgorithm = new Damerau();
                normalizedDevelopers = normalizedDevelopers.OrderBy(q => q.NormalizedName)
                                       .ToList();

                for (var i = 0; i < normalizedDevelopers.Count - 1; i++)
                {
                    var firstDev  = normalizedDevelopers[i];
                    var secondDev = normalizedDevelopers[i + 1];
                    var distance  = damerauDistanceAlgorithm.Distance(firstDev.NormalizedName, secondDev.NormalizedName);

                    if (distance == 1)
                    {
                        secondDev.NormalizedName = firstDev.NormalizedName;
                    }
                }

                _logger.LogInformation("{datetime}: after normalization, there are {count} unique authors have been found.",
                                       DateTime.Now, normalizedDevelopers.Select(q => q.NormalizedName).Distinct().Count());

                dbContext.AddRange(normalizedDevelopers);
                await dbContext.SaveChangesAsync().ConfigureAwait(false);

                _logger.LogInformation("{datetime}: aliased results have been saves successfully.", DateTime.Now);
            }
        }
        private static async Task <Period[]> GetPeriods(ExtractBlameForEachPeriodOption options, GitRepositoryDbContext dbContext, string[] extractedCommits)
        {
            var periods = await dbContext.Periods.OrderBy(q => q.ToDateTime).ToArrayAsync().ConfigureAwait(false);

            periods = periods.Where(m => !extractedCommits.Any(c => c == m.LastCommitSha)).ToArray();

            if (options.PeriodIds != null && options.PeriodIds.Count() > 0)
            {
                periods = periods.Where(q => options.PeriodIds.Any(p => p == q.Id)).ToArray();
            }

            return(periods);
        }