Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes issues with preparePaparazzi{Variant}Resources task that is caching incorrectly for different variants. #720

Merged
merged 4 commits into from
Mar 25, 2023

Conversation

geoff-powell
Copy link
Collaborator

@geoff-powell geoff-powell commented Feb 21, 2023

Fixes the issue this pr attempted to reproduce/solve.

Investigation doc on this issue for Cash.

TL;DR

Looking into the generated cache key it seems that it creates a build cache for the same generated key. So to recap preparePaparazziDebugResources runs around 6m into the build process and generates the correct debug resource file for paparazzi. At 9m into the build preparePaparazziReleaseResources runs to generate the correct release resource file for paparazzi but stores the output for the same cache key 8c39bb.
So this validates why the output for the debug task contains references to release paths.

I added a test gradle plugin project here to simulate the exact issue in the first commit - Sample Build Failure

The last commit adds variantName as a build input and causes the failing test to pass.

cc @mohsin-motorway this may fix the issue you were having as well.

Fixes issue #560 as well.

@geoff-powell geoff-powell force-pushed the gpowell/cash-font-loading-issue-repro branch 2 times, most recently from 368c898 to 1f40444 Compare February 21, 2023 16:25
gradlew.bat Outdated
if "%OS%"=="Windows_NT" endlocal

:omega
@rem
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

my bad #721

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rebasing off of master as this seems to be fixed

@geoff-powell geoff-powell force-pushed the gpowell/cash-font-loading-issue-repro branch 4 times, most recently from d8c4e8f to 00a046e Compare February 21, 2023 16:55
@geoff-powell geoff-powell marked this pull request as ready for review February 21, 2023 17:05
Comment on lines +127 to +133
with(firstRun.task(":preparePaparazziDebugResources")) {
assertThat(this).isNotNull()
assertThat(this!!.outcome).isNotEqualTo(FROM_CACHE)
}

with(firstRun.task(":preparePaparazziReleaseResources")) {
assertThat(this).isNotNull()
assertThat(this!!.outcome).isNotEqualTo(FROM_CACHE)
}
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added these checks here as they should never use cache on the first run. This will fail due to the task inputs being treated by gradle as the same and therefore the preparePaparazziReleaseResources is cached and the preparePaparazziDebugResources uses that cache instead of running.

Comment on lines +137 to +143
var resourcesFile = File(fixtureRoot, "build/intermediates/paparazzi/debug/resources.txt")
assertThat(resourcesFile.exists()).isTrue()
var resourceFileContents = resourcesFile.readLines()
assertThat(resourceFileContents.any { it.contains("release") }).isFalse()

resourcesFile = File(fixtureRoot, "build/intermediates/paparazzi/release/resources.txt")
assertThat(resourcesFile.exists()).isTrue()
resourceFileContents = resourcesFile.readLines()
assertThat(resourceFileContents.any { it.contains("debug") }).isFalse()
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These will verify that the resource file shouldn't have any paths with debug for release or vice-versa. The first commit doesn't verify this but it does fail if you comment out the task outcome assertions above.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice test strategy!

Comment on lines +158 to +159
resourcesFile = File(fixtureRoot, "build/intermediates/paparazzi/debug/resources.txt")
assertThat(resourcesFile.exists()).isTrue()
resourceFileContents = resourcesFile.readLines()
assertThat(resourceFileContents.any { it.contains("release") }).isFalse()
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this will also fail for the same reason above. Uses release resource output for preparePaparazziDebugResources as it is cached with the same key as the previous preparePaparazziDebugResources

@geoff-powell geoff-powell force-pushed the gpowell/cash-font-loading-issue-repro branch from 922d3e9 to 5d4aefa Compare February 21, 2023 17:55
@geoff-powell
Copy link
Collaborator Author

geoff-powell commented Feb 22, 2023

After talking with @jrodbx yesterday, the fix I had here works but may not be the final answer. The main issue is that the paths for inputs mergeResourcesOutput and mergeAssetsOutput are incorrectly being treated as the same, even though the paths contain debug or release folders. I began investigating @PathSensitity annotation used to see why these are treated as the same.

PathSensitivity.RELATIVE (Issue)

When using this path sensitivity, the “root” directory is /paparazzi/sample/build/intermediates/merged_res/{variant}/. This means that the task sees the input files of the directory as ADDED: drawable/camera.png

PathSensitivity.NAME_ONLY

This reports the filenames only in the directory ADDED: camera.png which again is not what we want.

PathSensitivity.ABSOLUTE

This reports the absolute file path which is great for separation but doesn’t scale to different machines and environments. ADDED: /{sourceCodeRoot}/Development/paparazzi/sample/build/intermediates/merged_res/debug/drawable/camera.png

