Skip to content

Commit ed2f67e

Browse files
committed
feat(spdx): Expose the validation of license text files' existence
ORT has a complicate logic to search for a file containing the full license text of a given license: several search paths are tried. Unfortunately, the latter are not exposed, making it hard for an alternative `LicenseTextProvider` to have the same logic. Additionally, the current code assumes that the license files are on a local storage and the I/Os are therefore cheap. To allow the current utility function to be used with a `LicenseTextProvider` that works with license text files stored on a network storage, this commit exposes the validation function. Signed-off-by: Nicolas Nobelis <[email protected]>
1 parent a093540 commit ed2f67e

File tree

2 files changed

+46
-3
lines changed

2 files changed

+46
-3
lines changed

utils/spdx/src/main/kotlin/Utils.kt

+30-3
Original file line numberDiff line numberDiff line change
@@ -116,15 +116,42 @@ fun getLicenseText(
116116
licenseTextDirectories: List<File> = emptyList()
117117
): String? = getLicenseTextReader(id, handleExceptions, addScanCodeLicenseTextsDir(licenseTextDirectories))?.invoke()
118118

119+
/**
120+
* Get a lambda that allows to read the full text of the license with the provided SPDX [id]. Several locations are
121+
* searched for the license text: [licenseTextDirectories], the ScanCode license texts directory, the ORT's list of SPDX
122+
* licenses and the resources of this module. If [handleExceptions] is enabled, the [id] may also refer to a license
123+
* with an SPDX exception.
124+
*/
119125
fun getLicenseTextReader(
120126
id: String,
121127
handleExceptions: Boolean = false,
122128
licenseTextDirectories: List<File> = emptyList()
129+
): (() -> String)? {
130+
return getLicenseTextReader(id, handleExceptions, licenseTextDirectories) { dir, filename ->
131+
dir.resolve(filename).takeIf { it.isFile }
132+
}
133+
}
134+
135+
/**
136+
* Get a lambda that allows to read the full text of the license with the provided SPDX [id]. Several locations are
137+
* searched for the license text: [licenseTextDirectories], the ScanCode license texts directory, the ORT's list of SPDX
138+
* licenses and the resources of this module. If [handleExceptions] is enabled, the [id] may also refer to a license
139+
* with an SPDX exception.
140+
* [validateFile] is a lambda that is called with the directory and filename to look if the license file exists. It
141+
* should return the file if it exists, null otherwise.
142+
*/
143+
fun getLicenseTextReader(
144+
id: String,
145+
handleExceptions: Boolean = false,
146+
licenseTextDirectories: List<File> = emptyList(),
147+
validateFile: (File, String) -> File?
123148
): (() -> String)? {
124149
return if (id.startsWith(LICENSE_REF_PREFIX)) {
125150
getLicenseTextResource(id)?.let { { it.readText() } }
126151
?: addScanCodeLicenseTextsDir(licenseTextDirectories).firstNotNullOfOrNull { dir ->
127-
getLicenseTextFile(id, dir)?.let { file ->
152+
getLicenseTextFile(id) { filename ->
153+
validateFile(dir, filename)
154+
}?.let { file ->
128155
{
129156
file.readText().removeYamlFrontMatter()
130157
}
@@ -140,7 +167,7 @@ private fun getLicenseTextResource(id: String): URL? = object {}.javaClass.getRe
140167

141168
private val LICENSE_REF_FILENAME_REGEX by lazy { Regex("^$LICENSE_REF_PREFIX\\w+-") }
142169

143-
private fun getLicenseTextFile(id: String, dir: File): File? =
170+
fun getLicenseTextFile(id: String, validateFile: (String) -> File?): File? =
144171
id.replace(LICENSE_REF_FILENAME_REGEX, "").let { idWithoutLicenseRefNamespace ->
145172
listOfNotNull(
146173
id,
@@ -153,7 +180,7 @@ private fun getLicenseTextFile(id: String, dir: File): File? =
153180
id == "LicenseRef-scancode-x11-xconsortium-veillard"
154181
}
155182
).firstNotNullOfOrNull { filename ->
156-
dir.resolve(filename).takeIf { it.isFile }
183+
validateFile(filename)
157184
}
158185
}
159186

utils/spdx/src/test/kotlin/UtilsTest.kt

+16
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,22 @@ class UtilsTest : WordSpec() {
198198
}
199199
}
200200

201+
"getLicenseTextReader provided a custom dir" should {
202+
"call the custom validation lambda if provided" {
203+
val id = "LicenseRef-ort-abc"
204+
val text = "a\nb\nc"
205+
val candidateFilenames = mutableListOf<String>()
206+
207+
setupTempFile(id, text)
208+
209+
getLicenseTextReader(id, true, listOf(tempDir)) { directory, filename ->
210+
candidateFilenames += filename
211+
directory.resolve(filename).takeIf { it.isFile }
212+
}?.invoke() shouldBe text
213+
candidateFilenames shouldBe listOf("LicenseRef-ort-abc")
214+
}
215+
}
216+
201217
"removeYamlFrontMatter" should {
202218
"remove a YAML front matter" {
203219
val text = """

0 commit comments

Comments
 (0)