-
Notifications
You must be signed in to change notification settings - Fork 171
Expand file tree
/
Copy pathbuild.gradle.kts
More file actions
328 lines (283 loc) · 11.6 KB
/
build.gradle.kts
File metadata and controls
328 lines (283 loc) · 11.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
import com.github.gradle.node.npm.task.NpxTask
import io.sdkman.vendors.tasks.SdkAnnounceVersion
import io.sdkman.vendors.tasks.SdkDefaultVersion
import io.sdkman.vendors.tasks.SdkReleaseVersion
import io.sdkman.vendors.tasks.SdkmanVendorBaseTask
import java.util.Locale
plugins {
id("profiler.java-library")
id("profiler.ide-setup")
groovy
application
`maven-publish`
id("profiler.publication")
alias(libs.plugins.node)
alias(libs.plugins.sdkman)
alias(libs.plugins.nexus)
}
description = "A tool to profile and benchmark Gradle builds"
val gradleRuntime by configurations.creating
val profilerPlugins by configurations.creating
dependencies {
// gradle/gradle uses these as part of Gradle Profiler-as-a-library
api(project(":build-action"))
api(project(":build-operations-measuring"))
implementation(libs.toolingApi)
implementation(project(":client-protocol"))
implementation(project(":scenario-definition"))
implementation(project(":perfetto-trace"))
implementation(libs.findbugs.annotations)
implementation(libs.guava)
implementation(libs.commons.math3)
implementation(libs.javaparser)
implementation(libs.jopt)
implementation(libs.ant.compress)
implementation(libs.commons.compress) {
because("Avoid old version of commons-compress introduced by ant-compress")
}
implementation(libs.commons.io)
implementation(libs.jmc.flightrecorder)
implementation(libs.dd.plist) {
because("To extract launch details from Android Studio installation")
}
implementation(libs.gson) {
because("To write JSON output")
}
gradleRuntime(gradleApi())
gradleRuntime(libs.toolingApi)
profilerPlugins(project(":chrome-trace"))
profilerPlugins(project(":build-operations"))
profilerPlugins(project(":build-operations-measuring"))
profilerPlugins(project(":instrumentation-support"))
profilerPlugins(project(":ide-agent"))
profilerPlugins(project(":heap-dump"))
profilerPlugins(project(":ide-plugin"))
runtimeOnly(libs.slf4j.simple)
testImplementation(libs.bundles.testDependencies)
testImplementation(libs.groovy.json)
testImplementation(libs.groovy.xml)
testImplementation(project(":tooling-action"))
testRuntimeOnly(libs.objenesis)
}
tasks.withType<Jar>().configureEach {
manifest {
attributes(
"Implementation-Title" to "Gradle Profiler",
"Implementation-Version" to project.version
)
}
}
application.mainClass.set("org.gradle.profiler.Main")
node {
download = true
version = "24.13.0"
}
val generateHtmlReportJavaScript = tasks.register<NpxTask>("generateHtmlReportJavaScript") {
dependsOn(tasks.npmInstall)
val source = file("src/main/js/org/gradle/profiler/report/report.js")
val outputDir = layout.buildDirectory.dir("html-report")
val output = outputDir.map { it.file("org/gradle/profiler/report/report.js") }
inputs.file(source)
outputs.dir(outputDir)
command.set("browserify")
args.addAll(source.absolutePath, "--outfile", output.get().asFile.absolutePath)
}
tasks.processResources {
into("META-INF/jars") {
from(profilerPlugins.minus(gradleRuntime)) {
// Removing the version from the JARs here, since they are referenced by name in production code.
rename("""(.*)-\d+\.\d+.*\.jar""", "$1.jar")
}
}
from(generateHtmlReportJavaScript)
}
fun launcherJavaHomeFor(javaVersion: Int): String {
return javaToolchains
.launcherFor { languageVersion = JavaLanguageVersion.of(javaVersion) }
.map { it.metadata.installationPath.asFile.absolutePath.toString() }
.get()
}
class AddOpensArgProvider(private val test: Test) : CommandLineArgumentProvider {
override fun asArguments(): Iterable<String> {
return if (test.javaVersion.isCompatibleWith(JavaVersion.VERSION_1_9)) {
listOf("--add-opens=java.base/java.lang=ALL-UNNAMED")
} else {
emptyList()
}
}
}
tasks.test {
// If testJavaVersion is not set use the current JVM. Some tests require JFR, which is only available
// in some JVM implementations. For now assume that the current JVM has JFR support.
// CI will inject the correct implementation.
val launcher = project.javaToolchains.launcherFor {
val javaVersion = providers
.gradleProperty("testJavaVersion")
.getOrElse(JavaVersion.current().majorVersion)
languageVersion.set(JavaLanguageVersion.of(javaVersion))
providers.gradleProperty("testJavaVendor").map {
when (it.lowercase(Locale.US)) {
"oracle" -> vendor.set(JvmVendorSpec.ORACLE)
"openjdk" -> vendor.set(JvmVendorSpec.ADOPTIUM)
}
}.getOrNull()
}
javaLauncher.set(launcher)
// So processes started from test also use same Java version
environment("JAVA_HOME" to javaLauncher.get().metadata.installationPath)
// We had some build failures on macOS, where it seems to be a Socket was already closed when trying to download the Gradle distribution.
// The tests failing were consistently in ProfilerIntegrationTest.
// Running only ProfilerIntegrationTest did not expose the failures.
// The problem went away when running every test class in its on JVM.
// So I suppose the problem is that the JVM shares the TAPI client, and one of the tests leave the client in a bad state.
// We now use forkEvery = 1 to run each test class in its own JVM, so we don't run into this problem anymore.
setForkEvery(1)
maxHeapSize = "2g"
// Required for mocks when running on Java 17+
jvmArgumentProviders.add(AddOpensArgProvider(this))
// Used by tests to select a different Daemon JVM when Test JVM is unsupported by older Gradle versions
systemProperty("javaHomes.java11", launcherJavaHomeFor(11))
// Run cross-version tests for all tested versions
val integTestVersions = providers.gradleProperty("testVersions").orElse("all")
systemProperty("org.gradle.integtest.versions", integTestVersions.get())
val keepTestDirs = providers.gradleProperty("keepTestDirs").orElse("false")
systemProperty("org.gradle.integtest.keepTestDirs", keepTestDirs.get())
}
val autoDownloadAndRunInHeadless = providers.gradleProperty("autoDownloadAndRunInHeadless")
.map { it.toBoolean() }
.orElse(false)
intellijTests {
autoDownload = autoDownloadAndRunInHeadless
headlessMode = autoDownloadAndRunInHeadless
version = libs.versions.testIntellijVersion
}
androidStudioTests {
headlessMode = autoDownloadAndRunInHeadless
autoDownload = autoDownloadAndRunInHeadless
version = libs.versions.testAndroidStudioVersion
codename = libs.versions.testAndroidStudioCodename
sdkVersion = libs.versions.testAndroidSdkVersion
// For local development it's easier to setup Android SDK with Android Studio, since auto download needs ANDROID_HOME or ANDROID_SDK_ROOT
// to be set with an accepted license in it. See https://developer.android.com/studio/intro/update.html#download-with-gradle.
autoDownloadAndroidSdk = autoDownloadAndRunInHeadless
}
val testReports = mapOf(
"testHtmlReport" to "example",
"testHtmlReportSingle" to "example-single",
"testHtmlReportCacheSize" to "example-cache-size",
"testHtmlReportWithOps" to "example-with-build-operations",
"testHtmlReportRegression" to "example-regression"
)
testReports.forEach { (taskName, fileName) ->
tasks.register<ProcessResources>(taskName) {
val dataFile = file("src/test/resources/org/gradle/profiler/report/${fileName}.json")
inputs.file(dataFile)
inputs.files(tasks.processResources)
from("src/main/resources/org/gradle/profiler/report")
into(layout.buildDirectory.dir("test-html-report"))
rename("report-template.html", "test-report-${fileName}.html")
filter { line ->
if (line == "@@BENCHMARK_RESULT_JSON@@") dataFile.readText()
else if (line == "@@SCRIPT@@") File(
tasks.processResources.get().destinationDir,
"org/gradle/profiler/report/report.js"
).readText(Charsets.UTF_8)
else line
}
}
}
tasks.register("testHtmlReports") {
dependsOn(testReports.keys)
}
val profilerDistribution = artifacts.add("archives", tasks.distZip.flatMap { it.archiveFile }) {
type = "zip"
}
publishing {
publications {
named<MavenPublication>("mavenJava") {
artifact(profilerDistribution)
pom {
// For some reason adding the zip artifact changes the packaging to "pom"
packaging = "jar"
}
}
}
}
nexusPublishing {
packageGroup.set(project.group.toString())
repositories {
sonatype {
nexusUrl.set(uri("https://ossrh-staging-api.central.sonatype.com/service/local/"))
snapshotRepositoryUrl.set(uri("https://central.sonatype.com/repository/maven-snapshots/"))
}
}
}
val releaseTagName = "v$version"
tasks.register<Exec>("gitTag") {
commandLine("git", "tag", releaseTagName)
onlyIf { !isSnapshot() }
}
val gitPushTag = tasks.register<Exec>("gitPushTag") {
mustRunAfter("closeSonatypeStagingRepository")
dependsOn("gitTag")
onlyIf { !isSnapshot() }
commandLine(
"git",
"push",
"https://bot-teamcity:${project.findProperty("githubToken")}@github.com/gradle/gradle-profiler.git",
releaseTagName
)
}
fun Project.isSnapshot() = version.toString().endsWith("-SNAPSHOT")
sdkman {
api = "https://vendors.sdkman.io"
candidate = "gradleprofiler"
hashtag = "#gradleprofiler"
version = project.version.toString()
url = "https://repo1.maven.org/maven2/org/gradle/profiler/gradle-profiler/$version/gradle-profiler-$version.zip"
consumerKey = project.findProperty("sdkmanKey") as String?
consumerToken = project.findProperty("sdkmanToken") as String?
}
tasks.withType<SdkmanVendorBaseTask>().configureEach {
mustRunAfter(gitPushTag)
}
tasks.withType<SdkDefaultVersion>().configureEach {
mustRunAfter(tasks.withType<SdkReleaseVersion>())
}
tasks.withType<SdkAnnounceVersion>().configureEach {
mustRunAfter(tasks.withType<SdkReleaseVersion>())
}
tasks.register("releaseToSdkMan") {
val versionString = project.version.toString()
// We don't publish snapshots and alphas at all to SDKman.
val isSnapshotOrAlphaRelease = versionString.lowercase(Locale.US).run { contains("snapshot") || contains("alpha") }
if (!isSnapshotOrAlphaRelease) {
dependsOn(tasks.withType<SdkReleaseVersion>())
// We only announce and set the default version for final releases
// A release is not final if it contains things different to numbers and dots.
// For example:
// - 1.3: final
// - 1.3.25: final
// - 1.3-rc-4: not final
// - 1.3.RC5: not final
// - 1.3-milestone5: not final
val isFinalRelease = Regex("""[0-9\.]*""").matchEntire(versionString) != null
if (isFinalRelease) {
dependsOn(tasks.withType<SdkDefaultVersion>())
dependsOn(tasks.withType<SdkAnnounceVersion>())
}
}
}
tasks.updateDaemonJvm {
toolchainDownloadUrls.empty()
}
tasks.register<Sync>("install") {
val installDirName = "gradle-profiler.install.dir"
val installDir = providers.gradleProperty(installDirName).orElse("distribution")
.map { layout.settingsDirectory.file(it) }
from(tasks.named<Sync>("installDist").map { it.destinationDir })
into(installDir)
doLast {
println("Installed gradle-profiler to '${installDir.get()}'")
}
}