/**
* # Copyright 2016 Infobip
* #
* # Licensed under the Apache License, Version 2.0 (the "License");
* # you may not use this file except in compliance with the License.
* # You may obtain a copy of the License at
* #
* # http://www.apache.org/licenses/LICENSE-2.0
* #
* # Unless required by applicable law or agreed to in writing, software
* # distributed under the License is distributed on an "AS IS" BASIS,
* # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* # See the License for the specific language governing permissions and
* # limitations under the License.
*/
package com.infobip.jira;
import com.atlassian.bitbucket.commit.Commit;
import java.time.Clock;
import java.time.LocalDate;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import static java.util.Objects.requireNonNull;
public class JiraVersionGenerator {
private final JiraService jiraService;
private final Commit releaseCommit;
private final Iterator<Commit> commitIterator;
private final CommitMessageVersionExtractor commitMessageVersionExtractor;
private final Clock clock;
public JiraVersionGenerator(JiraService jiraService,
Commit releaseCommit,
Iterator<Commit> commitIterator,
CommitMessageVersionExtractor commitMessageVersionExtractor,
Clock clock) {
this.releaseCommit = releaseCommit;
this.jiraService = requireNonNull(jiraService);
this.commitIterator = requireNonNull(commitIterator);
this.commitMessageVersionExtractor = requireNonNull(commitMessageVersionExtractor);
this.clock = clock;
}
public void generate(String jiraVersionPrefix,
ProjectKey projectKey) {
if (!commitIterator.hasNext()) {
return;
}
commitMessageVersionExtractor.extractVersionName(releaseCommit.getMessage())
.ifPresent(versionName -> generate(jiraVersionPrefix, projectKey, versionName));
}
private void generate(String jiraVersionPrefix,
ProjectKey projectKey,
String versionName) {
String prefixedVersionName = jiraVersionPrefix + versionName;
List<Commit> versionCommits = getAllCommitsNewerThanPreviousRelease();
SerializedVersion version = jiraService.findVersion(projectKey, prefixedVersionName)
.orElseGet(() -> createNewVersion(projectKey, prefixedVersionName));
List<IssueKey> issuesSolvedInVersion = getIssueKeys(versionCommits, projectKey);
jiraService.addVersionToIssues(version.getName(), projectKey, issuesSolvedInVersion);
LocalDate releaseDate = releaseCommit.getAuthorTimestamp().toInstant().atZone(clock.getZone()).toLocalDate();
jiraService.releaseVersion(version, releaseDate);
}
private SerializedVersion createNewVersion(ProjectKey projectKey, String prefixedVersionName) {
SerializedVersion version = new SerializedVersion(null, prefixedVersionName, projectKey.getValue(), null, false);
return jiraService.createJiraVersion(version);
}
private List<IssueKey> getIssueKeys(List<Commit> versionCommits, ProjectKey projectKey) {
return versionCommits.stream()
.flatMap(commit -> getIssueKeys(commit, projectKey).stream())
.collect(Collectors.toList());
}
private List<IssueKey> getIssueKeys(Commit commit, ProjectKey projectKey) {
return Optional.ofNullable(commit.getMessage())
.map(message -> {
Pattern pattern = Pattern.compile(projectKey.getValue() + "-([0-9]+)");
Matcher matcher = pattern.matcher(message);
List<IssueKey> issueKeys = new ArrayList<>();
while (matcher.find()) {
issueKeys.add(new IssueKey(projectKey, new IssueId(matcher.group(1))));
}
return issueKeys;
}).orElse(Collections.emptyList());
}
private List<Commit> getAllCommitsNewerThanPreviousRelease() {
List<Commit> versionCommit = new ArrayList<>();
while (commitIterator.hasNext()) {
Commit commit = commitIterator.next();
if (commitMessageVersionExtractor.extractVersionName(commit.getMessage()).isPresent()) {
break;
}
versionCommit.add(commit);
}
return versionCommit;
}
}