Skip to content

Commit

Permalink
vcs: Move out the Subversion WorkingTree to a separate file
Browse files Browse the repository at this point in the history
This increases reability and implicitly gives the formerly anonymous class
a name so it can later be referred to. Slightly reorder functions while at
it, so overridden function fo first and private functions go last.

Signed-off-by: Sebastian Schuberth <[email protected]>
  • Loading branch information
sschuberth committed Sep 23, 2022
1 parent fe88b1c commit b8b0463
Show file tree
Hide file tree
Showing 2 changed files with 95 additions and 59 deletions.
60 changes: 1 addition & 59 deletions downloader/src/main/kotlin/vcs/Subversion.kt
Original file line number Diff line number Diff line change
Expand Up @@ -69,65 +69,7 @@ class Subversion : VersionControlSystem() {

override fun getDefaultBranchName(url: String) = "trunk"

override fun getWorkingTree(vcsDirectory: File) =
object : WorkingTree(vcsDirectory, type) {
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

private fun listRemoteRefs(namespace: String): List<String> {
val refs = mutableListOf<String>()
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 $type repository at $remoteUrl." }
}

return refs
}

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

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

private fun doSvnInfo() =
runCatching { clientManager.wcClient.doInfo(workingDir, SVNRevision.WORKING) }.getOrNull()
}
override fun getWorkingTree(vcsDirectory: File) = SubversionWorkingTree(vcsDirectory, type, clientManager)

override fun isApplicableUrlInternal(vcsUrl: String) =
try {
Expand Down
94 changes: 94 additions & 0 deletions downloader/src/main/kotlin/vcs/SubversionWorkingTree.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
/*
* Copyright (C) 2022 The ORT Project Authors (see <https://github.com/oss-review-toolkit/ort/blob/main/NOTICE>)
*
* 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.downloader.vcs

import java.io.File

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

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<String> {
val refs = mutableListOf<String>()
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()

Subversion.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()
}

0 comments on commit b8b0463

Please sign in to comment.