private LossSimulation CreateLossSimulation(LossSimulationOption lossSimulationOption) { var lossSimulation = new LossSimulation() { StartDateTime = DateTime.Now, MegaPullRequestSize = lossSimulationOption.MegaPullRequestSize, KnowledgeShareStrategyType = lossSimulationOption.KnowledgeShareStrategyType, LeaversType = lossSimulationOption.LeaversType, FilesAtRiksOwnershipThreshold = lossSimulationOption.FilesAtRiksOwnershipThreshold, FilesAtRiksOwnersThreshold = lossSimulationOption.FilesAtRiksOwnersThreshold, LeaversOfPeriodExtendedAbsence = lossSimulationOption.LeaversOfPeriodExtendedAbsence, KnowledgeSaveReviewerReplacementType = lossSimulationOption.KnowledgeSaveReviewerReplacementType, FirstPeriod = lossSimulationOption.KnowledgeSaveReviewerFirstPeriod, SelectedReviewersType = lossSimulationOption.SelectedReviewersType, PullRequestReviewerSelectionStrategy = lossSimulationOption.PullRequestReviewerSelectionStrategy, AddOnlyToUnsafePullrequests = lossSimulationOption.AddOnlyToUnsafePullrequests, MinimumActualReviewersLength = lossSimulationOption.MinimumActualReviewersLength, NumberOfPeriodsForCalculatingProbabilityOfStay = lossSimulationOption.NumberOfPeriodsForCalculatingProbabilityOfStay, LgtmTerms = lossSimulationOption.LgtmTerms.Aggregate((a, b) => a + "," + b), MegaDevelopers = lossSimulationOption.MegaDevelopers, RecommenderOption = lossSimulationOption.RecommenderOption, ChangePast = lossSimulationOption.ChangePast.Value }; _dbContext.Add(lossSimulation); _dbContext.SaveChanges(); return(lossSimulation); }
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); } }
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 }); } } }