├── .github ├── renovate.json └── workflows │ └── build.yaml ├── .gitignore ├── LICENSE.md ├── README.md ├── build.gradle.kts ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── images └── buildscan.png ├── settings.gradle.kts └── src ├── main └── kotlin │ └── io │ └── github │ └── cdsap │ └── kotlinprocess │ ├── InfoKotlinProcessBuildService.kt │ ├── InfoKotlinProcessPlugin.kt │ └── output │ ├── ConsoleOutput.kt │ ├── DevelocityValues.kt │ └── EnterpriseValues.kt └── test └── kotlin └── io └── github └── cdsap └── kotlinprocess ├── InfoKotlinProcessPluginTest.kt └── InfoKotlinProcessPluginWtihBuildScanTest.kt /.github/renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://docs.renovatebot.com/renovate-schema.json", 3 | "extends": [ 4 | "config:base" 5 | ] 6 | } 7 | -------------------------------------------------------------------------------- /.github/workflows/build.yaml: -------------------------------------------------------------------------------- 1 | name: Run Gradle on PRs 2 | on: 3 | pull_request: 4 | push: 5 | branches: [main] 6 | jobs: 7 | prBranch: 8 | timeout-minutes: 300 9 | strategy: 10 | matrix: 11 | os: [ubuntu-latest,macos-latest] 12 | runs-on: ${{ matrix.os }} 13 | steps: 14 | - uses: actions/checkout@v4 15 | - uses: actions/setup-java@v4 16 | with: 17 | distribution: temurin 18 | java-version: 11 19 | 20 | - name: Setup Gradle 21 | uses: gradle/gradle-build-action@v3 22 | - name: Execute Gradle build 23 | run: ./gradlew test -PexcludeTests=*.InfoKotlinProcessPluginTest 24 | env: 25 | GE_URL: ${{ secrets.GE_URL }} 26 | GE_API_KEY: ${{ secrets.GE_API_KEY }} 27 | 28 | integrationJavaTests: 29 | timeout-minutes: 300 30 | strategy: 31 | matrix: 32 | os: [ubuntu-latest,macos-latest] 33 | version: [11, 17, 19] 34 | vendor: [temurin, zulu, liberica] 35 | runs-on: ${{ matrix.os }} 36 | steps: 37 | - uses: actions/checkout@v4 38 | - uses: actions/setup-java@v4 39 | with: 40 | distribution: ${{ matrix.vendor }} 41 | java-version: ${{ matrix.version }} 42 | 43 | - name: Setup Gradle 44 | uses: gradle/gradle-build-action@v3 45 | - name: Execute Gradle build 46 | run: ./gradlew test --tests io.github.cdsap.kotlinprocess.InfoKotlinProcessPluginTest 47 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # built application files 2 | *.apk 3 | *.ap_ 4 | 5 | # files for the dex VM 6 | *.dex 7 | 8 | # Java class files 9 | *.class 10 | 11 | # generated files 12 | bin/ 13 | gen/ 14 | out/ 15 | build/ 16 | 17 | # Local configuration file (sdk path, etc) 18 | local.properties 19 | 20 | # Eclipse project files 21 | .classpath 22 | .project 23 | 24 | # Windows thumbnail db 25 | .DS_Store 26 | 27 | # IDEA/Android Studio project files, because 28 | # the project can be imported from settings.gradle.kts 29 | *.iml 30 | .idea/* 31 | !.idea/copyright 32 | # Keep the code styles. 33 | !/.idea/codeStyles 34 | /.idea/codeStyles/* 35 | !/.idea/codeStyles/Project.xml 36 | !/.idea/codeStyles/codeStyleConfig.xml 37 | 38 | # Gradle cache 39 | .gradle 40 | 41 | # Sandbox stuff 42 | _sandbox 43 | 44 | # Android Studio captures folder 45 | captures/ 46 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Iñaki Villar 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Info Kotlin Process Plugin 2 | Includes information about Kotlin processes in the Build Scans or in the build output. 3 | The plugin is compatible with configuration cache. 4 | 5 | ## Usage 6 | Apply the plugin in the main `build.gradle(.kts)` configuration file: 7 | 8 | #### Kotlin 9 | Using the plugins DSL: 10 | ``` groovy 11 | plugins { 12 | id("io.github.cdsap.kotlinprocess") version "0.1.7" 13 | } 14 | ``` 15 | 16 | Using legacy plugin application: 17 | ``` groovy 18 | buildscript { 19 | repositories { 20 | gradlePluginPortal() 21 | } 22 | dependencies { 23 | classpath("io.github.cdsap:infokotlinprocess:0.1.7") 24 | } 25 | } 26 | 27 | apply(plugin = "io.github.cdsap.kotlinprocess") 28 | ``` 29 | 30 | #### Groovy 31 | Using the plugins DSL: 32 | ``` groovy 33 | plugins { 34 | id "io.github.cdsap.kotlinprocess" version "0.1.7" 35 | } 36 | 37 | ``` 38 | 39 | Using legacy plugin application: 40 | ``` groovy 41 | buildscript { 42 | repositories { 43 | gradlePluginPortal() 44 | } 45 | dependencies { 46 | classpath "io.github.cdsap:infokotlinprocess:0.1.7" 47 | } 48 | } 49 | 50 | apply plugin: "io.github.cdsap.kotlinprocess" 51 | ``` 52 | ## Output 53 | ### Build Scans 54 | If you are using Gradle Enterprise, the information about the Kotlin processes will be included as custom value in the 55 | Build Scan: 56 | 57 | ![](images/buildscan.png) 58 | 59 | The field `Usage` represents the value obtained at the end of the build using `jstat` on the JVM process. 60 | 61 | ### Build Output 62 | If you are not using Gradle Enterprise, the information about the Kotlin processes will be included at the end of the build: 63 | ``` 64 | > Task :core:ui:compileProdDebugKotlin 65 | ┌─────────────────────────────────────────────────────────────────────────────┐ 66 | │ Kotlin processes │ 67 | ├─────────┬──────────┬───────────┬────────────┬───────────────┬───────────────┤ 68 | │ PID │ Max │ Usage │ Capacity │ GC Time │ Uptime │ 69 | ├─────────┼──────────┼───────────┼────────────┼───────────────┼───────────────┤ 70 | │ 10865 │ 1.0 Gb │ 0.66 Gb │ 1.0 Gb │ 0.0 minutes │ 0.0 minutes │ 71 | ├─────────┼──────────┼───────────┼────────────┼───────────────┼───────────────┤ 72 | │ 9011 │ 0.5 Gb │ 0.2 Gb │ 0.5 Gb │ 0.0 minutes │ 0.0 minutes │ 73 | └─────────┴──────────┴───────────┴────────────┴───────────────┴───────────────┘ 74 | BUILD SUCCESSFUL in 35s 75 | 76 | ``` 77 | 78 | 79 | ## Requirements 80 | * Gradle 7.5 81 | 82 | ## Libraries 83 | * `com.gradle:develocity-gradle-plugin` 84 | * `com.gradle.enterprise:com.gradle.enterprise.gradle.plugin` 85 | * `com.jakewharton.picnic:picnic` 86 | -------------------------------------------------------------------------------- /build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | `java-gradle-plugin` 3 | `maven-publish` 4 | `kotlin-dsl` 5 | id("com.gradle.plugin-publish") version "1.0.0-rc-1" 6 | } 7 | 8 | group = "io.github.cdsap" 9 | version = "0.1.7" 10 | 11 | java { 12 | toolchain { 13 | languageVersion.set(JavaLanguageVersion.of(11)) 14 | } 15 | } 16 | 17 | dependencies { 18 | implementation("io.github.cdsap:jdk-tools-parser:0.1.1") 19 | implementation("io.github.cdsap:commandline-value-source:0.1.0") 20 | implementation("com.jakewharton.picnic:picnic:0.7.0") 21 | implementation("com.gradle:develocity-gradle-plugin:3.19.1") 22 | implementation("com.gradle.enterprise:com.gradle.enterprise.gradle.plugin:3.19.1") 23 | testImplementation("junit:junit:4.13.2") 24 | } 25 | tasks.withType().configureEach { 26 | filter { 27 | 28 | if (project.hasProperty("excludeTests")) { 29 | excludeTest(project.property("excludeTests").toString(),"") 30 | } 31 | } 32 | } 33 | gradlePlugin { 34 | plugins { 35 | create("InfoKotlinProcessPlugin") { 36 | id = "io.github.cdsap.kotlinprocess" 37 | displayName = "Info Kotlin Processes" 38 | description = "Retrieve information of the Kotlin processes after the build execution" 39 | implementationClass = "io.github.cdsap.kotlinprocess.InfoKotlinProcessPlugin" 40 | } 41 | } 42 | } 43 | 44 | pluginBundle { 45 | website = "https://github.com/cdsap/InfoKotlinProcess" 46 | vcsUrl = "https://github.com/cdsap/InfoKotlinProcess" 47 | tags = listOf("kotlin", "process") 48 | } 49 | 50 | publishing { 51 | repositories { 52 | maven { 53 | name = "Snapshots" 54 | url = uri("https://s01.oss.sonatype.org/content/repositories/snapshots/") 55 | 56 | credentials { 57 | username = System.getenv("USERNAME_SNAPSHOT") 58 | password = System.getenv("PASSWORD_SNAPSHOT") 59 | } 60 | } 61 | maven { 62 | name = "Release" 63 | url = uri("https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/") 64 | 65 | credentials { 66 | username = System.getenv("USERNAME_SNAPSHOT") 67 | password = System.getenv("PASSWORD_SNAPSHOT") 68 | } 69 | } 70 | } 71 | publications { 72 | create("kotlinProcessPublication") { 73 | from(components["java"]) 74 | artifactId = "kotlinprocess" 75 | versionMapping { 76 | usage("java-api") { 77 | fromResolutionOf("runtimeClasspath") 78 | } 79 | usage("java-runtime") { 80 | fromResolutionResult() 81 | } 82 | } 83 | pom { 84 | scm { 85 | connection.set("scm:git:git://github.com/cdsap/InfoKotlinProcess/") 86 | url.set("https://github.com/cdsap/InfoKotlinProcess/") 87 | } 88 | name.set("InfoKotlinProcess") 89 | url.set("https://github.com/cdsap/InfoKotlinProcess/") 90 | description.set( 91 | "Retrieve information of the Kotlin process in your Build Scan or console" 92 | ) 93 | licenses { 94 | license { 95 | name.set("The MIT License (MIT)") 96 | url.set("https://opensource.org/licenses/MIT") 97 | distribution.set("repo") 98 | } 99 | } 100 | developers { 101 | developer { 102 | id.set("cdsap") 103 | name.set("Inaki Villar") 104 | } 105 | } 106 | } 107 | } 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cdsap/InfoKotlinProcess/162f717eee5b9bc625ee3bd94a3a369c7bdca2aa/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.12.1-bin.zip 4 | networkTimeout=10000 5 | validateDistributionUrl=true 6 | zipStoreBase=GRADLE_USER_HOME 7 | zipStorePath=wrapper/dists 8 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # 4 | # Copyright © 2015-2021 the original authors. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # https://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | # SPDX-License-Identifier: Apache-2.0 19 | # 20 | 21 | ############################################################################## 22 | # 23 | # Gradle start up script for POSIX generated by Gradle. 24 | # 25 | # Important for running: 26 | # 27 | # (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is 28 | # noncompliant, but you have some other compliant shell such as ksh or 29 | # bash, then to run this script, type that shell name before the whole 30 | # command line, like: 31 | # 32 | # ksh Gradle 33 | # 34 | # Busybox and similar reduced shells will NOT work, because this script 35 | # requires all of these POSIX shell features: 36 | # * functions; 37 | # * expansions «$var», «${var}», «${var:-default}», «${var+SET}», 38 | # «${var#prefix}», «${var%suffix}», and «$( cmd )»; 39 | # * compound commands having a testable exit status, especially «case»; 40 | # * various built-in commands including «command», «set», and «ulimit». 41 | # 42 | # Important for patching: 43 | # 44 | # (2) This script targets any POSIX shell, so it avoids extensions provided 45 | # by Bash, Ksh, etc; in particular arrays are avoided. 46 | # 47 | # The "traditional" practice of packing multiple parameters into a 48 | # space-separated string is a well documented source of bugs and security 49 | # problems, so this is (mostly) avoided, by progressively accumulating 50 | # options in "$@", and eventually passing that to Java. 51 | # 52 | # Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, 53 | # and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; 54 | # see the in-line comments for details. 55 | # 56 | # There are tweaks for specific operating systems such as AIX, CygWin, 57 | # Darwin, MinGW, and NonStop. 58 | # 59 | # (3) This script is generated from the Groovy template 60 | # https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt 61 | # within the Gradle project. 62 | # 63 | # You can find Gradle at https://github.com/gradle/gradle/. 64 | # 65 | ############################################################################## 66 | 67 | # Attempt to set APP_HOME 68 | 69 | # Resolve links: $0 may be a link 70 | app_path=$0 71 | 72 | # Need this for daisy-chained symlinks. 73 | while 74 | APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path 75 | [ -h "$app_path" ] 76 | do 77 | ls=$( ls -ld "$app_path" ) 78 | link=${ls#*' -> '} 79 | case $link in #( 80 | /*) app_path=$link ;; #( 81 | *) app_path=$APP_HOME$link ;; 82 | esac 83 | done 84 | 85 | # This is normally unused 86 | # shellcheck disable=SC2034 87 | APP_BASE_NAME=${0##*/} 88 | # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) 89 | APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit 90 | 91 | # Use the maximum available, or set MAX_FD != -1 to use that value. 92 | MAX_FD=maximum 93 | 94 | warn () { 95 | echo "$*" 96 | } >&2 97 | 98 | die () { 99 | echo 100 | echo "$*" 101 | echo 102 | exit 1 103 | } >&2 104 | 105 | # OS specific support (must be 'true' or 'false'). 106 | cygwin=false 107 | msys=false 108 | darwin=false 109 | nonstop=false 110 | case "$( uname )" in #( 111 | CYGWIN* ) cygwin=true ;; #( 112 | Darwin* ) darwin=true ;; #( 113 | MSYS* | MINGW* ) msys=true ;; #( 114 | NONSTOP* ) nonstop=true ;; 115 | esac 116 | 117 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 118 | 119 | 120 | # Determine the Java command to use to start the JVM. 121 | if [ -n "$JAVA_HOME" ] ; then 122 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 123 | # IBM's JDK on AIX uses strange locations for the executables 124 | JAVACMD=$JAVA_HOME/jre/sh/java 125 | else 126 | JAVACMD=$JAVA_HOME/bin/java 127 | fi 128 | if [ ! -x "$JAVACMD" ] ; then 129 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 130 | 131 | Please set the JAVA_HOME variable in your environment to match the 132 | location of your Java installation." 133 | fi 134 | else 135 | JAVACMD=java 136 | if ! command -v java >/dev/null 2>&1 137 | then 138 | die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 139 | 140 | Please set the JAVA_HOME variable in your environment to match the 141 | location of your Java installation." 142 | fi 143 | fi 144 | 145 | # Increase the maximum file descriptors if we can. 146 | if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then 147 | case $MAX_FD in #( 148 | max*) 149 | # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. 150 | # shellcheck disable=SC2039,SC3045 151 | MAX_FD=$( ulimit -H -n ) || 152 | warn "Could not query maximum file descriptor limit" 153 | esac 154 | case $MAX_FD in #( 155 | '' | soft) :;; #( 156 | *) 157 | # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. 158 | # shellcheck disable=SC2039,SC3045 159 | ulimit -n "$MAX_FD" || 160 | warn "Could not set maximum file descriptor limit to $MAX_FD" 161 | esac 162 | fi 163 | 164 | # Collect all arguments for the java command, stacking in reverse order: 165 | # * args from the command line 166 | # * the main class name 167 | # * -classpath 168 | # * -D...appname settings 169 | # * --module-path (only if needed) 170 | # * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. 171 | 172 | # For Cygwin or MSYS, switch paths to Windows format before running java 173 | if "$cygwin" || "$msys" ; then 174 | APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) 175 | CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) 176 | 177 | JAVACMD=$( cygpath --unix "$JAVACMD" ) 178 | 179 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 180 | for arg do 181 | if 182 | case $arg in #( 183 | -*) false ;; # don't mess with options #( 184 | /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath 185 | [ -e "$t" ] ;; #( 186 | *) false ;; 187 | esac 188 | then 189 | arg=$( cygpath --path --ignore --mixed "$arg" ) 190 | fi 191 | # Roll the args list around exactly as many times as the number of 192 | # args, so each arg winds up back in the position where it started, but 193 | # possibly modified. 194 | # 195 | # NB: a `for` loop captures its iteration list before it begins, so 196 | # changing the positional parameters here affects neither the number of 197 | # iterations, nor the values presented in `arg`. 198 | shift # remove old arg 199 | set -- "$@" "$arg" # push replacement arg 200 | done 201 | fi 202 | 203 | 204 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 205 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' 206 | 207 | # Collect all arguments for the java command: 208 | # * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, 209 | # and any embedded shellness will be escaped. 210 | # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be 211 | # treated as '${Hostname}' itself on the command line. 212 | 213 | set -- \ 214 | "-Dorg.gradle.appname=$APP_BASE_NAME" \ 215 | -classpath "$CLASSPATH" \ 216 | org.gradle.wrapper.GradleWrapperMain \ 217 | "$@" 218 | 219 | # Stop when "xargs" is not available. 220 | if ! command -v xargs >/dev/null 2>&1 221 | then 222 | die "xargs is not available" 223 | fi 224 | 225 | # Use "xargs" to parse quoted args. 226 | # 227 | # With -n1 it outputs one arg per line, with the quotes and backslashes removed. 228 | # 229 | # In Bash we could simply go: 230 | # 231 | # readarray ARGS < <( xargs -n1 <<<"$var" ) && 232 | # set -- "${ARGS[@]}" "$@" 233 | # 234 | # but POSIX shell has neither arrays nor command substitution, so instead we 235 | # post-process each arg (as a line of input to sed) to backslash-escape any 236 | # character that might be a shell metacharacter, then use eval to reverse 237 | # that process (while maintaining the separation between arguments), and wrap 238 | # the whole thing up as a single "set" statement. 239 | # 240 | # This will of course break if any of these variables contains a newline or 241 | # an unmatched quote. 242 | # 243 | 244 | eval "set -- $( 245 | printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | 246 | xargs -n1 | 247 | sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | 248 | tr '\n' ' ' 249 | )" '"$@"' 250 | 251 | exec "$JAVACMD" "$@" 252 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | @rem SPDX-License-Identifier: Apache-2.0 17 | @rem 18 | 19 | @if "%DEBUG%"=="" @echo off 20 | @rem ########################################################################## 21 | @rem 22 | @rem Gradle startup script for Windows 23 | @rem 24 | @rem ########################################################################## 25 | 26 | @rem Set local scope for the variables with windows NT shell 27 | if "%OS%"=="Windows_NT" setlocal 28 | 29 | set DIRNAME=%~dp0 30 | if "%DIRNAME%"=="" set DIRNAME=. 31 | @rem This is normally unused 32 | set APP_BASE_NAME=%~n0 33 | set APP_HOME=%DIRNAME% 34 | 35 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 36 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 37 | 38 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 39 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 40 | 41 | @rem Find java.exe 42 | if defined JAVA_HOME goto findJavaFromJavaHome 43 | 44 | set JAVA_EXE=java.exe 45 | %JAVA_EXE% -version >NUL 2>&1 46 | if %ERRORLEVEL% equ 0 goto execute 47 | 48 | echo. 1>&2 49 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 50 | echo. 1>&2 51 | echo Please set the JAVA_HOME variable in your environment to match the 1>&2 52 | echo location of your Java installation. 1>&2 53 | 54 | goto fail 55 | 56 | :findJavaFromJavaHome 57 | set JAVA_HOME=%JAVA_HOME:"=% 58 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 59 | 60 | if exist "%JAVA_EXE%" goto execute 61 | 62 | echo. 1>&2 63 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 64 | echo. 1>&2 65 | echo Please set the JAVA_HOME variable in your environment to match the 1>&2 66 | echo location of your Java installation. 1>&2 67 | 68 | goto fail 69 | 70 | :execute 71 | @rem Setup the command line 72 | 73 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 74 | 75 | 76 | @rem Execute Gradle 77 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 78 | 79 | :end 80 | @rem End local scope for the variables with windows NT shell 81 | if %ERRORLEVEL% equ 0 goto mainEnd 82 | 83 | :fail 84 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 85 | rem the _cmd.exe /c_ return code! 86 | set EXIT_CODE=%ERRORLEVEL% 87 | if %EXIT_CODE% equ 0 set EXIT_CODE=1 88 | if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% 89 | exit /b %EXIT_CODE% 90 | 91 | :mainEnd 92 | if "%OS%"=="Windows_NT" endlocal 93 | 94 | :omega 95 | -------------------------------------------------------------------------------- /images/buildscan.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cdsap/InfoKotlinProcess/162f717eee5b9bc625ee3bd94a3a369c7bdca2aa/images/buildscan.png -------------------------------------------------------------------------------- /settings.gradle.kts: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | repositories { 3 | gradlePluginPortal() 4 | google() 5 | mavenCentral() 6 | } 7 | } 8 | 9 | dependencyResolutionManagement { 10 | repositoriesMode.set(RepositoriesMode.PREFER_SETTINGS) 11 | repositories { 12 | gradlePluginPortal() 13 | google() 14 | mavenCentral() 15 | } 16 | } 17 | 18 | rootProject.name = "infokotlinprocess" 19 | 20 | -------------------------------------------------------------------------------- /src/main/kotlin/io/github/cdsap/kotlinprocess/InfoKotlinProcessBuildService.kt: -------------------------------------------------------------------------------- 1 | package io.github.cdsap.kotlinprocess 2 | 3 | import io.github.cdsap.jdk.tools.parser.ConsolidateProcesses 4 | import io.github.cdsap.jdk.tools.parser.model.TypeProcess 5 | import io.github.cdsap.kotlinprocess.output.ConsoleOutput 6 | import org.gradle.api.provider.Provider 7 | import org.gradle.api.services.BuildService 8 | import org.gradle.api.services.BuildServiceParameters 9 | import org.gradle.tooling.events.FinishEvent 10 | import org.gradle.tooling.events.OperationCompletionListener 11 | 12 | abstract class InfoKotlinProcessBuildService : 13 | BuildService, AutoCloseable, 14 | OperationCompletionListener { 15 | interface Params : BuildServiceParameters { 16 | var jInfoProvider: Provider 17 | var jStatProvider: Provider 18 | } 19 | 20 | override fun close() { 21 | val processes = 22 | ConsolidateProcesses().consolidate( 23 | parameters.jStatProvider.get(), 24 | parameters.jInfoProvider.get(), 25 | TypeProcess.Kotlin 26 | ) 27 | if (processes.isNotEmpty()) { 28 | ConsoleOutput(processes).print() 29 | } 30 | } 31 | 32 | override fun onFinish(event: FinishEvent?) {} 33 | } 34 | -------------------------------------------------------------------------------- /src/main/kotlin/io/github/cdsap/kotlinprocess/InfoKotlinProcessPlugin.kt: -------------------------------------------------------------------------------- 1 | package io.github.cdsap.kotlinprocess 2 | 3 | import com.gradle.develocity.agent.gradle.DevelocityConfiguration 4 | import com.gradle.scan.plugin.BuildScanExtension 5 | import io.github.cdsap.jdk.tools.parser.ConsolidateProcesses 6 | import io.github.cdsap.jdk.tools.parser.model.Process 7 | import io.github.cdsap.jdk.tools.parser.model.TypeProcess 8 | import io.github.cdsap.kotlinprocess.output.DevelocityValues 9 | import io.github.cdsap.kotlinprocess.output.EnterpriseValues 10 | import io.github.cdsap.valuesourceprocess.jInfo 11 | import io.github.cdsap.valuesourceprocess.jStat 12 | import org.gradle.api.Plugin 13 | import org.gradle.api.Project 14 | import org.gradle.api.provider.Provider 15 | import org.gradle.build.event.BuildEventsListenerRegistry 16 | import org.gradle.kotlin.dsl.support.serviceOf 17 | 18 | 19 | class InfoKotlinProcessPlugin : Plugin { 20 | private val nameProcess = "KotlinCompileDaemon" 21 | override fun apply(target: Project) { 22 | target.gradle.rootProject { 23 | 24 | val develocityConfiguration = extensions.findByType(DevelocityConfiguration::class.java) 25 | val enterpriseExtension = extensions.findByType(com.gradle.scan.plugin.BuildScanExtension::class.java) 26 | 27 | if (develocityConfiguration != null) { 28 | buildScanDevelocityReporting(project, develocityConfiguration) 29 | } else if (enterpriseExtension != null) { 30 | buildScanEnterpriseReporting(project, enterpriseExtension) 31 | } else { 32 | consoleReporting(target) 33 | } 34 | } 35 | } 36 | 37 | private fun consoleReporting(project: Project) { 38 | val service = project.gradle.sharedServices.registerIfAbsent( 39 | "kotlinProcessService", InfoKotlinProcessBuildService::class.java 40 | ) { 41 | parameters.jInfoProvider = project.jInfo(nameProcess) 42 | parameters.jStatProvider = project.jStat(nameProcess) 43 | } 44 | project.serviceOf().onTaskCompletion(service) 45 | } 46 | 47 | private fun buildScanEnterpriseReporting( 48 | project: Project, 49 | buildScanExtension: BuildScanExtension 50 | ) { 51 | val (jStat, jInfo) = providerPair(project) 52 | 53 | buildScanExtension.buildFinished { 54 | val processes = processes(jStat, jInfo) 55 | EnterpriseValues(buildScanExtension, processes).addProcessesInfoToBuildScan() 56 | } 57 | } 58 | 59 | private fun buildScanDevelocityReporting( 60 | project: Project, 61 | buildScanExtension: DevelocityConfiguration 62 | ) { 63 | val (jStat, jInfo) = providerPair(project) 64 | 65 | buildScanExtension.buildScan.buildFinished { 66 | val processes = processes(jStat, jInfo) 67 | DevelocityValues(buildScanExtension, processes).addProcessesInfoToBuildScan() 68 | } 69 | } 70 | 71 | private fun processes( 72 | jStat: Provider, 73 | jInfo: Provider 74 | ): List { 75 | val processes = ConsolidateProcesses().consolidate(jStat.get(), jInfo.get(), TypeProcess.Kotlin) 76 | return processes 77 | } 78 | 79 | private fun providerPair(project: Project): Pair, Provider> { 80 | val jStat = project.jStat(nameProcess) 81 | val jInfo = project.jInfo(nameProcess) 82 | return Pair(jStat, jInfo) 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /src/main/kotlin/io/github/cdsap/kotlinprocess/output/ConsoleOutput.kt: -------------------------------------------------------------------------------- 1 | package io.github.cdsap.kotlinprocess.output 2 | 3 | import com.jakewharton.picnic.TextAlignment 4 | import com.jakewharton.picnic.table 5 | import io.github.cdsap.jdk.tools.parser.model.Process 6 | 7 | class ConsoleOutput(private val processes: List) { 8 | fun print() { 9 | println( 10 | table { 11 | cellStyle { 12 | border = true 13 | alignment = TextAlignment.MiddleLeft 14 | paddingLeft = 2 15 | paddingRight = 2 16 | } 17 | body { 18 | row { 19 | cell("Kotlin processes") { 20 | columnSpan = 7 21 | } 22 | } 23 | row { 24 | cell("PID") 25 | cell("Max") 26 | cell("Usage") 27 | cell("Capacity") 28 | cell("GC Time") 29 | cell("GC Type") 30 | cell("Uptime") 31 | } 32 | 33 | processes.forEach { 34 | row { 35 | cell(it.pid) 36 | cell("${it.max} Gb") 37 | cell("${it.usage} Gb") 38 | cell("${it.capacity} Gb") 39 | cell("${it.gcTime} minutes") 40 | cell(it.typeGc) 41 | cell("${it.uptime} minutes") 42 | } 43 | } 44 | } 45 | }) 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/main/kotlin/io/github/cdsap/kotlinprocess/output/DevelocityValues.kt: -------------------------------------------------------------------------------- 1 | package io.github.cdsap.kotlinprocess.output 2 | 3 | import com.gradle.develocity.agent.gradle.DevelocityConfiguration 4 | import io.github.cdsap.jdk.tools.parser.model.Process 5 | 6 | class DevelocityValues( 7 | private val develocityConfiguration: DevelocityConfiguration, 8 | private val processes: List, 9 | ) { 10 | 11 | fun addProcessesInfoToBuildScan() { 12 | processes.map { 13 | develocityConfiguration.buildScan { 14 | value("Kotlin-Process-${it.pid}-max", "${it.max} GB") 15 | value("Kotlin-Process-${it.pid}-usage", "${it.usage} GB") 16 | value("Kotlin-Process-${it.pid}-capacity", "${it.capacity} GB") 17 | value("Kotlin-Process-${it.pid}-uptime", "${it.uptime} minutes") 18 | value("Kotlin-Process-${it.pid}-gcTime", "${it.gcTime} minutes") 19 | value("Kotlin-Process-${it.pid}-gcType", it.typeGc) 20 | } 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/kotlin/io/github/cdsap/kotlinprocess/output/EnterpriseValues.kt: -------------------------------------------------------------------------------- 1 | package io.github.cdsap.kotlinprocess.output 2 | 3 | import com.gradle.scan.plugin.BuildScanExtension 4 | import io.github.cdsap.jdk.tools.parser.model.Process 5 | 6 | class EnterpriseValues( 7 | private val buildScanExtension: BuildScanExtension, 8 | private val processes: List, 9 | ) { 10 | 11 | fun addProcessesInfoToBuildScan() { 12 | processes.map { 13 | with(buildScanExtension) { 14 | value("Kotlin-Process-${it.pid}-max", "${it.max} GB") 15 | value("Kotlin-Process-${it.pid}-usage", "${it.usage} GB") 16 | value("Kotlin-Process-${it.pid}-capacity", "${it.capacity} GB") 17 | value("Kotlin-Process-${it.pid}-uptime", "${it.uptime} minutes") 18 | value("Kotlin-Process-${it.pid}-gcTime", "${it.gcTime} minutes") 19 | value("Kotlin-Process-${it.pid}-gcType", it.typeGc) 20 | } 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/test/kotlin/io/github/cdsap/kotlinprocess/InfoKotlinProcessPluginTest.kt: -------------------------------------------------------------------------------- 1 | package io.github.cdsap.kotlinprocess 2 | 3 | import junit.framework.TestCase.assertTrue 4 | import org.gradle.testkit.runner.BuildResult 5 | import org.gradle.testkit.runner.GradleRunner 6 | import org.junit.Assume 7 | import org.junit.Rule 8 | import org.junit.Test 9 | import org.junit.rules.TemporaryFolder 10 | 11 | class InfoKotlinProcessPluginTest { 12 | 13 | private val gradleVersions = listOf("8.6", "8.7", "8.12.1") 14 | 15 | @Rule 16 | @JvmField 17 | val testProjectDir = TemporaryFolder() 18 | 19 | @Test 20 | fun testOutputIsGeneratedWhenPluginIsApplied() { 21 | createBuildGradle() 22 | createKotlinClass() 23 | 24 | gradleVersions.forEach { 25 | val build = simpleKotlinCompileBuild(it) 26 | assertTerminalOutput(build) 27 | } 28 | } 29 | 30 | 31 | @Test 32 | fun testPluginIsCompatibleWithConfigurationCacheWithoutGradleEnterprise() { 33 | createBuildGradle() 34 | 35 | gradleVersions.forEach { 36 | val firstBuild = GradleRunner.create() 37 | .withProjectDir(testProjectDir.root) 38 | .withArguments("clean", "compileKotlin", "--no-build-cache", "--configuration-cache") 39 | .withPluginClasspath() 40 | .withGradleVersion(it) 41 | .build() 42 | val secondBuild = GradleRunner.create() 43 | .withProjectDir(testProjectDir.root) 44 | .withArguments("clean", "compileKotlin", "--no-build-cache", "--configuration-cache") 45 | .withPluginClasspath() 46 | .withGradleVersion(it) 47 | .build() 48 | assertTrue(firstBuild.output.contains("Configuration cache entry stored")) 49 | assertTrue(firstBuild.output.contains("Kotlin processes")) 50 | assertTrue(secondBuild.output.contains("Configuration cache entry reused.")) 51 | assertTrue(secondBuild.output.contains("Kotlin processes")) 52 | 53 | } 54 | } 55 | 56 | @Test 57 | fun testOutputIsGeneratedWhenPluginIsAppliedWithJvmArgs() { 58 | testProjectDir.newFile("gradle.properties").writeText( 59 | """ 60 | org.gradle.jvmargs=-Xmx256m -Dfile.encoding=UTF-8 61 | """.trimIndent() 62 | ) 63 | 64 | createBuildGradle() 65 | createKotlinClass() 66 | 67 | gradleVersions.forEach { 68 | val build = simpleKotlinCompileBuild(it) 69 | assertTerminalOutput(build) 70 | } 71 | } 72 | 73 | @Test 74 | fun testOutputIsGeneratedWhenPluginIsAppliedWithJvmArgsAndKotlinJvm() { 75 | testProjectDir.newFile("gradle.properties").writeText( 76 | """ 77 | org.gradle.jvmargs=-Xmx256m -Dfile.encoding=UTF-8 78 | kotlin.daemon.jvmargs=-Xmx128m 79 | """.trimIndent() 80 | ) 81 | createBuildGradle() 82 | createKotlinClass() 83 | 84 | gradleVersions.forEach { 85 | val build = simpleKotlinCompileBuild(it) 86 | assertTerminalOutput(build) 87 | } 88 | } 89 | 90 | @Test 91 | fun testOutputIsGeneratedWhenPluginIsAppliedWithJvmArgsAndKotlinGCJvm() { 92 | testProjectDir.newFile("gradle.properties").writeText( 93 | """ 94 | org.gradle.jvmargs=-Xmx256m -Dfile.encoding=UTF-8 95 | kotlin.daemon.jvmargs=-Xmx128m -XX:+UseParallelGC 96 | """.trimIndent() 97 | ) 98 | createBuildGradle() 99 | createKotlinClass() 100 | 101 | gradleVersions.forEach { 102 | val build = simpleKotlinCompileBuild(it) 103 | assertTerminalOutput(build) 104 | } 105 | } 106 | 107 | @Test 108 | fun testOutputIsGeneratedWhenPluginIsAppliedWithJvmGCArgsAndKotlinJvm() { 109 | testProjectDir.newFile("gradle.properties").writeText( 110 | """ 111 | org.gradle.jvmargs=-Xmx256m -XX:+UseParallelGC -Dfile.encoding=UTF-8 112 | """.trimIndent() 113 | ) 114 | createBuildGradle() 115 | createKotlinClass() 116 | 117 | gradleVersions.forEach { 118 | val build = simpleKotlinCompileBuild(it) 119 | assertTerminalOutput(build) 120 | assertTrue(build.output.contains("G1")) 121 | } 122 | } 123 | 124 | @Test 125 | fun testOutputIsGeneratedWhenPluginIsAppliedWithJvmGCArgsAndKotlinGCJvm() { 126 | testProjectDir.newFile("gradle.properties").writeText( 127 | """ 128 | org.gradle.jvmargs=-Xmx258m -XX:+UseParallelGC -Dfile.encoding=UTF-8 129 | kotlin.daemon.jvmargs=-Xmx600m -XX:+UseParallelGC 130 | """.trimIndent() 131 | ) 132 | createBuildGradle() 133 | createKotlinClass() 134 | 135 | gradleVersions.forEach { 136 | val build = simpleKotlinCompileBuild(it) 137 | assertTerminalOutput(build) 138 | assertTrue(build.output.contains("UseParallelGC")) 139 | } 140 | } 141 | 142 | @Test 143 | fun testOutputIsGeneratedWhenPluginIsAppliedWithJvmGCArgsAndKotlinZ1Jvm() { 144 | Assume.assumeTrue(Runtime.version().feature() >= 15) 145 | 146 | testProjectDir.newFile("gradle.properties").writeText( 147 | """ 148 | org.gradle.jvmargs=-Xmx256m -XX:+UseParallelGC -Dfile.encoding=UTF-8 149 | kotlin.daemon.jvmargs=-Xmx750m -XX:+UnlockExperimentalVMOptions -XX:+UseZGC 150 | """.trimIndent() 151 | ) 152 | 153 | createBuildGradle17() 154 | createKotlinClass() 155 | 156 | gradleVersions.forEach { 157 | val build = simpleKotlinCompileBuild(it) 158 | assertTerminalOutput(build) 159 | assertTrue(build.output.contains("Z")) 160 | 161 | } 162 | } 163 | 164 | private fun simpleKotlinCompileBuild(it: String): BuildResult = GradleRunner.create() 165 | .withProjectDir(testProjectDir.root) 166 | .withArguments("compileKotlin", "--info") 167 | .withPluginClasspath() 168 | .withGradleVersion(it) 169 | .withDebug(true) 170 | .build() 171 | 172 | private fun assertTerminalOutput(build: BuildResult) { 173 | print(build.output) 174 | assertTrue(build.output.contains("Kotlin processes")) 175 | assertTrue(build.output.contains("PID")) 176 | assertTrue(build.output.contains("Capacity")) 177 | assertTrue(build.output.contains("Uptime")) 178 | assertTrue(build.output.contains("minutes")) 179 | assertTrue(build.output.contains("Gb")) 180 | } 181 | 182 | private fun createBuildGradle() { 183 | testProjectDir.newFile("build.gradle").appendText( 184 | """ 185 | plugins { 186 | id 'org.jetbrains.kotlin.jvm' version '1.7.21' 187 | id 'application' 188 | id 'io.github.cdsap.kotlinprocess' 189 | } 190 | repositories { 191 | mavenCentral() 192 | } 193 | 194 | """.trimIndent() 195 | ) 196 | } 197 | 198 | private fun createBuildGradle17() { 199 | testProjectDir.newFile("build.gradle").appendText( 200 | """ 201 | plugins { 202 | id 'org.jetbrains.kotlin.jvm' version '1.7.21' 203 | id 'application' 204 | id 'io.github.cdsap.kotlinprocess' 205 | } 206 | repositories { 207 | mavenCentral() 208 | } 209 | java { 210 | toolchain { 211 | languageVersion = JavaLanguageVersion.of(17) 212 | } 213 | } 214 | """.trimIndent() 215 | ) 216 | } 217 | 218 | private fun createKotlinClass() { 219 | testProjectDir.newFolder("src/main/kotlin/com/example") 220 | testProjectDir.newFile("src/main/kotlin/com/example/Hello.kt").appendText( 221 | """ 222 | package com.example 223 | class Hello() { 224 | fun print() { 225 | println("hello") 226 | } 227 | } 228 | """.trimIndent() 229 | ) 230 | } 231 | } 232 | -------------------------------------------------------------------------------- /src/test/kotlin/io/github/cdsap/kotlinprocess/InfoKotlinProcessPluginWtihBuildScanTest.kt: -------------------------------------------------------------------------------- 1 | package io.github.cdsap.kotlinprocess 2 | 3 | import junit.framework.TestCase 4 | import org.gradle.internal.impldep.org.junit.Assume 5 | import org.gradle.testkit.runner.GradleRunner 6 | import org.junit.Rule 7 | import org.junit.Test 8 | import org.junit.rules.TemporaryFolder 9 | 10 | class InfoKotlinProcessPluginWtihBuildScanTest { 11 | 12 | @Rule 13 | @JvmField 14 | val testProjectDir = TemporaryFolder() 15 | @Test 16 | fun testPluginIsCompatibleWithConfigurationCacheWithGradleEnterprise() { 17 | Assume.assumeTrue( 18 | "Gradle Enterprise URL and Access Key are set", 19 | System.getenv("GE_URL") != null && System.getenv("GE_API_KEY") != null 20 | ) 21 | 22 | testProjectDir.newFile("settings.gradle").appendText( 23 | """ 24 | plugins { 25 | id 'com.gradle.enterprise' version '3.12.2' 26 | } 27 | gradleEnterprise { 28 | server = "${System.getenv("GE_URL")}" 29 | accessKey="${System.getenv("GE_API_KEY")}" 30 | buildScan { 31 | capture { taskInputFiles = true } 32 | publishAlways() 33 | 34 | } 35 | } 36 | """.trimIndent() 37 | ) 38 | testProjectDir.newFile("build.gradle").appendText( 39 | """ 40 | plugins { 41 | id 'org.jetbrains.kotlin.jvm' version '1.7.21' 42 | id 'application' 43 | id 'io.github.cdsap.kotlinprocess' 44 | } 45 | repositories { 46 | mavenCentral() 47 | } 48 | 49 | """.trimIndent() 50 | ) 51 | listOf("8.1.1").forEach { 52 | val firstBuild = GradleRunner.create() 53 | .withProjectDir(testProjectDir.root) 54 | .withArguments("compileKotlin", "--configuration-cache") 55 | .withPluginClasspath() 56 | .withGradleVersion(it) 57 | .build() 58 | val secondBuild = GradleRunner.create() 59 | .withProjectDir(testProjectDir.root) 60 | .withArguments("compileKotlin", "--configuration-cache") 61 | .withPluginClasspath() 62 | .withGradleVersion(it) 63 | .build() 64 | TestCase.assertTrue(firstBuild.output.contains("Configuration cache entry stored")) 65 | TestCase.assertTrue(secondBuild.output.contains("Configuration cache entry reused.")) 66 | } 67 | } 68 | 69 | @Test 70 | fun testPluginIsCompatibleWithConfigurationCacheWithDevelocity() { 71 | Assume.assumeTrue( 72 | "Gradle Enterprise URL and Access Key are set", 73 | System.getenv("GE_URL") != null && System.getenv("GE_API_KEY") != null 74 | ) 75 | 76 | testProjectDir.newFile("settings.gradle").appendText( 77 | """ 78 | plugins { 79 | id 'com.gradle.develocity' version '3.17.2' 80 | } 81 | develocity { 82 | server = "${System.getenv("GE_URL")}" 83 | accessKey="${System.getenv("GE_API_KEY")}" 84 | buildScan { 85 | publishing { true } 86 | } 87 | } 88 | """.trimIndent() 89 | ) 90 | testProjectDir.newFile("build.gradle").appendText( 91 | """ 92 | plugins { 93 | id 'org.jetbrains.kotlin.jvm' version '1.7.21' 94 | id 'application' 95 | id 'io.github.cdsap.kotlinprocess' 96 | } 97 | repositories { 98 | mavenCentral() 99 | } 100 | 101 | """.trimIndent() 102 | ) 103 | listOf("8.1.1").forEach { 104 | val firstBuild = GradleRunner.create() 105 | .withProjectDir(testProjectDir.root) 106 | .withArguments("compileKotlin", "--configuration-cache") 107 | .withPluginClasspath() 108 | .withGradleVersion(it) 109 | .build() 110 | val secondBuild = GradleRunner.create() 111 | .withProjectDir(testProjectDir.root) 112 | .withArguments("compileKotlin", "--configuration-cache") 113 | .withPluginClasspath() 114 | .withGradleVersion(it) 115 | .build() 116 | TestCase.assertTrue(firstBuild.output.contains("Configuration cache entry stored")) 117 | TestCase.assertTrue(secondBuild.output.contains("Configuration cache entry reused.")) 118 | } 119 | } 120 | } 121 | --------------------------------------------------------------------------------