private async Task <Dictionary <string, List <long> > > GetFileOwners(SophiaDbContext dbContext, long subscriptionId, IReadOnlyList <Octokit.PullRequestFile> pullRequestFiles) { var fileOwners = new Dictionary <string, List <long> >(); foreach (var pullRequestFile in pullRequestFiles) { fileOwners[pullRequestFile.FileName] = new List <long>(); var file = await GetFile(dbContext, subscriptionId, pullRequestFile); if (file == null) { continue; } var contributorIds = file.Contributions.Select(q => q.ContributorId); foreach (var contributorId in contributorIds) { var isActive = await IsContributorActive(dbContext, subscriptionId, contributorId); if (!isActive) { continue; } fileOwners[pullRequestFile.FileName].Add(contributorId); } } return(fileOwners); }
public PullRequestEventHandler(SophiaDbContext SophiaDbContext, GitHubRepositoryPullRequestService gitHubRepositoryPullRequestService, ILogger <PullRequestEventHandler> logger) { _gitHubRepositoryPullRequestService = gitHubRepositoryPullRequestService; _SophiaDbContext = SophiaDbContext; _logger = logger; }
public ApplyPullRequestsJob(SophiaDbContext SophiaDbContext , IServiceProvider serviceProvider , ILogger <ApplyPullRequestsJob> logger) { _logger = logger; _serviceProvider = serviceProvider; _SophiaDbContext = SophiaDbContext; }
public CommitAnalyzer(Subscription subscription, Octokit.GitHubClient installationClient, Dictionary <string, Contributor> contributors = null, Dictionary <string, string> fileCanonicalMapper = null, SophiaDbContext dbContext = null) { _fileCanonicalMapper = fileCanonicalMapper ?? new Dictionary <string, string>(); _contributors = contributors ?? new Dictionary <string, Contributor>(); _dbContext = dbContext; _subscription = subscription; _installationClient = installationClient; }
private async Task <int> GetTotalActiveMonth(Candidate candidate, SophiaDbContext dbContext) { var lastYear = DateTimeOffset.Now.AddYears(-1); return(await _dbContext.Contributions .Where(q => q.ContributorId == candidate.Contributor.Id && q.DateTime >= lastYear) .Select(q => q.DateTime.Value.Month) .Distinct() .CountAsync()); }
public ScanRepositoriesJob(SophiaDbContext SophiaDbContext, IOptions <GitHubOption> gitHubOptions, IServiceProvider serviceProvider, ILogger <ScanRepositoriesJob> logger) { _serviceProvider = serviceProvider; _SophiaDbContext = SophiaDbContext; _gitHubOptions = gitHubOptions; _logger = logger; }
private async Task <File> GetFile(SophiaDbContext dbContext, long subscriptionId, Octokit.PullRequestFile pullRequestFile) { var fileHistory = await dbContext.FileHistories.Where(q => q.Path == pullRequestFile.FileName && q.SubscriptionId == subscriptionId) .Include(q => q.File) .ThenInclude(q => q.Contributions) .ThenInclude(q => q.Contributor) .OrderByDescending(q => q.ContributionId) .FirstOrDefaultAsync(); return(fileHistory?.File); }
private async Task AnalyzePullRequests(long subscriptionId, SophiaDbContext dbContext, GitHubOption gitHubOption, GitHubRepositoryPullRequestService gitHubRepositoryPullRequestService) { try { var analyzer = new PullRequestAnalyzer(dbContext, gitHubOption, gitHubRepositoryPullRequestService); await analyzer.Analyze(subscriptionId); await dbContext.SaveChangesAsync(); } catch (Exception e) { _logger.LogError("ApplyPullRequestsJob: Exception {exception} in {subscriptionId}", e.ToString(), subscriptionId); throw; } }
private async Task SaveCandidates(SophiaDbContext dbContext, IEnumerable <Recommending.Candidate> candidates, Octokit.PullRequest pullRequest, Data.Models.Subscription subscription) { var dateTime = DateTimeOffset.UtcNow; dbContext.AddRange(candidates.Select(q => new Data.Models.Candidate() { GitHubLogin = q.Contributor.GitHubLogin, PullRequestNumber = pullRequest.Number, Rank = q.Rank, RecommenderType = RecommenderType.Chrev, SubscriptionId = subscription.Id, SuggestionDateTime = dateTime })); await dbContext.SaveChangesAsync(); }
private async Task GetCandidates(EventContext eventContext, SophiaDbContext dbContext, int issueNumber, long repositoryId, Data.Models.Subscription subscription, int topCandidatesLength) { var installationClient = eventContext.InstallationContext.Client; var recommender = new CodeReviewerRecommender(RecommenderType.Chrev, dbContext); var pullRequest = await installationClient.PullRequest.Get(repositoryId, issueNumber); var pullRequestFiles = await installationClient.PullRequest.Files(repositoryId, issueNumber); var candidates = await recommender.Recommend(subscription.Id, pullRequest, pullRequestFiles, topCandidatesLength); await SaveCandidates(dbContext, candidates, pullRequest, subscription); var message = GenerateMessage(candidates, pullRequestFiles); await installationClient.Issue.Comment.Create(repositoryId, issueNumber, message); }
private async Task GetCandidates(EventContext eventContext, SophiaDbContext dbContext, int issueNumber, long repositoryId, Data.Models.Subscription subscription, int topCandidatesLength) { var installationClient = eventContext.InstallationContext.Client; var pullRequest = await installationClient.PullRequest.Get(repositoryId, issueNumber); var pullRequestFiles = await installationClient.PullRequest.Files(repositoryId, issueNumber); var fileOwners = await GetFileOwners(dbContext, subscription.Id, pullRequestFiles); var expertCandidates = await GetExpertCandidates(dbContext, subscription.Id, pullRequest, pullRequestFiles, topCandidatesLength); var learnerCandidates = await GetLearnerCandidates(dbContext, subscription.Id, pullRequest, pullRequestFiles, topCandidatesLength); await SaveCandidates(dbContext, expertCandidates, learnerCandidates, pullRequest, subscription); var message = GenerateMessage(expertCandidates, learnerCandidates, pullRequestFiles, fileOwners); await installationClient.Issue.Comment.Create(repositoryId, issueNumber, message); }
public Task Execute(string action, string[] parts, string authorAssociation, EventContext eventContext, SophiaDbContext dbContext) { return(Task.CompletedTask); }
public PullRequestGatheringStep(SophiaDbContext dbContext, GitHubRepositoryPullRequestService gitHubRepositoryPullRequestService, GitHubOption gitHubOption) : base(dbContext) { _gitHubRepositoryPullRequestService = gitHubRepositoryPullRequestService; _gitHubOption = gitHubOption; }
public RepositoryCloningStep(SophiaDbContext dbContext, GitHubOption gitHubOption) : base(dbContext) { _gitHubOption = gitHubOption; }
private Task <bool> IsContributorActive(SophiaDbContext dbContext, long subscriptionId, long contributorId) { var lastCheck = DateTimeOffset.Now.Subtract(TimeSpan.FromDays(90)); return(dbContext.Contributions.AnyAsync(q => q.SubscriptionId == subscriptionId && q.ContributorId == contributorId && q.DateTime > lastCheck)); }
public async Task Execute(string action, string[] parts, string authorAssociation, EventContext eventContext, SophiaDbContext dbContext) { var issueNumber = (int)eventContext.WebHookEvent.GetPayload().issue.number; var repositoryId = (long)eventContext.WebHookEvent.GetPayload().repository.id; var subscription = await dbContext.Subscriptions.SingleOrDefaultAsync(q => q.RepositoryId == repositoryId); var top = 10; if (parts.Length == 5) { top = int.Parse(parts[4]); } if (subscription == null) { var commentResponse = await eventContext.InstallationContext.Client.Issue.Comment .Create(repositoryId, issueNumber, "You have not registered the repository. First, you need to ask Sofia to scan it before asking for suggestions."); return; } if (subscription.ScanningStatus != SubscriptionStatus.Completed) { var commentResponse = await eventContext.InstallationContext.Client.Issue.Comment .Create(repositoryId, issueNumber, "Sofia has not yet finished scanning the repository. You can ask for suggestion once it is done."); return; } try { await GetCandidates(eventContext, dbContext, issueNumber, repositoryId, subscription, top); } catch (NotFoundException e) { await eventContext.InstallationContext.Client.Issue.Comment .Create(repositoryId, issueNumber, "It's not a pull request. Sofia suggests reviewers for pull requests."); } }
public CommitGatheringStep(SophiaDbContext dbContext, GitHubOption gitHubOption) : base(dbContext) { _gitHubOption = gitHubOption; }
public PersistBasedSpreadingRecommender(SophiaDbContext dbContext) { _dbContext = dbContext; }
private async Task SaveSubscription(int issueNumber, long repositoryId, string owner, string repository, string repositoryUrl, string branch, long?installationId, SophiaDbContext dbContext) { var subscription = new Subscription() { Branch = branch, InstallationId = installationId.Value, RepositoryId = repositoryId, Owner = owner, Repo = repository, IssueNumber = issueNumber, SubscriptionDateTime = DateTime.Now, ScanningStatus = SubscriptionStatus.NotScanned, GitHubRepositoryUrl = repositoryUrl }; dbContext.Add(subscription); await dbContext.SaveChangesAsync(); }
private async Task <bool> AlreadyScanned(SophiaDbContext dbContext, long repositoryId) { return(await dbContext.Subscriptions.AnyAsync(q => q.RepositoryId == repositoryId)); }
public async Task Execute(string action, string[] parts, string authorAssociation, EventContext eventContext, SophiaDbContext dbContext) { var branch = parts[3]; var issueNumber = (int)eventContext.WebHookEvent.GetPayload().issue.number; var repositoryId = (long)eventContext.WebHookEvent.GetPayload().repository.id; var owenerName = (string)eventContext.WebHookEvent.GetPayload().repository.owner.login; var repositoryName = (string)eventContext.WebHookEvent.GetPayload().repository.name; var repositoryUrl = (string)eventContext.WebHookEvent.GetPayload().repository.html_url; if (await AlreadyScanned(dbContext, repositoryId)) { var commentResponse = await eventContext.InstallationContext.Client.Issue.Comment .Create(repositoryId, issueNumber, "Sofia has already scanned this branch and is monitoring it."); } else { var commentResponse = await eventContext.InstallationContext.Client.Issue.Comment.Create(repositoryId, issueNumber, "Sofia just started to scan your repository. After Completion you can ask for suggestions for code reviewers!"); await SaveSubscription(issueNumber, repositoryId, owenerName, repositoryName, repositoryUrl, branch, eventContext.WebHookEvent.GetInstallationId(), dbContext); } }
public CodeReviewerRecommender(RecommenderType recommenderType, SophiaDbContext dbContext) { _dbContext = dbContext; _recommenderType = recommenderType; }
public IssuesEventHandler(SophiaDbContext SophiaDbContext, ILogger <IssueCommentEventHandler> logger) { _logger = logger; _SophiaDbContext = SophiaDbContext; }
public PushEventHandler(SophiaDbContext SophiaDbContext, ILogger <PushEventHandler> logger) { _logger = logger; _SophiaDbContext = SophiaDbContext; }
public Step(SophiaDbContext dbContext) { DbContext = dbContext; }
public PullRequestAnalyzer(SophiaDbContext dbContext, GitHubOption gitHubOption, GitHubRepositoryPullRequestService gitHubRepositoryPullRequestService) { _dbContext = dbContext; _gitHubOption = gitHubOption; _gitHubRepositoryPullRequestService = gitHubRepositoryPullRequestService; }
private async Task <(int TotalReviews, int TotalCommts)> GetCandidateEffort(Candidate candidate, SophiaDbContext dbContext) { var lastYear = DateTimeOffset.Now.AddYears(-1); var totalReviews = await _dbContext.Contributions.Where(q => q.ContributorId == candidate.Contributor.Id && q.ContributionType == ContributionType.Review && q.DateTime >= lastYear) .Select(q => q.ActivityId) .Distinct() .CountAsync(); var totalCommits = await _dbContext.Contributions.Where(q => q.ContributorId == candidate.Contributor.Id && q.ContributionType == ContributionType.Commit && q.DateTime >= lastYear) .Select(q => q.ActivityId) .Distinct() .CountAsync(); return(totalReviews, totalCommits); }
private async Task <IEnumerable <Recommending.Candidate> > GetExpertCandidates(SophiaDbContext dbContext, long subscriptionId, Octokit.PullRequest pullRequest, IReadOnlyList <Octokit.PullRequestFile> pullRequestFiles, int topCandidatesLength) { var recommender = new CodeReviewerRecommender(RecommenderType.Chrev, dbContext); var candidates = await recommender.Recommend(subscriptionId, pullRequest, pullRequestFiles, topCandidatesLength); return(candidates); }
public ChrevRecommender(SophiaDbContext dbContext) { _dbContext = dbContext; }
public PullRequestAnalyzingStep(SophiaDbContext dbContext) : base(dbContext) { }