-
Notifications
You must be signed in to change notification settings - Fork 15
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
Configuration cache #51
Conversation
@handstandsam hello! Can you review this PR please? |
Ahh thanks, didn't see this one. Thanks for tagging, will review in the morning. Thanks! |
@handstandsam are there any updates on this PR? |
I didn't forget about this, but have been busy at work and haven't gotten a chance to pull down and review it. Sorry. Still on my radar. |
…sk's configurationAction
…pendencies tree rendering
65c3921
to
93356e2
Compare
Thanks for rebasing and updating. I might defer to @autonomousapps or @joshafeinberg as I haven't implemented configuration cache myself. |
Thanks for all this work! Because it's such a large change we'll probably have some back and forth on this one. I know you split things up into commits, but there are 14, so it's hard even with that. If you break this apart into smaller PRs that build on each other, that may make this easier to merge in. I added a bunch of comments, but I still will want eyes from someone who knows Configuration Cache (as I have not done any conversions). Additionally, I want to not use Internal APIs unless it's absolutely required like it was for Thanks, and sorry this took me a while to get to reviewing. |
@handstandsam yes, I agree that large changes make some subtle bugs harder to find.
Do you mean comments on the code? I have not seen ones.. |
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.
Sorry, I never submitted this. These are the comments I wrote earlier today.
Root project 'dependency-guard-root' | ||
------------------------------------------------------------ | ||
|
||
classpath | ||
+--- org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.10 |
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.
What causes this change in the way baselines are made?
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.
Earlier tree baseline was equal to the output of the dependencies
task, so it included some header and footer from that output. But dependencies
task does not support Configuration Cache, that's why it is not used for creating tree baseline now, and AsciiDependencyReportRenderer2
is used instead.
AsciiDependencyReportRenderer2
renders only dependencies tree without header and footer, because rendering header and footer required Configuration
. But Configuration
can't be used as task's @get:Input
and obtaining it during task's execution breaks Configuration Cache.
public abstract class com/dropbox/gradle/plugins/dependencyguard/internal/list/DependencyGuardListTask : org/gradle/api/DefaultTask { | ||
public fun <init> ()V | ||
public abstract fun getAvailableConfigurations ()Lorg/gradle/api/provider/ListProperty; | ||
public abstract fun getForRootProject ()Lorg/gradle/api/provider/Property; | ||
public abstract fun getMonitoredConfigurations ()Lorg/gradle/api/provider/ListProperty; | ||
public abstract fun getShouldBaseline ()Lorg/gradle/api/provider/Property; | ||
} |
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.
Why would this not be public anymore?
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.
dependency-guard plugin is configured by DependencyGuardConfiguration
and DependencyGuardPluginExtension
, while DependencyGuardListTask
is an implementation detail.
DependencyTreeDiffTask
was also internal
.
// verify tree baseline | ||
project.assertFileExistsWithContentEqual( | ||
filename = "lib/dependencies/compileClasspath.tree.txt", | ||
contentFile = "simple/tree_before_update.txt", |
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.
What's the rationale behind naming simple
for this directory?
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's named so after fixture/SimpleProject.kt
.
It contains files used to verify output of baselines for SimpleProject
, so it looks like an appropriate name.
// Gradle 7.4 is the minimum version for which this feature is relevant | ||
gradleVersion = GradleVersion.version("7.4"), | ||
args = arrayOf(":lib:dependencyGuard", "--configuration-cache") | ||
args = arrayOf(":lib:dependencyGuard") |
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.
I think for the purposes of being explicit, --configuration-cache
is still valid.
Also, by doing this, are we ending support for Gradle 7.4? At this point we've been supporting older versions. I'm open to potentially making this change, but need to discuss.
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.
--configuration-cache
flag is added in fun runner
in fixture/Builder
, so there is no need to add it here.
I also ran tests with gradle-7.4.2
-- they all passed successfully (#58).
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.
I'd suggest writing parameterized tests so you can test against various Gradle versions, if you want to ensure support for older versions as well as newer.
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.
Created #62
@@ -4,12 +4,17 @@ import com.dropbox.gradle.plugins.dependencyguard.util.createDirectories | |||
import com.dropbox.gradle.plugins.dependencyguard.util.writeText | |||
import java.nio.file.Path | |||
|
|||
class SimpleProject : AbstractProject() { | |||
class SimpleProject( | |||
private val tree: Boolean = true, |
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.
Could you make this be a parameter without a default value? I feel like the tests would be more explicit that way.
} else { | ||
DependencyTreeDiffTask::class.java | ||
} | ||
val taskClass = DependencyTreeDiffTask::class.java |
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.
🤔 - will have to see later on in this PR how you support the Build Environment tree for ./gradlew :buildEnvironment
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 tree baseline for the root project is created from classpath
configuration as before.
Now the tree baseline is created in a general way (via ResolvedComponentResult
) for the root project and for the usual gradle module.
import org.gradle.api.tasks.diagnostics.internal.TextReportRenderer | ||
import org.gradle.api.tasks.diagnostics.internal.dependencies.AsciiDependencyReportRenderer | ||
import org.gradle.api.tasks.diagnostics.internal.graph.DependencyGraphsRenderer | ||
import org.gradle.api.tasks.diagnostics.internal.graph.NodeRenderer | ||
import org.gradle.api.tasks.diagnostics.internal.graph.SimpleNodeRenderer | ||
import org.gradle.api.tasks.diagnostics.internal.graph.nodes.RenderableModuleResult | ||
import org.gradle.internal.graph.GraphRenderer | ||
import org.gradle.internal.logging.text.StyledTextOutput |
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.
I would like to stay away from internal Gradle APIs as much as possible. I had to do it for the buildEnvironment
tree only #25, but I want to stay away from internal APIs if there is anything public available. That will ensure better version compatibility in the future.
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.
I agree that it's better to avoid internal api usage, but dependencies
task does not support Configuration Cache. That's why AsciiDependencyReportRenderer2
was added to render ResolvedComponentResult
.
I didn't find another way to render dependencies tree, so I needed to stay on internal api. But I'm ready to switch to public api that I'm not aware of, if it makes the same thing.
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.
What does this class do? Could you reimplement it? Or even just copy and paste the code into this project?
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.
class AsciiDependencyReportRenderer2
renders dependencies tree of the particular configuration (represented by org.gradle.api.artifacts.result.ResolvedComponentResult
).
This is a modified copy of AsciiDependencyReportRenderer
from Gradle sources.
AsciiDependencyReportRenderer
works with org.gradle.api.artifacts.Configuration
, while AsciiDependencyReportRenderer2
works with org.gradle.api.artifacts.result.ResolvedComponentResult
. This is because org.gradle.api.artifacts.Configuration
is not available in task's actions, when configuration cache is enabled.
Actually, original AsciiDependencyReportRenderer
in public void render(Configuration configuration)
receives ResolvedComponentResult
from org.gradle.api.artifacts.Configuration
, so there is not much changes in AsciiDependencyReportRenderer2
.
Another change is that AsciiDependencyReportRenderer2
renders only dependencies tree without header and footer, because rendering header and footer requeires org.gradle.api.artifacts.Configuration
in original AsciiDependencyReportRenderer
. But that is not that important, because we are more interested in dependencies trees diff, that in header and footer.
/** | ||
* Simplified version of [AsciiDependencyReportRenderer] that renders [ResolvedComponentResult]. | ||
*/ | ||
internal class AsciiDependencyReportRenderer2 : TextReportRenderer() { |
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.
I have seen these internal APIs, but haven't used it. Can the comment declare if this is used for just Trees, and if it's used for :buildEnvironment
or normal :dependencies
tasks?
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.
DependencyTreeDiffTask
is not based on :buildEnvironment
or :dependencies
now.
It is a simple task that receives ResolvedComponentResult
as input and renders its dependencies tree to file using AsciiDependencyReportRenderer2
.
sample/app/build.gradle.kts
Outdated
@@ -21,6 +21,7 @@ dependencyGuard { | |||
// All dependencies included in Production Release APK | |||
configuration("releaseRuntimeClasspath") { | |||
modules = true | |||
tree = true |
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.
I'd like to discourage the use of tree
format as I feel like it's more helpful in local debugging. It's nice to have it there, but I didn't use it in the sample because 1) it's not as useful in most situations as it's so noisy 2) the build environment piece used internal APIs, so it's more of a "use at your own risk".
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.
Ok, tree format is actually not that useful, so I'll revert this change.
Arghh, the request for review from |
@handstandsam Hi! Are there any updates on this PR? |
@qwert2603 - Sorry, In order to feel comfortable merging, I would want to sit down and run the new code as it's not small changes. I sent you a DM on Kotlin Lang Slack about this topic if you can check and reply there. Thank you! |
@@ -5,5 +5,4 @@ import org.gradle.util.GradleVersion | |||
internal object GradleVersion { | |||
private val current = GradleVersion.current() | |||
val isAtLeast73 = current >= GradleVersion.version("7.3") |
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 drop this as well now?
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.
I think it may be dropped together will adding parameterized tests (#62)
Fixes #28 and improves test coverage.
Changes are split to commits to simplify review.