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

Configuration Cache support #666

Open
rahulsainani opened this issue May 13, 2022 · 14 comments
Open

Configuration Cache support #666

rahulsainani opened this issue May 13, 2022 · 14 comments

Comments

@rahulsainani
Copy link

Got this warning in Android Studio's build analyzer:

com.github.ben-manes.versions: not compatible 
You could save about 4.3s by turning Configuration cache  on. 
With Configuration cache, Gradle can skip the configuration phase entirely when nothing that affects the build configuration has changed.

The version of this plugin used in this build is not compatible with Configuration cache and we don’t know the version when it becomes compatible.  
 
 Plugin version: 0.42.0 
 Plugin dependency: com.github.ben-manes:gradle-versions-plugin

Is it possible to use configuration cache with this plugin?

@ben-manes
Copy link
Owner

Compatibility would require a rewrite to use per-project tasks and a root-level accumulator task (similar to jacoco). PRs are appreciated if someone wants to work on that. Instead we mark the task as not compatible so that the configuration cache ignores our task and lets you get the benefits in other builds.

@tprochazka
Copy link

Technically I think, that ignoring these plugin tasks until I call it is entirely enough. Because the most important is build speed during development and nobody actually needs to call this plugin as often as build&run operation. When you really want to check version updates, it is not so important that it will take a little bit longer.

Currently, last released version has this in the changelog

Merge pull request #585 from eygraber/dont-fail-w-configuration-cache
Prevent builds from failing w/ configuration cache enabled on Gradle 7.4+

So why does Android studio still display the warning that this plugin is blocking to use of compilation cache?

And there is also one possible workaround. It is possible detect that gradle is invoked from Android Studio IDE by this function

val Project.isIDEBuild: Boolean
    get() {
        return this.hasProperty("android.injected.invoked.from.ide")
    }

So you can apply the plugin only when the project is not invoked from IDE.

@jaredsburrows
Copy link
Collaborator

We would have to rewrite parts of this plugin to not pass project our @TaskAction to make --configuration-cache pass in a test.

@ianbrandt
Copy link

Testing upgrade to Gradle 8.1 RC1:

  • If I run dependencyUpdates with org.gradle.configuration-cache=true, it fails with, "Invocation of 'Task.project' by task ':dependencyUpdates' at execution time is unsupported."
  • If I add org.gradle.configuration-cache.problems=warn, the build doesn't fail, but dependencyUpdates reports, "No dependencies found."

One oddity here, without org.gradle.configuration-cache.problems=warn, I also get configuration cache errors for the compileJava and jar tasks in addition to the dependencyUpdates task when running dependencyUpdates. I don't get these additional errors when just running build or jar, or if I do add org.gradle.configuration-cache.problems=warn.

Reproducer with org.gradle.configuration-cache.problems=warn currently set: https://github.com/sdkotlin/sd-kotlin-talks/tree/gradle-8.1 (specifically, https://github.com/sdkotlin/sd-kotlin-talks/tree/73c97f04b1bbbe361ea6c51ae1886f70e208bfa0).

@ianbrandt
Copy link

Testing with Gradle 8.1 RC2:

  • If I run dependencyUpdates with just org.gradle.configuration-cache=true, it no longer fails now that "8.1 RC1: notCompatibleWithConfigurationCache is not always honored gradle/gradle#24411" is fixed.
    • I do get, "47 problems were found storing the configuration cache, 5 of which seem unique.", as expected given this open issue, but they don't include any errors for the compileJava or jar tasks anymore.
  • If I add org.gradle.configuration-cache.problems=warn, dependencyUpdates still reports, "No dependencies found."

It would be nice to be able to set org.gradle.configuration-cache=true, org.gradle.configuration-cache.problems=warn, and still be able to use this plugin.

Reproducer: https://github.com/sdkotlin/sd-kotlin-talks/tree/929b0ccfd607bb41019cce34accd4abf94f35408.

Should I file a separate issue for it, since it's not the same thing as full support for the configuration cache?

@ben-manes
Copy link
Owner

