name.remal.gradle_plugins.dsl.extensions.org.gradle.api.plugins.ExtensionContainer.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of gradle-plugins-kotlin-dsl Show documentation
Show all versions of gradle-plugins-kotlin-dsl Show documentation
Remal Gradle plugins: gradle-plugins-kotlin-dsl
package name.remal.gradle_plugins.dsl.extensions
import name.remal.uncheckedCast
import org.gradle.api.InvalidUserDataException
import org.gradle.api.plugins.Convention
import org.gradle.api.plugins.ExtensionContainer
operator fun ExtensionContainer.invoke(name: String, configurer: (T) -> Unit) {
if (this is Convention) this.plugins[name]?.let { it.configureWith(configurer); return }
try {
configure(name, configurer)
} catch (e: Exception) {
val isExtensionHasBeenAccessedException = e.javaClass == InvalidUserDataException::class.java
&& e.message == "Cannot configure the '$name' extension after it has been accessed."
if (isExtensionHasBeenAccessedException) {
getByName(name).configureWith(configurer)
} else {
throw e
}
}
}
operator fun ExtensionContainer.invoke(type: Class, configurer: (T) -> Unit) {
if (this is Convention) this.findPlugin(type)?.let { it.configureWith(configurer); return }
try {
configure(type, configurer)
} catch (e: Exception) {
val isExtensionHasBeenAccessedException = e.javaClass == InvalidUserDataException::class.java
&& (e.message?.startsWith("Cannot configure the '") ?: false)
&& (e.message?.endsWith("' extension after it has been accessed.") ?: false)
if (isExtensionHasBeenAccessedException) {
getByType(type).configureWith(configurer)
} else {
throw e
}
}
}
operator fun ExtensionContainer.get(name: String): T {
if (this is Convention) this.plugins[name]?.let { return it.uncheckedCast() }
return this.getByName(name).uncheckedCast()
}
operator fun ExtensionContainer.get(type: Class): T {
if (this is Convention) this.findPlugin(type)?.let { return it }
return this.getByType(type)
}
fun ExtensionContainer.getOrNull(name: String): T? {
if (this is Convention) this.plugins[name]?.let { return it.uncheckedCast() }
this.findByName(name)?.let { return it.uncheckedCast() }
return null
}
fun ExtensionContainer.getOrNull(type: Class): T? {
if (this is Convention) this.findPlugin(type)?.let { return it }
this.findByType(type)?.let { return it.uncheckedCast() }
return null
}
operator fun ExtensionContainer?.contains(type: Class<*>) = this != null && getOrNull(type) != null
operator fun ExtensionContainer?.contains(name: String) = this != null && getOrNull(name) != null
fun ExtensionContainer.add(publicType: Class, instance: T) = add(publicType, publicType.extensionName, instance)
fun ExtensionContainer.createWithAutoName(instanceType: Class, vararg args: Any?): T {
return create(instanceType.extensionName, instanceType, *args)
}
fun ExtensionContainer.getOrCreate(publicType: Class, instanceType: Class, extensionName: String, onCreate: (T) -> Unit = {}): T {
if (this is Convention) this.findPlugin(publicType)?.let { return it }
this.findByType(publicType)?.let { return it }
return create(publicType, extensionName, instanceType).apply(onCreate)
}
fun ExtensionContainer.getOrCreateWithAutoName(publicType: Class, instanceType: Class, onCreate: (T) -> Unit = {}) = getOrCreate(publicType, instanceType, publicType.extensionName, onCreate)
fun ExtensionContainer.getOrCreate(publicType: Class, extensionName: String, onCreate: (T) -> Unit = {}) = getOrCreate(publicType, publicType, extensionName, onCreate)
fun ExtensionContainer.getOrCreateWithAutoName(publicType: Class, onCreate: (T) -> Unit = {}) = getOrCreateWithAutoName(publicType, publicType, onCreate)
private val Class<*>.extensionName: String get() = "$$" + name.replace('.', '$')