Search in sources :

Example 1 with Issue

use of net.nemerosa.ontrack.extension.issues.model.Issue in project ontrack by nemerosa.

the class GitLabIssueServiceExtensionTest method no_link_for_all_issues.

@Test
public void no_link_for_all_issues() {
    Issue issue = mock(Issue.class);
    String link = extension.getLinkForAllIssues(configuration, Collections.singletonList(issue));
    assertNull(link);
}
Also used : GitlabIssue(org.gitlab.api.models.GitlabIssue) Issue(net.nemerosa.ontrack.extension.issues.model.Issue) Test(org.junit.Test)

Example 2 with Issue

use of net.nemerosa.ontrack.extension.issues.model.Issue in project ontrack by nemerosa.

the class JIRAServiceExtension method followLinks.

/**
 * Given an issue seed, and a list of link names, follows the given links recursively and
 * puts the associated issues into the {@code collectedIssues} map.
 *
 * @param configuration   JIRA configuration to use to load the issues
 * @param seed            Issue to start from.
 * @param linkNames       Links to follow
 * @param collectedIssues Collected issues, indexed by their key
 */
public void followLinks(JIRAConfiguration configuration, JIRAIssue seed, Set<String> linkNames, Map<String, JIRAIssue> collectedIssues) {
    try (Transaction tx = transactionService.start()) {
        JIRASession session = getJIRASession(tx, configuration);
        // Gets the client from the current session
        JIRAClient client = session.getClient();
        // Puts the seed into the list
        collectedIssues.put(seed.getKey(), seed);
        // Gets the linked issue keys
        seed.getLinks().stream().filter(linkedIssue -> linkNames.contains(linkedIssue.getLinkName())).filter(linkedIssue -> !collectedIssues.containsKey(linkedIssue.getKey())).map(linkedIssue -> client.getIssue(linkedIssue.getKey(), configuration)).forEach(linkedIssue -> followLinks(configuration, linkedIssue, linkNames, collectedIssues));
    }
}
Also used : PropertyService(net.nemerosa.ontrack.model.structure.PropertyService) java.util(java.util) Autowired(org.springframework.beans.factory.annotation.Autowired) JIRAIssue(net.nemerosa.ontrack.extension.jira.model.JIRAIssue) JIRAClient(net.nemerosa.ontrack.extension.jira.client.JIRAClient) StringUtils(org.apache.commons.lang3.StringUtils) Issue(net.nemerosa.ontrack.extension.issues.model.Issue) Transaction(net.nemerosa.ontrack.tx.Transaction) Matcher(java.util.regex.Matcher) MessageAnnotation(net.nemerosa.ontrack.model.support.MessageAnnotation) JIRASessionFactory(net.nemerosa.ontrack.extension.jira.tx.JIRASessionFactory) JIRASession(net.nemerosa.ontrack.extension.jira.tx.JIRASession) AbstractIssueServiceExtension(net.nemerosa.ontrack.extension.issues.support.AbstractIssueServiceExtension) Collectors(java.util.stream.Collectors) Sets(com.google.common.collect.Sets) String.format(java.lang.String.format) Component(org.springframework.stereotype.Component) URLEncoder(java.net.URLEncoder) Validate(org.apache.commons.lang3.Validate) IssueExportServiceFactory(net.nemerosa.ontrack.extension.issues.export.IssueExportServiceFactory) MessageAnnotator(net.nemerosa.ontrack.model.support.MessageAnnotator) RegexMessageAnnotator(net.nemerosa.ontrack.model.support.RegexMessageAnnotator) TransactionService(net.nemerosa.ontrack.tx.TransactionService) Project(net.nemerosa.ontrack.model.structure.Project) UnsupportedEncodingException(java.io.UnsupportedEncodingException) IssueServiceConfiguration(net.nemerosa.ontrack.extension.issues.model.IssueServiceConfiguration) JIRAClient(net.nemerosa.ontrack.extension.jira.client.JIRAClient) Transaction(net.nemerosa.ontrack.tx.Transaction) JIRASession(net.nemerosa.ontrack.extension.jira.tx.JIRASession)

Example 3 with Issue

use of net.nemerosa.ontrack.extension.issues.model.Issue 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 4 with Issue

use of net.nemerosa.ontrack.extension.issues.model.Issue in project ontrack by nemerosa.

the class SVNController method changeLog.

/**
 * Change log export
 */
