Skip to content

Commit

Permalink
Merge branch 'develop' of https://github.com/ls1intum/Hephaestus into…
Browse files Browse the repository at this point in the history
… 82-pull-request-component-for-collaboration-dashboard
  • Loading branch information
GODrums committed Sep 24, 2024
2 parents 51c1dfc + 6d04150 commit 7cb785f
Show file tree
Hide file tree
Showing 29 changed files with 514 additions and 183 deletions.
42 changes: 33 additions & 9 deletions server/application-server/openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,6 @@ components:
$ref: "#/components/schemas/PullRequest"
PullRequest:
required:
- prNumber
- state
- title
- url
Expand All @@ -233,13 +232,13 @@ components:
updatedAt:
type: string
format: date-time
number:
type: integer
format: int32
title:
type: string
url:
type: string
prNumber:
type: integer
format: int32
state:
type: string
description: |-
Expand Down Expand Up @@ -466,11 +465,36 @@ components:
type: integer
format: int32
changesRequested:
type: integer
format: int32
type: array
items:
$ref: "#/components/schemas/PullRequestReviewDTO"
approvals:
type: integer
format: int32
type: array
items:
$ref: "#/components/schemas/PullRequestReviewDTO"
comments:
type: array
items:
$ref: "#/components/schemas/PullRequestReviewDTO"
PullRequestReviewDTO:
type: object
properties:
id:
type: integer
format: int32
format: int64
createdAt:
type: string
format: date-time
updatedAt:
type: string
format: date-time
submittedAt:
type: string
format: date-time
state:
type: string
enum:
- COMMENTED
- APPROVED
- CHANGES_REQUESTED
- DISMISSED
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,21 @@
import java.util.HashSet;
import java.util.Set;

import jakarta.persistence.*;
import org.springframework.lang.NonNull;