PathSensitivity.NONE

This should not be used here as the files in the directory are ignored.

Very important note in gradle documentation that task caching is that Gradle will try and reuse outputs for the different task given the inputs. This is basically the root cause of the issue as we are using relative paths for the directory inputs, which are identical for different task variants.

So when looking at the @InputDirectory annotation there is a note which signifies using @Input instead if you only care about the directory and not the files within it (Similar issue asked on gradle discussion).

  • Note: To make the task dependent on the directory's location but not its contents, expose the path of the directory as an Input property instead.

This is exactly what we are looking to do and I have updated the pr to reflect a simpler and more direct solution.

@geoff-powell geoff-powell force-pushed the gpowell/cash-font-loading-issue-repro branch from 5215c6b to c6af0aa Compare February 23, 2023 11:46
Comment on lines -102 to -104
private fun Directory.relativize(child: Directory): String {
return asFile.toPath().relativize(child.asFile.toPath()).toFile().invariantSeparatorsPath
}
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moved this function to the plugin to relativize the path input for mergeAssetsOutput and mergeResourcesOutput

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we move this function as is to the plugin as a private extension method?

Comment on lines 102 to 108
fun DirectoryProperty.asRelativePathString(childDirectory: Provider<Directory>): Provider<String> =
flatMap { buildDir ->
childDirectory.map { childDir ->
buildDir.asFile.toPath().relativize(childDir.asFile.toPath()).invariantSeparatorsPathString
}
}

Copy link
Collaborator Author

@geoff-powell geoff-powell Feb 23, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using mapping functions here to keep this property lazy for configuration perf

@get:PathSensitive(PathSensitivity.RELATIVE)
abstract val mergeResourcesOutput: DirectoryProperty
@get:Input
abstract val mergeResourcesOutput: Property<String>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It has to be a String? Gradle is so annoying

Copy link
Collaborator Author

@geoff-powell geoff-powell Feb 23, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, basically DirectoryProperty with @PathSensitive(PathSensitivity.RELATIVE) is used for a directory where you want a sub folder or file changes to run the task. Since its relative and the base directory is .../debug and .../release gradle sees the underlying files as the same.

The suggestion for using Property here is if you only want the path to be used as an input and the contents don't matter. This was our exact usecase as we just use the path in the generated resources.txt file.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The worst is when Gradle simply ignores your parameter without telling you it's not the right type and that what you expect to happen is never gonna be!

.withArguments("testRelease", "testDebug", "--build-cache", "--stacktrace")
.runFixture(fixtureRoot) { build() }

println(firstRun.output)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: remove?

var resourcesFile = File(fixtureRoot, "build/intermediates/paparazzi/debug/resources.txt")
assertThat(resourcesFile.exists()).isTrue()
var resourceFileContents = resourcesFile.readLines()
assertThat(resourceFileContents.any { it.contains("release") }).isFalse()
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice

url "file://${projectDir.absolutePath}/../../../../../build/localMaven"
}
mavenCentral()
//mavenLocal()
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: remove?

Copy link
Collaborator

@swankjesse swankjesse left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very much looking forward to having these fixes. THANK YOU!

@geoff-powell geoff-powell force-pushed the gpowell/cash-font-loading-issue-repro branch from c6af0aa to 1dca484 Compare February 23, 2023 19:08
@geoff-powell
Copy link
Collaborator Author

Very much looking forward to having these fixes. THANK YOU!

Ya no problem! Fixed up your suggested changes. Will merge once CI passes 👍🏽

gabrielittner added a commit to freeletics/paparazzi that referenced this pull request Mar 18, 2023
@jrodbx jrodbx added this to the 1.3 milestone Mar 24, 2023
Copy link
Collaborator

@jrodbx jrodbx left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice work, def learned a lot more about Input properties as a result of this PR!

Comment on lines -102 to -104
private fun Directory.relativize(child: Directory): String {
return asFile.toPath().relativize(child.asFile.toPath()).toFile().invariantSeparatorsPath
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we move this function as is to the plugin as a private extension method?

@geoff-powell geoff-powell force-pushed the gpowell/cash-font-loading-issue-repro branch 3 times, most recently from 11b5df6 to 2e04e2f Compare March 25, 2023 12:21
@geoff-powell geoff-powell force-pushed the gpowell/cash-font-loading-issue-repro branch from 2e04e2f to cfc4b6d Compare March 25, 2023 12:25
@geoff-powell geoff-powell merged commit 75b9ead into master Mar 25, 2023
@geoff-powell geoff-powell deleted the gpowell/cash-font-loading-issue-repro branch March 25, 2023 14:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants