@@ -24,13 +24,14 @@ import java.io.IOException
2424
2525import org.apache.logging.log4j.kotlin.logger
2626
27+ import org.ossreviewtoolkit.downloader.VersionControlSystemFactory.Companion.ALL
2728import org.ossreviewtoolkit.model.Package
2829import org.ossreviewtoolkit.model.VcsInfo
2930import org.ossreviewtoolkit.model.VcsType
3031import org.ossreviewtoolkit.model.config.LicenseFilePatterns
32+ import org.ossreviewtoolkit.model.config.VersionControlSystemConfiguration
3133import org.ossreviewtoolkit.model.orEmpty
3234import org.ossreviewtoolkit.utils.common.CommandLineTool
33- import org.ossreviewtoolkit.utils.common.Plugin
3435import org.ossreviewtoolkit.utils.common.collectMessages
3536import org.ossreviewtoolkit.utils.common.uppercaseFirstChar
3637import org.ossreviewtoolkit.utils.ort.ORT_REPO_CONFIG_FILENAME
@@ -44,22 +45,23 @@ abstract class VersionControlSystem(
4445 * the version control system is available.
4546 */
4647 private val commandLineTool : CommandLineTool ? = null
47- ) : Plugin {
48+ ) {
4849 companion object {
49- /* *
50- * All [version control systems][VersionControlSystem] available in the classpath, sorted by their priority.
51- */
52- val ALL by lazy {
53- Plugin .getAll<VersionControlSystem >().toList().sortedByDescending { (_, vcs) -> vcs.priority }.toMap()
54- }
55-
5650 /* *
5751 * Return the applicable VCS for the given [vcsType], or null if none is applicable.
5852 */
59- fun forType (vcsType : VcsType ) =
60- ALL .values.find {
61- it.isAvailable() && it.isApplicableType(vcsType)
53+ fun forType (
54+ vcsType : VcsType ,
55+ versionControlSystemsConfiguration : Map <String , VersionControlSystemConfiguration > = emptyMap()
56+ ) = ALL .values.filter { vcsFactory -> vcsFactory.type == vcsType.toString() }
57+ .map { vcsFactory ->
58+ // If there is a configuration for the VCS type, use it, otherwise create
59+ // the VCS with an empty configuration.
60+ versionControlSystemsConfiguration[vcsFactory.type]?.let { vcsConfig ->
61+ vcsFactory.create(options = vcsConfig.options, secrets = emptyMap())
62+ } ? : vcsFactory.create(options = emptyMap(), secrets = emptyMap())
6263 }
64+ .firstOrNull { vcs -> vcs.isAvailable() }
6365
6466 /* *
6567 * A map to cache the [VersionControlSystem], if any, for previously queried URLs. This helps to speed up
@@ -72,8 +74,10 @@ abstract class VersionControlSystem(
7274 * Return the applicable VCS for the given [vcsUrl], or null if none is applicable.
7375 */
7476 @Synchronized
75- fun forUrl (vcsUrl : String ) =
76- // Do not use getOrPut() here as it cannot handle null values, also see
77+ fun forUrl (
78+ vcsUrl : String ,
79+ versionControlSystemsConfiguration : Map <String , VersionControlSystemConfiguration > = emptyMap()
80+ ) = // Do not use getOrPut() here as it cannot handle null values, also see
7781 // https://youtrack.jetbrains.com/issue/KT-21392.
7882 if (vcsUrl in urlToVcsMap) {
7983 urlToVcsMap[vcsUrl]
@@ -82,12 +86,18 @@ abstract class VersionControlSystem(
8286 when (val type = VcsHost .parseUrl(vcsUrl).type) {
8387 VcsType .UNKNOWN -> {
8488 // ...then eventually try to determine the type also dynamically.
85- ALL .values.find {
86- it.isAvailable() && it.isApplicableUrl(vcsUrl)
87- }
89+ ALL .values
90+ .map { vcsFactory ->
91+ // If there is a configuration for the VCS type, use it, otherwise create
92+ // the VCS with an empty configuration.
93+ versionControlSystemsConfiguration[vcsFactory.type]
94+ ?.let { vcsConfig ->
95+ vcsFactory.create(options = vcsConfig.options, secrets = emptyMap())
96+ } ? : vcsFactory.create(options = emptyMap(), secrets = emptyMap())
97+ }.firstOrNull { vcs -> vcs.isAvailable() && vcs.isApplicableUrl(vcsUrl) }
8898 }
8999
90- else -> forType(type)
100+ else -> forType(type, versionControlSystemsConfiguration )
91101 }.also {
92102 urlToVcsMap[vcsUrl] = it
93103 }
@@ -109,28 +119,31 @@ abstract class VersionControlSystem(
109119 return if (absoluteVcsDirectory in dirToVcsMap) {
110120 dirToVcsMap[absoluteVcsDirectory]
111121 } else {
112- ALL .values.asSequence().mapNotNull {
113- if (it is CommandLineTool && ! it.isInPath()) {
114- null
115- } else {
116- it.getWorkingTree(absoluteVcsDirectory)
117- }
118- }.find {
119- try {
120- it.isValid()
121- } catch (e: IOException ) {
122- e.showStackTrace()
123-
124- logger.debug {
125- " Exception while validating ${it.vcsType} working tree, treating it as non-applicable: " +
126- e.collectMessages()
122+ ALL .values.asSequence()
123+ .map { vcsFactory -> vcsFactory.create(options = emptyMap(), secrets = emptyMap()) }
124+ .mapNotNull {
125+ if (it is CommandLineTool && ! it.isInPath()) {
126+ null
127+ } else {
128+ it.getWorkingTree(absoluteVcsDirectory)
127129 }
128-
129- false
130+ }.find {
131+ try {
132+ it.isValid()
133+ } catch (e: IOException ) {
134+ e.showStackTrace()
135+
136+ logger.debug {
137+ " Exception while validating ${it.vcsType} working tree, " +
138+ " treating it as non-applicable: " +
139+ e.collectMessages()
140+ }
141+
142+ false
143+ }
144+ }.also {
145+ dirToVcsMap[absoluteVcsDirectory] = it
130146 }
131- }.also {
132- dirToVcsMap[absoluteVcsDirectory] = it
133- }
134147 }
135148 }
136149
@@ -165,9 +178,9 @@ abstract class VersionControlSystem(
165178 }
166179
167180 /* *
168- * The priority in which this VCS should be probed. A higher value means a higher priority .
181+ * The type of CVS that is supported by this VCS plugin .
169182 */
170- protected open val priority : Int = 0
183+ abstract val type : String
171184
172185 /* *
173186 * A list of symbolic names that point to the latest revision.
0 commit comments