use of net.nemerosa.ontrack.extension.issues.model.ConfiguredIssueService in project ontrack by nemerosa.
the class GitServiceImpl method collectIssueCommitInfos.
private List<OntrackGitIssueCommitInfo> collectIssueCommitInfos(Project project, Issue issue) {
// Index of commit infos
Map<String, OntrackGitIssueCommitInfo> commitInfos = new LinkedHashMap<>();
// For all configured branches
forEachConfiguredBranch((branch, branchConfiguration) -> {
// Filter per project
if (branch.projectId() != project.id()) {
return;
}
// Gets the branch configuration
GitConfiguration configuration = branchConfiguration.getConfiguration();
// Gets the Git client for this project
GitRepositoryClient client = gitRepositoryClientFactory.getClient(configuration.getGitRepository());
// Issue service
ConfiguredIssueService configuredIssueService = configuration.getConfiguredIssueService().orElse(null);
if (configuredIssueService != null) {
// List of commits for this branch
List<RevCommit> revCommits = new ArrayList<>();
// Scanning this branch's repository for the commit
client.scanCommits(branchConfiguration.getBranch(), revCommit -> {
String message = revCommit.getFullMessage();
Set<String> keys = configuredIssueService.extractIssueKeysFromMessage(message);
// Gets all linked issues
boolean matching = configuredIssueService.getLinkedIssues(branch.getProject(), issue).stream().map(Issue::getKey).anyMatch(key -> configuredIssueService.containsIssueKey(key, keys));
if (matching) {
// We have a commit for this branch!
revCommits.add(revCommit);
}
// Scanning all commits
return false;
});
// If at least one commit
if (revCommits.size() > 0) {
// Gets the last commit (which is the first in the list)
RevCommit revCommit = revCommits.get(0);
// Commit explained (independent from the branch)
GitCommit commit = client.toCommit(revCommit);
String commitId = commit.getId();
// Gets any existing commit info
OntrackGitIssueCommitInfo commitInfo = commitInfos.get(commitId);
// If not defined, creates an entry
if (commitInfo == null) {
// UI commit (independent from the branch)
GitUICommit uiCommit = toUICommit(configuration.getCommitLink(), getMessageAnnotators(configuration), commit);
// Commit info
commitInfo = OntrackGitIssueCommitInfo.of(uiCommit);
// Indexation
commitInfos.put(commitId, commitInfo);
}
// Collects branch info
SCMIssueCommitBranchInfo branchInfo = SCMIssueCommitBranchInfo.of(branch);
// Gets the last build for this branch
Optional<Build> buildAfterCommit = getEarliestBuildAfterCommit(commitId, branch, branchConfiguration, client);
branchInfo = scmService.getBranchInfo(buildAfterCommit, branchInfo);
// Adds the info
commitInfo.add(branchInfo);
}
}
});
// OK
return Lists.newArrayList(commitInfos.values());
}
use of net.nemerosa.ontrack.extension.issues.model.ConfiguredIssueService in project ontrack by nemerosa.
the class SVNInfoServiceImpl method getIssueInfo.
@Override
public OntrackSVNIssueInfo getIssueInfo(String configurationName, String issueKey) {
// Repository
SVNRepository repository = svnService.getRepository(configurationName);
// Issue service
ConfiguredIssueService configuredIssueService = repository.getConfiguredIssueService();
if (configuredIssueService == null) {
// No issue service configured
return OntrackSVNIssueInfo.empty(repository.getConfiguration());
}
// Gets the details about the issue
Issue issue = configuredIssueService.getIssue(issueKey);
// For each configured branch
Map<String, BranchRevision> branchRevisions = new HashMap<>();
svnService.forEachConfiguredBranch(config -> Objects.equals(configurationName, config.getConfiguration().getName()), (branch, branchConfig) -> {
String branchPath = branchConfig.getCuredBranchPath();
// List of linked issues
Collection<String> linkedIssues = configuredIssueService.getLinkedIssues(branch.getProject(), issue).stream().map(Issue::getKey).collect(Collectors.toList());
// Gets the last raw revision on this branch
issueRevisionDao.findLastRevisionByIssuesAndBranch(repository.getId(), linkedIssues, branchPath).ifPresent(revision -> branchRevisions.put(branchPath, new BranchRevision(branchPath, revision, false)));
});
// Until all revisions are complete in respect of their merges...
while (!BranchRevision.areComplete(branchRevisions.values())) {
// Gets the incomplete revisions
Collection<BranchRevision> incompleteRevisions = branchRevisions.values().stream().filter(br -> !br.isComplete()).collect(Collectors.toList());
// For each of them, gets the list of revisions it was merged to
incompleteRevisions.forEach(br -> {
List<Long> merges = revisionDao.getMergesForRevision(repository.getId(), br.getRevision());
// Marks the current revision as complete
branchRevisions.put(br.getPath(), br.complete());
// Gets the revision info for each merged revision
List<TRevision> revisions = merges.stream().map(r -> revisionDao.get(repository.getId(), r)).collect(Collectors.toList());
// For each revision path, compares with current stored revision
revisions.forEach(t -> {
String branch = t.getBranch();
// Existing branch revision?
BranchRevision existingBranchRevision = branchRevisions.get(branch);
if (existingBranchRevision == null || t.getRevision() > existingBranchRevision.getRevision()) {
branchRevisions.put(branch, new BranchRevision(branch, t.getRevision(), true));
}
});
});
}
// We now have the last revision for this issue on each branch...
List<OntrackSVNIssueRevisionInfo> issueRevisionInfos = new ArrayList<>();
branchRevisions.values().forEach(br -> {
// Loads the revision info
SVNRevisionInfo basicInfo = svnService.getRevisionInfo(repository, br.getRevision());
SVNChangeLogRevision changeLogRevision = svnService.createChangeLogRevision(repository, basicInfo);
// Info to collect
OntrackSVNIssueRevisionInfo issueRevisionInfo = OntrackSVNIssueRevisionInfo.of(changeLogRevision);
// Gets the branch from the branch path
AtomicReference<Branch> rBranch = new AtomicReference<>();
svnService.forEachConfiguredBranch(config -> Objects.equals(configurationName, config.getConfiguration().getName()), (candidate, branchConfig) -> {
String branchPath = branchConfig.getCuredBranchPath();
if (Objects.equals(br.getPath(), branchPath)) {
rBranch.set(candidate);
}
});
Branch branch = rBranch.get();
if (branch != null) {
// Collects branch info
SCMIssueCommitBranchInfo branchInfo = SCMIssueCommitBranchInfo.of(branch);
// Gets the first copy event on this path after this revision
SVNLocation firstCopy = svnService.getFirstCopyAfter(repository, basicInfo.toLocation());
// Identifies a possible build given the path/revision and the first copy
Optional<Build> buildAfterCommit = lookupBuild(basicInfo.toLocation(), firstCopy, branch);
branchInfo = scmService.getBranchInfo(buildAfterCommit, branchInfo);
// OK
issueRevisionInfo.add(branchInfo);
}
// OK
issueRevisionInfos.add(issueRevisionInfo);
});
// Gets the list of revisions & their basic info (order from latest to oldest)
List<SVNChangeLogRevision> revisions = svnService.getRevisionsForIssueKey(repository, issueKey).stream().map(revision -> svnService.createChangeLogRevision(repository, svnService.getRevisionInfo(repository, revision))).collect(Collectors.toList());
// OK
return new OntrackSVNIssueInfo(repository.getConfiguration(), repository.getConfiguredIssueService().getIssueServiceConfigurationRepresentation(), issue, issueRevisionInfos, revisions);
}
use of net.nemerosa.ontrack.extension.issues.model.ConfiguredIssueService in project ontrack by nemerosa.
the class SVNServiceUtils method createChangeLogRevision.
public static SVNChangeLogRevision createChangeLogRevision(SVNRepository repository, String path, int level, long revision, String message, String author, LocalDateTime revisionDate) {
// Issue service
ConfiguredIssueService configuredIssueService = repository.getConfiguredIssueService();
// Formatted message
String formattedMessage;
if (configuredIssueService != null) {
formattedMessage = configuredIssueService.formatIssuesInMessage(message);
} else {
formattedMessage = message;
}
// Revision URL
String revisionUrl = repository.getRevisionBrowsingURL(revision);
// OK
return new SVNChangeLogRevision(path, level, revision, author, revisionDate, message, revisionUrl, formattedMessage);
}
use of net.nemerosa.ontrack.extension.issues.model.ConfiguredIssueService in project ontrack by nemerosa.
the class IndexationServiceImpl method indexIssues.
private void indexIssues(SVNRepository repository, SVNLogEntry logEntry) {
// Is the repository associated with any issue service?
ConfiguredIssueService configuredIssueService = repository.getConfiguredIssueService();
if (configuredIssueService != null) {
IssueServiceExtension issueServiceExtension = configuredIssueService.getIssueServiceExtension();
IssueServiceConfiguration issueServiceConfiguration = configuredIssueService.getIssueServiceConfiguration();
// Revision information to scan
long revision = logEntry.getRevision();
String message = logEntry.getMessage();
// Cache for issues
Set<String> revisionIssues = new HashSet<>();
// Gets all issues from the message
Set<String> issues = issueServiceExtension.extractIssueKeysFromMessage(issueServiceConfiguration, message);
// For each issue in the message
issues.stream().filter(issueKey -> !revisionIssues.contains(issueKey)).forEach(issueKey -> {
revisionIssues.add(issueKey);
logger.info(String.format(" Indexing revision %d <-> %s", revision, issueKey));
// Indexes this issue
issueRevisionDao.link(repository.getId(), revision, issueKey);
});
}
}
use of net.nemerosa.ontrack.extension.issues.model.ConfiguredIssueService in project ontrack by nemerosa.
the class SVNChangeLogServiceImpl method getChangeLogIssues.
@Override
@Transactional
public SVNChangeLogIssues getChangeLogIssues(SVNChangeLog changeLog) {
// Revisions must have been loaded first
if (changeLog.getRevisions() == null) {
changeLog.withRevisions(getChangeLogRevisions(changeLog));
}
// In a transaction
try (Transaction ignored = transactionService.start()) {
// Repository
SVNRepository repository = changeLog.getRepository();
// Index of issues, sorted by keys
Map<String, SVNChangeLogIssue> issues = new TreeMap<>();
// For all revisions in this revision log
for (SVNChangeLogRevision changeLogRevision : changeLog.getRevisions().getList()) {
long revision = changeLogRevision.getRevision();
collectIssuesForRevision(repository, issues, revision);
}
// List of issues
List<SVNChangeLogIssue> issuesList = new ArrayList<>(issues.values());
// Validations
validateIssues(issuesList, changeLog);
// Issues link
IssueServiceConfigurationRepresentation issueServiceConfiguration = null;
String allIssuesLink = "";
ConfiguredIssueService configuredIssueService = repository.getConfiguredIssueService();
if (configuredIssueService != null) {
issueServiceConfiguration = configuredIssueService.getIssueServiceConfigurationRepresentation();
allIssuesLink = configuredIssueService.getLinkForAllIssues(issuesList.stream().map(SVNChangeLogIssue::getIssue).collect(Collectors.toList()));
}
// OK
return new SVNChangeLogIssues(allIssuesLink, issueServiceConfiguration, issuesList);
}
}
Aggregations