How can you pass values from a file to Property fo...
# community-support
p
How can you pass values from a file to Property for another task? I have a task that produces a Java
Properties
files, and I want to pass these properties to a `MapProperty<String, String>`:
Copy code
`val propertiesAsMapProvider = providers.fileContents(
  writePropertiesToFile.flatMap { it.output },
).asText.map {
  it.byteInputStream().use {
    Properties().apply { load(it) } as Map<String, String>
  }
}
This looses the task dependencies...
1
I definitivly tried this in the past... But maybe I had some other issues, this does work:
Copy code
val propertiesAsMapProvider = writePropertiesToFile.flatMap { it.output }.map {
  it.asFile.inputStream().use {
    Properties().apply { load(it) } as Map<String, String>
  }
}
a
Why not pass a file as
RegularFileProperty
and read a properties file in a task?
p
Because the task does not support it
🫤 1
@Anze Sodja what's the expectation? With lazy properties, as a plugin author I would not expect to create a file/fileconfiguration overload for each input my task needs but just use a Property as input and let the consumer decide how they want to populate the values. Otherwise, it does not scale. But IMHO Gradle lacks a way to transform a task output (file, files or directories) to a task input (any Property), ideally with classpath isolation transformations to not pollute your build script when you need a complex operation. A value source would serialize the values into CC, won't it?
a
> With lazy properties, as a plugin author I would not expect to create a file/fileconfiguration overload for each input my task needs but just use a Property as input and let the consumer decide how they want to populate the values. Otherwise, it does not scale. If you are building a task that can have properties that can be added as strings or as files I understand that having one property as
MapProperty<String, String>
makes sense. So what you do probably makes sense if is fast enough. If reading these properties is slow or file is really big and reading into memory is a bottlenect then it makes sense to add another property that is a
RegularFileProperty
. But I think normally properties files are small and what you do looks fine. > But IMHO Gradle lacks a way to transform a task output (file, files or directories) to a task input (any Property), ideally with classpath isolation transformations to not pollute your build script when you need a complex operation. Do you have any example what would be benefit compared to just using
map
? I know that having any property type as an output is a desired feature, e.g.
@Output Property<String>
. This could help with some boilerplate. And then if you would want to transform a file to a String or Map you would just write a task that does that and outputs
Property<String>
. Note that In the end Gradle would still need to write this output to a file or a database, since output have to persist even if daemon is stopped, but at least user won't need to deal with it.
p
is a bottlenect then it makes sense to add another property that is a RegularFileProperty . But I think normally properties files are small and what you do looks fine.
But as a task author, I don't know how other users will populate the values. In my example, I use a 3rd party tasks that exposes a
MapProperty<String, String>
and I wrote a (local) task to produce the values that will be passed to the MapProperty. I would never expect to ask the 3rd party plugin to include my use-case and change their tasks.
Do you have any example what would be benefit compared to just using map?
If the output is a Json, protobuf file, you cannot read it without polluting the buildscript classpath. Also, you often need Java Beans classes for these use-cases. But yeah, I would love to see
@Output
for all Gradle managed types.
v
"polluting" is a hard word, if you need the classes to implement build-logic, I'd not call it "polluting" 🙂 But if that is an issue, you could have another task that transforms the Json file to a properties file and then use that task's output for the other tasks input. 🤷‍♂️ 🙂
p
Well, I try to use as much classpath isolation workers as possible to not have any issues with conflicting classes/kotlin stdlib