This message was deleted.
# community-support
s
This message was deleted.
c
Have you tried untracked tasks? Unsure if that skips the @Input checks, it may as untracked sidesteps all the state tracking.
s
Oh, wow - thanks! No I have not, its the first time I have seen this one. I usually just look at the table
πŸ‘ 1
Oh, and apparently its still new - still incubating
not that that matters for me for this one
For the historical record, that does not work anyway. Gradle still complains
c
ugh. that’s good to know, but unfortunate.
s
Indeed. Your thought there seemed reasonable
Still good to know about that one even if it is just for documentation sake
v
It's not just for documentations sake actually. It skips checks otherwise done. The input and output annotations are used for more things than up-to-date checks though, for example implicit task dependencies.
s
In my case it is just documentation
I get what you are saying in the general case though
This is a long-running interactive task (not my design, so 🀷🏼 ). It shares no input nor output state with other tasks
v
What does it do?
s
Besides, aren't implicit dependencies frowned upon now? I get warnings about them all the time in my plugins now
If you are familar with Quarkus, it is the Quarkus "dev mode" functionality
c
inferred dependencies are good, implicit (undefined) ones are bad.
v
No, not properly declared dependencies are a problem if you mean that. Implicit task dependencies are what rocks. Explicit task dependencies are a code smell.
s
Dunno guys, I get warnings about one task relying on properties from other tasks as a "dependency"
v
implicit and inferred is the same. Using output of one task as input for another task without having either implicit or explicit dependencies is what is problematic.
c
what is one example of the problematic case?
s
tbh I always thought this was a very nice feature of Gradle and now it is gone
v
Can you show a concrete example of such a message? If it is the one we have in mind you should definitely fix them
s
e.g. if one task produces a file as output, Gradle knows this
v
If you think it was a nice feature, you maybe talk about something different
s
If I have Task1 which exposes RegularFileProperty let's say... and then Task2 which uses that as input (the same ref) but do not define a dep between them (
task1.dependsOn(task2)
) Gradle complains.
The output / input link implies a dependency
v
No, it does not if you did it properly
s
but recently I have found Gradle requiring me to do the explicit def whereas previously it did not
🀷🏼
v
If you get that warning, you are doing something wrong, that's the reason for the warning
The dependency is missing and never was there
s
well, when i warning next i will be sure to share it here
πŸ‘ 1
But regardless, this was something Gradle used to be able to work out itself but recent versison cannot. So...
v
Definitely, because using explicit dependency is the frowned upon part. πŸ˜„ Using implicit is still the idiomatic way to go.
s
Sure, and I'd love to
v
But regardless, this was something Gradle used to be able to work out itself but recent versison cannot. So...
No, that's not true
It just introduced a warning if not done properly
c
in recent versions they'
s
Man, the plugin used to work just fine. So yeah it did, on some level
c
oops. they’ve introduced the warning and the detection of various cases that are fragile.
it may have worked fine, coincidentally, but perhaps broken with say configuration cache that allows parallelism or other future changes (JVM upgrade that changes unspecfied behaviours, etc - who knows what the future holds…)
s
Anyway, when I get this again (I've fix it as I need and work on my plugins) I'll post
v
"Man", it was accidental that it worked. It depended on order of tasks. If you accidentally always run task A that produces the file first before you run task B that consumes the file, it works fine.
But as soon as this accidental order was not given, it maybe used a stale file, or it failed because it is not there, as the dependency from B to A is not there.
s
You know "man" has multiple meanings in English. No need to take it that way
v
In older versions it maybe seemed like it worked, but was flaky at best. Recent versions try to detect such problems and warn you that something is not correct in your build.
s
We've always been pretty polite with each other πŸ˜‰
πŸ‘Œ 1
v
You know "man" has multiple meanings in English. No need to take it that way
I'm not a native speaker, so I might got it wrongly. πŸ™‚
s
That's fine. And maybe it comes down to that. Dunno. Like I said, I have fixed all of those, though unfortunately so cannot reproduce it
But unfortunately++ I think my solution so far has been explicit task dependency
😒 1
v
If you fixed them by adding explicit task dependencies, you should re-fix them. πŸ™‚
πŸ˜„
s
iirc that is the solution implied by the warning
but regardless, that is all theoretical until i can get the warning again
v
It says ther is neither an implicit nor explicit dependency which both are fine regarding the problematic situation. Explicit dependency just is frowned upon as you stated. πŸ™‚
s
Here, it really is a shame that you cannot not add the annotations
Explicit dependency just is frowned upon as you stated.
Now then, that would be a good warning πŸ˜‰
c
lol. yea. stop with the PC stuff and call it like it is πŸ˜‰
v
Well, we don't even get warnings for not using task configuration avoidance api, so, ....
:'''-(
s
"task configuration avoidance api" == TaskContainer#register?
v
==
is too strong as there is more to it
s
(getting a bit off topic, but an interesting topic)
c
yea, the mixture of configuration avoidance stuff is SO VERY CONFUSING, warnings would be helpful. Even if we needed to opt-in to β€œI care about the performance and quality of my build script, please help where possible…”
v
But
register
is part of the task configuration avoidance api, yes
c
.register
is one of them. there are so many different ways to break the laziness.
s
I already heavily leverage Property, Provider, etc
which I guess is another part of it
And those are wonderful
c
yep. definitely those. though they can be abused, e.g. calling
.get
before getting to the execution phase. Often see folks embracing properties … and then calling
get
like 2 lines later…
v
They are not really task configuration avoidance
They are nice but a different aspect, they are for avoiding ordering issues and
afterEvaluate
hell.
s
mmm, to an extent they are imo. config avoidance anyway
well they also defer work
v
Not really, they do not avoid configuring tasks, they just allow to resolve as late as possible
s
but yes, i agree with what you said
c
yes, they defer getting configuration values (or doing work) until (maybe) needed.
v
And that is great
s
Potato/potato
v
But if you use
tasks.withType(Abc) { prop.set("") }
it is eagerly configuring the task
s
sure
but thats not what i do, so... πŸ˜‰
v
tasks.withType(Abc).configureEach { prop.set("") }
would be avoiding configuring the tasks if they are not part of the task graph
c
^^^ the missing
.configureEach
imo should be a warning.
v
The same way
tasks.withType(Abc).configureEach { oldString = "" }
would be properly task configuration avoidance, although it is a plain string
s
more i am thinking
oldString.convention
v
oldString
is not
Property<String>
it is just plain
String
s
which i do not do
i get your point
but its not relevant specifically to my case
i defer as much as possible
v
And that's good. All I tried to show is why Property / Provider has nothing to do with task configuration avoidance. It is just not releated. You can break task configuration avoidance with or without them and you can have task configuration avoidance with or without them.
c
yep. terminology. task configuration avoidance --> tasks, which is a subset of lazy configuration which included properties/providers.
s
Which is why I said potato/potato. Whatever term you use, Property#convention is avoiding task config
v
... no?
s
Does Gradle call it something else techincally? Sure, ok, probably.
v
tasks.withType(Abc) { prop.convention("") }
would immediately realize and configure the task
Or
tasks.foo.get().prop.convention("")
s
well you keep coming back to this "withType" not me πŸ˜‰
v
But
tasks.withType(Abc).configureEach { prop.convention("") }
would be fine
s
i always do this in register or in task ctor
v
And that's fine (well in task constructor is still slightly non-idiomatic)
s
generally i am not bulk configuring multiple tasks of the same type. but sure i get your point
v
Of course I come back with the
withType
, because you say
convention
avoids task configuration and that is wrong. And the
withType
is one of the counter-examples.
You think on the wrong level
s
you can misuse any tool
v
Of course you can πŸ˜„
s
if you say so
my set up avoids task config
however we want to call that
v
πŸ‘Œ
s
dunno about idiomatic. but i find that much more readable
v
Than what?
s
generally the tasks I am talking about have one instance per type
so to me, setting up the props in its ctor just makes it more readable than "polluting" the plugin code with all of that
ymmv
v
The point about idiomaticness there is, that neither tasks, nor extensions should have opinion. They should be "dumb"ly providing properties and work with what they were given. The plugins then add the actual opinion to the task instances they register. This way the extensions and tasks can more easily be reused, also in ways not forseeable now, or also be 3rd party code.
πŸ‘ 1
s
Copy code
tasks.register( 
      ..., 
      {
        someprop = this
        anotherprop = that
        ...
      }
);
versus
Copy code
task.register( ... )
I think that depends on the nature of the plugin and of the task(s)
we'll just agree to disagree here
v
I'm not at all talking about readability, just about idiomaticness and why it is the case. I also don't always stick to that of course. πŸ˜„
s
i think it is VERY natural to do it in the constructors of the tasks I am talking about
but for other tasks I write which generate multiple tasks of the same type... I agree with what you are saying
e.g. my Antlr tasks, one per grammar. my XJC tasks with one per schema. etc
v
I didn't made this up, it is from the creators of the tool and how they think it fits best. Of course you can do the opinion in the task, you are just hindering a bit free reuse, also outside your plugin. Builds can register own instances or other plugins can.
s
because the task configuring itself there is meaningless
v
And as I said, I also violate these rules of course occasionally. πŸ™‚
s
I think that depends on the nature of the plugin and of the task(s)
v
No build is fully idiomatic, just trying to spread the world to improve the builds out there. πŸ™‚
s
and I appreciate it
I'd be silly to sit here and say "you use Hibernate wrong" just because its not maybe how I intended you to use it
v
Yep, I also didn't say it is wrong to do it in the constructor, I just said it is non-idiomatic. πŸ™‚
s
not saying you are silly to be clear
v
Besides that it feels good to do something wrong sometimes. πŸ˜„
s
haha
v
not saying you are silly to be clear
Didn't get it like that. πŸ™‚
How should I? It is not my tool and I didn't say you use it wrong. So your sentence couldn't affect me πŸ˜„
s
the global you, not you you πŸ˜‰