I wonder, what is the current way to go for `Confi...
# community-support
v
I wonder, what is the current way to go for
ConfigurableFileCollection
vs
ListProperty<RegularFile>
Is there anything like “prefer
ConfigurableFileCollection
in newer code” or “prefer
ListProperty<RegularFile>
in newer code” ? I assume the answer should be the same for both task properties and extension properties, however, it would be great to learn if there’s a difference.
v
I'm not aware of a single case where I would prefer the latter, whatever that means to you :-)
v
The context of the question is I want to prepare a talk on “idiomatic Gradle” based on the items I collect. Recently I noticed
ListProperty<RegularFile>
usages while I previously sticked to
ConfigurableFileCollection
, so I decided to ask. --- I saw AGP was migrating off
FileCollection
, however, it looks like there was no
CFC#finalizeValue()
back then.
👀 1
v
The only reason I could imagine why people might tend to replace
ConfigurableFileCollection
to
Provider<...>
is because they want to lazify everything by using `Provider`s, but that is then just a misunderstanding, as
ConfigurableFileCollection
is properly lazy already and if you need its contents as
Provider<...>
, you can use
FileCollection#elements
.
That issue about the move from
ConfigurableFileCollection
to
Property
predates the
FileCollection.elements
method, so maybe back then it could have made sense. 🤷‍♂️
m
How do you express the normalized path of a
RegularFile
?
👍 1
ConfigurableFileCollection
can be "rooted" (if they are built from
FileTree
). I don't think you can do the same with
RegularFile
?
Say you want to input all the
*.graphql
in the hierarchy at
src/main/graphql
to a task but that graphql path is not important. It could very well be under
build/foobar/graphql
and the snapshotting should be exactly the same as long as the contents of the folder stays the same. You just can't do this with a
ListProperty<RegularFile>
e
Out of curiosity, one question I have faced a few times is how to convert a
FileCollection
to a
Provider<RegularFile>
when it is expected the collection only has a single element. For example in the case of a Task that has a
RegularFileProperty
as input, and it needs to be passed something coming from a dependency resolution. The best I have so far is this:
Copy code
fun setFilePropertyFromCollection(fileProperty: RegularFileProperty, collection: FileCollection) {
  fileProperty.fileProvider(collection.elements.map {
    it.singleOrNull()?.asFile ?: throw IllegalArgumentException("FileCollection must contain exactly one element")
  })
}
This seems to keep the task dependencies and all the right things. Do you have anything better? But this transforms
FileCollection
to a
Provider<File>
. I don't know how it can be transformed into a
Provider<RegularFile>
.
m
Best I've got so far to turn a
File
into a
RegularFile
is tricking Gradle dependency injection:
Copy code
abstract class Unused @Inject constructor( val files: FileFactory)

fun setFilePropertyFromCollection(collection: FileCollection): Provider<RegularFile> {
    val factory = objects.newInstance(Unused::class.java)
    return collection.elements.map {
        val file = it.singleOrNull()?.asFile ?: throw IllegalArgumentException("FileCollection must contain exactly one element")
        check(file.isFile)
        factory.files.file(file)
    }
}
I would probably just use
Provider<File>
though 🤷
v
What do you think of
layout.file(provider { File(".") }
? See https://chatgpt.com/share/6810f339-92ec-800f-8edd-89b32dbf93a6
m
That works as well I think It's more "Providers" but the end result should be the same I think
The fact that there is both
RegularFileProperty
and
Provider<RegularFile>
`PropertyRegularFile`is always making me a bit uncomfortable but 🤷
v
Did you mean
Property<RegularFile>
vs
RegularFileProperty
? The
Provider<..>
does not have setter methods,
m
Yes, sorry
I just want
Provider
and
Property
, all the specialized classes like
ListProperty
as well are complexifying stuff But I'm rambling, don't mind me
v
v
Copy code
val files: FileCollection = null!!
val fileProperty: RegularFileProperty = null!!
val file: Provider<RegularFile?> = layout.file(files.elements.map { it.single().asFile })
fileProperty.set(file)
👌 1