Skip to content

Commit

Permalink
Integrated code lifecycle: Add auxiliary repository view (#9321)
Browse files Browse the repository at this point in the history
  • Loading branch information
SimonEntholzer authored Oct 19, 2024
1 parent b52e25e commit 34f4410
Show file tree
Hide file tree
Showing 24 changed files with 1,242 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import de.tum.cit.aet.artemis.exercise.domain.participation.Participation;
import de.tum.cit.aet.artemis.exercise.repository.ParticipationRepository;
import de.tum.cit.aet.artemis.exercise.repository.TeamRepository;
import de.tum.cit.aet.artemis.programming.domain.AuxiliaryRepository;
import de.tum.cit.aet.artemis.programming.domain.ProgrammingExercise;
import de.tum.cit.aet.artemis.programming.domain.ProgrammingExerciseParticipation;
import de.tum.cit.aet.artemis.programming.domain.ProgrammingExerciseStudentParticipation;
Expand Down Expand Up @@ -517,6 +518,22 @@ public List<CommitInfoDTO> getCommitInfos(ProgrammingExerciseParticipation parti
}
}

/**
* Get the commits information for the given auxiliary repository.
*
* @param auxiliaryRepository the auxiliary repository for which to get the commits.
* @return a list of CommitInfo DTOs containing author, timestamp, commit-hash and commit message.
*/
public List<CommitInfoDTO> getAuxiliaryRepositoryCommitInfos(AuxiliaryRepository auxiliaryRepository) {
try {
return gitService.getCommitInfos(auxiliaryRepository.getVcsRepositoryUri());
}
catch (GitAPIException e) {
log.error("Could not get commit infos for auxiliaryRepository {} with repository uri {}", auxiliaryRepository.getId(), auxiliaryRepository.getVcsRepositoryUri());
return List.of();
}
}