import de.tum.in.www1.hephaestus.codereview.base.BaseGitServiceEntity;
import de.tum.in.www1.hephaestus.codereview.comment.IssueComment;
import de.tum.in.www1.hephaestus.codereview.pullrequest.review.PullRequestReview;
import de.tum.in.www1.hephaestus.codereview.repository.Repository;
import de.tum.in.www1.hephaestus.codereview.user.User;
import jakarta.persistence.CascadeType;
import jakarta.persistence.ElementCollection;
import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.OneToMany;
import jakarta.persistence.Table;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
Expand All @@ -24,15 +31,15 @@
@NoArgsConstructor
@ToString(callSuper = true)
public class PullRequest extends BaseGitServiceEntity {

private int number;

@NonNull
private String title;

@NonNull
private String url;

@NonNull
private int prNumber;

/**
* State of the PullRequest.
* Does not include the state of the merge.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;

import org.kohsuke.github.GHLabel;
import org.kohsuke.github.GHLabel;
import org.kohsuke.github.GHPullRequest;
import org.slf4j.Logger;
Expand All @@ -24,10 +28,10 @@ public PullRequest convert(@NonNull GHPullRequest source) {
IssueState state = convertState(source.getState());
PullRequest pullRequest = new PullRequest();
convertBaseFields(source, pullRequest);
pullRequest.setNumber(source.getNumber());
pullRequest.setTitle(source.getTitle());
pullRequest.setUrl(source.getHtmlUrl().toString());
pullRequest.setState(state);
pullRequest.setPrNumber(source.getNumber());
pullRequest.setPullRequestLabels(convertLabels(source.getLabels()));
try {
pullRequest.setAdditions(source.getAdditions());
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package de.tum.in.www1.hephaestus.codereview.pullrequest.review;

import java.time.OffsetDateTime;

import com.fasterxml.jackson.annotation.JsonInclude;

@JsonInclude(JsonInclude.Include.NON_EMPTY)
public record PullRequestReviewDTO(Long id, OffsetDateTime createdAt, OffsetDateTime updatedAt,
OffsetDateTime submittedAt, PullRequestReviewState state) {
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package de.tum.in.www1.hephaestus.leaderboard;

import com.fasterxml.jackson.annotation.JsonInclude;

import de.tum.in.www1.hephaestus.codereview.pullrequest.review.PullRequestReviewDTO;
import de.tum.in.www1.hephaestus.codereview.user.UserType;
import lombok.AllArgsConstructor;
import lombok.Getter;
Expand All @@ -19,7 +21,7 @@ public class LeaderboardEntry {
private UserType type;
private int score;
private int rank;
private int changesRequested;
private int approvals;
private int comments;
private PullRequestReviewDTO[] changesRequested;
private PullRequestReviewDTO[] approvals;
private PullRequestReviewDTO[] comments;
}
Original file line number Diff line number Diff line change
@@ -1,17 +1,24 @@
package de.tum.in.www1.hephaestus.leaderboard;

import java.time.OffsetDateTime;
import java.time.ZoneOffset;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import de.tum.in.www1.hephaestus.codereview.pullrequest.PullRequest;
import de.tum.in.www1.hephaestus.codereview.pullrequest.review.PullRequestReviewDTO;
import de.tum.in.www1.hephaestus.codereview.user.User;
import de.tum.in.www1.hephaestus.codereview.user.UserService;
import de.tum.in.www1.hephaestus.codereview.user.UserType;
Expand All @@ -22,6 +29,9 @@ public class LeaderboardService {

private final UserService userService;

@Value("${monitoring.timeframe}")
private int timeframe;

public LeaderboardService(UserService userService) {
this.userService = userService;
}
Expand All @@ -30,34 +40,52 @@ public List<LeaderboardEntry> createLeaderboard() {
logger.info("Creating leaderboard dataset");

List<User> users = userService.getAllUsers();
logger.info("Found " + users.size() + " users");
logger.info("Leaderboard has " + users.size() + " users");

OffsetDateTime cutOffTime = new Date(System.currentTimeMillis() - 1000 * 60 * 60 * 24 * timeframe)
.toInstant().atOffset(ZoneOffset.UTC);

List<LeaderboardEntry> leaderboard = users.stream().map(user -> {
if (user.getType() != UserType.USER) {
return null;
}
int comments = user.getIssueComments().size();
AtomicInteger changesRequested = new AtomicInteger(0);
AtomicInteger changesApproved = new AtomicInteger(0);
AtomicInteger score = new AtomicInteger(0);
user.getReviews().stream().forEach(review -> {
switch (review.getState()) {
case CHANGES_REQUESTED:
changesRequested.incrementAndGet();
break;
case APPROVED:
changesApproved.incrementAndGet();
break;
default:
break;
}
score.addAndGet(calculateScore(review.getPullRequest()));
});
Set<PullRequestReviewDTO> changesRequestedSet = new HashSet<>();
Set<PullRequestReviewDTO> approvedSet = new HashSet<>();
Set<PullRequestReviewDTO> commentSet = new HashSet<>();

user.getReviews().stream()
.filter(review -> (review.getCreatedAt() != null && review.getCreatedAt().isAfter(cutOffTime))
|| (review.getUpdatedAt() != null && review.getUpdatedAt().isAfter(cutOffTime)))
.forEach(review -> {
if (review.getPullRequest().getAuthor().getLogin().equals(user.getLogin())) {
return;
}
PullRequestReviewDTO reviewDTO = new PullRequestReviewDTO(review.getId(), review.getCreatedAt(),
review.getUpdatedAt(), review.getSubmittedAt(), review.getState());

switch (review.getState()) {
case CHANGES_REQUESTED:
changesRequestedSet.add(reviewDTO);
break;
case APPROVED:
approvedSet.add(reviewDTO);
break;
case COMMENTED:
commentSet.add(reviewDTO);
break;
default:
// ignore other states and don't add to score
return;
}
score.addAndGet(calculateScore(review.getPullRequest()));
});
return new LeaderboardEntry(user.getLogin(), user.getAvatarUrl(), user.getName(), user.getType(),
score.get(),
0, // preliminary rank
changesRequested.get(),
changesApproved.get(), comments);
changesRequestedSet.toArray(new PullRequestReviewDTO[changesRequestedSet.size()]),
approvedSet.toArray(new PullRequestReviewDTO[approvedSet.size()]),
commentSet.toArray(new PullRequestReviewDTO[commentSet.size()]));
}).filter(Objects::nonNull).collect(Collectors.toCollection(ArrayList::new));

// update ranks by score
Expand All @@ -80,8 +108,8 @@ public List<LeaderboardEntry> createLeaderboard() {
* @return score
*/
private int calculateScore(PullRequest pullRequest) {
Double complexityScore = (pullRequest.getChangedFiles() * 3) + (pullRequest.getCommits() * 0.5)
+ pullRequest.getAdditions() + pullRequest.getDeletions();
Double complexityScore = ((pullRequest.getChangedFiles() * 3) + (pullRequest.getCommits() * 0.5)
+ pullRequest.getAdditions() + pullRequest.getDeletions()) / 10;
if (complexityScore < 10) {
return 1; // Simple
} else if (complexityScore < 50) {
Expand Down
Loading

0 comments on commit 7cb785f

Please sign in to comment.