All Downloads are FREE. Search and download functionalities are using the official Maven repository.

lu.uni.serval.commons.git.utils.CommitCollector Maven / Gradle / Ivy

package lu.uni.serval.commons.git.utils;

import org.apache.commons.io.FilenameUtils;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.diff.DiffEntry;

import java.io.IOException;
import java.time.Instant;
import java.util.*;
import java.util.stream.Collectors;

public class CommitCollector {
    private Git git;
    private Instant start;
    private Instant end;
    private String branch = "master";
    private Set ignored = Collections.emptySet();
    private Frequency frequency = Frequency.UNIQUE;
    private int limit = 0;
    private Set filterNoChangeIn = Collections.emptySet();
    private Set extensions = Collections.emptySet();
    private boolean withDifference = true;

    public CommitCollector forGit(Git git){
        this.git = git;
        return this;
    }

    public CommitCollector onBranch(String branch){
        this.branch = branch;
        return this;
    }

    public CommitCollector from(Instant start){
        this.start = start;
        return this;
    }

    public CommitCollector to(Instant end){
        this.end = end;
        return this;
    }

    public CommitCollector ignoring(Set commitIds){
        this.ignored = commitIds;
        return this;
    }

    public CommitCollector filterNoChangeIn(Set foldersToWatch){
        this.filterNoChangeIn = foldersToWatch;
        return this;
    }

    public CommitCollector forExtensions(Set extensions){
        this.extensions = extensions.stream().map(String::toLowerCase).collect(Collectors.toSet());
        return this;
    }

    public CommitCollector every(Frequency frequency){
        this.frequency = frequency;
        return this;
    }

    public CommitCollector limit(int limit){
        this.limit = limit;
        return this;
    }

    public CommitCollector withDifference(boolean withDifference){
        this.withDifference = withDifference;
        return this;
    }

    public List collect() throws IOException, GitAPIException {
        List commits;

        if(frequency == Frequency.RELEASE){
            commits = GitUtils.getTags(
                    this.git,
                    this.start,
                    this.end
            );
        }
        else{
            commits = GitUtils.getCommits(
                    this.git,
                    this.start,
                    this.end,
                    this.branch
            );
        }

        if(ignored != null && !ignored.isEmpty()){
            commits = commits.stream()
                    .filter(commit -> !ignored.contains(commit.getId()))
                    .collect(Collectors.toList());
        }

        if(!extensions.isEmpty() || !filterNoChangeIn.isEmpty()){
            GitUtils.setDifferences(git, commits);
            commits = commits.stream()
                    .filter(c -> isContainExtension(c, extensions))
                    .filter(c -> isSubfolderChanged(c, filterNoChangeIn, extensions))
                    .collect(Collectors.toList());
        }

        if(commits.isEmpty()){
            return commits;
        }

        commits = processFrequency(commits);
        finalizeCollection(commits);

        return commits;
    }

    private List processFrequency(List commits){
        commits = GitUtils.filterCommitsByFrequency(commits, frequency);

        if(frequency == Frequency.LATEST){
            commits = commits.subList(commits.size() - 1, commits.size());
        }
        else{
            commits = limit > 0 ? commits.subList(0, Math.min(commits.size(), limit)) : commits;
        }

        return commits;
    }

    private static boolean hasExtension(String path, Set extensions){
        if(extensions == null || extensions.isEmpty()){
            return true;
        }

        return extensions.contains(FilenameUtils.getExtension(path));
    }

    private static boolean isContainExtension(GitCommit commit, Set extensions) {
        if(extensions == null || extensions.isEmpty()){
            return true;
        }

        for(DiffEntry diffEntry: commit.getDifference().getEntries()){
            if(hasExtension(diffEntry.getOldPath(), extensions)){
                return true;
            }

            if(hasExtension(diffEntry.getNewPath(), extensions)){
                return true;
            }
        }

        return false;
    }

    private static boolean isSubfolderChanged(GitCommit commit, Set subFolders, Set extensions) {
        if((subFolders == null || subFolders.isEmpty())){
            return true;
        }

        for(DiffEntry diffEntry: commit.getDifference().getEntries()){
            if(isEntryInSubFolder(diffEntry, subFolders, extensions)){
                return true;
            }
        }

        return false;
    }

    private static boolean isEntryInSubFolder(DiffEntry diffEntry, Set subFolders, Set extensions){
        for(String subFolder: subFolders){
            try {
                if(FilenameUtils.directoryContains(subFolder, diffEntry.getOldPath())
                        && hasExtension(diffEntry.getOldPath(), extensions)){
                    return true;
                }

                if(FilenameUtils.directoryContains(subFolder, diffEntry.getNewPath())
                        && hasExtension(diffEntry.getNewPath(), extensions)){
                    return true;
                }
            } catch (IOException e) {
                return true;
            }
        }

        return false;
    }

    public List cherryPick(String... commitIds) throws IOException, GitAPIException {
        List commits = new ArrayList<>(commitIds.length);

        for(String commitId: commitIds){
            GitUtils.getCommitById(git, commitId).ifPresent(commits::add);
        }

        finalizeCollection(commits);
        return commits;
    }

    private void finalizeCollection(List commits) throws IOException, GitAPIException {
        if(withDifference){
            GitUtils.setDifferences(git, commits);
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy