diff --git a/src/main/kotlin/com/gabrielfeo/gradle/enterprise/api/Api.kt b/src/main/kotlin/com/gabrielfeo/gradle/enterprise/api/Api.kt index b0ddcd76..d3b48a15 100644 --- a/src/main/kotlin/com/gabrielfeo/gradle/enterprise/api/Api.kt +++ b/src/main/kotlin/com/gabrielfeo/gradle/enterprise/api/Api.kt @@ -13,25 +13,6 @@ val api: GradleEnterpriseApi by lazy { retrofit.create(GradleEnterpriseApi::class.java) } -/** - * Provides the URL of a Gradle Enterprise API instance. By default, uses environment variable - * `GRADLE_ENTERPRISE_URL`. - */ -var baseUrl: () -> String = { - requireBaseUrl(envName = "GRADLE_ENTERPRISE_URL") -} - -/** - * Provides the access token for a Gradle Enterprise API instance. By default, uses keychain entry - * `gradle-enterprise-api-token` or environment variable `GRADLE_ENTERPRISE_URL`. - */ -var accessToken: () -> String = { - requireToken( - keychainName = "gradle-enterprise-api-token", - envName = "GRADLE_ENTERPRISE_API_TOKEN", - ) -} - /** * Shutdown the internal client, releasing resources and allowing the program to * finish before the client's idle timeout. @@ -45,79 +26,3 @@ fun shutdown() { cache?.close(); } } - -/** - * Regex pattern to match API URLs that are OK to store long-term in the HTTP cache, up to - * [longTermCacheMaxAge] (1y by default, max value). By default, uses environment variable - * `GRADLE_ENTERPRISE_API_LONG_TERM_CACHE_URL_PATTERN` or a pattern matching: - * - {host}/api/builds/{id}/gradle-attributes - * - {host}/api/builds/{id}/maven-attributes - * - * Gradle Enterprise API disallows HTTP caching, but this library forcefully removes such - * restriction. - * - * Use `|` to define multiple patterns in one, e.g. `.*gradle-attributes|.*test-distribution`. -*/ -var longTermCacheUrlPattern: Regex = - System.getenv("GRADLE_ENTERPRISE_API_LONG_TERM_CACHE_URL_PATTERN")?.toRegex() - ?: """.*/api/builds/[\d\w]+/(?:gradle|maven)-attributes""".toRegex() - -/** - * Max age in seconds for URLs to be cached long-term (matched by [longTermCacheUrlPattern]). - * By default, uses environment variable `GRADLE_ENTERPRISE_API_LONG_TERM_CACHE_MAX_AGE` or 1 year. - */ -var longTermCacheMaxAge: Long = - System.getenv("GRADLE_ENTERPRISE_API_SHORT_TERM_CACHE_MAX_AGE")?.toLong() - ?: 365.days.inWholeSeconds - -/** - * Regex pattern to match API URLs that are OK to store short-term in the HTTP cache, up to - * [shortTermCacheMaxAge] (1d by default). By default, uses environment variable - * `GRADLE_ENTERPRISE_API_SHORT_TERM_CACHE_URL_PATTERN` or a pattern matching: - * - {host}/api/builds - * - * Gradle Enterprise API disallows HTTP caching, but this library forcefully removes such - * restriction. - * - * Use `|` to define multiple patterns in one, e.g. `.*gradle-attributes|.*test-distribution`. - */ -var shortTermCacheUrlPattern: Regex = - System.getenv("GRADLE_ENTERPRISE_API_SHORT_TERM_CACHE_URL_PATTERN")?.toRegex() - ?: """.*/builds(?:\?.*|\Z)""".toRegex() - -/** - * Max age in seconds for URLs to be cached short-term (matched by [shortTermCacheUrlPattern]). - * By default, uses environment variable `GRADLE_ENTERPRISE_API_SHORT_TERM_CACHE_MAX_AGE` or 1 day. - */ -var shortTermCacheMaxAge: Long = - System.getenv("GRADLE_ENTERPRISE_API_SHORT_TERM_CACHE_MAX_AGE")?.toLong() - ?: 1.days.inWholeSeconds - -/** - * Maximum amount of concurrent requests allowed. Further requests will be queued. By default, - * uses environment variable `GRADLE_ENTERPRISE_API_MAX_CONCURRENT_REQUESTS` or 15. - * - * https://square.github.io/okhttp/4.x/okhttp/okhttp3/-dispatcher - */ -var maxConcurrentRequests = System.getenv("GRADLE_ENTERPRISE_API_MAX_CONCURRENT_REQUESTS")?.toInt() - ?: 15 - -/** - * Max size of the HTTP cache. By default, uses environment variable - * `GRADLE_ENTERPRISE_API_MAX_CACHE_SIZE` or ~1 GB. - */ -var maxCacheSize = System.getenv("GRADLE_ENTERPRISE_API_MAX_CACHE_SIZE")?.toLong() - ?: 1_000_000_000L - -/** - * HTTP cache location. By default, uses environment variable `GRADLE_ENTERPRISE_API_CACHE_DIR` - * or the system temporary folder (`java.io.tmpdir` / gradle-enterprise-api-kotlin-cache). - */ -var cacheDir = System.getenv("GRADLE_ENTERPRISE_API_CACHE_DIR")?.let(::File) - ?: File(System.getProperty("java.io.tmpdir"), "gradle-enterprise-api-kotlin-cache") - -/** - * Enables debug logging from the library. All logging is output to stderr. By default, uses - * environment variable `GRADLE_ENTERPRISE_API_DEBUG_LOGGING` or `false`. - */ -var debugLoggingEnabled = System.getenv("GRADLE_ENTERPRISE_API_DEBUG_LOGGING").toBoolean() diff --git a/src/main/kotlin/com/gabrielfeo/gradle/enterprise/api/GradleEnterpriseApiExtensions.kt b/src/main/kotlin/com/gabrielfeo/gradle/enterprise/api/ApiExtensions.kt similarity index 100% rename from src/main/kotlin/com/gabrielfeo/gradle/enterprise/api/GradleEnterpriseApiExtensions.kt rename to src/main/kotlin/com/gabrielfeo/gradle/enterprise/api/ApiExtensions.kt diff --git a/src/main/kotlin/com/gabrielfeo/gradle/enterprise/api/Options.kt b/src/main/kotlin/com/gabrielfeo/gradle/enterprise/api/Options.kt new file mode 100644 index 00000000..61cd9ea9 --- /dev/null +++ b/src/main/kotlin/com/gabrielfeo/gradle/enterprise/api/Options.kt @@ -0,0 +1,108 @@ +package com.gabrielfeo.gradle.enterprise.api + +import com.gabrielfeo.gradle.enterprise.api.internal.requireBaseUrl +import com.gabrielfeo.gradle.enterprise.api.internal.requireToken +import java.io.File +import kotlin.time.Duration.Companion.days + +object Options { + + /** + * Provides the URL of a Gradle Enterprise API instance. By default, uses environment variable + * `GRADLE_ENTERPRISE_URL`. + */ + var baseUrl: () -> String = { + requireBaseUrl(envName = "GRADLE_ENTERPRISE_URL") + } + + /** + * Provides the access token for a Gradle Enterprise API instance. By default, uses keychain entry + * `gradle-enterprise-api-token` or environment variable `GRADLE_ENTERPRISE_URL`. + */ + var accessToken: () -> String = { + requireToken( + keychainName = "gradle-enterprise-api-token", + envName = "GRADLE_ENTERPRISE_API_TOKEN", + ) + } + + /** + * Maximum amount of concurrent requests allowed. Further requests will be queued. By default, + * uses environment variable `GRADLE_ENTERPRISE_API_MAX_CONCURRENT_REQUESTS` or 15. + * + * https://square.github.io/okhttp/4.x/okhttp/okhttp3/-dispatcher + */ + var maxConcurrentRequests = + System.getenv("GRADLE_ENTERPRISE_API_MAX_CONCURRENT_REQUESTS")?.toInt() + ?: 15 + + /** + * HTTP cache location. By default, uses environment variable `GRADLE_ENTERPRISE_API_CACHE_DIR` + * or the system temporary folder (`java.io.tmpdir` / gradle-enterprise-api-kotlin-cache). + */ + var cacheDir = + System.getenv("GRADLE_ENTERPRISE_API_CACHE_DIR")?.let(::File) + ?: File(System.getProperty("java.io.tmpdir"), "gradle-enterprise-api-kotlin-cache") + + /** + * Max size of the HTTP cache. By default, uses environment variable + * `GRADLE_ENTERPRISE_API_MAX_CACHE_SIZE` or ~1 GB. + */ + var maxCacheSize = + System.getenv("GRADLE_ENTERPRISE_API_MAX_CACHE_SIZE")?.toLong() + ?: 1_000_000_000L + + /** + * Regex pattern to match API URLs that are OK to store long-term in the HTTP cache, up to + * [longTermCacheMaxAge] (1y by default, max value). By default, uses environment variable + * `GRADLE_ENTERPRISE_API_LONG_TERM_CACHE_URL_PATTERN` or a pattern matching: + * - {host}/api/builds/{id}/gradle-attributes + * - {host}/api/builds/{id}/maven-attributes + * + * Gradle Enterprise API disallows HTTP caching, but this library forcefully removes such + * restriction. + * + * Use `|` to define multiple patterns in one, e.g. `.*gradle-attributes|.*test-distribution`. + */ + var longTermCacheUrlPattern: Regex = + System.getenv("GRADLE_ENTERPRISE_API_LONG_TERM_CACHE_URL_PATTERN")?.toRegex() + ?: """.*/api/builds/[\d\w]+/(?:gradle|maven)-attributes""".toRegex() + + /** + * Max age in seconds for URLs to be cached long-term (matched by [longTermCacheUrlPattern]). + * By default, uses environment variable `GRADLE_ENTERPRISE_API_LONG_TERM_CACHE_MAX_AGE` or 1 year. + */ + var longTermCacheMaxAge: Long = + System.getenv("GRADLE_ENTERPRISE_API_SHORT_TERM_CACHE_MAX_AGE")?.toLong() + ?: 365.days.inWholeSeconds + + /** + * Regex pattern to match API URLs that are OK to store short-term in the HTTP cache, up to + * [shortTermCacheMaxAge] (1d by default). By default, uses environment variable + * `GRADLE_ENTERPRISE_API_SHORT_TERM_CACHE_URL_PATTERN` or a pattern matching: + * - {host}/api/builds + * + * Gradle Enterprise API disallows HTTP caching, but this library forcefully removes such + * restriction. + * + * Use `|` to define multiple patterns in one, e.g. `.*gradle-attributes|.*test-distribution`. + */ + var shortTermCacheUrlPattern: Regex = + System.getenv("GRADLE_ENTERPRISE_API_SHORT_TERM_CACHE_URL_PATTERN")?.toRegex() + ?: """.*/builds(?:\?.*|\Z)""".toRegex() + + /** + * Max age in seconds for URLs to be cached short-term (matched by [shortTermCacheUrlPattern]). + * By default, uses environment variable `GRADLE_ENTERPRISE_API_SHORT_TERM_CACHE_MAX_AGE` or 1 day. + */ + var shortTermCacheMaxAge: Long = + System.getenv("GRADLE_ENTERPRISE_API_SHORT_TERM_CACHE_MAX_AGE")?.toLong() + ?: 1.days.inWholeSeconds + + /** + * Enables debug logging from the library. All logging is output to stderr. By default, uses + * environment variable `GRADLE_ENTERPRISE_API_DEBUG_LOGGING` or `false`. + */ + var debugLoggingEnabled = + System.getenv("GRADLE_ENTERPRISE_API_DEBUG_LOGGING").toBoolean() +} \ No newline at end of file diff --git a/src/main/kotlin/com/gabrielfeo/gradle/enterprise/api/internal/Authentication.kt b/src/main/kotlin/com/gabrielfeo/gradle/enterprise/api/internal/Authentication.kt index c9340daa..d67cea00 100644 --- a/src/main/kotlin/com/gabrielfeo/gradle/enterprise/api/internal/Authentication.kt +++ b/src/main/kotlin/com/gabrielfeo/gradle/enterprise/api/internal/Authentication.kt @@ -1,6 +1,6 @@ package com.gabrielfeo.gradle.enterprise.api.internal -import com.gabrielfeo.gradle.enterprise.api.debugLoggingEnabled +import com.gabrielfeo.gradle.enterprise.api.Options import java.util.logging.Level.INFO import java.util.logging.Logger @@ -20,7 +20,7 @@ internal fun requireToken( private fun tokenFromEnv(varName: String): String? { return System.getenv(varName).also { - if (debugLoggingEnabled && it.isNullOrBlank()) { + if (Options.debugLoggingEnabled && it.isNullOrBlank()) { Logger.getGlobal().log(INFO, "Env var $varName=$it") } } @@ -36,7 +36,7 @@ private fun tokenFromKeychain(keyName: String): String? { return process.inputStream.bufferedReader().use { it.readText().trim() } - } else if (debugLoggingEnabled) { + } else if (Options.debugLoggingEnabled) { Logger.getGlobal().log(INFO, "Failed to get key from keychain (exit $status)") } return null diff --git a/src/main/kotlin/com/gabrielfeo/gradle/enterprise/api/internal/OkHttpClient.kt b/src/main/kotlin/com/gabrielfeo/gradle/enterprise/api/internal/OkHttpClient.kt index f226e9cf..234ab3da 100644 --- a/src/main/kotlin/com/gabrielfeo/gradle/enterprise/api/internal/OkHttpClient.kt +++ b/src/main/kotlin/com/gabrielfeo/gradle/enterprise/api/internal/OkHttpClient.kt @@ -1,33 +1,28 @@ package com.gabrielfeo.gradle.enterprise.api.internal +import com.gabrielfeo.gradle.enterprise.api.* import com.gabrielfeo.gradle.enterprise.api.internal.auth.HttpBearerAuth import com.gabrielfeo.gradle.enterprise.api.internal.caching.CacheEnforcingInterceptor import com.gabrielfeo.gradle.enterprise.api.internal.caching.CacheHitLoggingInterceptor -import com.gabrielfeo.gradle.enterprise.api.internal.caching.cache -import com.gabrielfeo.gradle.enterprise.api.accessToken -import com.gabrielfeo.gradle.enterprise.api.longTermCacheMaxAge -import com.gabrielfeo.gradle.enterprise.api.longTermCacheUrlPattern -import com.gabrielfeo.gradle.enterprise.api.maxConcurrentRequests -import com.gabrielfeo.gradle.enterprise.api.shortTermCacheMaxAge -import com.gabrielfeo.gradle.enterprise.api.shortTermCacheUrlPattern +import com.gabrielfeo.gradle.enterprise.api.internal.caching.buildCache import okhttp3.OkHttpClient internal val okHttpClient: OkHttpClient by lazy { OkHttpClient.Builder() - .cache(cache) - .addInterceptor(HttpBearerAuth("bearer", accessToken())) + .cache(buildCache()) + .addInterceptor(HttpBearerAuth("bearer", Options.accessToken())) .addInterceptor(CacheHitLoggingInterceptor()) .addNetworkInterceptor(buildCacheEnforcingInterceptor()) .build() .apply { - dispatcher.maxRequests = maxConcurrentRequests - dispatcher.maxRequestsPerHost = maxConcurrentRequests + dispatcher.maxRequests = Options.maxConcurrentRequests + dispatcher.maxRequestsPerHost = Options.maxConcurrentRequests } } private fun buildCacheEnforcingInterceptor() = CacheEnforcingInterceptor( - longTermCacheUrlPattern = longTermCacheUrlPattern, - longTermCacheMaxAge = longTermCacheMaxAge, - shortTermCacheUrlPattern = shortTermCacheUrlPattern, - shortTermCacheMaxAge = shortTermCacheMaxAge, + longTermCacheUrlPattern = Options.longTermCacheUrlPattern, + longTermCacheMaxAge = Options.longTermCacheMaxAge, + shortTermCacheUrlPattern = Options.shortTermCacheUrlPattern, + shortTermCacheMaxAge = Options.shortTermCacheMaxAge, ) diff --git a/src/main/kotlin/com/gabrielfeo/gradle/enterprise/api/internal/Retrofit.kt b/src/main/kotlin/com/gabrielfeo/gradle/enterprise/api/internal/Retrofit.kt index 6c603ead..2477e5e1 100644 --- a/src/main/kotlin/com/gabrielfeo/gradle/enterprise/api/internal/Retrofit.kt +++ b/src/main/kotlin/com/gabrielfeo/gradle/enterprise/api/internal/Retrofit.kt @@ -1,6 +1,6 @@ package com.gabrielfeo.gradle.enterprise.api.internal -import com.gabrielfeo.gradle.enterprise.api.baseUrl +import com.gabrielfeo.gradle.enterprise.api.Options import com.gabrielfeo.gradle.enterprise.api.internal.infrastructure.Serializer import retrofit2.Retrofit import retrofit2.converter.moshi.MoshiConverterFactory @@ -8,7 +8,7 @@ import retrofit2.converter.scalars.ScalarsConverterFactory internal val retrofit: Retrofit by lazy { Retrofit.Builder() - .baseUrl(baseUrl()) + .baseUrl(Options.baseUrl()) .addConverterFactory(ScalarsConverterFactory.create()) .addConverterFactory(MoshiConverterFactory.create(Serializer.moshi)) .client(okHttpClient) diff --git a/src/main/kotlin/com/gabrielfeo/gradle/enterprise/api/internal/caching/Cache.kt b/src/main/kotlin/com/gabrielfeo/gradle/enterprise/api/internal/caching/Cache.kt index 94176f09..4441e06c 100644 --- a/src/main/kotlin/com/gabrielfeo/gradle/enterprise/api/internal/caching/Cache.kt +++ b/src/main/kotlin/com/gabrielfeo/gradle/enterprise/api/internal/caching/Cache.kt @@ -1,15 +1,14 @@ package com.gabrielfeo.gradle.enterprise.api.internal.caching -import com.gabrielfeo.gradle.enterprise.api.cacheDir -import com.gabrielfeo.gradle.enterprise.api.debugLoggingEnabled -import com.gabrielfeo.gradle.enterprise.api.maxCacheSize +import com.gabrielfeo.gradle.enterprise.api.Options import okhttp3.Cache import java.util.logging.Level.INFO import java.util.logging.Logger -internal val cache: Cache = run { - if (debugLoggingEnabled) { - Logger.getGlobal().log(INFO, "HTTP cache dir with max size $maxCacheSize: $cacheDir") +internal fun buildCache(): Cache { + if (Options.debugLoggingEnabled) { + val logger = Logger.getGlobal() + logger.log(INFO, "HTTP cache dir: ${Options.cacheDir} (max ${Options.maxCacheSize}B)") } - Cache(cacheDir, maxSize = maxCacheSize) + return Cache(Options.cacheDir, maxSize = Options.maxCacheSize) } diff --git a/src/main/kotlin/com/gabrielfeo/gradle/enterprise/api/internal/caching/CacheHitLoggingInterceptor.kt b/src/main/kotlin/com/gabrielfeo/gradle/enterprise/api/internal/caching/CacheHitLoggingInterceptor.kt index 250c29bf..46bc83b0 100644 --- a/src/main/kotlin/com/gabrielfeo/gradle/enterprise/api/internal/caching/CacheHitLoggingInterceptor.kt +++ b/src/main/kotlin/com/gabrielfeo/gradle/enterprise/api/internal/caching/CacheHitLoggingInterceptor.kt @@ -1,6 +1,6 @@ package com.gabrielfeo.gradle.enterprise.api.internal.caching -import com.gabrielfeo.gradle.enterprise.api.debugLoggingEnabled +import com.gabrielfeo.gradle.enterprise.api.Options import okhttp3.Interceptor import okhttp3.Response import java.util.logging.Level @@ -11,7 +11,7 @@ internal class CacheHitLoggingInterceptor( ) : Interceptor { override fun intercept(chain: Interceptor.Chain): Response { - if (!debugLoggingEnabled) { + if (!Options.debugLoggingEnabled) { return chain.proceed(chain.request()) } val url = chain.request().url