diff --git a/CHANGELOG.md b/CHANGELOG.md index c37535c3..13e065d1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ - LogManager plugin - dataforge-context API dependency on SLF4j - Context `withEnv` and `fetch` methods to manipulate plugins without changing plugins after creation. +- Split `ItemDescriptor` into builder and read-only part ### Changed - Kotlin-logging moved from common to JVM and JS. Replaced by console for native. diff --git a/build.gradle.kts b/build.gradle.kts index 98a941bb..9b8051e4 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -4,7 +4,7 @@ plugins { allprojects { group = "space.kscience" - version = "0.4.0-dev-7" + version = "0.4.0-dev-8" } subprojects { @@ -22,5 +22,8 @@ ksciencePublish { } apiValidation { + if(project.version.toString().contains("dev")) { + validationDisabled = true + } nonPublicMarkers.add("space.kscience.dataforge.misc.DFExperimental") } \ No newline at end of file diff --git a/dataforge-context/src/commonMain/kotlin/space/kscience/dataforge/properties/ConfigProperty.kt b/dataforge-context/src/commonMain/kotlin/space/kscience/dataforge/properties/ConfigProperty.kt index a079241e..c51f809e 100644 --- a/dataforge-context/src/commonMain/kotlin/space/kscience/dataforge/properties/ConfigProperty.kt +++ b/dataforge-context/src/commonMain/kotlin/space/kscience/dataforge/properties/ConfigProperty.kt @@ -8,6 +8,7 @@ import space.kscience.dataforge.meta.transformations.nullableItemToObject import space.kscience.dataforge.meta.transformations.nullableObjectToMetaItem import space.kscience.dataforge.misc.DFExperimental import space.kscience.dataforge.names.Name +import space.kscience.dataforge.names.startsWith @DFExperimental public class ConfigProperty( @@ -24,7 +25,7 @@ public class ConfigProperty( override fun onChange(owner: Any?, callback: (T?) -> Unit) { config.onChange(owner) { name, oldItem, newItem -> - if (name == this.name && oldItem != newItem) callback(converter.nullableItemToObject(newItem)) + if (name.startsWith(this.name) && oldItem != newItem) callback(converter.nullableItemToObject(newItem)) } } diff --git a/dataforge-context/src/commonMain/kotlin/space/kscience/dataforge/properties/schemeProperty.kt b/dataforge-context/src/commonMain/kotlin/space/kscience/dataforge/properties/schemeProperty.kt index a2f39eed..798154d5 100644 --- a/dataforge-context/src/commonMain/kotlin/space/kscience/dataforge/properties/schemeProperty.kt +++ b/dataforge-context/src/commonMain/kotlin/space/kscience/dataforge/properties/schemeProperty.kt @@ -2,6 +2,7 @@ package space.kscience.dataforge.properties import space.kscience.dataforge.meta.ItemPropertyProvider import space.kscience.dataforge.misc.DFExperimental +import space.kscience.dataforge.names.startsWith import space.kscience.dataforge.names.toName import kotlin.reflect.KMutableProperty1 @@ -16,7 +17,7 @@ public fun

