Skip to content

Commit 3574f26

Browse files
committed
Fix an issue where changing git HEAD does not invalidate task cache.
1 parent 4df1fc0 commit 3574f26

File tree

5 files changed

+118
-1
lines changed

5 files changed

+118
-1
lines changed

api/app-versioning.api

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ public final class io/github/reactivecircus/appversioning/internal/CommitId {
105105
public final class io/github/reactivecircus/appversioning/internal/GitClient {
106106
public static final field Companion Lio/github/reactivecircus/appversioning/internal/GitClient$Companion;
107107
public synthetic fun <init> (Ljava/io/File;Lkotlin/jvm/internal/DefaultConstructorMarker;)V
108+
public final fun checkoutTag (Ljava/lang/String;)V
108109
public final fun commit-HhBVPuw (Ljava/lang/String;Z)Ljava/lang/String;
109110
public static synthetic fun commit-HhBVPuw$default (Lio/github/reactivecircus/appversioning/internal/GitClient;Ljava/lang/String;ZILjava/lang/Object;)Ljava/lang/String;
110111
public final fun describeLatestTag (Ljava/lang/String;)Ljava/lang/String;
@@ -129,6 +130,7 @@ public abstract class io/github/reactivecircus/appversioning/tasks/GenerateAppVe
129130
public fun <init> (Lorg/gradle/workers/WorkerExecutor;)V
130131
public final fun generate ()V
131132
public abstract fun getFetchTagsWhenNoneExistsLocally ()Lorg/gradle/api/provider/Property;
133+
public abstract fun getGitHead ()Lorg/gradle/api/file/RegularFileProperty;
132134
public abstract fun getGitRefsDirectory ()Lorg/gradle/api/file/DirectoryProperty;
133135
public abstract fun getGroovyVersionCodeCustomizer ()Lorg/gradle/api/provider/Property;
134136
public abstract fun getGroovyVersionNameCustomizer ()Lorg/gradle/api/provider/Property;

src/functionalTest/kotlin/io/github/reactivecircus/appversioning/tasks/GenerateAppVersionInfoTest.kt

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -946,6 +946,83 @@ class GenerateAppVersionInfoTest {
946946
gitClient.tag(name = "1.3.0", message = "2nd tag", commitId = commitId2)
947947

948948
runner.runAndCheckResult(
949+
"clean",
950+
"generateAppVersionInfoForRelease",
951+
"--build-cache"
952+
) {
953+
assertThat(task(":app:generateAppVersionInfoForRelease")?.outcome).isEqualTo(TaskOutcome.SUCCESS)
954+
}
955+
}
956+
957+
@Test
958+
fun `GenerateAppVersionInfo (up-to-date) is re-executed after changing git HEAD`() {
959+
val gitClient = GitClient.initialize(fixtureDir.root).apply {
960+
val commitId1 = commit(message = "1st commit.")
961+
tag(name = "1.2.3", message = "1st tag", commitId = commitId1)
962+
val commitId2 = commit(message = "2nd commit.")
963+
tag(name = "1.2.4", message = "2st tag", commitId = commitId2)
964+
}
965+
966+
val runner = withFixtureRunner(
967+
fixtureDir = fixtureDir,
968+
subprojects = listOf(AppProjectTemplate())
969+
)
970+
971+
runner.runAndCheckResult(
972+
"generateAppVersionInfoForRelease"
973+
) {
974+
assertThat(task(":app:generateAppVersionInfoForRelease")?.outcome).isEqualTo(TaskOutcome.SUCCESS)
975+
}
976+
977+
runner.runAndCheckResult(
978+
"generateAppVersionInfoForRelease"
979+
) {
980+
assertThat(task(":app:generateAppVersionInfoForRelease")?.outcome).isEqualTo(TaskOutcome.UP_TO_DATE)
981+
}
982+
983+
gitClient.checkoutTag(tag = "1.2.3")
984+
985+
runner.runAndCheckResult(
986+
"generateAppVersionInfoForRelease"
987+
) {
988+
assertThat(task(":app:generateAppVersionInfoForRelease")?.outcome).isEqualTo(TaskOutcome.SUCCESS)
989+
}
990+
}
991+
992+
@Test
993+
fun `GenerateAppVersionInfo (from cache) is re-executed after changing git HEAD`() {
994+
val gitClient = GitClient.initialize(fixtureDir.root).apply {
995+
val commitId1 = commit(message = "1st commit.")
996+
tag(name = "1.2.3", message = "1st tag", commitId = commitId1)
997+
val commitId2 = commit(message = "2nd commit.")
998+
tag(name = "1.2.4", message = "2st tag", commitId = commitId2)
999+
}
1000+
1001+
val runner = withFixtureRunner(
1002+
fixtureDir = fixtureDir,
1003+
subprojects = listOf(AppProjectTemplate())
1004+
)
1005+
1006+
runner.runAndCheckResult(
1007+
"generateAppVersionInfoForRelease",
1008+
"--build-cache"
1009+
) {
1010+
assertThat(task(":app:generateAppVersionInfoForRelease")?.outcome).isEqualTo(TaskOutcome.SUCCESS)
1011+
}
1012+
1013+
runner.runAndCheckResult(
1014+
"clean",
1015+
"generateAppVersionInfoForRelease",
1016+
"--build-cache"
1017+
) {
1018+
assertThat(task(":app:clean")?.outcome).isEqualTo(TaskOutcome.SUCCESS)
1019+
assertThat(task(":app:generateAppVersionInfoForRelease")?.outcome).isEqualTo(TaskOutcome.FROM_CACHE)
1020+
}
1021+
1022+
gitClient.checkoutTag(tag = "1.2.3")
1023+
1024+
runner.runAndCheckResult(
1025+
"clean",
9491026
"generateAppVersionInfoForRelease",
9501027
"--build-cache"
9511028
) {

src/main/kotlin/io/github/reactivecircus/appversioning/AppVersioningPlugin.kt

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ class AppVersioningPlugin : Plugin<Project> {
7777
group = APP_VERSIONING_TASK_GROUP
7878
description = "${GenerateAppVersionInfo.TASK_DESCRIPTION_PREFIX} for the ${variant.name} variant."
7979
gitRefsDirectory.set(findGitRefsDirectory(extension))
80+
gitHead.set(findGitHeadFile(extension))
8081
rootProjectDirectory.set(project.rootProject.rootDir)
8182
rootProjectDisplayName.set(project.rootProject.displayName)
8283
fetchTagsWhenNoneExistsLocally.set(extension.fetchTagsWhenNoneExistsLocally)
@@ -133,6 +134,22 @@ class AppVersioningPlugin : Plugin<Project> {
133134
}
134135
}
135136

137+
private fun Project.findGitHeadFile(extension: AppVersioningExtension): File? {
138+
return when {
139+
extension.bareGitRepoDirectory.isPresent -> {
140+
extension.bareGitRepoDirectory.let { bareGitRepoDirectory ->
141+
bareGitRepoDirectory.asFile.orNull?.resolve(HEAD_FILE)?.takeIf { it.exists() }
142+
}
143+
}
144+
extension.gitRootDirectory.isPresent -> {
145+
extension.gitRootDirectory.let { gitRootDirectory ->
146+
gitRootDirectory.asFile.orNull?.resolve(STANDARD_GIT_HEAD_FILE)?.takeIf { it.exists() }
147+
}
148+
}
149+
else -> project.rootProject.file(STANDARD_GIT_HEAD_FILE).takeIf { it.exists() }
150+
}
151+
}
152+
136153
companion object {
137154
private const val MIN_GRADLE_VERSION = "6.8"
138155
private const val MIN_AGP_VERSION = "7.0.0-beta04"
@@ -142,6 +159,8 @@ class AppVersioningPlugin : Plugin<Project> {
142159
private const val APP_VERSIONING_TASK_GROUP = "versioning"
143160
private const val APP_VERSIONING_TASK_OUTPUT_DIR = "outputs/app_versioning"
144161
private const val REFS_DIRECTORY = "refs"
162+
private const val HEAD_FILE = "HEAD"
145163
private const val STANDARD_GIT_REFS_DIRECTORY = ".git/$REFS_DIRECTORY"
164+
private const val STANDARD_GIT_HEAD_FILE = ".git/$HEAD_FILE"
146165
private const val VERSION_CODE_RESULT_FILE = "version_code.txt"
147166
private const val VERSION_NAME_RESULT_FILE = "version_name.txt"

src/main/kotlin/io/github/reactivecircus/appversioning/internal/GitClient.kt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,15 @@ class GitClient private constructor(private val projectDir: File) {
5959
command.execute(projectDir)
6060
}
6161

62+
fun checkoutTag(tag: String) {
63+
val commitCommand = buildList {
64+
add("git")
65+
add("checkout")
66+
add(tag)
67+
}
68+
commitCommand.execute(projectDir)
69+
}
70+
6271
companion object {
6372

6473
fun initialize(projectDir: File): GitClient {

src/main/kotlin/io/github/reactivecircus/appversioning/tasks/GenerateAppVersionInfo.kt

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import org.gradle.api.tasks.CacheableTask
2121
import org.gradle.api.tasks.IgnoreEmptyDirectories
2222
import org.gradle.api.tasks.Input
2323
import org.gradle.api.tasks.InputDirectory
24+
import org.gradle.api.tasks.InputFile
2425
import org.gradle.api.tasks.Internal
2526
import org.gradle.api.tasks.Optional
2627
import org.gradle.api.tasks.OutputFile
@@ -48,6 +49,12 @@ abstract class GenerateAppVersionInfo @Inject constructor(
4849
@get:NormalizeLineEndings
4950
abstract val gitRefsDirectory: DirectoryProperty
5051

52+
@get:Optional
53+
@get:InputFile
54+
@get:PathSensitive(PathSensitivity.RELATIVE)
55+
@get:NormalizeLineEndings
56+
abstract val gitHead: RegularFileProperty
57+
5158
@get:Internal
5259
abstract val rootProjectDirectory: DirectoryProperty
5360

@@ -90,6 +97,7 @@ abstract class GenerateAppVersionInfo @Inject constructor(
9097
fun generate() {
9198
workerExecutor.noIsolation().submit(GenerateAppVersionInfoWorkAction::class.java) {
9299
gitRefsDirectory.set(this@GenerateAppVersionInfo.gitRefsDirectory)
100+
gitHead.set(this@GenerateAppVersionInfo.gitHead)
93101
rootProjectDirectory.set(this@GenerateAppVersionInfo.rootProjectDirectory)
94102
rootProjectDisplayName.set(this@GenerateAppVersionInfo.rootProjectDisplayName)
95103
fetchTagsWhenNoneExistsLocally.set(this@GenerateAppVersionInfo.fetchTagsWhenNoneExistsLocally)
@@ -114,6 +122,7 @@ abstract class GenerateAppVersionInfo @Inject constructor(
114122

115123
private interface GenerateAppVersionInfoWorkParameters : WorkParameters {
116124
val gitRefsDirectory: DirectoryProperty
125+
val gitHead: RegularFileProperty
117126
val rootProjectDirectory: DirectoryProperty
118127
val rootProjectDisplayName: Property<String>
119128
val fetchTagsWhenNoneExistsLocally: Property<Boolean>
@@ -135,6 +144,7 @@ private abstract class GenerateAppVersionInfoWorkAction @Inject constructor(
135144

136145
override fun execute() {
137146
val gitRefsDirectory = parameters.gitRefsDirectory
147+
val gitHead = parameters.gitHead
138148
val rootProjectDirectory = parameters.rootProjectDirectory
139149
val rootProjectDisplayName = parameters.rootProjectDisplayName
140150
val fetchTagsWhenNoneExistsLocally = parameters.fetchTagsWhenNoneExistsLocally
@@ -147,7 +157,7 @@ private abstract class GenerateAppVersionInfoWorkAction @Inject constructor(
147157
val versionNameFile = parameters.versionNameFile
148158
val variantInfo = parameters.variantInfo
149159

150-
check(gitRefsDirectory.isPresent) {
160+
check(gitRefsDirectory.isPresent && gitHead.isPresent) {
151161
"Android App Versioning Gradle Plugin works with git tags but ${rootProjectDisplayName.get()} is not a git root directory, and a valid gitRootDirectory is not provided."
152162
}
153163

0 commit comments

Comments
 (0)