@@ -29,8 +29,9 @@ import org.ossreviewtoolkit.model.Package
29
29
import org.ossreviewtoolkit.model.VcsInfo
30
30
import org.ossreviewtoolkit.model.VcsType
31
31
import org.ossreviewtoolkit.model.config.LicenseFilePatterns
32
- import org.ossreviewtoolkit.model.config.PluginConfiguration
33
32
import org.ossreviewtoolkit.model.orEmpty
33
+ import org.ossreviewtoolkit.plugins.api.Plugin
34
+ import org.ossreviewtoolkit.plugins.api.PluginConfig
34
35
import org.ossreviewtoolkit.utils.common.CommandLineTool
35
36
import org.ossreviewtoolkit.utils.common.collectMessages
36
37
import org.ossreviewtoolkit.utils.common.uppercaseFirstChar
@@ -39,19 +40,22 @@ import org.ossreviewtoolkit.utils.ort.showStackTrace
39
40
40
41
import org.semver4j.Semver
41
42
42
- abstract class VersionControlSystem {
43
+ abstract class VersionControlSystem : Plugin {
43
44
companion object {
45
+ private fun getAllVcsByPriority (configs : Map <String , PluginConfig >) =
46
+ ALL .map { (id, factory) ->
47
+ val config = configs[id] ? : PluginConfig ()
48
+ factory.create(config)
49
+ }.sortedByDescending {
50
+ it.priority
51
+ }
52
+
44
53
/* *
45
54
* Return the applicable VCS for the given [vcsType], or null if none is applicable.
46
55
*/
47
- fun forType (vcsType : VcsType , configs : Map <String , PluginConfiguration > = emptyMap()) =
48
- ALL .values.filter { factory ->
49
- VcsType .forName(factory.type) == vcsType
50
- }.asSequence().map { factory ->
51
- val config = configs[factory.type]
52
- factory.create(options = config?.options.orEmpty(), secrets = emptyMap())
53
- }.find { vcs ->
54
- vcs.isAvailable()
56
+ fun forType (vcsType : VcsType , configs : Map <String , PluginConfig > = emptyMap()) =
57
+ getAllVcsByPriority(configs).find { vcs ->
58
+ vcs.type == vcsType && vcs.isAvailable()
55
59
}
56
60
57
61
/* *
@@ -65,7 +69,7 @@ abstract class VersionControlSystem {
65
69
* Return the applicable VCS for the given [vcsUrl], or null if none is applicable.
66
70
*/
67
71
@Synchronized
68
- fun forUrl (vcsUrl : String , configs : Map <String , PluginConfiguration > = emptyMap()) =
72
+ fun forUrl (vcsUrl : String , configs : Map <String , PluginConfig > = emptyMap()) =
69
73
// Do not use getOrPut() here as it cannot handle null values, also see
70
74
// https://youtrack.jetbrains.com/issue/KT-21392.
71
75
if (vcsUrl in urlToVcsMap) {
@@ -75,11 +79,8 @@ abstract class VersionControlSystem {
75
79
when (val type = VcsHost .parseUrl(vcsUrl).type) {
76
80
VcsType .UNKNOWN -> {
77
81
// ...then eventually try to determine the type also dynamically.
78
- ALL .values.asSequence().map { factory ->
79
- val config = configs[factory.type]
80
- factory.create(options = config?.options.orEmpty(), secrets = emptyMap())
81
- }.find { vcs ->
82
- vcs.isAvailable() && vcs.isApplicableUrl(vcsUrl)
82
+ getAllVcsByPriority(configs).find { vcs ->
83
+ vcs.isApplicableUrl(vcsUrl) && vcs.isAvailable()
83
84
}
84
85
}
85
86
@@ -99,16 +100,13 @@ abstract class VersionControlSystem {
99
100
* Return the applicable VCS working tree for the given [vcsDirectory], or null if none is applicable.
100
101
*/
101
102
@Synchronized
102
- fun forDirectory (vcsDirectory : File , configs : Map <String , PluginConfiguration > = emptyMap()): WorkingTree ? {
103
+ fun forDirectory (vcsDirectory : File , configs : Map <String , PluginConfig > = emptyMap()): WorkingTree ? {
103
104
val absoluteVcsDirectory = vcsDirectory.absoluteFile
104
105
105
106
return if (absoluteVcsDirectory in dirToVcsMap) {
106
107
dirToVcsMap[absoluteVcsDirectory]
107
108
} else {
108
- ALL .values.asSequence().map { factory ->
109
- val config = configs[factory.type]
110
- factory.create(options = config?.options.orEmpty(), secrets = emptyMap())
111
- }.mapNotNull {
109
+ getAllVcsByPriority(configs).mapNotNull {
112
110
if (it is CommandLineTool && ! it.isInPath()) {
113
111
null
114
112
} else {
@@ -168,6 +166,12 @@ abstract class VersionControlSystem {
168
166
*/
169
167
abstract val type: VcsType
170
168
169
+ /* *
170
+ * The [priority] defines the order in which VCS implementaions are to be used. A higher value means a higher
171
+ * priority.
172
+ */
173
+ abstract val priority: Int
174
+
171
175
/* *
172
176
* A list of symbolic names that point to the latest revision.
173
177
*/
0 commit comments