Skip to content

Commit 49727c9

Browse files
perf(internal): make formatting faster
Running the formatter through Spotless is slow because Spotless synchronously runs the formatter on each file. Running the formatter directly parallelizes the formatting across cores.
1 parent 98980ed commit 49727c9

File tree

9 files changed

+185
-27
lines changed

9 files changed

+185
-27
lines changed

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,6 @@
22
.gradle
33
.idea
44
.kotlin
5-
build
5+
build/
66
codegen.log
77
kls_database.db

build.gradle.kts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,19 @@ allprojects {
1111
version = "3.0.3" // x-release-please-version
1212
}
1313

14+
subprojects {
15+
// These are populated with dependencies by `buildSrc` scripts.
16+
tasks.register("format") {
17+
group = "Verification"
18+
description = "Formats all source files."
19+
}
20+
tasks.register("lint") {
21+
group = "Verification"
22+
description = "Verifies all source files are formatted."
23+
}
24+
apply(plugin = "org.jetbrains.dokka")
25+
}
26+
1427
subprojects {
1528
apply(plugin = "org.jetbrains.dokka")
1629
}

buildSrc/build.gradle.kts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ repositories {
1010
}
1111

1212
dependencies {
13-
implementation("com.diffplug.spotless:spotless-plugin-gradle:7.0.2")
1413
implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.20")
1514
implementation("com.vanniktech:gradle-maven-publish-plugin:0.28.0")
1615
}

buildSrc/src/main/kotlin/openai.java.gradle.kts

Lines changed: 83 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,13 @@
1-
import com.diffplug.gradle.spotless.SpotlessExtension
21
import org.gradle.api.tasks.testing.logging.TestExceptionFormat
32

43
plugins {
54
`java-library`
6-
id("com.diffplug.spotless")
75
}
86

97
repositories {
108
mavenCentral()
119
}
1210

