This gradle plugin helps developers, who organise dependencies with Kotlin files in a central place such as buildSrc
or includeBuild
, to check if new updates are available and add them to comments along with the dependencies therefore
they can easily upgrade without needing to search it in repositories. Simply just update your version by looking at the
updates in comments. The goal is to keep whatever you have in your Kotlin files such as property declarations, formatting
and comments, but just adding extra comments of updates.
Furthermore, if you are using Android Studio and you have Newer Library Versions Available
turned on, in your gradle
files you can see hints for dependency updates:
But if you declare dependencies variables in Kotlin files then you lose the ability:
This plugin helps to solve the problem.
There are already some libraries there to address this problem, but some require you to migrate your code to use them. It is also a hassle to revert those changes if you later decide to stop using them. Some require you to run command to see updates. For me, it is not intuitive. I want to see updates along with dependencies, I don't want to make any changes to my declaration. What is why I made this plugin.
This is the quick example:
Before
object Junit {
const val junit = "junit:junit:4.12"
}
After
import io.github.zeroarst.dependencyupdatescommenter.CommentUpdates
object Junit {
// Available versions:
// 4.13-rc-2
// 4.13-rc-1
// 4.13-beta-3
// 4.13-beta-2
// 4.13-beta-1
@CommentUpdates
const val junit = "junit:junit:4.12"
}
-
Under the hood, the plugin uses Regular Expression to parse the Kotlin file content to find dependency coordinate and query repositories for updates. Because of that, it is not 100% reliable. It relies on the format of the Kotlin files. You might ask why don't use KSP or AST parser? Please refer to Verbosity.
-
Line breaks are supported:
- ✅CRLF - Windows (\r\n)
- ✅LF - macOS and Unix (\n)
-
Line break is not supported:
- ❌CR - Classic Mac OS (\r)
-
It only searches
search.maven.org
andmaven.google.com
repositories at the moment. If there are other repositories you want to support please let me know. -
This is my first Gradle plugin so be gentle. I am still learning and welcome any feedback! 😊
Make sure you have gradlePluginPortal repository in setting.gradle
or setting.gradle.kts
.
pluginManagement {
repositories {
gradlePluginPortal()
}
}
Kotlin DSL
plugins {
id("io.github.zeroarst.dependency-updates-commenter") version "0.2.4"
}
Groovy
plugins {
id 'io.github.zeroarst.dependency-updates-commenter' version '0.2.4'
}
import io.github.zeroarst.dependencyupdatescommenter.CommentUpdates
object Junit {
@CommentUpdates
const val junit = "junit:junit:4.12"
}
If you have a group of dependencies that use the same version, for example, androidx.activity:activity
and androidx.activity:activity-ktx
. You can specify dependency coordinate along with annotation.
import io.github.zeroarst.dependencyupdatescommenter.CommentUpdates
object AndroidX {
@CommentUpdates(coordinate = "androidx.activity:activity")
const val activityVersion = "1.6.1"
const val activity = "androidx.activity:activity:$activityVersion"
const val activityKtx = "androidx.activity:activity-ktx:$activityVersion"
}
If you are using JetBrains IDEs, you can find the gradle task in Gradle panel. The task is commentDependencyUpdates
under dependenc update commenter
. Double click can execute it.
Note if you apply the plugin to buildSrc
, you might not able to see the task. This link says it is because Gradle does not deliver the buildSrc
tasks to JetBrains IDEs. Please use command line instead: ./gradlew -p buildSrc cDU
or ./gradlew -p buildSrc commentDependencyUpdates
. With the fix in Gradle 8.0, you might be able to run ./gradlew :buildSrc:cDU
.
Composite build works fine in this case.
You could also run the task it via command line ./gradlew :module-if-have:cDU
or ./gradlew :module-if-have:commentDependencyUpdates
with Options. Note this only works on gradle version 7.6.
Again, if apply this plugin to buildSrc
, ./gradlew :buildSrc:cDU
will not work. Check the explanation above.
Once executed, wait for the task completed, then you will get:
import io.github.zeroarst.dependencyupdatescommenter.CommentUpdates
object Junit {
// Available versions:
// 4.13-rc-2
// 4.13-rc-1
// 4.13-beta-3
// 4.13-beta-2
// 4.13-beta-1
@CommentUpdates
const val junit = "junit:junit:4.12"
}
import io.github.zeroarst.dependencyupdatescommenter.CommentUpdates
object AndroidX {
// Available versions:
// 1.6.0
// 1.6.1
// 1.7.0-alpha01
// 1.7.0-alpha02
// 1.7.0-alpha03
@CommentUpdates("androidx.activity:activity")
const val activityVersion = "1.6.1"
const val activity = "androidx.activity:activity:$activityVersion"
const val activityKtx = "androidx.activity:activity-ktx:$activityVersion"
}
Currently only below property declarations are supported.
import io.github.zeroarst.dependencyupdatescommenter.CommentUpdates
Object Junit {
// read-only property.
@CommentUpdates
val junit = "junit:junit:4.12"
// compile-time constants.
@CommentUpdates
const val junit = "junit:junit:4.12"
// lazy property.
@CommentUpdates
val composeUI: String by lazy { "junit:junit:4.12" }
// lazy property with multiple lines.
@CommentUpdates
val composeUI: String by lazy {
"junit:junit:4.12"
}
}
// nested object
object AndroidX {
object Compose {
@CommentUpdates
const val animation = "androidx.compose.animation:animation:1.3.0"
}
}
In the project's build.gradle.kts
or build.gradle
, you can configure options like this:
dependencyUpdatesCommenter {
scanPath = ""
scanSubDirectories = false
order = Order.LATEST_AT_BOTTOM
onlyReleaseVersion = false
maximumVersionCount = 5
usingLatestVerComment = "You are using the latest version."
generateNewFile = true
}
If you use command line, run ./gradlew help --task :module-if-have:cDU
will show you all options. You can execute the
task with options like
this: ./gradlew task --help :module-if-have:cDU --maximumVersionCount=5 --onlyReleaseVersion=true
default: ""
If not specified (empty or null), plugin looks up the first available source dir.
Typically yourProject/src/main/kotlin
or yourProject/src/main/java
.
default: false
Whether to process Kotlin files in sub dirs.
default: LATEST_AT_BOTTOM
Ex.
order = LATEST_AT_BOTTOM
order = LATEST_AT_TOP
default: 20
How many new version items to be added. Using 1 just get the latest version. Combine with onlyReleaseVersion = true
only shows the latest release version.
Ex. maximumVersionCount = 1
default: "State of the art! You are using the latest version."
What to put in the comment if using the latest version
Ex. usingLatestVerComment = "You are using the latest version."
default: false
Whether generate new file for the result with suffix "2". Useful if you want to see the result instead of overwriting
the content.
Ex. generateNewFile = true
default: false
Ignore all updates that have qualifier. Ex. beta, alpha, RC...etc.
Ex. onlyReleaseVersion = true
default: true
Group all versions by major and minor numbers then pick the latest one from each group. For example, if there are updates "1.1.0", "1.1.1", "1.1.2", "1.2.0", "1.2.1", "1.2.2", it will give "1.1.1", "1.2.2". This is turned on by default because in most cases you are like to use the latest major version instead of old ones, which might have bugs that have been fixed.
Ex.
pickLatestGroupedByMajorAndMinor = true
Using Regex as the core of the plugin parser was not my first intention. Before I decided to use implement this via Regex, I did some research and tried different things to find out what is the best way to do it.
The first thing I tried is Kotlin KSP, which is not applicable because it can only generate files in build folder, although it is the best way to process annotations.
Second thing I tried is Kotlin parsers. There are some libraries that parse the Kotlin file into AST (Abstract Syntax Tree) then allow you to manipulate the tree, write back to the file. The one that I got the closest result is: certz's kastree. However, it is not 100% perfect because it changes the original file content unexpectedly such as removing line breaks.
There are some other tools that I investigated : https://github.com/square/kotlinpoet
Nevertheless, there might be something that I missed or there are better ways to parse Kotlin files than using Regular Expression. If you know any please let me know.
If you come across any issue please report it with the log printed via command line: ./gradlew :module-if-have:cDU --debug | grep duc-log
. For buildSrc
run ./gradlew -p buildSrc cDU --debug | grep duc-log
.