Sergej Koščejev
02/08/2025, 8:08 AMDirectory
and RegularFile
over File
in my API? The API that Gradle provides for working with Directory and RegularFile objects seems to be a bit lacking compared to plain Files.Vampire
02/08/2025, 11:56 AMFile
with asFile
or what it was called.Sergej Koščejev
02/08/2025, 12:04 PMproject.file(Object)
method that gives you a File from whatever you pass to it. There's no such method to get a Directory
or RegularFile
from a String or a File. There's one method to get it from String (but NOT from a File) using project.layout.projectDirectory.file
which is a lot to write. There's a different method, project.layout.file
to get a Provider<RegularFile>
from a Provider<File> (but NOT from a Provider<String>).
This is what I call a lacking API. Whether it's a "real" lack or not is debatable.Sergej Koščejev
02/08/2025, 12:10 PMMapProperty<String, Directory>
and MapProperty<String, File>
and it seems like the File option would be easier for the users to fill.)Vampire
02/10/2025, 8:49 AMFile
might be easier to fill, but Directory
has more semantic and clearly states in the type that you need a directory, not a file.
That the new ways are a bit longer is right, but that is because the old ways are too short and type-un-unsafe.
Back in the beginning many things were added as "convention property" or method directly to the Project
instance and many things accepted Object
as argument.
This made it quite comfortable to use non-intelligently from Groovy DSL due to its duck-typing, so you can access any method and any property that just is there, independent of the type.
But this also meant that things like methods taking Object
could only fail at runtime.
With the introduction of Kotlin DSL and thus more type-safety in the build scripts,
this trend reversed and things are usually not added anymore to the Project
instance dynamically, but to extensions,
methods do not accept Object
anymore, but the things they accept, ...
This allows to fail early at compile time already and also to have much more intelligence in the support by a good IDE.
So yes, if you nowaday want to get a modern version of a file relative to the project directory by String
, you usually use layout.projectDirectory.file(...)
.
And if you want it from a File
you would use layout.file(provider { theFile })
, and thus could also use layout.file(provider { file(whatever) })
if you really want to.
This is what I call a lacking API. Whether it's a "real" lack or not is debatable.I'd say not, it is clear API. For
layout.projectDirectory.file
it does not make much sense to accept a File
as it represents a file with path and could also be an absolute path, this would make the API less clear and more complex regarding what happens when, and also a user can always transform the File
to a String
with the information he intends to be used like the full path as he knows it is a relative path, or just the name.
For layout.file
it does not make much sense to accept a String
, as usually such strings are not absolute paths but relative paths and for relative paths you have layout.projectDirectory
and layout.buildDirectory
to make it crystal clear relative to what the path is resolved.
But feel free to open feature requests or pull requests for the additional API, then you get to know what the Gradle folks think about it. I'm must a user like you. 🙂Sergej Koščejev
02/10/2025, 8:54 AMVampire
02/10/2025, 1:21 PMlayout.file()
for example?