/**
* Get the commits information for the test repository of the given participation's exercise.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1048,4 +1048,15 @@ public ProgrammingExercise loadProgrammingExercise(long exerciseId, boolean with
programmingExerciseTaskService.replaceTestIdsWithNames(programmingExercise);
return programmingExercise;
}

/**
* Load a programming exercise, only with eager auxiliary repositories
*
* @param exerciseId the ID of the programming exercise to load
* @return the loaded programming exercise entity
*/
public ProgrammingExercise loadProgrammingExerciseWithAuxiliaryRepositories(long exerciseId) {
final Set<ProgrammingExerciseRepository.ProgrammingExerciseFetchOptions> fetchOptions = Set.of(AuxiliaryRepositories);
return programmingExerciseRepository.findByIdWithDynamicFetchElseThrow(exerciseId, fetchOptions);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
import de.tum.cit.aet.artemis.programming.domain.VcsRepositoryUri;
import de.tum.cit.aet.artemis.programming.dto.CommitInfoDTO;
import de.tum.cit.aet.artemis.programming.dto.VcsAccessLogDTO;
import de.tum.cit.aet.artemis.programming.repository.AuxiliaryRepositoryRepository;
import de.tum.cit.aet.artemis.programming.repository.ProgrammingExerciseRepository;
import de.tum.cit.aet.artemis.programming.repository.ProgrammingExerciseStudentParticipationRepository;
import de.tum.cit.aet.artemis.programming.repository.VcsAccessLogRepository;
Expand Down Expand Up @@ -89,11 +90,13 @@ public class ProgrammingExerciseParticipationResource {

private final Optional<VcsAccessLogRepository> vcsAccessLogRepository;

private final AuxiliaryRepositoryRepository auxiliaryRepositoryRepository;

public ProgrammingExerciseParticipationResource(ProgrammingExerciseParticipationService programmingExerciseParticipationService, ResultRepository resultRepository,
ParticipationRepository participationRepository, ProgrammingExerciseStudentParticipationRepository programmingExerciseStudentParticipationRepository,
ProgrammingSubmissionService submissionService, ProgrammingExerciseRepository programmingExerciseRepository, AuthorizationCheckService authCheckService,
ResultService resultService, ParticipationAuthorizationCheckService participationAuthCheckService, RepositoryService repositoryService,
StudentExamRepository studentExamRepository, Optional<VcsAccessLogRepository> vcsAccessLogRepository) {
StudentExamRepository studentExamRepository, Optional<VcsAccessLogRepository> vcsAccessLogRepository, AuxiliaryRepositoryRepository auxiliaryRepositoryRepository) {
this.programmingExerciseParticipationService = programmingExerciseParticipationService;
this.participationRepository = participationRepository;
this.programmingExerciseStudentParticipationRepository = programmingExerciseStudentParticipationRepository;
Expand All @@ -105,6 +108,7 @@ public ProgrammingExerciseParticipationResource(ProgrammingExerciseParticipation
this.participationAuthCheckService = participationAuthCheckService;
this.repositoryService = repositoryService;
this.studentExamRepository = studentExamRepository;
this.auxiliaryRepositoryRepository = auxiliaryRepositoryRepository;
this.vcsAccessLogRepository = vcsAccessLogRepository;
}

Expand Down Expand Up @@ -339,22 +343,25 @@ public ResponseEntity<List<VcsAccessLogDTO>> getVcsAccessLogForParticipationRepo

/**
* GET /programming-exercise/{exerciseID}/commit-history/{repositoryType} : Get the commit history of a programming exercise repository. The repository type can be TEMPLATE or
* SOLUTION or TESTS.
* SOLUTION, TESTS or AUXILIARY.
* Here we check is at least a teaching assistant for the exercise.
*
* @param exerciseID the id of the exercise for which to retrieve the commit history
* @param repositoryType the type of the repository for which to retrieve the commit history
* @param repositoryId the id of the repository
* @return the ResponseEntity with status 200 (OK) and with body a list of commitInfo DTOs with the commits information of the repository
*/
@GetMapping("programming-exercise/{exerciseID}/commit-history/{repositoryType}")
@EnforceAtLeastTutor
public ResponseEntity<List<CommitInfoDTO>> getCommitHistoryForTemplateSolutionOrTestRepo(@PathVariable long exerciseID, @PathVariable RepositoryType repositoryType) {
public ResponseEntity<List<CommitInfoDTO>> getCommitHistoryForTemplateSolutionTestOrAuxRepo(@PathVariable long exerciseID, @PathVariable RepositoryType repositoryType,
@RequestParam Optional<Long> repositoryId) {
boolean isTemplateRepository = repositoryType.equals(RepositoryType.TEMPLATE);
boolean isSolutionRepository = repositoryType.equals(RepositoryType.SOLUTION);
boolean isTestRepository = repositoryType.equals(RepositoryType.TESTS);
boolean isAuxiliaryRepository = repositoryType.equals(RepositoryType.AUXILIARY);
ProgrammingExerciseParticipation participation;

if (!isTemplateRepository && !isSolutionRepository && !isTestRepository) {
if (!isTemplateRepository && !isSolutionRepository && !isTestRepository && !isAuxiliaryRepository) {
throw new BadRequestAlertException("Invalid repository type", ENTITY_NAME, "invalidRepositoryType");
}
else if (isTemplateRepository) {
Expand All @@ -364,6 +371,15 @@ else if (isTemplateRepository) {
participation = programmingExerciseParticipationService.findSolutionParticipationByProgrammingExerciseId(exerciseID);
}
participationAuthCheckService.checkCanAccessParticipationElseThrow(participation);

if (isAuxiliaryRepository) {
var auxiliaryRepo = auxiliaryRepositoryRepository.findByIdElseThrow(repositoryId.orElseThrow());
if (!auxiliaryRepo.getExercise().getId().equals(exerciseID)) {
throw new BadRequestAlertException("Invalid repository id", ENTITY_NAME, "invalidRepositoryId");
}
return ResponseEntity.ok(programmingExerciseParticipationService.getAuxiliaryRepositoryCommitInfos(auxiliaryRepo));
}

if (isTestRepository) {
return ResponseEntity.ok(programmingExerciseParticipationService.getCommitInfosTestRepo(participation));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -534,6 +534,21 @@ public ResponseEntity<ProgrammingExercise> getProgrammingExerciseWithTemplateAnd
return ResponseEntity.ok(programmingExercise);
}

/**
* GET /programming-exercises/:exerciseId/with-auxiliary-repository
*
* @param exerciseId the id of the programmingExercise to retrieve
* @return the ResponseEntity with status 200 (OK) and the programming exercise with template and solution participation, or with status 404 (Not Found)
*/
@GetMapping("programming-exercises/{exerciseId}/with-auxiliary-repository")
@EnforceAtLeastTutorInExercise
public ResponseEntity<ProgrammingExercise> getProgrammingExerciseWithAuxiliaryRepository(@PathVariable long exerciseId) {

log.debug("REST request to get programming exercise with auxiliary repositories: {}", exerciseId);
final var programmingExercise = programmingExerciseService.loadProgrammingExerciseWithAuxiliaryRepositories(exerciseId);
return ResponseEntity.ok(programmingExercise);
}

/**
* DELETE /programming-exercises/:id : delete the "id" programmingExercise.
*
Expand Down
Loading

0 comments on commit 34f4410

Please sign in to comment.