Vlastimil Brecka
06/14/2022, 12:25 AMdef props = ...read profs from file
appAutomateUpload {
username = props["username"]
password = props["password"]
}
I have a plugin which needs credentails. I have those in a file. How would I best set this up so the properties are not read every build?
Is this a bad design on plugin part? Should it be working expecting a file path and read the file lazily when actually running the task?
Or can I lazy configure a extension?Chris Lee
06/14/2022, 12:34 AMVlastimil Brecka
06/14/2022, 12:42 AMloop all android variants
...
tasks.register("appAutomateUpload$variant") {
def props = .... read prefs from file
username = props["username"]
password = props["password"]
}
(as you can see props are read lazily)
with task body being in buildSrc, to creating a plugin which will be moved out to a separate repo
now it feels like a downgradeVlastimil Brecka
06/14/2022, 12:42 AMChris Lee
06/14/2022, 12:43 AMChris Lee
06/14/2022, 12:44 AMproviders.fileContents(file)
that allows for lazy reading of a file.Vlastimil Brecka
06/14/2022, 12:46 AMplay {
serviceAccountCredentials.set(file("your-key.json"))
}
Vlastimil Brecka
06/14/2022, 12:46 AMVlastimil Brecka
06/14/2022, 12:48 AMappAutomateUpload {
def props = ...read profs from file
username = props["username"]
password = props["password"]
}
just moving the reading into the extension? not sure when are those resolved tbhChris Lee
06/14/2022, 12:49 AMVlastimil Brecka
06/14/2022, 12:50 AMChris Lee
06/14/2022, 12:51 AMChris Lee
06/14/2022, 12:52 AMprovider {
def props = ...read profs from file
props
} // assuming props is a Map<String,String>
Vlastimil Brecka
06/14/2022, 12:53 AMVlastimil Brecka
06/14/2022, 12:54 AMChris Lee
06/14/2022, 12:55 AMprops["username"]
.
Yea, type safety and groovy ugh…Vlastimil Brecka
06/14/2022, 12:55 AMappAutomateUpload {
credentials {
def props = ...read profs from file
Credentials(props["username"], props["password"])
}
}
something like this?Chris Lee
06/14/2022, 12:55 AMVlastimil Brecka
06/14/2022, 12:56 AMVlastimil Brecka
06/14/2022, 1:00 AMChris Lee
06/14/2022, 1:01 AMpublic abstract class AppAutomateUploadExtension {
@get:Input
public abstract val credentials : Property<Credentials>
}
val credProvider = providers.provider {
val props = readFile(...)
return Credentials(props["username"], props["password"])
}
…Credentials can be your type, if that exists and is what you are modelling.Vlastimil Brecka
06/14/2022, 1:02 AMVlastimil Brecka
06/14/2022, 1:02 AMVlastimil Brecka
06/14/2022, 1:03 AMProvider
, hence I need the providers.provider
factory?Chris Lee
06/14/2022, 1:04 AM.get
.Chris Lee
06/14/2022, 1:05 AMVlastimil Brecka
06/14/2022, 1:05 AMChris Lee
06/14/2022, 1:06 AMChris Lee
06/14/2022, 1:07 AM.get()
on a property/provider inside the execution phase, usually in a task action.Vlastimil Brecka
06/14/2022, 1:07 AMproviders.provider
factory is nicerChris Lee
06/14/2022, 1:09 AM.map()
. Say you have a Provider<Map<String,String>> and want to pass one specific map entry into a task - you can go prop.map { this["username"] }
to turn that into a Provider<String>. also available are conventions (defaults) for properties via .convention()
.Chris Lee
06/14/2022, 1:11 AMproject.layout.projectDir.file("myFile.properties").map { // process file }
Vlastimil Brecka
06/14/2022, 1:12 AMVlastimil Brecka
06/14/2022, 1:15 AMChris Lee
06/14/2022, 1:15 AMephemient
06/14/2022, 6:40 AMproviders
, then
tasks.register("myTask") {
val credentials = project.providers.credentials(PasswordCredentials::class, name)
doLast {
val credentials = credentials.get()
println("${credentials.username}:${credentials.password}")
}
}
lets you provide it via any of
# gradle.properties
myTaskUsername = foo
myTaskPassword = bar
or
./gradlew myTask -PmyTaskUsername=foo -PmyTaskPassword=bar
or
env ORG_GRADLE_PROJECT_myTaskUsername=foo ORG_GRADLE_PROJECT_myTaskPassword=bar ./gradlew myTask
without requiring credentials if the task isn't run