P.property(property: KMutableProp override fun onChange(owner: Any?, callback: (T?) -> Unit) { this@property.onChange(this) { name, oldItem, newItem -> - if (name == property.name.toName() && oldItem != newItem) { + if (name.startsWith(property.name.toName()) && oldItem != newItem) { callback(property.get(this@property)) } } diff --git a/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/Config.kt b/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/Config.kt index 20fb1cb2..14beb87b 100644 --- a/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/Config.kt +++ b/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/Config.kt @@ -98,6 +98,12 @@ public fun Meta.toConfig(): Config = Config().also { builder -> } } +/** + * Create a copy of this config, optionally applying the given [block]. + * The listeners of the original Config are not retained. + */ +public inline fun Config.copy(block: Config.() -> Unit = {}): Config = toConfig().apply(block) + /** * Return this [Meta] as [Config] if it is [Config] and create a new copy otherwise */ diff --git a/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/ObservableItemProvider.kt b/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/ObservableItemProvider.kt index c66ec858..d5183fb9 100644 --- a/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/ObservableItemProvider.kt +++ b/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/ObservableItemProvider.kt @@ -2,6 +2,7 @@ package space.kscience.dataforge.meta import space.kscience.dataforge.misc.DFExperimental import space.kscience.dataforge.names.Name +import space.kscience.dataforge.names.startsWith import space.kscience.dataforge.names.toName import kotlin.reflect.KProperty1 @@ -34,7 +35,7 @@ public fun O.useProperty( //Pass initial value. callBack(property.get(this)) onChange(owner) { name, oldItem, newItem -> - if (name == property.name.toName() && oldItem != newItem) { + if (name.startsWith(property.name.toName()) && oldItem != newItem) { callBack(property.get(this)) } } diff --git a/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/descriptors/ItemDescriptor.kt b/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/descriptors/ItemDescriptor.kt index d2decefe..a1a6a595 100644 --- a/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/descriptors/ItemDescriptor.kt +++ b/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/descriptors/ItemDescriptor.kt @@ -3,28 +3,26 @@ package space.kscience.dataforge.meta.descriptors import space.kscience.dataforge.meta.* import space.kscience.dataforge.misc.DFBuilder import space.kscience.dataforge.names.* -import space.kscience.dataforge.values.* /** * A common parent for [ValueDescriptor] and [NodeDescriptor]. Describes a single [TypedMetaItem] or a group of same-name-siblings. */ -@DFBuilder -public sealed class ItemDescriptor(final override val config: Config) : Configurable { +public sealed interface ItemDescriptor: MetaRepr { /** * True if same name siblings with this name are allowed */ - public var multiple: Boolean by config.boolean(false) + public val multiple: Boolean /** * The item description text */ - public var info: String? by config.string() + public val info: String? /** * True if the item is required */ - public abstract var required: Boolean + public val required: Boolean /** @@ -32,14 +30,56 @@ public sealed class ItemDescriptor(final override val config: Config) : Configur * * @return */ - public var attributes: Config? by config.node() + public val attributes: Meta? /** * An index field by which this node is identified in case of same name siblings construct */ - public var indexKey: String by config.string(DEFAULT_INDEX_KEY) + public val indexKey: String - public abstract fun copy(): ItemDescriptor + public companion object { + public const val DEFAULT_INDEX_KEY: String = "@index" + } +} + + +/** + * The builder for [ItemDescriptor] + */ +@DFBuilder +public sealed class ItemDescriptorBuilder(final override val config: Config) : Configurable, ItemDescriptor { + + /** + * True if same name siblings with this name are allowed + */ + override var multiple: Boolean by config.boolean(false) + + /** + * The item description text + */ + override var info: String? by config.string() + + /** + * True if the item is required + */ + abstract override var required: Boolean + + + /** + * Additional attributes of an item. For example validation and widget parameters + * + * @return + */ + override var attributes: Config? by config.node() + + /** + * An index field by which this node is identified in case of same name siblings construct + */ + override var indexKey: String by config.string(DEFAULT_INDEX_KEY) + + public abstract fun build(): ItemDescriptor + + override fun toMeta(): Meta = config public companion object { public const val DEFAULT_INDEX_KEY: String = "@index" @@ -49,7 +89,7 @@ public sealed class ItemDescriptor(final override val config: Config) : Configur /** * Configure attributes of the descriptor, creating an attributes node if needed. */ -public inline fun ItemDescriptor.attributes(block: Config.() -> Unit) { +public inline fun ItemDescriptorBuilder.attributes(block: Config.() -> Unit) { (attributes ?: Config().also { this.attributes = it }).apply(block) } @@ -66,140 +106,6 @@ public fun ItemDescriptor.validateItem(item: MetaItem?): Boolean { } } -/** - * Descriptor for meta node. Could contain additional information for viewing - * and editing. - * - * @author Alexander Nozik - */ -@DFBuilder -public class NodeDescriptor(config: Config = Config()) : ItemDescriptor(config) { - init { - config[IS_NODE_KEY] = true - } - - /** - * True if the node is required - * - * @return - */ - override var required: Boolean by config.boolean { default == null } - - /** - * The default for this node. Null if there is no default. - * - * @return - */ - public var default: Config? by config.node() - - /** - * The map of children item descriptors (both nodes and values) - */ - public val items: Map - get() = config.getIndexed(ITEM_KEY).entries.associate { (name, item) -> - if (name == null) error("Child item index should not be null") - val node = item.node ?: error("Node descriptor must be a node") - if (node[IS_NODE_KEY].boolean == true) { - name to NodeDescriptor(node as Config) - } else { - name to ValueDescriptor(node as Config) - } - } - - /** - * The map of children node descriptors - */ - @Suppress("UNCHECKED_CAST") - public val nodes: Map - get() = config.getIndexed(ITEM_KEY).entries.filter { - it.value.node[IS_NODE_KEY].boolean == true - }.associate { (name, item) -> - if (name == null) error("Child node index should not be null") - val node = item.node ?: error("Node descriptor must be a node") - name to NodeDescriptor(node as Config) - } - - /** - * The list of children value descriptors - */ - public val values: Map - get() = config.getIndexed(ITEM_KEY).entries.filter { - it.value.node[IS_NODE_KEY].boolean != true - }.associate { (name, item) -> - if (name == null) error("Child value index should not be null") - val node = item.node ?: error("Node descriptor must be a node") - name to ValueDescriptor(node as Config) - } - - private fun buildNode(name: Name): NodeDescriptor { - return when (name.length) { - 0 -> this - 1 -> { - val token = NameToken(ITEM_KEY.toString(), name.toString()) - val config: Config = config[token].node ?: Config().also { - it[IS_NODE_KEY] = true - config[token] = it - } - NodeDescriptor(config) - } - else -> buildNode(name.firstOrNull()?.asName()!!).buildNode(name.cutFirst()) - } - } - - /** - * Define a child item descriptor for this node - */ - private fun newItem(key: String, descriptor: ItemDescriptor) { - if (items.keys.contains(key)) error("The key $key already exists in descriptor") - val token = ITEM_KEY.withIndex(key) - config[token] = descriptor.config - } - - public fun item(name: Name, descriptor: ItemDescriptor) { - buildNode(name.cutLast()).newItem(name.lastOrNull().toString(), descriptor) - } - - public fun item(name: String, descriptor: ItemDescriptor) { - item(name.toName(), descriptor) - } - - /** - * Create and configure a child node descriptor - */ - public fun node(name: Name, block: NodeDescriptor.() -> Unit) { - item(name, NodeDescriptor().apply(block)) - } - - public fun node(name: String, block: NodeDescriptor.() -> Unit) { - node(name.toName(), block) - } - - /** - * Create and configure child value descriptor - */ - public fun value(name: Name, block: ValueDescriptor.() -> Unit) { - require(name.length >= 1) { "Name length for value descriptor must be non-empty" } - item(name, ValueDescriptor().apply(block)) - } - - public fun value(name: String, block: ValueDescriptor.() -> Unit) { - value(name.toName(), block) - } - - override fun copy(): NodeDescriptor = NodeDescriptor(config.toConfig()) - - public companion object { - - internal val ITEM_KEY: Name = "item".asName() - internal val IS_NODE_KEY: Name = "@isNode".asName() - - //TODO infer descriptor from spec - } -} - -public inline fun NodeDescriptor(block: NodeDescriptor.() -> Unit): NodeDescriptor = - NodeDescriptor().apply(block) - /** * Get a descriptor item associated with given name or null if item for given name not provided */ @@ -213,93 +119,3 @@ public operator fun ItemDescriptor.get(name: Name): ItemDescriptor? { public operator fun ItemDescriptor.get(name: String): ItemDescriptor? = get(name.toName()) -/** - * A descriptor for meta value - * - * Descriptor can have non-atomic path. It is resolved when descriptor is added to the node - * - * @author Alexander Nozik - */ -@DFBuilder -public class ValueDescriptor(config: Config = Config()) : ItemDescriptor(config) { - - /** - * True if the value is required - * - * @return - */ - override var required: Boolean by config.boolean { default == null } - - /** - * The default for this value. Null if there is no default. - * - * @return - */ - public var default: Value? by config.value() - - public fun default(v: Any) { - this.default = Value.of(v) - } - - /** - * A list of allowed ValueTypes. Empty if any value type allowed - * - * @return - */ - public var type: List? by config.listValue { ValueType.valueOf(it.string) } - - public fun type(vararg t: ValueType) { - this.type = listOf(*t) - } - - /** - * Check if given value is allowed for here. The type should be allowed and - * if it is value should be within allowed values - * - * @param value - * @return - */ - public fun isAllowedValue(value: Value): Boolean { - return (type?.let { it.contains(ValueType.STRING) || it.contains(value.type) } ?: true) - && (allowedValues.isEmpty() || allowedValues.contains(value)) - } - - /** - * A list of allowed values with descriptions. If empty than any value is - * allowed. - * - * @return - */ - public var allowedValues: List by config.item().convert( - reader = { - val value = it.value - when { - value?.list != null -> value.list - type?.let { type -> type.size == 1 && type[0] === ValueType.BOOLEAN } ?: false -> listOf(True, False) - else -> emptyList() - } - }, - writer = { - MetaItemValue(it.asValue()) - } - ) - - /** - * Allow given list of value and forbid others - */ - public fun allow(vararg v: Any) { - this.allowedValues = v.map { Value.of(it) } - } - - override fun copy(): ValueDescriptor = ValueDescriptor(config.toConfig()) -} - -/** - * Merge two node descriptors into one using first one as primary - */ -public operator fun NodeDescriptor.plus(other: NodeDescriptor): NodeDescriptor { - return NodeDescriptor().apply { - config.update(other.config) - config.update(this@plus.config) - } -} \ No newline at end of file diff --git a/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/descriptors/NodeDescriptor.kt b/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/descriptors/NodeDescriptor.kt new file mode 100644 index 00000000..e677ea32 --- /dev/null +++ b/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/descriptors/NodeDescriptor.kt @@ -0,0 +1,191 @@ +package space.kscience.dataforge.meta.descriptors + +import space.kscience.dataforge.meta.* +import space.kscience.dataforge.misc.DFBuilder +import space.kscience.dataforge.names.* + + +/** + * Descriptor for meta node. Could contain additional information for viewing + * and editing. + * + * @author Alexander Nozik + */ +@DFBuilder +public sealed interface NodeDescriptor: ItemDescriptor { + /** + * True if the node is required + * + * @return + */ + override val required: Boolean + + /** + * The default for this node. Null if there is no default. + * + * @return + */ + public val default: Config? + + /** + * The map of children item descriptors (both nodes and values) + */ + public val items: Map + + /** + * The map of children node descriptors + */ + public val nodes: Map + + /** + * The list of children value descriptors + */ + public val values: Map + + public companion object { + + internal val ITEM_KEY: Name = "item".asName() + internal val IS_NODE_KEY: Name = "@isNode".asName() + + //TODO infer descriptor from spec + } +} + + +@DFBuilder +public class NodeDescriptorBuilder(config: Config = Config()) : ItemDescriptorBuilder(config), NodeDescriptor { + init { + config[IS_NODE_KEY] = true + } + + /** + * True if the node is required + * + * @return + */ + override var required: Boolean by config.boolean { default == null } + + /** + * The default for this node. Null if there is no default. + * + * @return + */ + override var default: Config? by config.node() + + /** + * The map of children item descriptors (both nodes and values) + */ + override val items: Map + get() = config.getIndexed(ITEM_KEY).entries.associate { (name, item) -> + if (name == null) error("Child item index should not be null") + val node = item.node ?: error("Node descriptor must be a node") + if (node[IS_NODE_KEY].boolean == true) { + name to NodeDescriptorBuilder(node as Config) + } else { + name to ValueDescriptorBuilder(node as Config) + } + } + + /** + * The map of children node descriptors + */ + @Suppress("UNCHECKED_CAST") + override val nodes: Map + get() = config.getIndexed(ITEM_KEY).entries.filter { + it.value.node[IS_NODE_KEY].boolean == true + }.associate { (name, item) -> + if (name == null) error("Child node index should not be null") + val node = item.node ?: error("Node descriptor must be a node") + name to NodeDescriptorBuilder(node as Config) + } + + /** + * The list of children value descriptors + */ + override val values: Map + get() = config.getIndexed(ITEM_KEY).entries.filter { + it.value.node[IS_NODE_KEY].boolean != true + }.associate { (name, item) -> + if (name == null) error("Child value index should not be null") + val node = item.node ?: error("Node descriptor must be a node") + name to ValueDescriptorBuilder(node as Config) + } + + private fun buildNode(name: Name): NodeDescriptorBuilder { + return when (name.length) { + 0 -> this + 1 -> { + val token = NameToken(ITEM_KEY.toString(), name.toString()) + val config: Config = config[token].node ?: Config().also { + it[IS_NODE_KEY] = true + config[token] = it + } + NodeDescriptorBuilder(config) + } + else -> buildNode(name.firstOrNull()?.asName()!!).buildNode(name.cutFirst()) + } + } + + /** + * Define a child item descriptor for this node + */ + private fun newItem(key: String, descriptor: ItemDescriptor) { + if (items.keys.contains(key)) error("The key $key already exists in descriptor") + val token = ITEM_KEY.withIndex(key) + config[token] = descriptor.toMeta() + } + + public fun item(name: Name, descriptor: ItemDescriptor) { + buildNode(name.cutLast()).newItem(name.lastOrNull().toString(), descriptor) + } + + public fun item(name: String, descriptor: ItemDescriptor) { + item(name.toName(), descriptor) + } + + /** + * Create and configure a child node descriptor + */ + public fun node(name: Name, block: NodeDescriptorBuilder.() -> Unit) { + item(name, NodeDescriptorBuilder().apply(block)) + } + + public fun node(name: String, block: NodeDescriptorBuilder.() -> Unit) { + node(name.toName(), block) + } + + /** + * Create and configure child value descriptor + */ + public fun value(name: Name, block: ValueDescriptorBuilder.() -> Unit) { + require(name.length >= 1) { "Name length for value descriptor must be non-empty" } + item(name, ValueDescriptorBuilder().apply(block)) + } + + public fun value(name: String, block: ValueDescriptorBuilder.() -> Unit) { + value(name.toName(), block) + } + + override fun build(): NodeDescriptor = NodeDescriptorBuilder(config.copy()) + + public companion object { + + internal val ITEM_KEY: Name = "item".asName() + internal val IS_NODE_KEY: Name = "@isNode".asName() + + //TODO infer descriptor from spec + } +} + +public inline fun NodeDescriptor(block: NodeDescriptorBuilder.() -> Unit): NodeDescriptor = + NodeDescriptorBuilder().apply(block) + +/** + * Merge two node descriptors into one using first one as primary + */ +public operator fun NodeDescriptor.plus(other: NodeDescriptor): NodeDescriptor { + return NodeDescriptorBuilder().apply { + config.update(other.toMeta()) + config.update(this@plus.toMeta()) + } +} \ No newline at end of file diff --git a/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/descriptors/ValueDescriptor.kt b/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/descriptors/ValueDescriptor.kt new file mode 100644 index 00000000..6642346f --- /dev/null +++ b/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/descriptors/ValueDescriptor.kt @@ -0,0 +1,135 @@ +package space.kscience.dataforge.meta.descriptors + +import space.kscience.dataforge.meta.* +import space.kscience.dataforge.misc.DFBuilder +import space.kscience.dataforge.values.* + + + +/** + * A descriptor for meta value + * + * Descriptor can have non-atomic path. It is resolved when descriptor is added to the node + * + * @author Alexander Nozik + */ +@DFBuilder +public sealed interface ValueDescriptor: ItemDescriptor{ + + /** + * True if the value is required + * + * @return + */ + override val required: Boolean + + /** + * The default for this value. Null if there is no default. + * + * @return + */ + public val default: Value? + + + /** + * A list of allowed ValueTypes. Empty if any value type allowed + * + * @return + */ + public val type: List? + /** + * Check if given value is allowed for here. The type should be allowed and + * if it is value should be within allowed values + * + * @param value + * @return + */ + public fun isAllowedValue(value: Value): Boolean = + (type?.let { it.contains(ValueType.STRING) || it.contains(value.type) } ?: true) + && (allowedValues.isEmpty() || allowedValues.contains(value)) + + /** + * A list of allowed values with descriptions. If empty than any value is + * allowed. + * + * @return + */ + public val allowedValues: List +} + +/** + * A builder fir [ValueDescriptor] + */ +@DFBuilder +public class ValueDescriptorBuilder(config: Config = Config()) : ItemDescriptorBuilder(config), ValueDescriptor { + + /** + * True if the value is required + * + * @return + */ + override var required: Boolean by config.boolean { default == null } + + /** + * The default for this value. Null if there is no default. + * + * @return + */ + override var default: Value? by config.value() + + public fun default(v: Any) { + this.default = Value.of(v) + } + + /** + * A list of allowed ValueTypes. Empty if any value type allowed + * + * @return + */ + override var type: List? by config.listValue { ValueType.valueOf(it.string) } + + public fun type(vararg t: ValueType) { + this.type = listOf(*t) + } + + /** + * Check if given value is allowed for here. The type should be allowed and + * if it is value should be within allowed values + * + * @param value + * @return + */ + override fun isAllowedValue(value: Value): Boolean { + return (type?.let { it.contains(ValueType.STRING) || it.contains(value.type) } ?: true) + && (allowedValues.isEmpty() || allowedValues.contains(value)) + } + + /** + * A list of allowed values with descriptions. If empty than any value is + * allowed. + * + * @return + */ + override var allowedValues: List by config.item().convert( + reader = { + val value = it.value + when { + value?.list != null -> value.list + type?.let { type -> type.size == 1 && type[0] === ValueType.BOOLEAN } ?: false -> listOf(True, False) + else -> emptyList() + } + }, + writer = { + MetaItemValue(it.asValue()) + } + ) + + /** + * Allow given list of value and forbid others + */ + public fun allow(vararg v: Any) { + this.allowedValues = v.map { Value.of(it) } + } + + override fun build(): ValueDescriptor = ValueDescriptorBuilder(config.copy()) +} diff --git a/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/descriptors/descriptorExtensions.kt b/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/descriptors/descriptorExtensions.kt index 24a09df9..8149843e 100644 --- a/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/descriptors/descriptorExtensions.kt +++ b/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/descriptors/descriptorExtensions.kt @@ -4,7 +4,7 @@ import space.kscience.dataforge.names.Name import space.kscience.dataforge.values.ValueType import space.kscience.dataforge.values.asValue -public inline fun > NodeDescriptor.enum( +public inline fun > NodeDescriptorBuilder.enum( key: Name, default: E?, crossinline modifier: ValueDescriptor.() -> Unit = {}, diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 442d9132..f371643e 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.8.3-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.0-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/settings.gradle.kts b/settings.gradle.kts index 7bebb33f..6db60f3d 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -7,7 +7,7 @@ pluginManagement { maven("https://dl.bintray.com/kotlin/kotlin-eap") } - val toolsVersion = "0.9.4" + val toolsVersion = "0.9.5-dev" val kotlinVersion = "1.5.0-M2" plugins {