use of de.tum.in.www1.artemis.domain.Repository in project ArTEMiS by ls1intum.
the class BitbucketService method forkRepository.
/**
* Uses the configured Bitbucket account to fork the given repository inside the project.
*
* @param baseProjectKey The project key of the base project.
* @param baseRepositorySlug The repository slug of the base repository.
* @param username The user for whom the repository is being forked.
* @return The slug of the forked repository (i.e. its identifier).
*/
private Map<String, String> forkRepository(String baseProjectKey, String baseRepositorySlug, String username) throws BitbucketException {
String forkName = String.format("%s-%s", baseRepositorySlug, username);
Map<String, Object> body = new HashMap<>();
body.put("name", forkName);
body.put("project", new HashMap<>());
((Map) body.get("project")).put("key", baseProjectKey);
HttpHeaders headers = HeaderUtil.createAuthorization(BITBUCKET_USER, BITBUCKET_PASSWORD);
HttpEntity<?> entity = new HttpEntity<>(body, headers);
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<Map> response;
try {
response = restTemplate.exchange(BITBUCKET_SERVER_URL + "/rest/api/1.0/projects/" + baseProjectKey + "/repos/" + baseRepositorySlug, HttpMethod.POST, entity, Map.class);
} catch (HttpClientErrorException e) {
if (e.getStatusCode().equals(HttpStatus.CONFLICT)) {
log.info("Repository already exists. Going to recover repository information...");
Map<String, String> result = new HashMap<>();
result.put("slug", forkName);
result.put("cloneUrl", buildCloneUrl(baseProjectKey, forkName, username).toString());
return result;
} else {
throw e;
}
} catch (Exception e) {
log.error("Could not fork base repository for user " + username, e);
throw new BitbucketException("Error while forking repository");
}
if (response != null && response.getStatusCode().equals(HttpStatus.CREATED)) {
String slug = (String) response.getBody().get("slug");
String cloneUrl = buildCloneUrl(baseProjectKey, forkName, username).toString();
Map<String, String> result = new HashMap<>();
result.put("slug", slug);
result.put("cloneUrl", cloneUrl);
return result;
}
return null;
}
use of de.tum.in.www1.artemis.domain.Repository in project ArTEMiS by ls1intum.
the class ExerciseService method cleanup.
/**
* Delete build plans (except BASE) and optionally repositores of all exercise participations.
*
* @param id id of the exercise for which build plans in respective participations are deleted
*/
@Transactional
public java.io.File cleanup(Long id, boolean deleteRepositories) throws java.io.IOException {
Exercise exercise = findOneLoadParticipations(id);
log.info("Request to cleanup all participations for Exercise : {}", exercise.getTitle());
List<Repository> studentRepositories = new ArrayList<>();
Path finalZipFilePath = null;
if (Optional.ofNullable(exercise).isPresent() && exercise instanceof ProgrammingExercise) {
exercise.getParticipations().forEach(participation -> {
if (participation.getBuildPlanId() != null) {
// ignore participations without build plan id
try {
continuousIntegrationService.get().deleteBuildPlan(participation.getBuildPlanId());
} catch (BambooException ex) {
log.error(ex.getMessage());
if (ex.getCause() != null) {
log.error(ex.getCause().getMessage());
}
}
participation.setInitializationState(ParticipationState.INACTIVE);
participation.setBuildPlanId(null);
participationService.save(participation);
}
if (deleteRepositories == true && participation.getRepositoryUrl() != null) {
// ignore participations without repository URL
try {
// 1. clone the repository
Repository repo = gitService.get().getOrCheckoutRepository(participation);
// 2. collect the repo file
studentRepositories.add(repo);
} catch (GitAPIException | IOException ex) {
log.error("Archiving and deleting the repository " + participation.getRepositoryUrlAsUrl() + " did not work as expected", ex);
}
}
});
if (deleteRepositories == false) {
// in this case, we are done
return null;
}
if (studentRepositories.isEmpty()) {
log.info("No student repositories have been found.");
return null;
}
// from here on, deleteRepositories is true and does not need to be evaluated again
log.info("Create zip file for all repositories");
Files.createDirectories(Paths.get("zippedRepos"));
finalZipFilePath = Paths.get("zippedRepos", exercise.getCourse().getTitle() + " " + exercise.getTitle() + " Student Repositories.zip");
zipAllRepositories(studentRepositories, finalZipFilePath);
exercise.getParticipations().forEach(participation -> {
if (participation.getRepositoryUrl() != null) {
// ignore participations without repository URL
try {
// 3. delete the locally cloned repo again
gitService.get().deleteLocalRepository(participation);
} catch (IOException e) {
log.error("Archiving and deleting the repository " + participation.getRepositoryUrlAsUrl() + " did not work as expected", e);
}
// 4. finally delete the repository on the VC Server
versionControlService.get().deleteRepository(participation.getRepositoryUrlAsUrl());
participation.setRepositoryUrl(null);
participation.setInitializationState(ParticipationState.FINISHED);
participationService.save(participation);
}
});
scheduleForDeletion(finalZipFilePath, 300);
} else {
log.info("Exercise with id {} is not an instance of ProgrammingExercise. Ignoring the request to cleanup repositories and build plan", id);
return null;
}
return new java.io.File(finalZipFilePath.toString());
}
use of de.tum.in.www1.artemis.domain.Repository in project ArTEMiS by ls1intum.
the class ExerciseService method zipAllRepositories.
public Path zipAllRepositories(List<Repository> repositories, Path zipFilePath) throws IOException {
try (ZipOutputStream zipOutputStream = new ZipOutputStream(Files.newOutputStream(zipFilePath))) {
repositories.forEach(repository -> {
Path repoPath = repository.getLocalPath();
Path parentRepoPath = repoPath.getParent();
try {
Files.walk(repoPath).filter(path -> !Files.isDirectory(path)).forEach(path -> {
ZipEntry zipEntry = new ZipEntry(parentRepoPath.relativize(path).toString());
try {
zipOutputStream.putNextEntry(zipEntry);
Files.copy(path, zipOutputStream);
zipOutputStream.closeEntry();
} catch (Exception e) {
log.error("Create zip file error", e);
}
});
} catch (IOException e) {
log.error("Create zip file error", e);
}
});
}
return zipFilePath;
}
use of de.tum.in.www1.artemis.domain.Repository in project ArTEMiS by ls1intum.
the class GitService method getOrCheckoutRepository.
/**
* Get the local repository for a given participation.
* If the local repo does not exist yet, it will be checked out.
*
* @param participation Participation the remote repository belongs to.
* @return
* @throws IOException
* @throws GitAPIException
*/
public Repository getOrCheckoutRepository(Participation participation) throws IOException, GitAPIException {
URL repoUrl = participation.getRepositoryUrlAsUrl();
Repository repository = getOrCheckoutRepository(repoUrl);
repository.setParticipation(participation);
return repository;
}
use of de.tum.in.www1.artemis.domain.Repository in project ArTEMiS by ls1intum.
the class GitService method getOrCheckoutRepository.
/**
* Get the local repository for a given remote repository URL.
* If the local repo does not exist yet, it will be checked out.
*
* @param repoUrl The remote repository.
* @return
* @throws IOException
* @throws GitAPIException
*/
public Repository getOrCheckoutRepository(URL repoUrl) throws IOException, GitAPIException {
Path localPath = new java.io.File(REPO_CLONE_PATH + folderNameForRepositoryUrl(repoUrl)).toPath();
// check if Repository object already created and available in cachedRepositories
if (cachedRepositories.containsKey(localPath)) {
return cachedRepositories.get(localPath);
}
// Check if the repository is already checked out on the server
if (!Files.exists(localPath)) {
// Repository is not yet available on the server
// We need to check it out from the remote repository
log.info("Cloning from " + repoUrl + " to " + localPath);
Git result = Git.cloneRepository().setURI(repoUrl.toString()).setCredentialsProvider(new UsernamePasswordCredentialsProvider(GIT_USER, GIT_PASSWORD)).setDirectory(localPath.toFile()).call();
result.close();
} else {
log.info("Repository at " + localPath + " already exists");
}
// Open the repository from the filesystem
FileRepositoryBuilder builder = new FileRepositoryBuilder();
builder.setGitDir(new java.io.File(localPath + "/.git")).readEnvironment().findGitDir().setup();
// Create the JGit repository object
Repository repository = new Repository(builder);
repository.setLocalPath(localPath);
// Cache the JGit repository object for later use
// Avoids the expensive re-opening of local repositories
cachedRepositories.put(localPath, repository);
return repository;
}
Aggregations