Search in sources :

Example 1 with SVNRepository

use of net.nemerosa.ontrack.extension.svn.db.SVNRepository 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 2 with SVNRepository

use of net.nemerosa.ontrack.extension.svn.db.SVNRepository in project ontrack by nemerosa.

the class SVNSyncServiceImpl method sync.

protected void sync(Branch branch, JobRunListener runListener) {
    // Number of created builds
    AtomicInteger createdBuilds = new AtomicInteger();
    // Gets the configuration property
    SVNSyncProperty syncProperty = propertyService.getProperty(branch, SVNSyncPropertyType.class).getValue();
    // Gets the project configurations for SVN
    SVNProjectConfigurationProperty projectConfigurationProperty = propertyService.getProperty(branch.getProject(), SVNProjectConfigurationPropertyType.class).getValue();
    // Gets the branch configurations for SVN
    SVNBranchConfigurationProperty branchConfigurationProperty = propertyService.getProperty(branch, SVNBranchConfigurationPropertyType.class).getValue();
    // SVN repository configuration
    SVNRepository repository = svnService.getRepository(projectConfigurationProperty.getConfiguration().getName());
    // Link
    ConfiguredBuildSvnRevisionLink<?> revisionLink = buildSvnRevisionLinkService.getConfiguredBuildSvnRevisionLink(branchConfigurationProperty.getBuildRevisionLink());
    // Gets the base path
    svnService.getBasePath(repository, branchConfigurationProperty.getCuredBranchPath()).ifPresent(basePath -> {
        // Tags path
        String tagsPath = basePath + "/tags";
        // Gets the list of tags from the copy events, filtering them
        List<TCopyEvent> copies = eventDao.findCopies(// In this repository
        repository.getId(), // from path...
        branchConfigurationProperty.getCuredBranchPath(), // to path with prefix...
        tagsPath, // filter the target path with...
        (copyEvent) -> getBuildNameFromPath(tagsPath, revisionLink, copyEvent.copyToLocation()).isPresent());
        // Creates the builds (in a transaction)
        for (TCopyEvent copy : copies) {
            Optional<Build> build = transactionTemplate.execute(status -> createBuild(tagsPath, syncProperty, branch, copy, revisionLink, repository));
            // Completes the information collection (build created)
            if (build.isPresent()) {
                int count = createdBuilds.incrementAndGet();
                runListener.message("Running build synchronisation from SVN for branch %s/%s: %d build(s) created", branch.getProject().getName(), branch.getName(), count);
            }
        }
    });
}
Also used : TCopyEvent(net.nemerosa.ontrack.extension.svn.db.TCopyEvent) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) SVNRepository(net.nemerosa.ontrack.extension.svn.db.SVNRepository)

Example 3 with SVNRepository

use of net.nemerosa.ontrack.extension.svn.db.SVNRepository in project ontrack by nemerosa.

the class SVNChangeLogServiceImpl method getChangeLogRevisions.

@Override
@Transactional
public SVNChangeLogRevisions getChangeLogRevisions(SVNChangeLog changeLog) {
    // Reference
    Collection<SVNChangeLogReference> references = changeLog.getChangeLogReferences();
    // No difference?
    if (references.isEmpty()) {
        return SVNChangeLogRevisions.none();
    }
    // SVN transaction
    try (Transaction ignored = transactionService.start()) {
        List<SVNChangeLogRevision> revisions = new ArrayList<>();
        for (SVNChangeLogReference reference : references) {
            if (!reference.isNone()) {
                SVNRepository repository = changeLog.getRepository();
                // List of log entries
                SVNLogEntryCollector logEntryCollector = new SVNLogEntryCollector();
                // SVN change log
                svnClient.log(repository, SVNUtils.toURL(repository.getUrl(reference.getPath())), SVNRevision.create(reference.getEnd()), SVNRevision.create(reference.getStart() + 1), SVNRevision.create(reference.getEnd()), // Stops on copy
                true, // No path discovering (yet)
                false, // no limit
                0L, // Includes merged revisions
                true, logEntryCollector);
                // Loops through all SVN log entries, taking the merged revisions into account
                int level = 0;
                for (SVNLogEntry svnEntry : logEntryCollector.getEntries()) {
                    long revision = svnEntry.getRevision();
                    if (SVNRevision.isValidRevisionNumber(revision)) {
                        // Conversion
                        SVNChangeLogRevision entry = createChangeLogRevision(repository, reference.getPath(), level, svnEntry);
                        // Adds it to the list
                        revisions.add(entry);
                        // New parent?
                        if (svnEntry.hasChildren()) {
                            level++;
                        }
                    } else {
                        level--;
                    }
                }
            }
        }
        // Sorting the revisions
        Collections.sort(revisions, // From the newest revision to the oldest
        (o1, o2) -> Long.compare(o2.getRevision(), o1.getRevision()));
        // OK
        return new SVNChangeLogRevisions(revisions);
    }
}
Also used : SVNLogEntryCollector(net.nemerosa.ontrack.extension.svn.support.SVNLogEntryCollector) Transaction(net.nemerosa.ontrack.tx.Transaction) SVNLogEntry(org.tmatesoft.svn.core.SVNLogEntry) SVNRepository(net.nemerosa.ontrack.extension.svn.db.SVNRepository) Transactional(org.springframework.transaction.annotation.Transactional)

Example 4 with SVNRepository

use of net.nemerosa.ontrack.extension.svn.db.SVNRepository 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)

Example 5 with SVNRepository

use of net.nemerosa.ontrack.extension.svn.db.SVNRepository in project ontrack by nemerosa.

the class SVNConfigurationServiceImpl method validate.

@Override
protected ConnectionResult validate(SVNConfiguration configuration) {
    // No trailing slash
    String url = configuration.getUrl();
    if (StringUtils.endsWith(url, "/")) {
        throw new SVNURLFormatException("The Subversion URL must not end with a slash: %s", url);
    }
    try (Transaction ignored = transactionService.start()) {
        // Creates a repository
        SVNRepository repository = SVNRepository.of(0, configuration, null);
        // Configuration URL
        SVNURL svnurl = SVNUtils.toURL(configuration.getUrl());
        // Connection to the root
        if (!svnClient.exists(repository, svnurl, SVNRevision.HEAD)) {
            return ConnectionResult.error(configuration.getUrl() + " does not exist.");
        }
        // Gets base info
        SVNInfo info = svnClient.getInfo(repository, svnurl, SVNRevision.HEAD);
        // Checks the repository root
        if (!Objects.equals(info.getRepositoryRootURL(), svnurl)) {
            return ConnectionResult.error(configuration.getUrl() + " must be the root of the repository.");
        }
        // OK
        return ConnectionResult.ok();
    } catch (Exception ex) {
        return ConnectionResult.error(ex.getMessage());
    }
}
Also used : Transaction(net.nemerosa.ontrack.tx.Transaction) SVNURL(org.tmatesoft.svn.core.SVNURL) SVNURLFormatException(net.nemerosa.ontrack.extension.svn.model.SVNURLFormatException) SVNRepository(net.nemerosa.ontrack.extension.svn.db.SVNRepository) SVNInfo(org.tmatesoft.svn.core.wc.SVNInfo) ConfigurationValidationException(net.nemerosa.ontrack.model.support.ConfigurationValidationException) SVNURLFormatException(net.nemerosa.ontrack.extension.svn.model.SVNURLFormatException)

Aggregations

SVNRepository (net.nemerosa.ontrack.extension.svn.db.SVNRepository)14 Transaction (net.nemerosa.ontrack.tx.Transaction)6 ConfiguredIssueService (net.nemerosa.ontrack.extension.issues.model.ConfiguredIssueService)3 SCMBuildView (net.nemerosa.ontrack.extension.scm.model.SCMBuildView)3 Test (org.junit.Test)3 Transactional (org.springframework.transaction.annotation.Transactional)3 TCopyEvent (net.nemerosa.ontrack.extension.svn.db.TCopyEvent)2 SVNBranchConfigurationProperty (net.nemerosa.ontrack.extension.svn.property.SVNBranchConfigurationProperty)2 SVNProjectConfigurationProperty (net.nemerosa.ontrack.extension.svn.property.SVNProjectConfigurationProperty)2 SVNURL (org.tmatesoft.svn.core.SVNURL)2 java.util (java.util)1 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)1 AtomicReference (java.util.concurrent.atomic.AtomicReference)1 Collectors (java.util.stream.Collectors)1 EntityInformation (net.nemerosa.ontrack.extension.api.model.EntityInformation)1 Issue (net.nemerosa.ontrack.extension.issues.model.Issue)1 IssueServiceConfigurationRepresentation (net.nemerosa.ontrack.extension.issues.model.IssueServiceConfigurationRepresentation)1 SCMIssueCommitBranchInfo (net.nemerosa.ontrack.extension.scm.model.SCMIssueCommitBranchInfo)1 SCMUtilsService (net.nemerosa.ontrack.extension.scm.service.SCMUtilsService)1 SVNIssueRevisionDao (net.nemerosa.ontrack.extension.svn.db.SVNIssueRevisionDao)1