Carl Benson
11/22/2022, 9:49 AMCarl Benson
11/22/2022, 9:51 AMabstract class SyncFigmaPluginExtension {
abstract fun getAccessToken(): Property<String>
abstract fun getIconsFileId(): Property<String>
}
class SyncFigmaPlugin : Plugin<Project> {
override fun apply(project: Project) {
val extension = project.extensions.create("syncIcons", SyncFigmaPluginExtension::class.java)
project.tasks.create("syncIcons", SyncFigmaIcons::class.java)
project.afterEvaluate {
project.tasks.getByName("syncIcons") {
val task = it as SyncFigmaIcons
task.accessToken.set(extension.getAccessToken())
task.iconsFileId.set(extension.getIconsFileId())
}
}
}
}
abstract class SyncFigmaIcons : DefaultTask() {
@get:Input
abstract var accessToken: Property<String>
@get:Input
abstract var iconsFileId: Property<String>
this is my task and I've tried so many approaches but I always get the error that
the extension is not foundCarl Benson
11/22/2022, 9:52 AMid 'com.sitoo.figma.sync' apply false
because if I apply it, it will crash with getAccessToken
returning nullCarl Benson
11/22/2022, 9:52 AMsyncIcons {
accessToken = "xxx"
iconsFileId = "abc"
}
Vampire
11/22/2022, 10:42 AMinterface SyncFigmaPluginExtension {
fun getAccessToken(): Property<String>
fun getIconsFileId(): Property<String>
}
Also, when using Kotlin you shouldn't use getter functions but properties, otherwise you will not be able to access them like you want from Kotlin DSL, so
interface SyncFigmaPluginExtension {
val accessToken: Property<String>
val iconsFileId: Property<String>
}
Then, you should never use afterEvaluate
whenever you can prevent it. The only thing you do in most situations is introducing timing problems and race conditions. And with using the lazy property APIs it is also totally non-sense, they are introduced to exactly eliminate the horrible afterEvaluate
need. Besides that it makes your code super-clumsy, so
project.tasks.create("syncIcons", SyncFigmaIcons::class.java) {
accessToken.set(extension.accessToken)
iconsFileId.set(extension.iconsFileId)
}
or
project.tasks.create("syncIcons", SyncFigmaIcons::class.java) {
accessToken.convention(extension.accessToken)
iconsFileId.convention(extension.iconsFileId)
}
depending on the intended semantics.
Next thing is, that you should use task configuration avoidance wherever you can to not do unnecessary work, so do not use tasks.create
, but tasks.register
, so
project.tasks.register("syncIcons", SyncFigmaIcons::class.java) {
accessToken.convention(extension.accessToken)
iconsFileId.convention(extension.iconsFileId)
}
And if you use the kotlin-dsl
plugin on the project building the plugin, you can also use the Kotlin DSL extensions of the Gradle API like
project.tasks.register<SyncFigmaIcons>("syncIcons") {
accessToken.convention(extension.accessToken)
iconsFileId.convention(extension.iconsFileId)
}
Or if you want to avoid strings or need the reference to the task later anyway,
val syncIcons by project.tasks.registering(SyncFigmaIcons::class) {
accessToken.convention(extension.accessToken)
iconsFileId.convention(extension.iconsFileId)
}
But those were all just improvement suggestions.
I apply the plugin like
No, that does not apply the plugin, you tell it not to. You just add the plugin to the classpath, but do not apply it. Then the extension of course is also not available.Copy codeid 'com.sitoo.figma.sync' apply false
because if I apply it, it will crash withMaybe that was due to not using a property but a getter function, I'm not sure.returning nullgetAccessToken
Carl Benson
11/22/2022, 10:54 AMCarl Benson
11/22/2022, 10:54 AMafterEvalute
at first, but found it while googling solutionsRajar
11/23/2022, 1:30 PMafterEvaluate
it doesn't work at all. With it, each time app build is triggered the plugin stores git-time data in a JSON (business need). How to not use afterEvaluate in this case ?Vampire
11/23/2022, 4:19 PMafterEvaluate
would change anything. If it does, you need to provide more information.