package de.hftstuttgart.rest.v1.unittest; import de.hftstuttgart.config.ModocotProperties; import de.hftstuttgart.utils.BackendUtil; import de.hftstuttgart.utils.FileUtil; import de.hftstuttgart.utils.GitTeaUtil; import de.hftstuttgart.utils.JGitUtil; import de.hftstuttgart.utils.UnzipUtil; import io.gitea.model.Repository; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.eclipse.jgit.transport.PushResult; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.multipart.MultipartFile; import javax.servlet.annotation.MultipartConfig; import java.io.File; import java.io.IOException; import java.util.List; import java.util.Objects; import java.util.UUID; import java.util.stream.Collectors; import java.util.stream.Stream; /** * Rest controller for anything related to the TEST files. */ @RestController @RequestMapping("/v1/unittest") @MultipartConfig public class UnitTestUpload { private static final Logger LOG = LogManager.getLogger(UnitTestUpload.class); private final ModocotProperties modocotProperties; private final GitTeaUtil gitTeaUtil; private final JGitUtil jGitUtil; private final String assignmentBasePath; public UnitTestUpload(ModocotProperties modocotProperties, GitTeaUtil gitTeaUtil, JGitUtil jGitUtil) { this.modocotProperties = modocotProperties; this.gitTeaUtil = gitTeaUtil; this.jGitUtil = jGitUtil; this.assignmentBasePath = modocotProperties.getModocotParentDirectory() + File.separator + modocotProperties.getModocotAssignmentFolderPrefix(); } /** * Create a subfolder for the specific assignment. * This is called when the teacher creates an assignment and uploads the JUnit test files * * @param unitTestFileRef The zip file which contains the JUnit tests * @param assignmentId ID of the created assignment. Generated by Moodle */ @RequestMapping(method = RequestMethod.POST) public void uploadUnitTestFile(@RequestParam("unitTestFile") MultipartFile unitTestFileRef, @RequestParam("assignmentId") String assignmentId) throws IOException { // path to the directory in which we will be working String subFolderPath = this.assignmentBasePath + assignmentId; LOG.info("work-directory: " + subFolderPath); // creating the work-directory File workDirectory = new File(subFolderPath); workDirectory.mkdirs(); // creating the file which the unitTestFileRef will be transferred into File file = new File(subFolderPath, String.valueOf(UUID.randomUUID())); // transferring MultipartFile into temporary file unitTestFileRef.transferTo(file); // unzipping temporary file to work-directory List zipFiles = UnzipUtil.unzip(file); // unzipping temporary file (not needed anymore) if (file.exists()) file.delete(); // check if any extracted files are named repo.txt if (zipFiles.stream().anyMatch(zipFile -> zipFile.getName().equalsIgnoreCase("repo.txt"))) { // reading all from the repo.txt List lines = BackendUtil.extractLinesFromRepoFile(zipFiles, "repo.txt"); // either set the first line of repo.txt or "" String repoUrl = (lines.size() > 0 && !lines.get(0).equals("")) ? lines.get(0) : ""; LOG.info("repoUrl: " + repoUrl); // either set the second line of repo.txt or null String credentials = ((lines.size() > 1) && !lines.get(1).equals("")) ? lines.get(1) : null; LOG.info("credentials: " + credentials); // cloning repository repoUrl into work-directory, using credentials from second line in repo.txt this.jGitUtil.cloneRepository(repoUrl, workDirectory, credentials, credentials != null,true); } Stream.of(Objects.requireNonNull(workDirectory.listFiles())) .forEach(fi -> System.out.println(fi.getAbsolutePath())); if(this.gitTeaUtil.repositoryExists(assignmentId)) { this.gitTeaUtil.deleteRepository(assignmentId); } // creating repository on internal giTea, name = assignmentId Repository repo = this.gitTeaUtil.createRepository(assignmentId); System.out.println(repo); // giTea runs in docker and returns CloneUrl as localhost, replacing localhost with docker-host ip repo.setCloneUrl(repo.getCloneUrl().replace("localhost", modocotProperties.getDockerHostIp())); // committing everything in work-directory and push to created repository Iterable pushResults = this.jGitUtil.commitAllAndPush(workDirectory, repo, false); if (pushResults != null) { for (PushResult pushResult : pushResults) { LOG.info("Push-Result: " + pushResult.getMessages()); } } // deleting created work-directory FileUtil.deleteFolderRecursively(workDirectory); LOG.info("Uploaded unit test file: " + workDirectory); } /** * Delete the folder for the assignment. * Called when the teacher deletes the JUnitTest assignment *

* {{url}}:8080/v1/unittest?assignmentId=111 * * @param assignmentId ID of the assignment to delete. Generated by Moodle */ @RequestMapping(method = RequestMethod.DELETE) public void deleteUnitTestFiles(@RequestParam("assignmentId") String assignmentId) { String path = this.assignmentBasePath + assignmentId; File dir = new File(path); FileUtil.deleteFolderRecursively(dir); } }