Skip to content

Commit d35c0e5

Browse files
committed
Update README and javadoc
Improve docs - Use Dokka HTML format which is better for Kotlin - Move Model classes to new package so docs are better organized - Hide internal package from generated docs, along with OpenApi infrastructure packages
1 parent e5b073f commit d35c0e5

File tree

8 files changed

+162
-69
lines changed

8 files changed

+162
-69
lines changed

.openapi-generator-ignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ build/generated/openapi-generator/api/*
44
build/generated/openapi-generator/gradle/**/*
55
build/generated/openapi-generator/docs/*
66
build/generated/openapi-generator/src/main/AndroidManifest.xml
7-
build/generated/openapi-generator/src/main/kotlin/com/gabrielfeo/gradle/enterprise/api/ApiClient.kt
7+
build/generated/openapi-generator/src/main/kotlin/com/gabrielfeo/gradle/enterprise/api/internal/infrastructure/ApiClient.kt
88
build/generated/openapi-generator/src/main/kotlin/com/gabrielfeo/gradle/enterprise/api/BuildsApi.kt
99
build/generated/openapi-generator/src/main/kotlin/com/gabrielfeo/gradle/enterprise/api/BuildCacheApi.kt
1010
build/generated/openapi-generator/src/main/kotlin/com/gabrielfeo/gradle/enterprise/api/MetaApi.kt

README.md

Lines changed: 127 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -12,96 +12,167 @@ builds.forEach {
1212

1313
## Setup
1414

15-
Add a dependency by copying these lines to the top of your `kts` scripts:
15+
Set up your environment once and use the library from any script in your machine.
16+
17+
- `GRADLE_ENTERPRISE_URL` environment variable: the URL of your Gradle Enterprise instance
18+
- `GRADLE_ENTERPRISE_API_TOKEN` environment variable: an API access token for the Gradle
19+
Enterprise instance. Alternatively, can be a macOS keychain entry labeled
20+
`gradle-enterprise-api-token` (recommended).
21+
22+
That's it! From any `kts` script, you can add a dependency on the library and start querying the
23+
API:
1624

1725
```kotlin
1826
@file:Repository("https://jitpack.io")
1927
@file:DependsOn("com.github.gabrielfeo:gradle-enterprise-api-kotlin:1.0")
28+
29+
val builds = api.getBuilds(since = 0, maxBuilds = 10).execute().body()!!
30+
builds.forEach {
31+
println(it)
32+
}
2033
```
2134

22-
Following convention over configuration, set:
23-
- the URL of your Gradle Enterprise instance, in environment variable `GRADLE_ENTERPRISE_URL`
24-
- an API access token, either in macOS keychain labeled as "gradle-enterprise-api-token"
25-
or in an environment variable named `GRADLE_ENTERPRISE_API_TOKEN`
35+
See the [sample script](./sample.main.kts) for a complete example.
36+
37+
<details>
38+
<summary>Optional setup</summary>
39+
40+
All of the following have default values and are completely optional. See
41+
[Api.kt](src/main/kotlin/com/gabrielfeo/gradle/enterprise/api/Api.kt) for details.
42+
43+
##### Caching
44+
45+
Gradle Enterprise API disallows HTTP caching, but this library forces
46+
caching for faster queries. Caching is split in two categories:
47+
48+
1. Short-term cache (default max-age of 1 day)
49+
- `/api/builds`
50+
2. Long-term cache (default max-age of 1 year)
51+
- `/api/builds/{id}/gradle-attributes`
52+
- `/api/builds/{id}/maven-attributes`
2653

27-
By doing so, any script can query `api` without additional setup. See the [sample
28-
script](./sample.main.kts) for a complete example.
54+
max-age and cached URLs can be changed with options below.
55+
56+
- `GRADLE_ENTERPRISE_API_CACHE_DIR`: HTTP cache location. Defaults to the system temporary
57+
directory.
58+
- `GRADLE_ENTERPRISE_API_MAX_CACHE_SIZE`: Max size of the HTTP cache in bytes. Defaults to ~1GB.
59+
- `GRADLE_ENTERPRISE_API_SHORT_TERM_CACHE_URL_PATTERN`: Regex pattern to match API URLs that are
60+
OK to store short-term in the HTTP cache.
61+
- `GRADLE_ENTERPRISE_API_SHORT_TERM_CACHE_MAX_AGE`: Max age in seconds of each response stored
62+
short-term in the HTTP cache.
63+
- `GRADLE_ENTERPRISE_API_LONG_TERM_CACHE_URL_PATTERN`: Regex pattern to match API URLs that are
64+
OK to store long-term in the HTTP cache.
65+
- `GRADLE_ENTERPRISE_API_LONG_TERM_CACHE_MAX_AGE`: Max age in seconds of each response stored
66+
long-term in the HTTP cache.
67+
68+
##### Concurrency
69+
70+
- `GRADLE_ENTERPRISE_API_MAX_CONCURRENT_REQUESTS`: Maximum amount of concurrent requests
71+
allowed. Defaults to 15.
72+
73+
##### Debugging
74+
75+
- `GRADLE_ENTERPRISE_API_DEBUG_LOGGING`: `true` to enable debug logging from the library. Defaults
76+
to `false`.
77+
78+
</details>
79+
80+
<details>
81+
<summary>Setup in full projects (non-scripts)</summary>
82+
83+
You can also use it in a full Kotlin project instead of a script. Just add a dependency:
84+
85+
```kotlin
86+
repositories {
87+
maven(url = "https://jitpack.io")
88+
}
89+
dependencies {
90+
implementation("com.github.gabrielfeo:gradle-enterprise-api-kotlin:1.0")
91+
}
92+
```
93+
94+
<details>
95+
<summary>Groovy</summary>
96+
97+
```groovy
98+
repositories {
99+
maven { url = 'https://jitpack.io' }
100+
}
101+
dependencies {
102+
implementation 'com.github.gabrielfeo:gradle-enterprise-api-kotlin:1.0'
103+
}
104+
```
105+
106+
</details>
107+
108+
Any option can also be changed from code rather than from environment, as long as it's done
109+
before the first `api` usage.
110+
111+
```kotlin
112+
baseUrl = { "https://my.ge.org" }
113+
accessToken = { getFromVault("ge-api-token") }
114+
api.getBuilds(id = "hy5nxbzfjxe5k")
115+
```
116+
117+
</details>
29118

30119
## Usage
31120

32-
The library provides API endpoints as a single [Retrofit][2] Service interface:
33-
`GradleEnterpriseApi`. It's ready-to-use as the global `api` instance:
121+
API endpoints are provided as a single interface: `GradleEnterpriseApi`. It's
122+
initialized and ready-to-use as the global `api` instance:
34123

35124
```kotlin
36125
api.getBuild(id = "hy5nxbzfjxe5k")
37126
```
38127

39128
It's recommended to learn about endpoints and their responses through IDE auto-complete. Javadoc
40-
appearing in auto-complete is the full API manual. Each method is documented with
41-
params and possible status codes.
129+
appearing in auto-complete is the full API manual, same as Gradle's online docs.
130+
131+
This library provides a few extension functions on top of the regular API:
132+
133+
```kotlin
134+
// Regular query to /api/builds, limited to 1000 builds server-side
135+
api.getBuilds(since = lastMonth)
136+
// Streams all available builds from a given date, split in as getBuilds
137+
// as needed
138+
api.getBuildsFlow(since = lastMonth)
139+
```
140+
141+
```kotlin
142+
// To get build scan data such as username, tags and custom values, one
143+
// must usually query /api/builds/{id}/gradle-attributes per-build, which
144+
// is verbose and slow (1 request at a time)
145+
api.getBuildsFlow(since = lastMonth)
146+
.map { build -> api.getGradleAttributes(id = build.id) }
147+
// Streams all available builds as GradleAttributes from a given date,
148+
// requesting more than 1 build at a time.
149+
api.getGradleAttributesFlow(since = lastMonth)
150+
```
42151

43-
Helper functions are also available:
44-
- `GradleEnterpriseApi.buildsSequence()` returns a sequence making paged requests underneath
45152

46153
## More info
47154

48155
- Currently built for Gradle Enterprise `2022.4`, but can be used with previous versions.
49156
- Use JDK 8 or 14+ to run, if you want to avoid the ["illegal reflective access" warning about
50157
Retrofit][3]
51-
- There is a global instance `okHttpClient` so you can change what's needed, but also concurrency
158+
- There is a global instance `okHttpClient` so you can change what's needed, but also concurrency
52159
shortcuts `maxConcurrentRequests` and `shutdown()`.
53160
- `maxConcurrentRequests` is useful to speed up scripts, but if you start getting HTTP 504 from
54-
your GE instance, decreasing this value should help.
161+
your GE instance, decreasing this value should help.
55162
- The script will keep running for an extra ~60s after code finishes, as an [expected behavior
56-
of OkHttp][4], unless you call `shutdown()` (global function).
57-
- All classes are in the same package, so that if you need to make small edits to scripts where
58-
there's no auto-complete, a single wildcard import can be used:
163+
of OkHttp][4], unless you call `shutdown()` (global function).
164+
- All classes live in these two packages. If you need to make small edits to scripts where
165+
there's no auto-complete, wildcard imports can be used:
59166

60167
```kotlin
61168
import com.gabrielfeo.gradle.enterprise.api.*
169+
import com.gabrielfeo.gradle.enterprise.api.model.*
62170
```
63171

64172
### Internals
65173

66174
API classes such as `GradleEnterpriseApi` and response models are generated from the offical
67-
[API spec][5], using the [OpenAPI Generator Gradle Plugin][6]. Actual project classes are a thin
68-
layer over the generated code, to make it easy to use from scripts.
69-
70-
### Custom setups
71-
72-
You can also use it in a full Kotlin project instead of a script. Just add a dependency:
73-
74-
```kotlin
75-
repositories {
76-
maven(url = "https://jitpack.io")
77-
}
78-
dependencies {
79-
implementation("com.github.gabrielfeo:gradle-enterprise-api-kotlin:1.0")
80-
}
81-
```
82-
83-
<details>
84-
<summary>Groovy</summary>
85-
86-
```groovy
87-
repositories {
88-
maven { url = 'https://jitpack.io' }
89-
}
90-
dependencies {
91-
implementation 'com.github.gabrielfeo:gradle-enterprise-api-kotlin:1.0'
92-
}
93-
```
94-
95-
</details>
96-
97-
`api` is ready-to-use if conventions are followed, but if you'd rather you can set `baseUrl` and
98-
`accessToken` from code instead, before using `api`:
99-
100-
```kotlin
101-
baseUrl = "https://my.ge.org"
102-
accessToken = "abcdefg"
103-
api.getBuild(id = "hy5nxbzfjxe5k")
104-
```
175+
[API spec][5], using the [OpenAPI Generator Gradle Plugin][6].
105176

106177
[1]: https://docs.gradle.com/enterprise/api-manual/
107178
[2]: https://square.github.io/retrofit/

build.gradle.kts

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
import org.jetbrains.dokka.DokkaConfiguration.Visibility.PUBLIC
2+
import org.jetbrains.dokka.gradle.DokkaTask
3+
14
plugins {
25
val kotlinVersion = "1.7.10"
36
id("org.jetbrains.kotlin.jvm") version kotlinVersion
@@ -8,7 +11,7 @@ plugins {
811
}
912

1013
group = "com.github.gabrielfeo"
11-
version = "1.0"
14+
version = "0.7"
1215

1316
val downloadApiSpec by tasks.registering {
1417
val geVersion = providers.gradleProperty("gradle.enterprise.version").get()
@@ -30,9 +33,9 @@ openApiGenerate {
3033
val ignoreFile = project.layout.projectDirectory.file(".openapi-generator-ignore")
3134
ignoreFileOverride.set(ignoreFile.asFile.absolutePath)
3235
apiPackage.set("com.gabrielfeo.gradle.enterprise.api")
33-
modelPackage.set("com.gabrielfeo.gradle.enterprise.api")
34-
packageName.set("com.gabrielfeo.gradle.enterprise.api")
35-
invokerPackage.set("com.gabrielfeo.gradle.enterprise.api")
36+
modelPackage.set("com.gabrielfeo.gradle.enterprise.api.model")
37+
packageName.set("com.gabrielfeo.gradle.enterprise.api.internal")
38+
invokerPackage.set("com.gabrielfeo.gradle.enterprise.api.internal")
3639
additionalProperties.put("library", "jvm-retrofit2")
3740
}
3841

@@ -52,8 +55,25 @@ java {
5255
}
5356
}
5457

58+
tasks.withType<DokkaTask>().configureEach {
59+
dokkaSourceSets.all {
60+
jdkVersion.set(8)
61+
suppressGeneratedFiles.set(false)
62+
documentedVisibilities.set(setOf(PUBLIC))
63+
perPackageOption {
64+
matchingRegex.set(""".*\.internal.*""")
65+
suppress.set(true)
66+
}
67+
externalDocumentationLink("https://kotlinlang.org/api/kotlinx.coroutines/")
68+
externalDocumentationLink("https://square.github.io/okhttp/4.x/okhttp/")
69+
externalDocumentationLink("https://square.github.io/retrofit/2.x/retrofit/")
70+
externalDocumentationLink("https://square.github.io/moshi/1.x/moshi/")
71+
externalDocumentationLink("https://square.github.io/moshi/1.x/moshi-kotlin/")
72+
}
73+
}
74+
5575
tasks.named<Jar>("javadocJar") {
56-
from(tasks.dokkaJavadoc)
76+
from(tasks.dokkaHtml)
5777
}
5878

5979
publishing {

src/main/kotlin/com/gabrielfeo/gradle/enterprise/api/Api.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ var cacheDir = System.getenv("GRADLE_ENTERPRISE_API_CACHE_DIR")?.let(::File)
113113
?: File(System.getProperty("java.io.tmpdir"), "gradle-enterprise-api-kotlin-cache")
114114

115115
/**
116-
* Enables debug logging from the library. All logging is output to the program's standard streams.
117-
* By default, uses environment variable `GRADLE_ENTERPRISE_API_DEBUG_LOGGING` or `false`.
116+
* Enables debug logging from the library. All logging is output to stderr. By default, uses
117+
* environment variable `GRADLE_ENTERPRISE_API_DEBUG_LOGGING` or `false`.
118118
*/
119119
var debugLoggingEnabled = System.getenv("GRADLE_ENTERPRISE_API_DEBUG_LOGGING").toBoolean()