I don't think there is any problem here? The task is correctly declaring that it does not support the configuration cache, which violates the idiom by spamming the logs regardless (gradle/gradle#24435). You can suppress this noise using --quiet (or -q). Since this cache is not required and our incompatibility not harmful as an infrequent task, I don't see this being a problem for the plugin. The noise pollution is a Gradle issue.

A rewrite to support the configuration cache is more invasive. As a ten year old weekend project, I don't think myself or others are really up for that, especially since the Gradle/Github folks are discussing improvements for use by dependabot. I'd like to see if the Gradle team adds direct support or engineers a preferred solution. If not, then I think they would not break compatibility due to the need for this type of plugin, so it becomes hard to really justify the work involved given everyone contributes in their limited free time. If someone feels really passionate and sends a PR then I am always happy to review and add another wonderful contributor & maintainer.

@ianbrandt
Copy link

ianbrandt commented Mar 29, 2023

I'd expect the plugin to still print available updates even if org.gradle.configuration-cache=true and org.gradle.configuration-cache.problems=warn are set. With Gradle 8.1 RC2 it just prints, "No dependencies found."

@ben-manes
Copy link
Owner

Then that sounds like a Gradle bug if it broke between 8.0 and 8.1?

I upgraded and ran it on Caffeine where the report came out as expected. I'll try yours when I get some downtime, but I think you should report your findings for the Gradle team to hopefully fix during the RC process.

@ben-manes
Copy link
Owner

Running your reproducer and I think you should open a Gradle issue. I see that passing --no-configuration-cache will generate a report. This means all of our logic works correctly, except when caching is enabled in which case it must get empty results?

I am still trying to reproduce it outside of the plugin to understand where it deviates. I will likely have to build a custom version with logging to see where it breaks down, since it is very obscure.

Can you start a conversation with the Gradle folks?

@ben-manes
Copy link
Owner

subprojects {
  tasks {
    register("allConfigurationDependencies") {
      notCompatibleWithConfigurationCache("incompatible")
      doLast {
        project.configurations
        .forEach { conf ->
          conf
          .allDependencies
          .forEach { dep ->
            System.out.println(conf.name + ":\t" + dep.name)
          }
        }
      }
    }
  }
}

That will print out the dependencies when the configuration cache is disabled or if performed within an afterEvaluate block. If the cache is enabled then the task results are empty and the swallowed exception is logged, InvalidUserCodeException: Invocation of 'Task.project' by task ... at execution time is unsupported.

The notCompatibleWithConfigurationCache() should not enforce this as it is valid behavior to use without caching which adds this restriction, but it should be disabled when planning the task executions. The notCompatibleWithConfigurationCache has no effect if applied or not, as the build is always successful.

This is a regression in the build tool.

@ben-manes
Copy link
Owner

Hacking up your build, and I believe the configuration cache is buggy when crossing the includeBuild boundary.

If I add a dependency in platform:test-platform and the allConfigurationDependencies task defined above then,

  • gradle platform:test-platform:allConfigurationDependencies -> no results
  • cd platforms/test-platform && gradle allConfigurationDependencies -> dependencies

hope that helps.

@ianbrandt
Copy link

Thanks for looking into the "No dependencies" issue! Initial comment posted to gradle/gradle#24411 (comment).

@ianbrandt
Copy link

Filed gradle/gradle#24636.

@FunkyMuse
Copy link

Stacktrace

3 problems were found storing the configuration cache, 2 of which seem unique.
- Task `:dependencyUpdates` of type `com.github.benmanes.gradle.versions.updates.DependencyUpdatesTask`: cannot serialize a lambda that captures or accepts a parameter of type 'org.gradle.api.artifacts.Configuration' as these are not supported with the configuration cache.
  See https://docs.gradle.org/8.2/userguide/configuration_cache.html#config_cache:requirements:disallowed_types
- Task `:dependencyUpdates` of type `com.github.benmanes.gradle.versions.updates.DependencyUpdatesTask`: invocation of 'Task.project' at execution time is unsupported.
  See https://docs.gradle.org/8.2/userguide/configuration_cache.html#config_cache:requirements:use_project_during_execution

invocation of Task.project📋 at execution time is unsupported

This is the error I get

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants