From 5dd19ffb2dee5414060c69c5bfb7d0818231e55a Mon Sep 17 00:00:00 2001 From: Oliver Heger Date: Fri, 2 Aug 2024 15:12:23 +0200 Subject: [PATCH] refactor(bazel): Simplify creating Bazel module registries There were multiple places that checked and transformed URLs to create either local or remote Bazel module registry service instances. Centralize this logic, so that redundancy can be reduced. Signed-off-by: Oliver Heger --- .../kotlin/LocalBazelModuleRegistryService.kt | 23 +++++++++++++++++++ .../RemoteBazelModuleRegistryService.kt | 8 ++++++- .../bazel/src/main/kotlin/Bazel.kt | 20 +++------------- .../CompositeBazelModuleRegistryService.kt | 20 ++++------------ 4 files changed, 38 insertions(+), 33 deletions(-) diff --git a/clients/bazel-module-registry/src/main/kotlin/LocalBazelModuleRegistryService.kt b/clients/bazel-module-registry/src/main/kotlin/LocalBazelModuleRegistryService.kt index f1c69cc97ca6..6bb39b31ce57 100644 --- a/clients/bazel-module-registry/src/main/kotlin/LocalBazelModuleRegistryService.kt +++ b/clients/bazel-module-registry/src/main/kotlin/LocalBazelModuleRegistryService.kt @@ -24,12 +24,35 @@ import java.io.File import kotlinx.serialization.Serializable import kotlinx.serialization.json.decodeFromStream +import org.apache.logging.log4j.kotlin.logger + private const val BAZEL_MODULES_DIR = "modules" /** * A Bazel registry which is located on the local file system. */ class LocalBazelModuleRegistryService(directory: File) : BazelModuleRegistryService { + companion object { + /** A prefix for URLs pointing to local files. */ + private const val FILE_URL_PREFIX = "file://" + + /** Constant for a placeholder that is replaced by the current project directory. */ + private const val WORKSPACE_PLACEHOLDER = "%workspace%" + + /** + * Create a [LocalBazelModuleRegistryService] if the given [url] points to a local file. In this case, + * also replace the placeholder for the workspace by the given [projectDir]. Return *null* for all other URLs. + */ + fun createForLocalUrl(url: String?, projectDir: File): LocalBazelModuleRegistryService? = + url.takeIf { it?.startsWith(FILE_URL_PREFIX) == true }?.let { fileUrl -> + val directory = fileUrl.removePrefix(FILE_URL_PREFIX) + .replace(WORKSPACE_PLACEHOLDER, projectDir.absolutePath) + + logger.info { "Creating local Bazel module registry at '$directory'." } + LocalBazelModuleRegistryService(File(directory)) + } + } + private val moduleDirectory: File private val bazelRegistry: BazelRegistry diff --git a/clients/bazel-module-registry/src/main/kotlin/RemoteBazelModuleRegistryService.kt b/clients/bazel-module-registry/src/main/kotlin/RemoteBazelModuleRegistryService.kt index c632530aca1d..fdc2e96b3111 100644 --- a/clients/bazel-module-registry/src/main/kotlin/RemoteBazelModuleRegistryService.kt +++ b/clients/bazel-module-registry/src/main/kotlin/RemoteBazelModuleRegistryService.kt @@ -22,6 +22,8 @@ package org.ossreviewtoolkit.clients.bazelmoduleregistry import okhttp3.MediaType.Companion.toMediaType import okhttp3.OkHttpClient +import org.apache.logging.log4j.kotlin.logger + import retrofit2.Retrofit import retrofit2.converter.kotlinx.serialization.asConverterFactory import retrofit2.http.GET @@ -46,9 +48,13 @@ interface RemoteBazelModuleRegistryService : BazelModuleRegistryService { val bmrClient = client ?: OkHttpClient() val contentType = "application/json".toMediaType() + val baseUrl = url ?: DEFAULT_URL + + logger.info { "Creating remote Bazel module registry at '$baseUrl'." } + val retrofit = Retrofit.Builder() .client(bmrClient) - .baseUrl(url ?: DEFAULT_URL) + .baseUrl(baseUrl) .addConverterFactory(JSON.asConverterFactory(contentType)) .build() diff --git a/plugins/package-managers/bazel/src/main/kotlin/Bazel.kt b/plugins/package-managers/bazel/src/main/kotlin/Bazel.kt index 901c82dee355..be1e0b09ca7c 100644 --- a/plugins/package-managers/bazel/src/main/kotlin/Bazel.kt +++ b/plugins/package-managers/bazel/src/main/kotlin/Bazel.kt @@ -145,27 +145,13 @@ class Bazel( if (lockfile.flags != null) { val registryUrl = lockfile.registryUrl() - return registryUrl.withoutPrefix("file://")?.let { - val localRegistryURL = it.replace("%workspace%", projectDir.absolutePath) - logger.info { - "Using local Bazel module registry at '$localRegistryURL'." - } - - LocalBazelModuleRegistryService(File(localRegistryURL)) - } ?: RemoteBazelModuleRegistryService.create(registryUrl) + return LocalBazelModuleRegistryService.createForLocalUrl(registryUrl, projectDir) + ?: RemoteBazelModuleRegistryService.create(registryUrl) } // Bazel version >= 7.2.0. if (lockfile.registryFileHashes != null) { - val registryFileHashes = lockfile.registryFileHashes.map { (url, _) -> - if (url.startsWith("file://")) { - url.replace("%workspace%", projectDir.absolutePath) - } else { - url - } - }.toSet() - - return CompositeBazelModuleRegistryService.create(registryFileHashes) + return CompositeBazelModuleRegistryService.create(lockfile.registryFileHashes.keys, projectDir) } val msg = "Bazel registry URL cannot be determined from the lockfile." diff --git a/plugins/package-managers/bazel/src/main/kotlin/CompositeBazelModuleRegistryService.kt b/plugins/package-managers/bazel/src/main/kotlin/CompositeBazelModuleRegistryService.kt index bafeae3991ec..b19fd5165044 100644 --- a/plugins/package-managers/bazel/src/main/kotlin/CompositeBazelModuleRegistryService.kt +++ b/plugins/package-managers/bazel/src/main/kotlin/CompositeBazelModuleRegistryService.kt @@ -43,9 +43,10 @@ internal class CompositeBazelModuleRegistryService( internal val URL_REGEX = "^(?.*/)modules/(?[^/]+)/[^/]+/source\\.json$".toRegex() /** - * Create a Composite Bazel Module Registry client instance. + * Create a Composite Bazel Module Registry client instance. The wrapped [BazelModuleRegistryService]s are + * created based on the passed in [urls]; local registries use the given [projectDir] as workspace. */ - fun create(urls: Set): CompositeBazelModuleRegistryService { + fun create(urls: Set, projectDir: File): CompositeBazelModuleRegistryService { val packageNamesForServer = urls.filter { it.endsWith("source.json") }.mapNotNull { url -> val groups = URL_REGEX.matchEntire(url)?.groups @@ -63,19 +64,8 @@ internal class CompositeBazelModuleRegistryService( }.groupByTo(mutableMapOf(), { it.first }) { it.second }.mapValues { it.value.toSet() } val packageNamesForRegistry = packageNamesForServer.mapKeys { (url, _) -> - if (url.startsWith("file://")) { - logger.info { - "Using local Bazel module registry at '$url'." - } - - LocalBazelModuleRegistryService(File(url)) - } else { - logger.info { - "Using remote Bazel module registry at '$url'." - } - - RemoteBazelModuleRegistryService.create(url) - } + LocalBazelModuleRegistryService.createForLocalUrl(url, projectDir) + ?: RemoteBazelModuleRegistryService.create(url) } return CompositeBazelModuleRegistryService(packageNamesForRegistry)