13-
configure<SpotlessExtension> {
14-
java {
15-
importOrder()
16-
removeUnusedImports()
17-
palantirJavaFormat()
18-
toggleOffOn()
19-
}
20-
}
21-
2211
java {
2312
toolchain {
2413
languageVersion.set(JavaLanguageVersion.of(21))
@@ -53,3 +42,86 @@ tasks.withType<Test>().configureEach {
5342
exceptionFormat = TestExceptionFormat.FULL
5443
}
5544
}
45+
46+
val palantir by configurations.creating
47+
dependencies {
48+
palantir("com.palantir.javaformat:palantir-java-format:2.73.0")
49+
}
50+
51+
fun registerPalantir(
52+
name: String,
53+
description: String,
54+
) {
55+
val javaName = "${name}Java"
56+
tasks.register<JavaExec>(javaName) {
57+
group = "Verification"
58+
this.description = description
59+
60+
classpath = palantir
61+
mainClass = "com.palantir.javaformat.java.Main"
62+
63+
// Avoid an `IllegalAccessError` on Java 9+.
64+
jvmArgs(
65+
"--add-exports", "jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED",
66+
"--add-exports", "jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED",
67+
"--add-exports", "jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED",
68+
"--add-exports", "jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED",
69+
"--add-exports", "jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED",
70+
)
71+
72+
// Use paths relative to the current module.
73+
val argumentFile =
74+
project.layout.buildDirectory.file("palantir-$name-args.txt").get().asFile
75+
val lastRunTimeFile =
76+
project.layout.buildDirectory.file("palantir-$name-last-run.txt").get().asFile
77+
78+
// Read the time when this task was last executed for this module (if ever).
79+
val lastRunTime = lastRunTimeFile.takeIf { it.exists() }?.readText()?.toLongOrNull() ?: 0L
80+
81+
// Use a `fileTree` relative to the module's source directory.
82+
val javaFiles = project.fileTree("src") { include("**/*.java") }
83+
84+
// Determine if any files need to be formatted or linted and continue only if there is at least
85+
// one file.
86+
onlyIf { javaFiles.any { it.lastModified() > lastRunTime } }
87+
88+
inputs.files(javaFiles)
89+
90+
doFirst {
91+
// Create the argument file and set the preferred formatting style.
92+
argumentFile.parentFile.mkdirs()
93+
argumentFile.writeText("--palantir\n")
94+
95+
if (name == "lint") {
96+
// For lint, do a dry run, so no files are modified. Set the exit code to 1 (instead of
97+
// the default 0) if any files need to be formatted, indicating that linting has failed.
98+
argumentFile.appendText("--dry-run\n")
99+
argumentFile.appendText("--set-exit-if-changed\n")
100+
} else {
101+
// `--dry-run` and `--replace` (for in-place formatting) are mutually exclusive.
102+
argumentFile.appendText("--replace\n")
103+
}
104+
105+
// Write the modified files to the argument file.
106+
javaFiles.filter { it.lastModified() > lastRunTime }
107+
.forEach { argumentFile.appendText("${it.absolutePath}\n") }
108+
}
109+
110+
doLast {
111+
// Record the last execution time for later up-to-date checking.
112+
lastRunTimeFile.writeText(System.currentTimeMillis().toString())
113+
}
114+
115+
// Pass the argument file using the @ symbol
116+
args = listOf("@${argumentFile.absolutePath}")
117+
118+
outputs.upToDateWhen { javaFiles.none { it.lastModified() > lastRunTime } }
119+
}
120+
121+
tasks.named(name) {
122+
dependsOn(tasks.named(javaName))
123+
}
124+
}
125+
126+
registerPalantir(name = "format", description = "Formats all Java source files.")
127+
registerPalantir(name = "lint", description = "Verifies all Java source files are formatted.")

buildSrc/src/main/kotlin/openai.kotlin.gradle.kts

Lines changed: 74 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import com.diffplug.gradle.spotless.SpotlessExtension
21
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
32
import org.jetbrains.kotlin.gradle.dsl.KotlinVersion
43

@@ -7,6 +6,10 @@ plugins {
76
kotlin("jvm")
87
}
98

9+
repositories {
10+
mavenCentral()
11+
}
12+
1013
kotlin {
1114
jvmToolchain {
1215
languageVersion.set(JavaLanguageVersion.of(21))
@@ -27,14 +30,77 @@ kotlin {
2730
}
2831
}
2932

30-
configure<SpotlessExtension> {
31-
kotlin {
32-
ktfmt().kotlinlangStyle()
33-
toggleOffOn()
34-
}
35-
}
36-
3733
tasks.withType<Test>().configureEach {
3834
systemProperty("junit.jupiter.execution.parallel.enabled", true)
3935
systemProperty("junit.jupiter.execution.parallel.mode.default", "concurrent")
4036
}
37+
38+
val ktfmt by configurations.creating
39+
dependencies {
40+
ktfmt("com.facebook:ktfmt:0.56")
41+
}
42+
43+
fun registerKtfmt(
44+
name: String,
45+
description: String,
46+
) {
47+
val kotlinName = "${name}Kotlin"
48+
tasks.register<JavaExec>(kotlinName) {
49+
group = "Verification"
50+
this.description = description
51+
52+
classpath = ktfmt
53+
mainClass = "com.facebook.ktfmt.cli.Main"
54+
55+
// Use paths relative to the current module.
56+
val argumentFile = project.layout.buildDirectory.file("ktfmt-$name-args.txt").get().asFile
57+
val lastRunTimeFile =
58+
project.layout.buildDirectory.file("ktfmt-$name-last-run.txt").get().asFile
59+
60+
// Read the time when this task was last executed for this module (if ever).
61+
val lastRunTime = lastRunTimeFile.takeIf { it.exists() }?.readText()?.toLongOrNull() ?: 0L
62+
63+
// Use a `fileTree` relative to the module's source directory.
64+
val kotlinFiles = project.fileTree("src") { include("**/*.kt") }
65+
66+
// Determine if any files need to be formatted or linted and continue only if there is at least
67+
// one file (otherwise Ktfmt will fail).
68+
onlyIf { kotlinFiles.any { it.lastModified() > lastRunTime } }
69+
70+
inputs.files(kotlinFiles)
71+
72+
doFirst {
73+
// Create the argument file and set the preferred formatting style.
74+
argumentFile.parentFile.mkdirs()
75+
argumentFile.writeText("--kotlinlang-style\n")
76+
77+
if (name == "lint") {
78+
// For lint, do a dry run, so no files are modified. Set the exit code to 1 (instead of
79+
// the default 0) if any files need to be formatted, indicating that linting has failed.
80+
argumentFile.appendText("--dry-run\n")
81+
argumentFile.appendText("--set-exit-if-changed\n")
82+
}
83+
84+
// Write the modified files to the argument file.
85+
kotlinFiles.filter { it.lastModified() > lastRunTime }
86+
.forEach { argumentFile.appendText("${it.absolutePath}\n") }
87+
}
88+
89+
doLast {
90+
// Record the last execution time for later up-to-date checking.
91+
lastRunTimeFile.writeText(System.currentTimeMillis().toString())
92+
}
93+
94+
// Pass the argument file using the @ symbol
95+
args = listOf("@${argumentFile.absolutePath}")
96+
97+
outputs.upToDateWhen { kotlinFiles.none { it.lastModified() > lastRunTime } }
98+
}
99+
100+
tasks.named(name) {
101+
dependsOn(tasks.named(kotlinName))
102+
}
103+
}
104+
105+
registerKtfmt(name = "format", description = "Formats all Kotlin source files.")
106+
registerKtfmt(name = "lint", description = "Verifies all Kotlin source files are formatted.")

openai-java-core/src/main/kotlin/com/openai/models/embeddings/EmbeddingValue.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,10 +115,10 @@ private constructor(
115115
return true
116116
}
117117

118-
return /* spotless:off */ other is EmbeddingValue && floats == other.floats && base64 == other.base64 /* spotless:on */
118+
return other is EmbeddingValue && floats == other.floats && base64 == other.base64
119119
}
120120

121-
override fun hashCode(): Int = /* spotless:off */ Objects.hash(floats, base64) /* spotless:on */
121+
override fun hashCode(): Int = Objects.hash(floats, base64)
122122

123123
override fun toString(): String =
124124
when {

scripts/build

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#!/usr/bin/env bash
2+
3+
set -e
4+
5+
cd "$(dirname "$0")/.."
6+
7+
echo "==> Building classes"
8+
./gradlew build testClasses -x test

scripts/format

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,5 @@ set -e
44

55
cd "$(dirname "$0")/.."
66

7-
echo "==> Running spotlessApply"
8-
./gradlew spotlessApply
7+
echo "==> Running formatters"
8+
./gradlew format

scripts/lint

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,5 @@ set -e
44

55
cd "$(dirname "$0")/.."
66

7-
echo "==> Build classes"
8-
./gradlew build testClasses -x test
7+
echo "==> Running lints"
8+
./gradlew lint

0 commit comments

Comments
 (0)