@RequestMapping(value = "changelog/export", method = RequestMethod.GET)
public ResponseEntity<String> changeLog(IssueChangeLogExportRequest request) {
    // Gets the change log
    SVNChangeLog changeLog = changeLogService.changeLog(request);
    // Gets the issue service
    ConfiguredIssueService configuredIssueService = changeLog.getRepository().getConfiguredIssueService();
    if (configuredIssueService == null) {
        return new ResponseEntity<>("The branch is not configured for issues", HttpStatus.NO_CONTENT);
    }
    // Gets the issue change log
    SVNChangeLogIssues changeLogIssues = changeLogService.getChangeLogIssues(changeLog);
    // List of issues
    List<Issue> issues = changeLogIssues.getList().stream().map(SCMChangeLogIssue::getIssue).collect(Collectors.toList());
    // Exports the change log using the given format
    ExportedIssues exportedChangeLogIssues = configuredIssueService.getIssueServiceExtension().exportIssues(configuredIssueService.getIssueServiceConfiguration(), issues, request);
    // Content type
    HttpHeaders responseHeaders = new HttpHeaders();
    responseHeaders.set("Content-Type", exportedChangeLogIssues.getFormat());
    // Body and headers
    return new ResponseEntity<>(exportedChangeLogIssues.getContent(), responseHeaders, HttpStatus.OK);
}
Also used : ExportedIssues(net.nemerosa.ontrack.extension.issues.export.ExportedIssues) HttpHeaders(org.springframework.http.HttpHeaders) ConfiguredIssueService(net.nemerosa.ontrack.extension.issues.model.ConfiguredIssueService) ResponseEntity(org.springframework.http.ResponseEntity) Issue(net.nemerosa.ontrack.extension.issues.model.Issue) SCMChangeLogIssue(net.nemerosa.ontrack.extension.scm.model.SCMChangeLogIssue)

Example 5 with Issue

use of net.nemerosa.ontrack.extension.issues.model.Issue in project ontrack by nemerosa.

the class IssueServiceUtils method groupIssues.

public static Map<String, List<Issue>> groupIssues(IssueServiceConfiguration issueServiceConfiguration, List<? extends Issue> issues, IssueChangeLogExportRequest request, BiFunction<IssueServiceConfiguration, Issue, Set<String>> issueTypesFn) {
    // Excluded issues
    Set<String> excludedTypes = request.getExcludedTypes();
    // Gets the grouping specification
    Map<String, Set<String>> groupingSpecification = request.getGroupingSpecification();
    // Map of issues, ordered by group
    Map<String, List<Issue>> groupedIssues = new LinkedHashMap<>();
    // Pre-enter the empty group list, in order to guarantee the ordering
    for (String groupName : groupingSpecification.keySet()) {
        groupedIssues.put(groupName, new ArrayList<>());
    }
    // For all issues
    for (Issue issue : issues) {
        // Issue type(s)
        Set<String> issueTypes = issueTypesFn.apply(issueServiceConfiguration, issue);
        // Excluded issue?
        if (Collections.disjoint(excludedTypes, issueTypes)) {
            // Issue is not excluded
            // Gets the groups this issue belongs to
            Set<String> issueGroups = getIssueGroups(issueTypes, groupingSpecification);
            // Target group
            String targetGroup;
            if (issueGroups.size() > 1) {
                throw new IssueExportMoreThanOneGroupException(issue.getKey(), issueGroups);
            } else if (issueGroups.isEmpty()) {
                if (groupingSpecification.isEmpty()) {
                    targetGroup = IssueExportService.NO_GROUP;
                } else {
                    targetGroup = request.getAltGroup();
                }
            } else {
                targetGroup = Iterables.get(issueGroups, 0);
            }
            // Grouping
            List<Issue> issueList = groupedIssues.get(targetGroup);
            if (issueList == null) {
                issueList = new ArrayList<>();
                groupedIssues.put(targetGroup, issueList);
            }
            issueList.add(issue);
        }
    }
    // Prunes empty groups
    Iterator<Map.Entry<String, List<Issue>>> iterator = groupedIssues.entrySet().iterator();
    while (iterator.hasNext()) {
        Map.Entry<String, List<Issue>> entry = iterator.next();
        if (entry.getValue().isEmpty()) {
            iterator.remove();
        }
    }
    // OK
    return groupedIssues;
}
Also used : Issue(net.nemerosa.ontrack.extension.issues.model.Issue) IssueExportMoreThanOneGroupException(net.nemerosa.ontrack.extension.issues.model.IssueExportMoreThanOneGroupException)

Aggregations

Issue (net.nemerosa.ontrack.extension.issues.model.Issue)10 ConfiguredIssueService (net.nemerosa.ontrack.extension.issues.model.ConfiguredIssueService)5 java.util (java.util)2 Collectors (java.util.stream.Collectors)2 ExportedIssues (net.nemerosa.ontrack.extension.issues.export.ExportedIssues)2 SCMChangeLogIssue (net.nemerosa.ontrack.extension.scm.model.SCMChangeLogIssue)2 Project (net.nemerosa.ontrack.model.structure.Project)2 Transaction (net.nemerosa.ontrack.tx.Transaction)2 GitlabIssue (org.gitlab.api.models.GitlabIssue)2 Test (org.junit.Test)2 Autowired (org.springframework.beans.factory.annotation.Autowired)2 HttpHeaders (org.springframework.http.HttpHeaders)2 ResponseEntity (org.springframework.http.ResponseEntity)2 Sets (com.google.common.collect.Sets)1 UnsupportedEncodingException (java.io.UnsupportedEncodingException)1 String.format (java.lang.String.format)1 URLEncoder (java.net.URLEncoder)1 AtomicReference (java.util.concurrent.atomic.AtomicReference)1 Matcher (java.util.regex.Matcher)1 IssueExportServiceFactory (net.nemerosa.ontrack.extension.issues.export.IssueExportServiceFactory)1