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

com.release_notes_for_bitbucket.release_helper.ReleaseHelper Maven / Gradle / Ivy

Go to download

This tool collects all issues that were fixed in some/the latest release and assigns them a corresponding milestone. In effect this milestone is basis for your release notes. This is the command line tool - a maven plugin is available too.

The newest version!
package com.release_notes_for_bitbucket.release_helper;

import com.release_notes_for_bitbucket.fetcher.ChangesetFetcher;
import com.release_notes_for_bitbucket.fetcher.IssueFetcher;
import com.release_notes_for_bitbucket.model.Changeset;
import com.release_notes_for_bitbucket.model.Issue;
import com.release_notes_for_bitbucket.model.Milestone;
import com.release_notes_for_bitbucket.version_tree.Commit;
import com.release_notes_for_bitbucket.version_tree.CommitTree;

import java.io.IOException;
import java.util.ArrayDeque;
import java.util.Deque;
import java.util.HashSet;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class ReleaseHelper {

    private final CommitTree commitTree;
    private final ChangesetFetcher changesetFetcher;
    private final IssueFetcher issueFetcher;

    public ReleaseHelper(String user, String password, String repoOwner, String repoName) {

        issueFetcher = new IssueFetcher(user, password, repoOwner, repoName);
        changesetFetcher = new ChangesetFetcher(user, password, repoOwner, repoName);
        commitTree = new CommitTree(changesetFetcher);
    }

    /**
     * For testing only!
     * @param commitTree
     * @param changesetFetcher
     * @param issueFetcher
     */
    ReleaseHelper(CommitTree commitTree, ChangesetFetcher changesetFetcher, IssueFetcher issueFetcher) {
        this.commitTree = commitTree;
        this.changesetFetcher = changesetFetcher;
        this.issueFetcher = issueFetcher;
    }

    /**
     * Fetches changeset for release
     *
     * @param version get most current release if null
     * @return
     * @throws IOException
     */
    public Changeset getReleaseCommit(String version) throws IOException {
        for (int i = 0; i < changesetFetcher.getTotal(); i++) {
            if (i >= changesetFetcher.getAllFetchedChangesets().size()) {
                changesetFetcher.fetchMore(50);
            }
            Commit commit = new Commit(changesetFetcher.getAllFetchedChangesets().get(i));
            if (commit.getRelease() != null) {
                if (version == null) {
                    return commit.getChangeset();
                } else {
                    if (version.equals(commit.getRelease())) {
                        return commit.getChangeset();
                    }
                }
            }
        }

        return null;
    }

    /**
     * Commits that are (also) part of a newer release are returned as well!
     *
     * @param releaseCommit
     * @return all Commits that are part of the given release, but not part of any other release (does not include given release)
     */
    public Set getCommitsNotInSomeOtherRelease(Changeset releaseCommit) {
        Commit release = commitTree.getForChangeset(releaseCommit);

        Deque candidates = new ArrayDeque<>();
        candidates.addAll(commitTree.getPredecessors(release));
        Set result = new HashSet<>();
        Set checkedCandidates = new HashSet<>();

        while (!candidates.isEmpty()) {
            Commit candidate = candidates.poll();
            boolean candidateOk = true;
            if (!release.equals(candidate) && candidate.getRelease() == null) {
                //check all successors (oder than 'release') for beeing release:
                for (Commit successor : commitTree.getRecursiveSuccessors(candidate)) {
                    if (successor.getDate().after(release.getDate())) {
                        continue;
                    }
                    if (!release.equals(successor) && successor.getRelease() != null) {
                        candidateOk = false;
                    }
                }
                if (candidateOk) {
                    result.add(candidate);
                    for (Commit predecessor : candidate.getPredecessors()) {
                        if (!candidates.contains(predecessor) && !checkedCandidates.contains(predecessor)) {
                            candidates.addLast(predecessor);
                        }
                    }
                }
                checkedCandidates.add(candidate);
            }
        }

        return result;
    }

    public Set getResolvedIssues(Set commits) {
        Set result = new HashSet<>();
        for (Commit commit : commits) {
            //See https://confluence.atlassian.com/display/BITBUCKET/Resolve+issues+automatically+when+users+push+code
            Pattern fixedIssuePattern = Pattern.compile("(?:close|closes|closed|closing|fix|fixed|fixes|fixing|resolve|resolves|resolved|resolving) (?:bug |issue |ticket )?#(\\d+)", Pattern.CASE_INSENSITIVE);
            Matcher matcher = fixedIssuePattern.matcher(commit.getChangeset().getMessage());
            System.out.println("Checking: " + commit.getId() + " - " + commit.getChangeset().getMessage().trim());
            while (matcher.find()) {
                result.add(Integer.parseInt(matcher.group(1)));
            }
        }
        return result;
    }

    public Set getFixedIssues(Set markedAsResolvedIssues) throws IOException {
        Set fixedIssues = new HashSet<>();
        for (Integer issueId : markedAsResolvedIssues) {
            Issue issue = issueFetcher.fetchIssue(issueId);
            if ("resolved".equals(issue.getStatus())) {
                fixedIssues.add(issue);
            }
        }
        return fixedIssues;
    }

    public void setMilestoneForIssues(Milestone milestone, Set fixedIssues) throws IOException {
        // for all theses issues, set milestone (if already some other milestone is set -> warning (overwrite via conf.?)
        for (Issue issue : fixedIssues) {
            if(milestone.getName().equals(issue.getMetadata().getMilestone())) {
                continue; // don't reset to exising version
            }
            if (issue.getMetadata().getMilestone() != null) {
                System.out.println("Warning: overwriting milestone (" + issue.getMetadata().getMilestone() + ") for issue: #" + issue.getLocalId());
            }
            issueFetcher.setMilestone(issue.getLocalId(), milestone.getName());
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy