Search in sources :

Example 1 with ConfiguredIssueService

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());
}
Also used : ConfiguredIssueService(net.nemerosa.ontrack.extension.issues.model.ConfiguredIssueService) GitRepositoryClient(net.nemerosa.ontrack.git.GitRepositoryClient) RevCommit(org.eclipse.jgit.revwalk.RevCommit) SCMIssueCommitBranchInfo(net.nemerosa.ontrack.extension.scm.model.SCMIssueCommitBranchInfo)

Example 2 with ConfiguredIssueService

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);
}
Also used : java.util(java.util) SCMUtilsService(net.nemerosa.ontrack.extension.scm.service.SCMUtilsService) SVNBranchConfigurationProperty(net.nemerosa.ontrack.extension.svn.property.SVNBranchConfigurationProperty) SVNProjectConfigurationPropertyType(net.nemerosa.ontrack.extension.svn.property.SVNProjectConfigurationPropertyType) SVNProjectConfigurationProperty(net.nemerosa.ontrack.extension.svn.property.SVNProjectConfigurationProperty) Autowired(org.springframework.beans.factory.annotation.Autowired) ConfiguredBuildSvnRevisionLink(net.nemerosa.ontrack.extension.svn.support.ConfiguredBuildSvnRevisionLink) AtomicReference(java.util.concurrent.atomic.AtomicReference) Collectors(java.util.stream.Collectors) Issue(net.nemerosa.ontrack.extension.issues.model.Issue) ConfiguredIssueService(net.nemerosa.ontrack.extension.issues.model.ConfiguredIssueService) TRevision(net.nemerosa.ontrack.extension.svn.db.TRevision) SCMIssueCommitBranchInfo(net.nemerosa.ontrack.extension.scm.model.SCMIssueCommitBranchInfo) SVNRepository(net.nemerosa.ontrack.extension.svn.db.SVNRepository) Service(org.springframework.stereotype.Service) net.nemerosa.ontrack.model.structure(net.nemerosa.ontrack.model.structure) SVNIssueRevisionDao(net.nemerosa.ontrack.extension.svn.db.SVNIssueRevisionDao) SVNRevisionDao(net.nemerosa.ontrack.extension.svn.db.SVNRevisionDao) net.nemerosa.ontrack.extension.svn.model(net.nemerosa.ontrack.extension.svn.model) SVNBranchConfigurationPropertyType(net.nemerosa.ontrack.extension.svn.property.SVNBranchConfigurationPropertyType) Issue(net.nemerosa.ontrack.extension.issues.model.Issue) TRevision(net.nemerosa.ontrack.extension.svn.db.TRevision) SVNRepository(net.nemerosa.ontrack.extension.svn.db.SVNRepository) ConfiguredIssueService(net.nemerosa.ontrack.extension.issues.model.ConfiguredIssueService) AtomicReference(java.util.concurrent.atomic.AtomicReference) SCMIssueCommitBranchInfo(net.nemerosa.ontrack.extension.scm.model.SCMIssueCommitBranchInfo)

Example 3 with ConfiguredIssueService

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);
}
Also used : ConfiguredIssueService(net.nemerosa.ontrack.extension.issues.model.ConfiguredIssueService) SVNChangeLogRevision(net.nemerosa.ontrack.extension.svn.model.SVNChangeLogRevision)

Example 4 with ConfiguredIssueService

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);
        });
    }
}
Also used : java.util(java.util) SVNUtils(net.nemerosa.ontrack.extension.svn.support.SVNUtils) LoggerFactory(org.slf4j.LoggerFactory) LocalDateTime(java.time.LocalDateTime) Autowired(org.springframework.beans.factory.annotation.Autowired) org.tmatesoft.svn.core(org.tmatesoft.svn.core) StringUtils(org.apache.commons.lang3.StringUtils) net.nemerosa.ontrack.extension.svn.db(net.nemerosa.ontrack.extension.svn.db) Transaction(net.nemerosa.ontrack.tx.Transaction) Service(org.springframework.stereotype.Service) StartupService(net.nemerosa.ontrack.model.support.StartupService) net.nemerosa.ontrack.job(net.nemerosa.ontrack.job) SVNConfiguration(net.nemerosa.ontrack.extension.svn.model.SVNConfiguration) Ack(net.nemerosa.ontrack.model.Ack) Logger(org.slf4j.Logger) TransactionCallbackWithoutResult(org.springframework.transaction.support.TransactionCallbackWithoutResult) IssueServiceExtension(net.nemerosa.ontrack.extension.issues.IssueServiceExtension) GlobalSettings(net.nemerosa.ontrack.model.security.GlobalSettings) ConfigurationServiceListener(net.nemerosa.ontrack.model.support.ConfigurationServiceListener) LastRevisionInfo(net.nemerosa.ontrack.extension.svn.model.LastRevisionInfo) IssueServiceRegistry(net.nemerosa.ontrack.extension.issues.IssueServiceRegistry) ApplicationContext(org.springframework.context.ApplicationContext) Collectors(java.util.stream.Collectors) SVNClient(net.nemerosa.ontrack.extension.svn.client.SVNClient) ConfiguredIssueService(net.nemerosa.ontrack.extension.issues.model.ConfiguredIssueService) Consumer(java.util.function.Consumer) SecurityService(net.nemerosa.ontrack.model.security.SecurityService) Time(net.nemerosa.ontrack.common.Time) SVNIndexationException(net.nemerosa.ontrack.extension.svn.model.SVNIndexationException) PlatformTransactionManager(org.springframework.transaction.PlatformTransactionManager) SVNRevision(org.tmatesoft.svn.core.wc.SVNRevision) TransactionTemplate(org.springframework.transaction.support.TransactionTemplate) TransactionStatus(org.springframework.transaction.TransactionStatus) TransactionService(net.nemerosa.ontrack.tx.TransactionService) IssueServiceConfiguration(net.nemerosa.ontrack.extension.issues.model.IssueServiceConfiguration) ConfiguredIssueService(net.nemerosa.ontrack.extension.issues.model.ConfiguredIssueService) IssueServiceExtension(net.nemerosa.ontrack.extension.issues.IssueServiceExtension) IssueServiceConfiguration(net.nemerosa.ontrack.extension.issues.model.IssueServiceConfiguration)

Example 5 with ConfiguredIssueService

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);
    }
}
Also used : IssueServiceConfigurationRepresentation(net.nemerosa.ontrack.extension.issues.model.IssueServiceConfigurationRepresentation) ConfiguredIssueService(net.nemerosa.ontrack.extension.issues.model.ConfiguredIssueService) Transaction(net.nemerosa.ontrack.tx.Transaction) SVNRepository(net.nemerosa.ontrack.extension.svn.db.SVNRepository) Transactional(org.springframework.transaction.annotation.Transactional)

Aggregations

ConfiguredIssueService (net.nemerosa.ontrack.extension.issues.model.ConfiguredIssueService)12 Issue (net.nemerosa.ontrack.extension.issues.model.Issue)5 SVNRepository (net.nemerosa.ontrack.extension.svn.db.SVNRepository)3 Transaction (net.nemerosa.ontrack.tx.Transaction)3 java.util (java.util)2 Collectors (java.util.stream.Collectors)2 ExportedIssues (net.nemerosa.ontrack.extension.issues.export.ExportedIssues)2 IssueServiceConfigurationRepresentation (net.nemerosa.ontrack.extension.issues.model.IssueServiceConfigurationRepresentation)2 SCMChangeLogIssue (net.nemerosa.ontrack.extension.scm.model.SCMChangeLogIssue)2 SCMIssueCommitBranchInfo (net.nemerosa.ontrack.extension.scm.model.SCMIssueCommitBranchInfo)2 Autowired (org.springframework.beans.factory.annotation.Autowired)2 HttpHeaders (org.springframework.http.HttpHeaders)2 ResponseEntity (org.springframework.http.ResponseEntity)2 Service (org.springframework.stereotype.Service)2 LocalDateTime (java.time.LocalDateTime)1 AtomicReference (java.util.concurrent.atomic.AtomicReference)1 Consumer (java.util.function.Consumer)1 Time (net.nemerosa.ontrack.common.Time)1 IssueServiceExtension (net.nemerosa.ontrack.extension.issues.IssueServiceExtension)1 IssueServiceRegistry (net.nemerosa.ontrack.extension.issues.IssueServiceRegistry)1