76 lines
3.1 KiB
Java
76 lines
3.1 KiB
Java
package tk.antoine_roux.wiki.service;
|
|
|
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
|
import org.eclipse.jgit.api.Git;
|
|
import org.eclipse.jgit.api.errors.GitAPIException;
|
|
import org.eclipse.jgit.lib.ObjectId;
|
|
import org.eclipse.jgit.revwalk.RevCommit;
|
|
import org.eclipse.jgit.revwalk.RevWalk;
|
|
import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider;
|
|
import org.eclipse.jgit.treewalk.TreeWalk;
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
import org.springframework.beans.factory.annotation.Qualifier;
|
|
import org.springframework.stereotype.Service;
|
|
import tk.antoine_roux.wiki.model.internal.GitlabCI;
|
|
import tk.antoine_roux.wiki.model.request.HookEvent;
|
|
import tk.antoine_roux.wiki.model.request.secondary.Commit;
|
|
|
|
import java.io.IOException;
|
|
import java.nio.file.Files;
|
|
import java.util.Optional;
|
|
|
|
@Service
|
|
public class GitService {
|
|
|
|
public static final String GITLAB_CI_FILE_PATH = ".gitlab-ci.yml";
|
|
private static final String GITLAB_RUNNER_CLONE_PREFIX = "gitlab-runner-clone";
|
|
public final UsernamePasswordCredentialsProvider credentialsProvider;
|
|
private final ObjectMapper objectMapper;
|
|
|
|
@Autowired
|
|
public GitService(UsernamePasswordCredentialsProvider credentialsProvider, @Qualifier("YAMLObjectMapper") ObjectMapper objectMapper) {
|
|
this.credentialsProvider = credentialsProvider;
|
|
this.objectMapper = objectMapper;
|
|
}
|
|
|
|
/**
|
|
* return .gitlab-ci.yml content for {@link HookEvent}
|
|
*/
|
|
public Optional<GitlabCI> getYMLGitlabCI(HookEvent hookEvent) throws IOException, GitAPIException {
|
|
Optional<GitlabCI> optJob;
|
|
if (hookEvent.commits.isEmpty()) {
|
|
optJob = Optional.empty();
|
|
} else {
|
|
// search for head commit or take first in event's list of commit
|
|
Commit commit = hookEvent.commits.stream().filter(co -> co.id.equals(hookEvent.headCommit))
|
|
.findFirst().orElse(hookEvent.commits.get(0));
|
|
|
|
optJob = Optional.of(this.getGitlabCIContent(hookEvent.repository.cloneUrl, commit));
|
|
}
|
|
return optJob;
|
|
}
|
|
|
|
/**
|
|
* return .gitlab-ci.yml content for given commit into cloneUrl repository
|
|
*/
|
|
private GitlabCI getGitlabCIContent(String cloneURL, Commit commit) throws IOException, GitAPIException {
|
|
Git call = Git.cloneRepository()
|
|
.setURI(cloneURL)
|
|
.setCredentialsProvider(this.credentialsProvider)
|
|
.setDirectory(Files.createTempDirectory(GITLAB_RUNNER_CLONE_PREFIX).toFile())
|
|
.call();
|
|
|
|
RevWalk revWalk = new RevWalk(call.getRepository());
|
|
RevCommit revCommit = revWalk.parseCommit(ObjectId.fromString(commit.id));
|
|
|
|
try (TreeWalk walk = TreeWalk.forPath(call.getRepository(), GITLAB_CI_FILE_PATH, revCommit.getTree())) {
|
|
if (walk != null) {
|
|
byte[] bytes = call.getRepository().open(walk.getObjectId(0)).getBytes();
|
|
return this.objectMapper.readValue(bytes, GitlabCI.class);
|
|
} else {
|
|
throw new IllegalArgumentException("No path found.");
|
|
}
|
|
}
|
|
}
|
|
}
|