https://gradle.com/ logo
Docs
Join the conversationJoin Slack
Channels
android
caching
community-news
community-support
config-avoidance
configuration-cache
contributing
dependabot
dependency-management
design
design-specs
developer-productivity-engineering
docs
dpe-summit
feed
file-system-watching
flutter
general
gradle-enterprise
jobs
kotlin-dsl
linen
maven
migrating-from-ant
migrating-from-maven
native
performance
playframework
plugin-development
releases
roadmap
self-promotion
Powered by Linen
config-avoidance
  • s

    Satyarth Sampath

    07/19/2022, 2:42 PM
    Hey Folks, Is there a way to identify((in a build scan) ) which tasks were created during configuration ? I’m following the Task Configuration Avoidance guide which then shows me that some tasks were created during configuration. However I cannot identify which tasks were created.
    m
    v
    • 3
    • 6
  • c

    CristianGM

    07/20/2022, 9:36 AM
    I was trying to enable configuration-cache at CI, but I'm finding it very hard, everyone seems to read environment variables everywhere. First example: MavenPublication
    version
    is a string, not a property, so as we use our CI build number (it's an env var) we can't do anything. In this case I think MavenPublication should allow us to use Properties so it's only read in execution time.
    • 1
    • 1
  • c

    CristianGM

    07/20/2022, 9:38 AM
    another example: `com.gradle.common-custom-user-data-gradle-plugin`does read a lot of env vars, you may think it's my fault for using it, but the thing is, GE Scans benefit from all that info, is just that we shouldn't need it in configuration time
    d
    • 2
    • 14
  • v

    Vladimir Sitnikov

    07/13/2022, 2:37 PM
    There’s an unspoken rule that modern builds should use configuration avoidance. I just filed several inspection requests to IntelliJ IDEA so it would warn users on the uses of stale API: https://youtrack.jetbrains.com/issue/IDEA-297893/Inspection-for-tasksall-taskswithType-prefer-lazy-task-configuration https://youtrack.jetbrains.com/issue/IDEA-297896/Inspection-tasksfindByName-tasksgetAt-tasksget-eagerly-creates-task-prefer-tasknamed-instead https://youtrack.jetbrains.com/issue/IDEA-297894/Inspection-taskscreate-eagerly-creates-task-prefer-taskregister Please vote for the issues ;-)
    👍 7
    d
    j
    +4
    • 7
    • 32
  • p

    Paul Woitaschek

    07/26/2022, 5:22 AM
    We use Gitlab and for our internal maven repo use the CI_JOB_TOKEN. As that one is changing this is also completely preventing the usage of config Cache on the CI (this is an answer to the two threads above ☝️ )
    v
    c
    • 3
    • 12
  • t

    twisterrob

    08/17/2022, 8:21 AM
    I'm having a fun problem. I have eager code that I want to turn in to lazy, but it's not clicking how to. Here's a simplified version of the code:
    val task1: VariantTask? = project.findTaskFor(variant, Task1::class.java)
    val task2: VariantTask? = project.findTaskFor(variant, Task2::class.java)
    val task = task1 ?: task2
    if (task != null) { task.dependsOn(someOtherTask) }
    and the definition of the utility
    private fun <T : VariantTask> Project.findTaskFor(variant: String, taskClass: Class<T>): T? =
       this
          .tasks
          .withType(taskClass)
          .matching { it.variantName == variant }
          .singleOrNull()
    The problem is two-fold as I see it: • find a way to do
    matching
    without creating the tasks • find a way to do
    ?:
    on
    Provider<Task>
    or another way to deal with no matching tasks for variant Please 🧵 with any response.
    v
    • 2
    • 5
  • t

    twisterrob

    08/21/2022, 5:59 PM
    My first idea is to do
    project.tasks.configureEach { created.add(it) }
    and then invoke
    gradlew :help
    .
    p
    t
    • 3
    • 6
  • ł

    Łukasz Wasylkowski

    10/14/2022, 10:38 AM
    Hey folks, do I understand correctly that running
    ./gradlew <anyTask> --dry-run
    should never create a single
    Task
    instance during configuration phase, and if it does — that’s a place for improvement/fix? Even if the fix is not possible for some reason, no tasks created would be ideal, right?
    p
    t
    • 3
    • 9
  • c

    CristianGM

    10/24/2022, 4:30 PM
    I need to know about all
    tasks.withType(X)
    currently I can use
    TaskCollection.getNames()
    but that's not a live/lazy collection, so I need to wrap it in an
    afterEvaluate
    , I would say having
    names
    as a live collection, would be great. I want to know about the tasks, not to realize them all. Another approach would be using something like
    whenTaskAdded
    , but currently it would realize all tasks too. Any ideas? maybe a live collection version of names could be added
    v
    v
    j
    • 4
    • 16
  • v

    Vampire

    10/26/2022, 1:31 PM
    Does
    tasks.findByPath(':foo:bar')
    cause all tasks of
    foo
    to be realized? o_O I see task
    :foo:baz
    to be realized and configured although it is `register`ed, nowhere depended on, and also not triggered by command line.
    c
    v
    • 3
    • 13
  • ł

    Łukasz Wasylkowski

    02/07/2023, 7:24 PM
    What would be the proper way to set a
    taskProp: Property<Boolean>
    in a task based on a property passed via
    -P<prop>
    ? I can just do
    val value = roperties["prop"]
    and
    taskProp.set(value)
    but I’m wondering if there’s a way to map the
    prop
    in a more reactive way and read the
    prop
    as a
    Property
    itself
    v
    • 2
    • 12
Powered by Linen
Title
ł

Łukasz Wasylkowski

02/07/2023, 7:24 PM
What would be the proper way to set a
taskProp: Property<Boolean>
in a task based on a property passed via
-P<prop>
? I can just do
val value = roperties["prop"]
and
taskProp.set(value)
but I’m wondering if there’s a way to map the
prop
in a more reactive way and read the
prop
as a
Property
itself
v

Vampire

02/07/2023, 7:47 PM
You are probably after
providers.gradleProperty
I guess
But you should consider using proper `@Option`s instead. Except probably if you need to be able to set it via properties file.
ł

Łukasz Wasylkowski

02/08/2023, 8:06 AM
Thanks,
providers
is what I missed, I was looking for top-level stuff 🙂 So I got
val ignoreFailuresProp = providers.gradleProperty("ktlint.ignoreFormatFailures").map { it.toBoolean() }.orElse(
true)
tasks.withType<FormatTask>().configureEach {
    ignoreFailures.set(ignoreFailuresProp)
}
and I’m wondering if it’s in any way more appropriate or better than reading the property right away. I guess now it’s read lazily, what if there’s more than one
FormatTask
in the project — will it be read more than once? I tried to follow implemention and docs but can’t tell for sure
And I realize reading Gradle property might be pretty cheap, I’m wondering as a general rule if properties cache their values
But you should consider using proper `@Option`s instead.
That would be on the task author, right? In my case it’s a 3rd party plugin
Except probably if you need to be able to set it via properties file.
actually I do 😄 That’s a preference team members would set for themselves, having to pass it when running Gradle wouldn’t be ideal
v

Vampire

02/08/2023, 8:37 AM
Ah, ok, then yeah. And yes, would be the task author. A property is calculated each time it is requested afair. And a
map
for similar step the same. But you can easily create a cached provider like
inline fun <reified T> cachedProvider(crossinline block: () -> T): Provider<T> =
    objects
        .property<T>()
        .value(provider { block() })
        .apply {
            disallowChanges()
            finalizeValueOnRead()
        }
And then you can use it like
val foo =  cachedProvider { calculateComplexValue() }
ł

Łukasz Wasylkowski

02/08/2023, 8:39 AM
Is the caching part achieved by setting
value(provider { block() })
or by
disallowChanges(); finalizeValueOnRead();
? 🤔
ah, the disallow/finalize are methods on a
property
, not
provider
👍 Looks like it’s not really worth it for a gradle property per se, but good to know how to achieve laziness in similar cases 🙂
v

Vampire

02/08/2023, 8:41 AM
disallowChanges
effectively makes the
Property
a
Provider
or someone could downcast and call mutators.
finalizeValueOnRead
makes it calculate once and remember.
The
provider { block() }
makes the value be calculated only on first read
Alternatively the function could require a
Provider
as input, but I liked it better that way, usage-wise
ł

Łukasz Wasylkowski

02/08/2023, 11:19 AM
Got it, thanks a lot 🙂
View count: 8