Не подтверждена Коммит 6e316974 создал по автору Osip Fatkullin's avatar Osip Fatkullin Зафиксировано автором GitHub
Просмотр файлов

KTOR-7743 Make projects isolated (#4740)

* Apply project plugin in project build scripts
* Unify dependencies declaration API
* Remove shared configurations from parent projects
* Remove buildSrc
* Don't publish empty artifacts (KTOR-8336)
* Add ProjectTagsService to remove usage of rootProject.subprojects
* Remove usage of findProperty and rootProject.layout
владелец bbf42373
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
import ktorbuild.createCInterop import ktorbuild.createCInterop
plugins { plugins {
id("ktorbuild.project.library")
id("kotlinx-serialization") id("kotlinx-serialization")
id("test-server") id("test-server")
} }
...@@ -13,18 +14,14 @@ kotlin { ...@@ -13,18 +14,14 @@ kotlin {
createCInterop("winhttp", sourceSet = "windows") createCInterop("winhttp", sourceSet = "windows")
sourceSets { sourceSets {
windowsMain { windowsMain.dependencies {
dependencies { api(project(":ktor-client:ktor-client-core"))
api(project(":ktor-client:ktor-client-core")) api(project(":ktor-http:ktor-http-cio"))
api(project(":ktor-http:ktor-http-cio"))
}
} }
windowsTest { windowsTest.dependencies {
dependencies { implementation(project(":ktor-client:ktor-client-test-base"))
implementation(project(":ktor-client:ktor-client-test-base")) api(project(":ktor-client:ktor-client-plugins:ktor-client-logging"))
api(project(":ktor-client:ktor-client-plugins:ktor-client-logging")) api(project(":ktor-client:ktor-client-plugins:ktor-client-json"))
api(project(":ktor-client:ktor-client-plugins:ktor-client-json"))
}
} }
} }
} }
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
* Copyright 2014-2025 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license. * Copyright 2014-2025 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license.
*/ */
import ktorbuild.*
import java.time.Year import java.time.Year
plugins { plugins {
...@@ -9,14 +10,6 @@ plugins { ...@@ -9,14 +10,6 @@ plugins {
id("ktorbuild.dokka") id("ktorbuild.dokka")
} }
dependencies {
rootProject.subprojects.forEach { subproject ->
if (subproject != project && subproject.hasDokka) dokka(subproject)
}
dokkaHtmlPlugin(libs.dokka.plugin.versioning)
}
val projectVersion = project.version.toString() val projectVersion = project.version.toString()
val dokkaVersionsDirectory = resolveVersionsDirectory() val dokkaVersionsDirectory = resolveVersionsDirectory()
...@@ -36,13 +29,21 @@ dokka { ...@@ -36,13 +29,21 @@ dokka {
} }
dokkaPublications.html { dokkaPublications.html {
if (dokkaVersionsDirectory != null) outputDirectory = dokkaVersionsDirectory.dir(projectVersion) if (dokkaVersionsDirectory != null) outputDirectory = dokkaVersionsDirectory.resolve(projectVersion)
} }
} }
fun resolveVersionsDirectory(): Directory? { dependencies {
val outputDirectory = project.findProperty("ktor.dokka.versionsDirectory") as? String dokkaHtmlPlugin(libs.dokka.plugin.versioning)
return outputDirectory?.let(rootProject.layout.projectDirectory::dir) }
val libraryProjects = projectsWithTag(ProjectTag.Library, project.dependencies::create)
configurations.dokka {
dependencies.addAllLater(libraryProjects)
} }
val Project.hasDokka: Boolean get() = plugins.hasPlugin("ktorbuild.dokka") fun resolveVersionsDirectory(): File? {
val outputDirectory = providers.gradleProperty("ktor.dokka.versionsDirectory").orNull
return outputDirectory?.let(rootDir::resolve)
}
/* /*
* Copyright 2014-2024 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license. * Copyright 2014-2025 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license.
*/ */
plugins { plugins {
id("ktorbuild.project.library")
id("kotlinx-serialization") id("kotlinx-serialization")
} }
kotlin { kotlin {
sourceSets { sourceSets {
commonMain { commonMain.dependencies {
dependencies { api(project(":ktor-utils"))
api(project(":ktor-utils")) api(libs.kotlinx.serialization.core)
api(libs.kotlinx.serialization.core)
}
} }
jvmTest { jvmTest.dependencies {
dependencies { implementation(project(":ktor-shared:ktor-test-base"))
implementation(project(":ktor-shared:ktor-test-base")) implementation(project(":ktor-shared:ktor-serialization:ktor-serialization-kotlinx"))
implementation(project(":ktor-shared:ktor-serialization:ktor-serialization-kotlinx")) implementation(project(":ktor-shared:ktor-serialization:ktor-serialization-kotlinx:ktor-serialization-kotlinx-json"))
implementation(project(":ktor-shared:ktor-serialization:ktor-serialization-kotlinx:ktor-serialization-kotlinx-json"))
}
} }
} }
} }
/*
* Copyright 2014-2025 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license.
*/
description = "" description = ""
kotlin.sourceSets { plugins {
commonMain { id("ktorbuild.project.library")
dependencies { }
kotlin {
sourceSets {
commonMain.dependencies {
api(project(":ktor-http")) api(project(":ktor-http"))
api(project(":ktor-io")) api(project(":ktor-io"))
} }
}
jvmMain { jvmMain.dependencies {
dependencies {
api(project(":ktor-network")) api(project(":ktor-network"))
} }
}
jvmTest { jvmTest.dependencies {
dependencies {
implementation(libs.kotlinx.coroutines.test) implementation(libs.kotlinx.coroutines.test)
} }
} }
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
import ktorbuild.createCInterop import ktorbuild.createCInterop
plugins { plugins {
id("ktorbuild.project.library")
alias(libs.plugins.kover) alias(libs.plugins.kover)
} }
...@@ -12,15 +13,11 @@ kotlin { ...@@ -12,15 +13,11 @@ kotlin {
createCInterop("mutex", sourceSet = "posix") createCInterop("mutex", sourceSet = "posix")
sourceSets { sourceSets {
commonMain { commonMain.dependencies {
dependencies { api(libs.kotlinx.io.core)
api(libs.kotlinx.io.core)
}
} }
commonTest { commonTest.dependencies {
dependencies { api(project(":ktor-test-dispatcher"))
api(project(":ktor-test-dispatcher"))
}
} }
} }
} }
...@@ -2,18 +2,20 @@ ...@@ -2,18 +2,20 @@
* Copyright 2014-2025 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license. * Copyright 2014-2025 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license.
*/ */
import ktorbuild.*
import ktorbuild.targets.javaModuleName import ktorbuild.targets.javaModuleName
plugins { plugins {
id("ktorbuild.base")
id("java-library") id("java-library")
} }
description = "Internal module for checking JPMS compliance" description = "Internal module for checking JPMS compliance"
val jvmProjects = projectsWithTag(ProjectTag.Jvm)
val generateModuleInfo = tasks.register("generateModuleInfo") { val generateModuleInfo = tasks.register("generateModuleInfo") {
val modules = rootProject.subprojects val modules = jvmProjects.mapValue(Project::javaModuleName)
.filter { it.hasJavaModule }
.map { it.javaModuleName() }
inputs.property("modules", modules) inputs.property("modules", modules)
val moduleInfoFile = layout.projectDirectory.file("src/main/java/module-info.java") val moduleInfoFile = layout.projectDirectory.file("src/main/java/module-info.java")
...@@ -25,9 +27,9 @@ val generateModuleInfo = tasks.register("generateModuleInfo") { ...@@ -25,9 +27,9 @@ val generateModuleInfo = tasks.register("generateModuleInfo") {
parentFile.mkdirs() parentFile.mkdirs()
createNewFile() createNewFile()
} }
.writer().buffered().use { writer -> .bufferedWriter().use { writer ->
writer.write("module io.ktor.test.module {\n") writer.write("module io.ktor.test.module {\n")
modules.forEach { writer.write("\trequires $it;\n") } modules.get().forEach { writer.write("\trequires $it;\n") }
writer.write("}") writer.write("}")
} }
} }
...@@ -50,11 +52,6 @@ java { ...@@ -50,11 +52,6 @@ java {
} }
} }
dependencies { configurations.implementation {
rootProject.subprojects dependencies.addAllLater(jvmProjects.mapValue(project.dependencies::create))
.filter { it.hasJavaModule }
.forEach { implementation(project(it.path)) }
} }
internal val Project.hasJavaModule: Boolean
get() = plugins.hasPlugin("ktorbuild.project.library") && name != "ktor-serialization-kotlinx-xml" && ktorBuild.targets.hasJvm
...@@ -6,6 +6,10 @@ import ktorbuild.createCInterop ...@@ -6,6 +6,10 @@ import ktorbuild.createCInterop
description = "Ktor network utilities" description = "Ktor network utilities"
plugins {
id("ktorbuild.project.library")
}
kotlin { kotlin {
createCInterop("network", sourceSet = "nix") createCInterop("network", sourceSet = "nix")
createCInterop("un", sourceSet = "androidNative") createCInterop("un", sourceSet = "androidNative")
...@@ -13,23 +17,17 @@ kotlin { ...@@ -13,23 +17,17 @@ kotlin {
createCInterop("afunix", sourceSet = "windows") createCInterop("afunix", sourceSet = "windows")
sourceSets { sourceSets {
commonMain { commonMain.dependencies {
dependencies { api(project(":ktor-utils"))
api(project(":ktor-utils"))
}
} }
commonTest { commonTest.dependencies {
dependencies { api(project(":ktor-test-dispatcher"))
api(project(":ktor-test-dispatcher"))
}
} }
jvmTest { jvmTest.dependencies {
dependencies { implementation(project(":ktor-shared:ktor-test-base"))
implementation(project(":ktor-shared:ktor-test-base")) implementation(libs.mockk)
implementation(libs.mockk)
}
} }
} }
} }
/* /*
* Copyright 2014-2024 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license. * Copyright 2014-2025 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license.
*/ */
kotlin.sourceSets { plugins {
commonMain { id("ktorbuild.project.library")
dependencies { }
kotlin {
sourceSets {
commonMain.dependencies {
api(project(":ktor-http")) api(project(":ktor-http"))
api(project(":ktor-network")) api(project(":ktor-network"))
api(project(":ktor-utils")) api(project(":ktor-utils"))
} }
} jvmTest.dependencies {
jvmTest {
dependencies {
api(project(":ktor-shared:ktor-test-base")) api(project(":ktor-shared:ktor-test-base"))
api(project(":ktor-network:ktor-network-tls:ktor-network-tls-certificates")) api(project(":ktor-network:ktor-network-tls:ktor-network-tls-certificates"))
api(libs.netty.handler) api(libs.netty.handler)
......
/* /*
* Copyright 2014-2021 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license. * Copyright 2014-2025 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license.
*/ */
plugins {
id("ktorbuild.project.library")
}
kotlin { kotlin {
sourceSets { sourceSets {
jvmMain { jvmMain.dependencies {
dependencies { api(project(":ktor-network:ktor-network-tls"))
api(project(":ktor-network:ktor-network-tls"))
}
} }
jvmTest { jvmTest.dependencies {
dependencies { implementation(libs.mockk)
implementation(libs.mockk)
}
} }
} }
} }
...@@ -4,16 +4,18 @@ ...@@ -4,16 +4,18 @@
description = "Wrapper for ktor-server-core and base plugins" description = "Wrapper for ktor-server-core and base plugins"
kotlin.sourceSets { plugins {
jvmMain { id("ktorbuild.project.library")
dependencies { }
kotlin {
sourceSets {
jvmMain.dependencies {
api(project(":ktor-server:ktor-server-plugins:ktor-server-call-logging")) api(project(":ktor-server:ktor-server-plugins:ktor-server-call-logging"))
api(project(":ktor-server:ktor-server-plugins:ktor-server-default-headers")) api(project(":ktor-server:ktor-server-plugins:ktor-server-default-headers"))
api(project(":ktor-server:ktor-server-plugins:ktor-server-compression")) api(project(":ktor-server:ktor-server-plugins:ktor-server-compression"))
} }
} commonMain.dependencies {
commonMain {
dependencies {
api(project(":ktor-server:ktor-server-core")) api(project(":ktor-server:ktor-server-core"))
api(project(":ktor-server:ktor-server-plugins:ktor-server-auto-head-response")) api(project(":ktor-server:ktor-server-plugins:ktor-server-auto-head-response"))
api(project(":ktor-server:ktor-server-plugins:ktor-server-caching-headers")) api(project(":ktor-server:ktor-server-plugins:ktor-server-caching-headers"))
......
...@@ -4,17 +4,19 @@ ...@@ -4,17 +4,19 @@
description = "" description = ""
kotlin.sourceSets { plugins {
commonMain { id("ktorbuild.project.library")
dependencies { }
kotlin {
sourceSets {
commonMain.dependencies {
api(project(":ktor-server:ktor-server-core")) api(project(":ktor-server:ktor-server-core"))
api(project(":ktor-http:ktor-http-cio")) api(project(":ktor-http:ktor-http-cio"))
api(project(":ktor-shared:ktor-websockets")) api(project(":ktor-shared:ktor-websockets"))
api(project(":ktor-network")) api(project(":ktor-network"))
} }
} commonTest.dependencies {
commonTest {
dependencies {
api(project(":ktor-client:ktor-client-cio")) api(project(":ktor-client:ktor-client-cio"))
api(project(":ktor-server:ktor-server-test-suites")) api(project(":ktor-server:ktor-server-test-suites"))
api(project(":ktor-server:ktor-server-test-base")) api(project(":ktor-server:ktor-server-test-base"))
......
/* /*
* Copyright 2014-2020 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license. * Copyright 2014-2025 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license.
*/ */
kotlin.sourceSets { plugins {
commonMain { id("ktorbuild.project.library")
dependencies { }
kotlin {
sourceSets {
commonMain.dependencies {
api(project(":ktor-server:ktor-server-core")) api(project(":ktor-server:ktor-server-core"))
api(libs.yamlkt.serialization) api(libs.yamlkt.serialization)
} }
......
...@@ -6,44 +6,40 @@ import ktorbuild.createCInterop ...@@ -6,44 +6,40 @@ import ktorbuild.createCInterop
description = "" description = ""
plugins {
id("ktorbuild.project.library")
}
kotlin { kotlin {
createCInterop("host_common", sourceSet = "nix") createCInterop("host_common", sourceSet = "nix")
sourceSets { sourceSets {
commonMain { commonMain.dependencies {
dependencies { api(project(":ktor-utils"))
api(project(":ktor-utils")) api(project(":ktor-http"))
api(project(":ktor-http")) api(project(":ktor-shared:ktor-serialization"))
api(project(":ktor-shared:ktor-serialization")) api(project(":ktor-shared:ktor-events"))
api(project(":ktor-shared:ktor-events")) api(project(":ktor-http:ktor-http-cio"))
api(project(":ktor-http:ktor-http-cio")) api(project(":ktor-shared:ktor-websockets"))
api(project(":ktor-shared:ktor-websockets"))
api(libs.kotlin.reflect)
api(libs.kotlin.reflect)
}
} }
jvmMain { jvmMain.dependencies {
dependencies { api(libs.typesafe.config)
api(libs.typesafe.config) implementation(libs.jansi)
implementation(libs.jansi)
}
} }
commonTest { commonTest.dependencies {
dependencies { api(project(":ktor-server:ktor-server-test-host"))
api(project(":ktor-server:ktor-server-test-host"))
}
} }
jvmTest { jvmTest.dependencies {
dependencies { implementation(project(":ktor-server:ktor-server-config-yaml"))
implementation(project(":ktor-server:ktor-server-config-yaml")) implementation(project(":ktor-server:ktor-server-test-base"))
implementation(project(":ktor-server:ktor-server-test-base")) implementation(project(":ktor-server:ktor-server-test-suites"))
implementation(project(":ktor-server:ktor-server-test-suites"))
implementation(libs.mockk) implementation(libs.mockk)
}
} }
} }
} }
/*
* Copyright 2014-2025 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license.
*/
description = "This module is deprecated. All the contents are moved to `ktor-server-core`." description = "This module is deprecated. All the contents are moved to `ktor-server-core`."
plugins {
id("ktorbuild.project.library")
}
kotlin { kotlin {
sourceSets { sourceSets {
commonMain { commonMain.dependencies {
dependencies { api(project(":ktor-server:ktor-server-core"))
api(project(":ktor-server:ktor-server-core"))
}
} }
} }
} }
...@@ -4,6 +4,10 @@ ...@@ -4,6 +4,10 @@
description = "" description = ""
plugins {
id("ktorbuild.project.library")
}
ktorBuild { ktorBuild {
// The minimal JVM version required for Jetty 10+ // The minimal JVM version required for Jetty 10+
jvmToolchain(11) jvmToolchain(11)
...@@ -11,27 +15,23 @@ ktorBuild { ...@@ -11,27 +15,23 @@ ktorBuild {
kotlin { kotlin {
sourceSets { sourceSets {
jvmMain { jvmMain.dependencies {
dependencies { api(project(":ktor-server:ktor-server-core"))
api(project(":ktor-server:ktor-server-core")) api(project(":ktor-server:ktor-server-servlet-jakarta"))
api(project(":ktor-server:ktor-server-servlet-jakarta")) api(libs.jetty.server.jakarta)
api(libs.jetty.server.jakarta) api(libs.jetty.servlets.jakarta)
api(libs.jetty.servlets.jakarta) api(libs.jetty.alpn.server.jakarta)
api(libs.jetty.alpn.server.jakarta) api(libs.jetty.alpn.java.server.jakarta)
api(libs.jetty.alpn.java.server.jakarta) api(libs.jetty.alpn.openjdk8.server)
api(libs.jetty.alpn.openjdk8.server) api(libs.jetty.http2.server.jakarta)
api(libs.jetty.http2.server.jakarta)
}
} }
jvmTest { jvmTest.dependencies {
dependencies { api(libs.kotlin.test.junit5)
api(libs.kotlin.test.junit5) api(project(":ktor-server:ktor-server-core"))
api(project(":ktor-server:ktor-server-core")) api(project(":ktor-server:ktor-server-test-base"))
api(project(":ktor-server:ktor-server-test-base")) api(project(":ktor-server:ktor-server-test-suites"))
api(project(":ktor-server:ktor-server-test-suites"))
api(libs.jetty.servlet.jakarta) api(libs.jetty.servlet.jakarta)
}
} }
} }
} }
...@@ -4,14 +4,18 @@ ...@@ -4,14 +4,18 @@
import org.jetbrains.kotlin.gradle.targets.jvm.tasks.KotlinJvmTest import org.jetbrains.kotlin.gradle.targets.jvm.tasks.KotlinJvmTest
plugins {
id("ktorbuild.project.internal")
}
ktorBuild { ktorBuild {
// The minimal JVM version required for Jetty 10+ // The minimal JVM version required for Jetty 10+
jvmToolchain(11) jvmToolchain(11)
} }
kotlin.sourceSets { kotlin {
jvmTest { sourceSets {
dependencies { jvmTest.dependencies {
api(project(":ktor-server:ktor-server-test-base")) api(project(":ktor-server:ktor-server-test-base"))
api(project(":ktor-server:ktor-server-test-suites")) api(project(":ktor-server:ktor-server-test-suites"))
api(libs.jetty.servlet.jakarta) api(libs.jetty.servlet.jakarta)
......
...@@ -4,28 +4,28 @@ ...@@ -4,28 +4,28 @@
description = "" description = ""
plugins {
id("ktorbuild.project.library")
}
kotlin { kotlin {
sourceSets { sourceSets {
jvmMain { jvmMain.dependencies {
dependencies { api(project(":ktor-server:ktor-server-core"))
api(project(":ktor-server:ktor-server-core")) api(project(":ktor-server:ktor-server-servlet"))
api(project(":ktor-server:ktor-server-servlet")) api(libs.jetty.server)
api(libs.jetty.server) api(libs.jetty.servlets)
api(libs.jetty.servlets) api(libs.jetty.alpn.server)
api(libs.jetty.alpn.server) api(libs.jetty.alpn.java.server)
api(libs.jetty.alpn.java.server) api(libs.jetty.alpn.openjdk8.server)
api(libs.jetty.alpn.openjdk8.server) api(libs.jetty.http2.server)
api(libs.jetty.http2.server)
}
} }
jvmTest { jvmTest.dependencies {
dependencies { api(project(":ktor-server:ktor-server-core"))
api(project(":ktor-server:ktor-server-core")) api(project(":ktor-server:ktor-server-test-base"))
api(project(":ktor-server:ktor-server-test-base")) api(project(":ktor-server:ktor-server-test-suites"))
api(project(":ktor-server:ktor-server-test-suites"))
api(libs.jetty.servlet) api(libs.jetty.servlet)
}
} }
} }
} }
...@@ -4,9 +4,13 @@ ...@@ -4,9 +4,13 @@
import org.jetbrains.kotlin.gradle.targets.jvm.tasks.KotlinJvmTest import org.jetbrains.kotlin.gradle.targets.jvm.tasks.KotlinJvmTest
kotlin.sourceSets { plugins {
jvmTest { id("ktorbuild.project.internal")
dependencies { }
kotlin {
sourceSets {
jvmTest.dependencies {
api(project(":ktor-server:ktor-server-test-base")) api(project(":ktor-server:ktor-server-test-base"))
api(project(":ktor-server:ktor-server-test-suites")) api(project(":ktor-server:ktor-server-test-suites"))
api(libs.jetty.servlet) api(libs.jetty.servlet)
......
...@@ -6,6 +6,10 @@ import org.jetbrains.kotlin.gradle.targets.jvm.tasks.KotlinJvmTest ...@@ -6,6 +6,10 @@ import org.jetbrains.kotlin.gradle.targets.jvm.tasks.KotlinJvmTest
description = "" description = ""
plugins {
id("ktorbuild.project.library")
}
val enableAlpnProp = project.hasProperty("enableAlpn") val enableAlpnProp = project.hasProperty("enableAlpn")
val osName = System.getProperty("os.name").lowercase() val osName = System.getProperty("os.name").lowercase()
val nativeClassifier: String? = if (enableAlpnProp) { val nativeClassifier: String? = if (enableAlpnProp) {
...@@ -19,9 +23,9 @@ val nativeClassifier: String? = if (enableAlpnProp) { ...@@ -19,9 +23,9 @@ val nativeClassifier: String? = if (enableAlpnProp) {
null null
} }
kotlin.sourceSets { kotlin {
jvmMain { sourceSets {
dependencies { jvmMain.dependencies {
api(project(":ktor-server:ktor-server-core")) api(project(":ktor-server:ktor-server-core"))
api(libs.netty.codec.http2) api(libs.netty.codec.http2)
...@@ -33,9 +37,7 @@ kotlin.sourceSets { ...@@ -33,9 +37,7 @@ kotlin.sourceSets {
api(libs.netty.tcnative.boringssl.static) api(libs.netty.tcnative.boringssl.static)
} }
} }
} jvmTest.dependencies {
jvmTest {
dependencies {
api(project(":ktor-server:ktor-server-test-base")) api(project(":ktor-server:ktor-server-test-base"))
api(project(":ktor-server:ktor-server-test-suites")) api(project(":ktor-server:ktor-server-test-suites"))
api(project(":ktor-server:ktor-server-core")) api(project(":ktor-server:ktor-server-core"))
......
Поддерживает Markdown
0% или .
You are about to add 0 people to the discussion. Proceed with caution.
Сначала завершите редактирование этого сообщения!
Пожалуйста, зарегистрируйтесь или чтобы прокомментировать