src/main/kotlin/com/gabrielfeo/gradle/enterprise/api/GradleEnterpriseApiExtensions.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
package com.gabrielfeo.gradle.enterprise.api
22

3+
import com.gabrielfeo.gradle.enterprise.api.model.*
34
import kotlinx.coroutines.CoroutineScope
45
import kotlinx.coroutines.GlobalScope
56
import kotlinx.coroutines.async
67
import kotlinx.coroutines.flow.*
7-
import retrofit2.HttpException
88
import retrofit2.await
99

1010
private const val API_MAX_BUILDS = 1000

src/main/kotlin/com/gabrielfeo/gradle/enterprise/api/ModelExtensions.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package com.gabrielfeo.gradle.enterprise.api
22

3+
import com.gabrielfeo.gradle.enterprise.api.model.*
4+
35
operator fun List<BuildAttributesValue>.get(name: String): String? {
46
return find { it.name == name }?.value
57
}

src/main/kotlin/com/gabrielfeo/gradle/enterprise/api/internal/OkHttpClient.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
package com.gabrielfeo.gradle.enterprise.api.internal
22

3-
import com.gabrielfeo.gradle.enterprise.api.auth.HttpBearerAuth
3+
import com.gabrielfeo.gradle.enterprise.api.internal.auth.HttpBearerAuth
44
import com.gabrielfeo.gradle.enterprise.api.internal.caching.CacheEnforcingInterceptor
55
import com.gabrielfeo.gradle.enterprise.api.internal.caching.CacheHitLoggingInterceptor
66
import com.gabrielfeo.gradle.enterprise.api.internal.caching.cache
@@ -12,7 +12,7 @@ import com.gabrielfeo.gradle.enterprise.api.shortTermCacheMaxAge
1212
import com.gabrielfeo.gradle.enterprise.api.shortTermCacheUrlPattern
1313
import okhttp3.OkHttpClient
1414

15-
val okHttpClient: OkHttpClient by lazy {
15+
internal val okHttpClient: OkHttpClient by lazy {
1616
OkHttpClient.Builder()
1717
.cache(cache)
1818
.addInterceptor(HttpBearerAuth("bearer", accessToken()))

src/main/kotlin/com/gabrielfeo/gradle/enterprise/api/internal/Retrofit.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
package com.gabrielfeo.gradle.enterprise.api.internal
22

33
import com.gabrielfeo.gradle.enterprise.api.baseUrl
4-
import com.gabrielfeo.gradle.enterprise.api.infrastructure.Serializer
4+
import com.gabrielfeo.gradle.enterprise.api.internal.infrastructure.Serializer
55
import retrofit2.Retrofit
66
import retrofit2.converter.moshi.MoshiConverterFactory
77
import retrofit2.converter.scalars.ScalarsConverterFactory
88

9-
val retrofit: Retrofit by lazy {
9+
internal val retrofit: Retrofit by lazy {
1010
Retrofit.Builder()
1111
.baseUrl(baseUrl())
1212
.addConverterFactory(ScalarsConverterFactory.create())

0 commit comments

Comments
 (0)