This message was deleted.
# community-support
s
This message was deleted.
🤔 2
m
What's the code which is throwing that exception?
looks like you are passing your input to
file()
rather than
files()
?
t
I was using this:
Copy code
// task
@get:PathSensitive(PathSensitivity.RELATIVE)
@get:InputFiles
abstract val source: ConfigurableFileTree
Copy code
// plugin
source.from(/* a SourceDirectorySet */)

// I also tried
source.setDir(/* a SourceDirectorySet */)
both failed with the above error
I was trying to use an API analogous to
ConfigureFileCollection
, where I would call
setFrom(/* a FileCollection */)
m
A file tree can only have one root directory - you can only call from with whatever gives you a single file, so you cannot pass a file collection to
FileTree.from()
as far as I understand
Depending on what you want to achieve in your task, it sounds like what you actually want is to use a
ConfigurableFileCollection
as your input. I believe that if you do
ConfigurableFileCollection.from(FileTree)
what actually is then returned from
getFiles()
on that
FileCollection
are files in the file tree and not file tree roots (which would be just source directories in the case of a
SourceDirectorySet
).
👀 1
Whenever I want to add files and not directories to a file collection, I ensure that whatever I pass to
from()
on
ConfigurableFileCollection
(but not
ConfigurableFileTree
as
from()
for it is overloaded) is first turned into a
FileTree
using
FileCollection.getAsFileTree()
My mnemonic is "a
FileTree
contains only files, a
FileColleciton
contains whatever you put into it, can be both files and directories"
💯 1
I find that grokking `FileTree`s/`FileCollection`s takes a fair bit of mental exercise and I constantly revisit my solutions after I learn more and more about them
I think that https://docs.gradle.org/current/userguide/working_with_files.html could do with some improvement around describing working with, configuring and consuming file collections in custom tasks rather than just talk in terms of using file collections with built-in task types as there are differences between the two which seem to be the source of your questions, @tony.
t
that all seems very helpful! Thank you!
reasoning by analogy to a
ConfigurableFileCollection
, it just seems wrong, or at least inconsistent, that I can't just take a FileTree I have and set it as a task input, very simply and naively. It should Just Work ™️ cc @Tom Tresansky since you seem to care about Gradle docs 🙂
m
Oh, I see what you are after now. You can always make the input a mutable
FileTree
property and pass your existing tree to the setter for it but that would be a somewhat constraining API if all your task wants to do is to iterate over files. I think using a
ConfigurableFileCollection
for your input is much more flexible because that way it can be easily set from both an existing file tree, any
FileCollection
, paths or file objects.
On the other hand, there does seem to be an API missing, something like
ConfigurableFileTree.set(FileTree)
which would make the configuration of the
ConfigurableFileTree
match exactly the one of the passed
FileTree
.
t
@tony This API sounds reasonable to me. Can you please write up an issue and we'll consider it further?
👍 1
@Marcin Erdmann Our technical writer is very interested in receiving feedback about specific sections of the docs that are incomplete or incorrect. If you use the Send Feedback link on that docs page, she will add this to the list. Though there is a mountain of work there, the pace of change in improving the docs has increased these last couple of releases and should only continue to accelerate.
t
@Marcin Erdmann your approach of setting the file tree on the file collection worked perfectly. It just took way more friction than I expected, given that
ConfigurableFileTree
exists and seemed a natural API to use. Tom, I've made a note to write up an issue
thank you 1
m
Done, @Tom Tresansky
t
Thanks!
m
To be frank, I cannot imagine a situation where using
ConfigurableFileTree
as task input type would make sense, @tony. It seems like the usecase for that API is to find/filter files in a directory structure and then pass it to
ConfigurableFileCollection
as a source of files.
If you search for usages of
ConfigurableFileTree
in gradle codebase then there is very little and there is not a single usage of that class as a task input property.
And
FileTree
seems to be only used when you care about relative paths of the files and not just the files themselves.
t
the javadoc could be better at least, and point one in the right direction 🙂