Repository: Kotlin/kotlinx.coroutines
File: buildSrc/src/main/kotlin/CacheRedirector.kt (Kotlin)

Code before:
        logger.warn("WARNING - $msg\n$details")
    }
    return if (cacheRedirectorEnabled) redirected ?: url else url
}

private fun Project.checkRedirect(repositories: RepositoryHandler, containerName: String) {
    if (cacheRedirectorEnabled) {
        logger.info("Redirecting repositories for $containerName")
    }
    for (repository in repositories) {
        when (repository) {
            is MavenArtifactRepository -> repository.url = checkRedirectUrl(repository.url, containerName)
            is IvyArtifactRepository -> repository.url = checkRedirectUrl(repository.url, containerName)
        }
    }
}

private fun Project.configureYarnRedirects() {
    if (CacheRedirector.isEnabled) {
        plugins.withType(YarnPlugin::class) {
            extensions.configure(YarnRootEnvSpec::class.java) {
                // no API to modify the value in-place keeping it lazy: https://github.com/gradle/gradle/issues/27227
                val currentValue = downloadBaseUrl.orNull
                if (currentValue != null) {
                    downloadBaseUrl = CacheRedirector.maybeRedirect(currentValue)
                }
            }
        }
    }
}

private fun Project.configureNodeJsRedirects() {
    if (CacheRedirector.isEnabled) {
        plugins.withType(NodeJsPlugin::class) {
            extensions.configure(NodeJsEnvSpec::class.java) {
                // no API to modify the value in-place keeping it lazy: https://github.com/gradle/gradle/issues/27227
                val currentValue = downloadBaseUrl.orNull
                if (currentValue != null) {
                    downloadBaseUrl = CacheRedirector.maybeRedirect(currentValue)
                }
            }
        }
    }
}

// Used from Groovy scripts
// TODO get rid of Groovy, come up with a proper convention for rootProject vs arbitrary project argument
object CacheRedirector {
    /**
     * Substitutes repositories in buildScript { } block.
     */

Review comment (performance):
Can this not be written like it was before? That is,
```suggestion
                downloadBaseUrl.orNull?.let {
                    downloadBaseUrl = CacheRedirector.maybeRedirect(it)
                }
            }
```
I'd expect this to be a pure Kotlin construction, without any relation to what Gradle supports or doesn't support.

Code after:
        logger.warn("WARNING - $msg\n$details")
    }
    return if (cacheRedirectorEnabled) redirected ?: url else url
}

private fun Project.checkRedirect(repositories: RepositoryHandler, containerName: String) {
    if (cacheRedirectorEnabled) {
        logger.info("Redirecting repositories for $containerName")
    }
    for (repository in repositories) {
        when (repository) {
            is MavenArtifactRepository -> repository.url = checkRedirectUrl(repository.url, containerName)
            is IvyArtifactRepository -> repository.url = checkRedirectUrl(repository.url, containerName)
        }
    }
}

private fun Project.configureYarnRedirects() {
    if (CacheRedirector.isEnabled) {
        plugins.withType(YarnPlugin::class) {
            extensions.configure(YarnRootEnvSpec::class.java) {
                // no API to modify the value in-place keeping it lazy: https://github.com/gradle/gradle/issues/27227
                downloadBaseUrl.orNull?.let {
                    downloadBaseUrl = CacheRedirector.maybeRedirect(it)
                }
            }
        }
    }
}

private fun Project.configureNodeJsRedirects() {
    if (CacheRedirector.isEnabled) {
        plugins.withType(NodeJsPlugin::class) {
            extensions.configure(NodeJsEnvSpec::class.java) {
                // no API to modify the value in-place keeping it lazy: https://github.com/gradle/gradle/issues/27227
                downloadBaseUrl.orNull?.let {
                    downloadBaseUrl = CacheRedirector.maybeRedirect(it)
                }
            }
        }
    }
}

// Used from Groovy scripts
// TODO get rid of Groovy, come up with a proper convention for rootProject vs arbitrary project argument
object CacheRedirector {
    /**
     * Substitutes repositories in buildScript { } block.
     */
    @JvmStatic
    fun ScriptHandler.configureBuildScript(rootProject: Project) {