|
import org.gradle.api.Project |
|
import org.gradle.api.plugins.ExtraPropertiesExtension |
|
import org.gradle.kotlin.dsl.extra |
|
|
|
const val DEPS_ATTR = "deps" |
|
|
|
/** Supertype of a dependency definition */ |
|
interface DependencyItem { |
|
operator fun get(key: String): Any |
|
} |
|
|
|
/** Leaf nodes in the dependency tree, defines a single dependency */ |
|
data class DependencyNotation(private val notation: String) : CharSequence by notation, |
|
DependencyItem { |
|
override operator fun get(key: String): String = notation |
|
override fun toString() = notation |
|
} |
|
|
|
/** Defines a group of dependencies */ |
|
class DependencyGroup : DependencyItem { |
|
private val dependencies = mutableMapOf<String, DependencyItem>() |
|
|
|
/** Get dependency with the [key]. |
|
* |
|
* A `.` notation is also allowed to retrieve grouped dependencies, e.g, `deps["support.appCompat"]`. |
|
*/ |
|
override operator fun get(key: String): DependencyItem = key.split('.') |
|
.fold(this as DependencyItem) { acc, k -> |
|
(acc as? DependencyGroup)?.getItem(k) ?: acc |
|
} |
|
|
|
private fun getItem(key: String): DependencyItem = |
|
dependencies[key] ?: throw IllegalArgumentException( |
|
"dependency `$key` not found in group $this" |
|
) |
|
|
|
/** Define a dependency */ |
|
operator fun set(key: String, item: DependencyItem) = dependencies.set(key, item) |
|
|
|
/** Define a dependency */ |
|
operator fun set(key: String, notation: String) = |
|
dependencies.set(key, DependencyNotation(notation)) |
|
|
|
/** |
|
* The key/value syntax to define a dependency. |
|
* |
|
* ``` |
|
* deps { |
|
* "core-ktx" to "androidx.core:core-ktx:$ktx_version" |
|
* "appcompat" to "androidx.appcompat:appcompat:$appcompat_version" |
|
* } |
|
* ``` |
|
*/ |
|
infix fun String.to(notation: String) = set(this, notation) |
|
|
|
/** The `in` operator */ |
|
operator fun contains(key: String): Boolean = key in dependencies |
|
|
|
/** |
|
* The closure syntax to define grouped dependencies. |
|
* |
|
* ``` |
|
* "androidx" { |
|
* "core-ktx"("androidx.core:core-ktx:$ktx_version") |
|
* "appcompat"("androidx.appcompat:appcompat:$appcompat_version") |
|
* } |
|
* ``` |
|
*/ |
|
operator fun invoke(config: DependencyGroup.() -> Unit): DependencyGroup = apply(config) |
|
|
|
/** |
|
* The `()` syntax to define a single dependency. |
|
* |
|
* ``` |
|
* deps { |
|
* "core-ktx"("androidx.core:core-ktx:$ktx_version") |
|
* "appcompat"("androidx.appcompat:appcompat:$appcompat_version") |
|
* } |
|
* ``` |
|
*/ |
|
operator fun String.invoke(notation: String) = set(this, notation) |
|
|
|
/** |
|
* The key/value syntax to define grouped dependencies. |
|
* |
|
* ``` |
|
* "androidx"( |
|
* "core-ktx" to "androidx.core:core-ktx:$ktx_version" |
|
* "appcompat" to "androidx.appcompat:appcompat:$appcompat_version" |
|
* ) |
|
* ``` |
|
*/ |
|
operator fun String.invoke(vararg dependencies: Pair<String, Any>) = |
|
set(this, create(*dependencies)) |
|
|
|
/** |
|
* The closure syntax to define a dependency group. |
|
* |
|
* ``` |
|
* "androidx" { |
|
* "core-ktx"("androidx.core:core-ktx:$ktx_version") |
|
* "appcompat"("androidx.appcompat:appcompat:$appcompat_version") |
|
* } |
|
* ``` |
|
*/ |
|
operator fun String.invoke(init: DependencyGroup.() -> Unit) = set(this, create().apply(init)) |
|
|
|
override fun toString() = dependencies.toString() |
|
|
|
companion object { |
|
@Suppress("UNCHECKED_CAST") |
|
private fun create(dependencies: Map<String, Any>): DependencyGroup { |
|
val inst = DependencyGroup() |
|
dependencies.forEach { |
|
val (key, item) = it |
|
when (item) { |
|
is String -> inst[key] = item |
|
is DependencyItem -> inst[key] = item |
|
is Map<*, *> -> inst[key] = create(item as Map<String, Any>) |
|
else -> throw IllegalArgumentException("Unsupported dependency item type of `$item`") |
|
} |
|
} |
|
return inst |
|
} |
|
|
|
private fun create(vararg dependencies: Pair<String, Any>): DependencyGroup = |
|
create(mapOf(*dependencies)) |
|
} |
|
} |
|
|
|
/** |
|
* Retrieve the dependency tree from extra properties, a new one will be created for the first access. |
|
*/ |
|
val ExtraPropertiesExtension.deps: DependencyGroup get() = |
|
if (has(DEPS_ATTR)) this[DEPS_ATTR] as DependencyGroup |
|
else DependencyGroup().apply { |
|
this@deps[DEPS_ATTR] = this |
|
} |
|
|
|
/** |
|
* Retrieve current project's dependency tree. |
|
* |
|
* If no `deps` property defined in a sub-project, looks for it in the root project. |
|
*/ |
|
val Project.deps: DependencyGroup get() = |
|
if (parent == null || extra.has(DEPS_ATTR)) extra.deps |
|
else rootProject.deps |
Hello,
I think you should close FileInputStream instance in loadProperties extension method in utils.kt.
Maybe change to: