-
Notifications
You must be signed in to change notification settings - Fork 214
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
Conversation
368c898
to
1f40444
Compare
gradlew.bat
Outdated
if "%OS%"=="Windows_NT" endlocal | ||
|
||
:omega | ||
@rem |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
my bad #721
There was a problem hiding this comment.
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
d8c4e8f
to
00a046e
Compare
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) | ||
} |
There was a problem hiding this comment.
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.
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() |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice test strategy!
resourcesFile = File(fixtureRoot, "build/intermediates/paparazzi/debug/resources.txt") | ||
assertThat(resourcesFile.exists()).isTrue() | ||
resourceFileContents = resourcesFile.readLines() | ||
assertThat(resourceFileContents.any { it.contains("release") }).isFalse() |
There was a problem hiding this comment.
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
922d3e9
to
5d4aefa
Compare
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 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 PathSensitivity.NAME_ONLYThis reports the filenames only in the directory ADDED: camera.png which again is not what we want. PathSensitivity.ABSOLUTEThis 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.NONEThis 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
This is exactly what we are looking to do and I have updated the pr to reflect a simpler and more direct solution. |
5215c6b
to
c6af0aa
Compare
private fun Directory.relativize(child: Directory): String { | ||
return asFile.toPath().relativize(child.asFile.toPath()).toFile().invariantSeparatorsPath | ||
} |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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?
fun DirectoryProperty.asRelativePathString(childDirectory: Provider<Directory>): Provider<String> = | ||
flatMap { buildDir -> | ||
childDirectory.map { childDir -> | ||
buildDir.asFile.toPath().relativize(childDir.asFile.toPath()).invariantSeparatorsPathString | ||
} | ||
} | ||
|
There was a problem hiding this comment.
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> |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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) |
There was a problem hiding this comment.
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() |
There was a problem hiding this comment.
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() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: remove?
There was a problem hiding this 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!
c6af0aa
to
1dca484
Compare
Ya no problem! Fixed up your suggested changes. Will merge once CI passes 👍🏽 |
…hing incorrectly for different variants. cashapp#720
There was a problem hiding this 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!
...azzi/paparazzi-gradle-plugin/src/main/java/app/cash/paparazzi/gradle/PrepareResourcesTask.kt
Outdated
Show resolved
Hide resolved
private fun Directory.relativize(child: Directory): String { | ||
return asFile.toPath().relativize(child.asFile.toPath()).toFile().invariantSeparatorsPath | ||
} |
There was a problem hiding this comment.
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?
...azzi/paparazzi-gradle-plugin/src/main/java/app/cash/paparazzi/gradle/PrepareResourcesTask.kt
Show resolved
Hide resolved
paparazzi/paparazzi-gradle-plugin/src/main/java/app/cash/paparazzi/gradle/PaparazziPlugin.kt
Outdated
Show resolved
Hide resolved
paparazzi/paparazzi-gradle-plugin/src/main/java/app/cash/paparazzi/gradle/PaparazziPlugin.kt
Outdated
Show resolved
Hide resolved
...azzi/paparazzi-gradle-plugin/src/main/java/app/cash/paparazzi/gradle/PrepareResourcesTask.kt
Outdated
Show resolved
Hide resolved
...azzi/paparazzi-gradle-plugin/src/main/java/app/cash/paparazzi/gradle/PrepareResourcesTask.kt
Outdated
Show resolved
Hide resolved
paparazzi/paparazzi-gradle-plugin/src/main/java/app/cash/paparazzi/gradle/PaparazziPlugin.kt
Outdated
Show resolved
Hide resolved
paparazzi/paparazzi-gradle-plugin/src/main/java/app/cash/paparazzi/gradle/PaparazziPlugin.kt
Outdated
Show resolved
Hide resolved
…f preparePaparazzi{Variant}Resources in the same command.
…the appropriate variant
…String properties
11b5df6
to
2e04e2f
Compare
2e04e2f
to
cfc4b6d
Compare
Fixes the issue this pr attempted to reproduce/solve.
Investigation doc on this issue for Cash.
TL;DR
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.