All Downloads are FREE. Search and download functionalities are using the official Maven repository.

toolkit.plugins.versioncontrolsystems.subversion-version-control-system.44.0.0.source-code.SubversionWorkingTree.kt Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (C) 2022 The ORT Project Authors (see )
 *
 * 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
 *
 *     https://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.
 *
 * SPDX-License-Identifier: Apache-2.0
 * License-Filename: LICENSE
 */

package org.ossreviewtoolkit.plugins.versioncontrolsystems.subversion

import java.io.File

import org.apache.logging.log4j.kotlin.logger

import org.ossreviewtoolkit.downloader.WorkingTree
import org.ossreviewtoolkit.model.VcsType
import org.ossreviewtoolkit.utils.ort.showStackTrace

import org.tmatesoft.svn.core.SVNException
import org.tmatesoft.svn.core.SVNURL
import org.tmatesoft.svn.core.wc.SVNClientManager
import org.tmatesoft.svn.core.wc.SVNRevision

internal class SubversionWorkingTree(
    workingDir: File,
    vcsType: VcsType,
    private val clientManager: SVNClientManager
) : WorkingTree(workingDir, vcsType) {
    private val directoryNamespaces = listOf("branches", "tags", "trunk", "wiki")

    override fun isValid(): Boolean {
        if (!workingDir.isDirectory) {
            return false
        }

        return doSvnInfo() != null
    }

    override fun isShallow() = false

    override fun getRemoteUrl() = doSvnInfo()?.url?.toString().orEmpty()

    override fun getRevision() = doSvnInfo()?.committedRevision?.number?.toString().orEmpty()

    override fun getRootPath() = doSvnInfo()?.workingCopyRoot ?: workingDir

    override fun listRemoteBranches() = listRemoteRefs("branches")

    override fun listRemoteTags() = listRemoteRefs("tags")

    private fun listRemoteRefs(namespace: String): List {
        val refs = mutableListOf()
        val remoteUrl = getRemoteUrl()

        val projectRoot = if (directoryNamespaces.any { "/$it/" in remoteUrl }) {
            doSvnInfo()?.repositoryRootURL?.toString().orEmpty()
        } else {
            remoteUrl
        }

        // We assume a single project directory layout.
        val svnUrl = SVNURL.parseURIEncoded("$projectRoot/$namespace")

        try {
            clientManager.logClient.doList(
                svnUrl,
                SVNRevision.HEAD,
                SVNRevision.HEAD,
                /* fetchLocks = */ false,
                /* recursive = */ false
            ) { dirEntry ->
                if (dirEntry.name.isNotEmpty()) refs += "$namespace/${dirEntry.relativePath}"
            }
        } catch (e: SVNException) {
            e.showStackTrace()

            logger.info { "Unable to list remote refs for $vcsType repository at $remoteUrl." }
        }

        return refs
    }

    private fun doSvnInfo() = runCatching { clientManager.wcClient.doInfo(workingDir, SVNRevision.WORKING) }.getOrNull()
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy