Migrate KotlinGradlePluginIT to new test dsl
Moved some tests to another test suites ^KT-45745 In Progress
This commit is contained in:
committed by
teamcity
parent
f11ae83a3d
commit
76fc4328d1
-19
@@ -371,25 +371,6 @@ abstract class BaseGradleIT {
|
||||
|
||||
fun relativize(vararg files: File): List<String> =
|
||||
files.map { it.relativeTo(projectDir).path }
|
||||
|
||||
fun performModifications() {
|
||||
for (file in projectDir.walk()) {
|
||||
if (!file.isFile) continue
|
||||
|
||||
val fileWithoutExt = File(file.parentFile, file.nameWithoutExtension)
|
||||
|
||||
when (file.extension) {
|
||||
"new" -> {
|
||||
file.copyTo(fileWithoutExt, overwrite = true)
|
||||
file.delete()
|
||||
}
|
||||
"delete" -> {
|
||||
fileWithoutExt.delete()
|
||||
file.delete()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class CompiledProject(val project: Project, val output: String, val resultCode: Int)
|
||||
|
||||
+112
@@ -0,0 +1,112 @@
|
||||
/*
|
||||
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.gradle
|
||||
|
||||
import org.gradle.util.GradleVersion
|
||||
import org.jetbrains.kotlin.gradle.internal.build.metrics.GradleBuildMetricsData
|
||||
import org.jetbrains.kotlin.gradle.report.BuildReportType
|
||||
import org.jetbrains.kotlin.gradle.testbase.*
|
||||
import org.junit.jupiter.api.DisplayName
|
||||
import java.io.ObjectInputStream
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertNotNull
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
@DisplayName("Build reports")
|
||||
@JvmGradlePluginTests
|
||||
class BuildReportsIT : KGPBaseTest() {
|
||||
override val defaultBuildOptions: BuildOptions
|
||||
get() = super.defaultBuildOptions.copy(
|
||||
buildReport = listOf(BuildReportType.FILE)
|
||||
)
|
||||
|
||||
@DisplayName("Build report is created")
|
||||
@GradleTest
|
||||
fun testBuildReportSmokeTest(gradleVersion: GradleVersion) {
|
||||
project("simpleProject", gradleVersion) {
|
||||
build("assemble") {
|
||||
assertOutputContains("Kotlin build report is written to")
|
||||
}
|
||||
|
||||
build("clean", "assemble") {
|
||||
assertOutputContains("Kotlin build report is written to")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@DisplayName("Build report output property accepts only certain values")
|
||||
@GradleTest
|
||||
fun testBuildReportOutputProperty(gradleVersion: GradleVersion) {
|
||||
project("simpleProject", gradleVersion) {
|
||||
buildAndFail("assemble", "-Pkotlin.build.report.output=file,invalid") {
|
||||
assertOutputContains("Unknown output type:")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@DisplayName("Build metrics produces valid report")
|
||||
@GradleTest
|
||||
fun testBuildMetricsSmokeTest(gradleVersion: GradleVersion) {
|
||||
project("simpleProject", gradleVersion) {
|
||||
build("assemble") {
|
||||
assertOutputContains("Kotlin build report is written to")
|
||||
}
|
||||
val reportFolder = projectPath.resolve("build/reports/kotlin-build").toFile()
|
||||
val reports = reportFolder.listFiles()
|
||||
assertNotNull(reports)
|
||||
assertEquals(1, reports.size)
|
||||
val report = reports[0].readText()
|
||||
|
||||
//Should contains build metrics for all compile kotlin tasks
|
||||
assertTrue { report.contains("Time metrics:") }
|
||||
assertTrue { report.contains("Run compilation:") }
|
||||
assertTrue { report.contains("Incremental compilation in daemon:") }
|
||||
assertTrue { report.contains("Build performance metrics:") }
|
||||
assertTrue { report.contains("Total size of the cache directory:") }
|
||||
assertTrue { report.contains("Total compiler iteration:") }
|
||||
assertTrue { report.contains("ABI snapshot size:") }
|
||||
//for non-incremental builds
|
||||
assertTrue { report.contains("Build attributes:") }
|
||||
assertTrue { report.contains("REBUILD_REASON:") }
|
||||
}
|
||||
}
|
||||
|
||||
@DisplayName("Compiler build metrics report is produced")
|
||||
@GradleTest
|
||||
fun testCompilerBuildMetricsSmokeTest(gradleVersion: GradleVersion) {
|
||||
project("simpleProject", gradleVersion) {
|
||||
build("assemble") {
|
||||
assertOutputContains("Kotlin build report is written to")
|
||||
}
|
||||
val reportFolder = projectPath.resolve("build/reports/kotlin-build").toFile()
|
||||
val reports = reportFolder.listFiles()
|
||||
assertNotNull(reports)
|
||||
assertEquals(1, reports.size)
|
||||
val report = reports[0].readText()
|
||||
assertTrue { report.contains("Compiler code analysis:") }
|
||||
assertTrue { report.contains("Compiler code generation:") }
|
||||
assertTrue { report.contains("Compiler initialization time:") }
|
||||
}
|
||||
}
|
||||
|
||||
@DisplayName("")
|
||||
@GradleTest
|
||||
fun testSingleBuildMetricsFileSmoke(gradleVersion: GradleVersion) {
|
||||
project("simpleProject", gradleVersion) {
|
||||
val metricsFile = projectPath.resolve("metrics.bin").toFile()
|
||||
build(
|
||||
"compileKotlin",
|
||||
"-Pkotlin.internal.single.build.metrics.file=${metricsFile.absolutePath}"
|
||||
)
|
||||
|
||||
assertTrue { metricsFile.exists() }
|
||||
// test whether we can deserialize data from the file
|
||||
ObjectInputStream(metricsFile.inputStream().buffered()).use { input ->
|
||||
input.readObject() as GradleBuildMetricsData
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+94
-16
@@ -8,34 +8,24 @@ package org.jetbrains.kotlin.gradle
|
||||
import org.gradle.util.GradleVersion
|
||||
import org.jetbrains.kotlin.gradle.testbase.*
|
||||
import org.junit.jupiter.api.DisplayName
|
||||
import kotlin.io.path.appendText
|
||||
|
||||
@DisplayName("Tasks configuration avoidance")
|
||||
@SimpleGradlePluginTests
|
||||
class ConfigurationAvoidanceIT : KGPBaseTest() {
|
||||
|
||||
@DisplayName("Unrelated tasks are not configured")
|
||||
@JvmGradlePluginTests
|
||||
@DisplayName("JVM unrelated tasks are not configured")
|
||||
@GradleTest
|
||||
fun testUnrelatedTaskNotConfigured(gradleVersion: GradleVersion) {
|
||||
project("simpleProject", gradleVersion) {
|
||||
|
||||
val expensivelyConfiguredTaskName = "expensivelyConfiguredTask"
|
||||
|
||||
@Suppress("GroovyAssignabilityCheck")
|
||||
buildGradle.append(
|
||||
//language=Groovy
|
||||
"""
|
||||
|
||||
tasks.register("$expensivelyConfiguredTaskName") {
|
||||
throw new GradleException("Should not configure expensive task!")
|
||||
}
|
||||
""".trimIndent()
|
||||
)
|
||||
createTaskWithExpensiveConfiguration()
|
||||
|
||||
build("compileKotlin")
|
||||
}
|
||||
}
|
||||
|
||||
@DisplayName("Android tasks are not configured")
|
||||
@JvmGradlePluginTests // TODO: move it into Android tests tag
|
||||
@DisplayName("Android unrelated tasks are not configured")
|
||||
@GradleTestVersions(minVersion = TestVersions.Gradle.G_6_7)
|
||||
@GradleTest
|
||||
fun testAndroidUnrelatedTaskNotConfigured(gradleVersion: GradleVersion) {
|
||||
@@ -86,4 +76,92 @@ class ConfigurationAvoidanceIT : KGPBaseTest() {
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@JsGradlePluginTests
|
||||
@DisplayName("JS unrelated tasks are not configured")
|
||||
@GradleTest
|
||||
fun jsNoTasksConfigured(gradleVersion: GradleVersion) {
|
||||
project("kotlin2JsNoOutputFileProject", gradleVersion) {
|
||||
createTaskWithExpensiveConfiguration()
|
||||
|
||||
build("help")
|
||||
}
|
||||
}
|
||||
|
||||
@MppGradlePluginTests
|
||||
@DisplayName("MPP unrelated tasks are not configured")
|
||||
@GradleTest
|
||||
fun mppNoTasksConfigured(gradleVersion: GradleVersion) {
|
||||
project("new-mpp-lib-and-app/sample-app", gradleVersion) {
|
||||
createTaskWithExpensiveConfiguration()
|
||||
|
||||
build("help")
|
||||
}
|
||||
}
|
||||
|
||||
private fun TestProject.createTaskWithExpensiveConfiguration(
|
||||
expensivelyConfiguredTaskName: String = "expensivelyConfiguredTask"
|
||||
): String {
|
||||
@Suppress("GroovyAssignabilityCheck")
|
||||
buildGradle.append(
|
||||
//language=Groovy
|
||||
"""
|
||||
|
||||
tasks.register("$expensivelyConfiguredTaskName") {
|
||||
throw new GradleException("Should not configure expensive task!")
|
||||
}
|
||||
""".trimIndent()
|
||||
)
|
||||
|
||||
return expensivelyConfiguredTaskName
|
||||
}
|
||||
|
||||
@JvmGradlePluginTests
|
||||
@DisplayName("JVM early configuration resolution")
|
||||
@GradleTest
|
||||
fun testEarlyConfigurationsResolutionKotlin(gradleVersion: GradleVersion) {
|
||||
testEarlyConfigurationsResolution("kotlinProject", gradleVersion, kts = false)
|
||||
}
|
||||
|
||||
@JsGradlePluginTests
|
||||
@DisplayName("JS early configuration resolution")
|
||||
@GradleTest
|
||||
fun testEarlyConfigurationsResolutionKotlinJs(gradleVersion: GradleVersion) {
|
||||
testEarlyConfigurationsResolution("kotlin-js-browser-project", gradleVersion, kts = true)
|
||||
}
|
||||
|
||||
private fun testEarlyConfigurationsResolution(
|
||||
projectName: String,
|
||||
gradleVersion: GradleVersion,
|
||||
kts: Boolean
|
||||
) = project(projectName, gradleVersion) {
|
||||
(if (kts) buildGradleKts else buildGradle).appendText(
|
||||
//language=Gradle
|
||||
"""${'\n'}
|
||||
// KT-45834 start
|
||||
${if (kts) "var" else "def"} ready = false
|
||||
gradle.taskGraph.whenReady {
|
||||
println("Task Graph Ready")
|
||||
ready = true
|
||||
}
|
||||
|
||||
allprojects {
|
||||
configurations.forEach { configuration ->
|
||||
configuration.incoming.beforeResolve {
|
||||
println("Resolving ${'$'}configuration")
|
||||
if (!ready) {
|
||||
throw ${if (kts) "" else "new"} GradleException("${'$'}configuration is being resolved at configuration time")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// KT-45834 end
|
||||
""".trimIndent()
|
||||
)
|
||||
|
||||
build(
|
||||
"assemble",
|
||||
"-m"
|
||||
)
|
||||
}
|
||||
}
|
||||
+98
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.gradle
|
||||
|
||||
import org.gradle.util.GradleVersion
|
||||
import org.jetbrains.kotlin.gradle.plugin.MULTIPLE_KOTLIN_PLUGINS_LOADED_WARNING
|
||||
import org.jetbrains.kotlin.gradle.plugin.MULTIPLE_KOTLIN_PLUGINS_SPECIFIC_PROJECTS_WARNING
|
||||
import org.jetbrains.kotlin.gradle.testbase.*
|
||||
import org.jetbrains.kotlin.gradle.util.checkedReplace
|
||||
import org.junit.jupiter.api.DisplayName
|
||||
import kotlin.io.path.appendText
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
@DisplayName("Different Gradle classloaders warning")
|
||||
@MppGradlePluginTests
|
||||
class DifferentClassloadersIT : KGPBaseTest() {
|
||||
|
||||
@DisplayName("Different classloaders message is not displayed")
|
||||
@GradleTest
|
||||
fun testDifferentClassloadersNotDisplayed(gradleVersion: GradleVersion) {
|
||||
project("differentClassloaders", gradleVersion) {
|
||||
build("publish", "-PmppProjectDependency=true") {
|
||||
assertOutputDoesNotContain(MULTIPLE_KOTLIN_PLUGINS_LOADED_WARNING)
|
||||
assertOutputDoesNotContain(MULTIPLE_KOTLIN_PLUGINS_SPECIFIC_PROJECTS_WARNING)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@DisplayName("Different classloader message is displayed on different plugin versions")
|
||||
@GradleTest
|
||||
fun testDetectingDifferentClassLoaders(gradleVersion: GradleVersion) {
|
||||
project("differentClassloaders", gradleVersion) {
|
||||
setupDifferentClassloadersProject()
|
||||
|
||||
buildAndFail("publish", "-PmppProjectDependency=true") {
|
||||
assertOutputContains(MULTIPLE_KOTLIN_PLUGINS_LOADED_WARNING)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@DisplayName("KT-50598: Different classloaders message is only displayed on the first build")
|
||||
@GradleTest
|
||||
fun differentClassloadersOnlyFirstBuild(gradleVersion: GradleVersion) {
|
||||
project("differentClassloaders", gradleVersion) {
|
||||
setupDifferentClassloadersProject()
|
||||
|
||||
build("-PmppProjectDependency=true") {
|
||||
assertOutputContains(MULTIPLE_KOTLIN_PLUGINS_LOADED_WARNING)
|
||||
|
||||
val specificProjectsReported = Regex("$MULTIPLE_KOTLIN_PLUGINS_SPECIFIC_PROJECTS_WARNING((?:'.*'(?:, )?)+)")
|
||||
.find(output)!!.groupValues[1].split(", ").map { it.removeSurrounding("'") }.toSet()
|
||||
|
||||
assertEquals(setOf(":mpp-lib", ":jvm-app", ":js-app"), specificProjectsReported)
|
||||
}
|
||||
|
||||
// Test the flag that turns off the warnings
|
||||
build("-PmppProjectDependency=true", "-Pkotlin.pluginLoadedInMultipleProjects.ignore=true") {
|
||||
assertOutputDoesNotContain(MULTIPLE_KOTLIN_PLUGINS_LOADED_WARNING)
|
||||
assertOutputDoesNotContain(MULTIPLE_KOTLIN_PLUGINS_SPECIFIC_PROJECTS_WARNING)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun TestProject.setupDifferentClassloadersProject() {
|
||||
// Specify the plugin versions in the subprojects with different plugin sets –
|
||||
// this will make Gradle use separate class loaders
|
||||
buildGradle.modify {
|
||||
it.checkedReplace("id \"org.jetbrains.kotlin.multiplatform\"", "//")
|
||||
}
|
||||
subProject("mpp-lib").buildGradle.modify {
|
||||
it.checkedReplace(
|
||||
"id \"org.jetbrains.kotlin.multiplatform\"",
|
||||
"id \"org.jetbrains.kotlin.multiplatform\" version \"${TestVersions.Kotlin.CURRENT}\""
|
||||
)
|
||||
}
|
||||
subProject("jvm-app").buildGradle.modify {
|
||||
it.checkedReplace(
|
||||
"id \"org.jetbrains.kotlin.jvm\"",
|
||||
"id \"org.jetbrains.kotlin.jvm\" version \"${TestVersions.Kotlin.CURRENT}\""
|
||||
)
|
||||
}
|
||||
subProject("js-app").buildGradle.modify {
|
||||
it.checkedReplace(
|
||||
"id \"kotlin2js\"",
|
||||
"id \"kotlin2js\" version \"${TestVersions.Kotlin.CURRENT}\""
|
||||
)
|
||||
}
|
||||
|
||||
// Also include another project via a composite build:
|
||||
includeOtherProjectAsIncludedBuild("allopenPluginsDsl", "pluginsDsl")
|
||||
buildGradle.appendText(
|
||||
"\ntasks.create(\"publish\").dependsOn(gradle.includedBuild(\"allopenPluginsDsl\").task(\":assemble\"))"
|
||||
)
|
||||
}
|
||||
}
|
||||
+50
@@ -9,6 +9,11 @@ import org.gradle.util.GradleVersion
|
||||
import org.jetbrains.kotlin.gradle.testbase.*
|
||||
import org.junit.jupiter.api.DisplayName
|
||||
import java.nio.file.Path
|
||||
import kotlin.io.path.createDirectories
|
||||
import kotlin.io.path.deleteExisting
|
||||
import kotlin.io.path.relativeTo
|
||||
import kotlin.io.path.writeText
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
@DisplayName("Default incremental compilation with default precise java tracking")
|
||||
open class IncrementalJavaChangeDefaultIT : IncrementalCompilationJavaChangesBase(usePreciseJavaTracking = null) {
|
||||
@@ -44,6 +49,51 @@ open class IncrementalJavaChangeDefaultIT : IncrementalCompilationJavaChangesBas
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@DisplayName("KT-38692: should clean all outputs after removing all Kotlin sources")
|
||||
@GradleTest
|
||||
fun testIncrementalWhenNoKotlinSources(gradleVersion: GradleVersion) {
|
||||
project("kotlinProject", gradleVersion) {
|
||||
build(":compileKotlin") {
|
||||
assertTasksExecuted(":compileKotlin")
|
||||
}
|
||||
|
||||
// Remove all Kotlin sources and force non-incremental run
|
||||
projectPath.allKotlinFiles.forEach { it.deleteExisting() }
|
||||
javaSourcesDir().resolve("Sample.java").also {
|
||||
it.parent.createDirectories()
|
||||
it.writeText("public class Sample {}")
|
||||
}
|
||||
build("compileKotlin", "--rerun-tasks") {
|
||||
assertTasksExecuted(":compileKotlin")
|
||||
val compiledKotlinClasses = kotlinClassesDir().allFilesWithExtension("class").toList()
|
||||
|
||||
assertTrue(compiledKotlinClasses.isEmpty())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@DisplayName("Type alias change is incremental")
|
||||
@GradleTest
|
||||
fun testTypeAliasIncremental(gradleVersion: GradleVersion) {
|
||||
project("typeAlias", gradleVersion) {
|
||||
build("build")
|
||||
|
||||
val curryKt = kotlinSourcesDir().resolve("Curry.kt")
|
||||
val useCurryKt = kotlinSourcesDir().resolve("UseCurry.kt")
|
||||
|
||||
curryKt.modify {
|
||||
it.replace("class Curry", "internal class Curry")
|
||||
}
|
||||
|
||||
build("build") {
|
||||
assertCompiledKotlinSources(
|
||||
listOf(curryKt, useCurryKt).map { it.relativeTo(projectPath) },
|
||||
output
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@DisplayName("Incremental compilation via classpath snapshots with default precise java tracking")
|
||||
|
||||
+611
-1196
File diff suppressed because it is too large
Load Diff
+28
@@ -23,8 +23,10 @@ import org.jetbrains.kotlin.gradle.internals.KOTLIN_12X_MPP_DEPRECATION_WARNING
|
||||
import org.jetbrains.kotlin.gradle.plugin.EXPECTED_BY_CONFIG_NAME
|
||||
import org.jetbrains.kotlin.gradle.plugin.IMPLEMENT_CONFIG_NAME
|
||||
import org.jetbrains.kotlin.gradle.plugin.IMPLEMENT_DEPRECATION_WARNING
|
||||
import org.jetbrains.kotlin.gradle.util.AGPVersion
|
||||
import org.jetbrains.kotlin.gradle.util.getFileByName
|
||||
import org.jetbrains.kotlin.gradle.util.modify
|
||||
import org.jetbrains.kotlin.test.util.KtTestUtil
|
||||
import org.junit.Test
|
||||
import java.io.File
|
||||
import kotlin.test.assertTrue
|
||||
@@ -347,4 +349,30 @@ class MultiplatformGradleIT : BaseGradleIT() {
|
||||
assertNotContains("no duplicate handling strategy has been set")
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testKtKt35942InternalsFromMainInTestViaTransitiveDeps() = with(Project("kt-35942-jvm", GradleVersionRequired.FOR_MPP_SUPPORT)) {
|
||||
build(":lib1:compileTestKotlin") {
|
||||
assertSuccessful()
|
||||
assertTasksExecuted(":lib1:compileKotlin", ":lib2:jar")
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testKtKt35942InternalsFromMainInTestViaTransitiveDepsAndroid() = with(
|
||||
Project(
|
||||
projectName = "kt-35942-android"
|
||||
)
|
||||
) {
|
||||
build(
|
||||
":lib1:compileDebugUnitTestKotlin",
|
||||
options = defaultBuildOptions().copy(
|
||||
androidGradlePluginVersion = AGPVersion.v4_2_0,
|
||||
androidHome = KtTestUtil.findAndroidSdk().also { acceptAndroidSdkLicenses(it) },
|
||||
),
|
||||
) {
|
||||
assertSuccessful()
|
||||
assertTasksExecuted(":lib1:compileDebugKotlin")
|
||||
}
|
||||
}
|
||||
}
|
||||
+85
@@ -8,6 +8,10 @@ package org.jetbrains.kotlin.gradle
|
||||
import org.gradle.util.GradleVersion
|
||||
import org.jetbrains.kotlin.gradle.testbase.*
|
||||
import org.junit.jupiter.api.DisplayName
|
||||
import kotlin.io.path.appendText
|
||||
import kotlin.io.path.readLines
|
||||
import kotlin.io.path.readText
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
@DisplayName("Artifacts publication")
|
||||
@JvmGradlePluginTests
|
||||
@@ -22,4 +26,85 @@ class PublishingIT : KGPBaseTest() {
|
||||
build("publishToMavenLocal")
|
||||
}
|
||||
}
|
||||
|
||||
@DisplayName("Publishes Kotlin api dependencies as compile")
|
||||
@GradleTest
|
||||
fun testKotlinJvmProjectPublishesKotlinApiDependenciesAsCompile(gradleVersion: GradleVersion) {
|
||||
project("simpleProject", gradleVersion) {
|
||||
buildGradle.appendText(
|
||||
//language=Groovy
|
||||
"""
|
||||
|
||||
dependencies {
|
||||
api 'org.jetbrains.kotlin:kotlin-reflect'
|
||||
}
|
||||
|
||||
plugins.apply('maven-publish')
|
||||
|
||||
group "com.example"
|
||||
version "1.0"
|
||||
publishing {
|
||||
repositories { maven { url file("${'$'}buildDir/repo").toURI() } }
|
||||
publications { maven(MavenPublication) { from components.java } }
|
||||
}
|
||||
""".trimIndent()
|
||||
)
|
||||
|
||||
build("publish") {
|
||||
val pomText = projectPath
|
||||
.resolve("build/repo/com/example/simpleProject/1.0/simpleProject-1.0.pom")
|
||||
.readText()
|
||||
.replace("\\s+|\\n".toRegex(), "")
|
||||
assertTrue {
|
||||
pomText.contains(
|
||||
"<groupId>org.jetbrains.kotlin</groupId>" +
|
||||
"<artifactId>kotlin-reflect</artifactId>" +
|
||||
"<version>${buildOptions.kotlinVersion}</version>" +
|
||||
"<scope>compile</scope>"
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@DisplayName("Publishing includes stdlib version")
|
||||
@GradleTest
|
||||
fun testOmittedStdlibVersion(gradleVersion: GradleVersion) {
|
||||
project("kotlinProject", gradleVersion) {
|
||||
buildGradle.appendText(
|
||||
//language=Groovy
|
||||
"""
|
||||
|
||||
plugins.apply('maven-publish')
|
||||
|
||||
group = "com.example"
|
||||
version = "1.0"
|
||||
|
||||
publishing {
|
||||
publications {
|
||||
myLibrary(MavenPublication) {
|
||||
from components.kotlin
|
||||
}
|
||||
}
|
||||
repositories {
|
||||
maven {
|
||||
url = "${'$'}buildDir/repo"
|
||||
}
|
||||
}
|
||||
}
|
||||
""".trimIndent()
|
||||
)
|
||||
|
||||
build(
|
||||
"build",
|
||||
"publishAllPublicationsToMavenRepository",
|
||||
) {
|
||||
assertTasksExecuted(":compileKotlin", ":compileTestKotlin")
|
||||
val pomLines = projectPath.resolve("build/publications/myLibrary/pom-default.xml").readLines()
|
||||
val stdlibVersionLineNumber = pomLines.indexOfFirst { "<artifactId>kotlin-stdlib-jdk8</artifactId>" in it } + 1
|
||||
val versionLine = pomLines[stdlibVersionLineNumber]
|
||||
assertTrue { "<version>${buildOptions.kotlinVersion}</version>" in versionLine }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+12
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.gradle
|
||||
|
||||
import org.gradle.api.logging.LogLevel
|
||||
import org.gradle.util.GradleVersion
|
||||
import org.jetbrains.kotlin.gradle.scripting.internal.ScriptingGradleSubplugin
|
||||
import org.jetbrains.kotlin.gradle.testbase.*
|
||||
import org.junit.jupiter.api.DisplayName
|
||||
import org.junit.jupiter.api.condition.DisabledOnOs
|
||||
@@ -97,4 +98,15 @@ class ScriptingIT : KGPBaseTest() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@DisplayName("KT-31124: No scripting warning")
|
||||
@GradleTest
|
||||
fun testNoScriptingWarning(gradleVersion: GradleVersion) {
|
||||
project("simpleProject", gradleVersion) {
|
||||
build("help") {
|
||||
assertOutputDoesNotContain(ScriptingGradleSubplugin.MISCONFIGURATION_MESSAGE_SUFFIX)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+92
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.gradle
|
||||
|
||||
import org.gradle.testkit.runner.BuildResult
|
||||
import org.gradle.util.GradleVersion
|
||||
import org.jetbrains.kotlin.gradle.testbase.*
|
||||
import org.junit.jupiter.api.DisplayName
|
||||
|
||||
@DisplayName("Tasks don't have unnamed inputs and outputs")
|
||||
class UnnamedTaskInputsIT : KGPBaseTest() {
|
||||
|
||||
override val defaultBuildOptions: BuildOptions
|
||||
get() = super.defaultBuildOptions.copy(buildCacheEnabled = true)
|
||||
|
||||
private val localBuildCacheDir get() = workingDir.resolve("custom-jdk-build-cache-2")
|
||||
|
||||
@JvmGradlePluginTests
|
||||
@DisplayName("JVM")
|
||||
@GradleTest
|
||||
fun inputsJvm(gradleVersion: GradleVersion) {
|
||||
project("simpleProject", gradleVersion) {
|
||||
enableLocalBuildCache(localBuildCacheDir)
|
||||
|
||||
build("assemble") {
|
||||
assertNoUnnamedInputsOutputs()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@JsGradlePluginTests
|
||||
@DisplayName("JS - kotlin2js plugin")
|
||||
@GradleTest
|
||||
fun inputsKotlin2Js(gradleVersion: GradleVersion) {
|
||||
project("kotlin2JsProject", gradleVersion) {
|
||||
enableLocalBuildCache(localBuildCacheDir)
|
||||
|
||||
build("assemble") {
|
||||
assertNoUnnamedInputsOutputs()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@JsGradlePluginTests
|
||||
@DisplayName("JS")
|
||||
@GradleTest
|
||||
fun inputsJs(gradleVersion: GradleVersion) {
|
||||
project("kotlin-js-nodejs-project", gradleVersion) {
|
||||
enableLocalBuildCache(localBuildCacheDir)
|
||||
|
||||
build("assemble") {
|
||||
assertNoUnnamedInputsOutputs()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@MppGradlePluginTests
|
||||
@DisplayName("MPP")
|
||||
@GradleTest
|
||||
fun inputsMpp(gradleVersion: GradleVersion) {
|
||||
project("multiplatformProject", gradleVersion) {
|
||||
enableLocalBuildCache(localBuildCacheDir)
|
||||
|
||||
build("assemble") {
|
||||
assertNoUnnamedInputsOutputs()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@OtherGradlePluginTests
|
||||
@DisplayName("Kapt")
|
||||
@GradleTest
|
||||
fun inputsKapt(gradleVersion: GradleVersion) {
|
||||
project("kapt2/simple", gradleVersion) {
|
||||
enableLocalBuildCache(localBuildCacheDir)
|
||||
|
||||
build("assemble") {
|
||||
assertNoUnnamedInputsOutputs()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun BuildResult.assertNoUnnamedInputsOutputs() {
|
||||
// Check that all inputs/outputs added at runtime have proper names
|
||||
// (the unnamed ones are listed as $1, $2 etc.):
|
||||
assertOutputDoesNotContain("Appending inputPropertyHash for '\\$\\d+'".toRegex())
|
||||
assertOutputDoesNotContain("Appending outputPropertyName to build cache key: \\$\\d+".toRegex())
|
||||
}
|
||||
}
|
||||
+2
-11
@@ -1,15 +1,7 @@
|
||||
buildscript {
|
||||
repositories {
|
||||
mavenLocal()
|
||||
mavenCentral()
|
||||
}
|
||||
dependencies {
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||
}
|
||||
plugins {
|
||||
id "org.jetbrains.kotlin.jvm"
|
||||
}
|
||||
|
||||
apply plugin: "kotlin"
|
||||
|
||||
repositories {
|
||||
mavenLocal()
|
||||
mavenCentral()
|
||||
@@ -18,7 +10,6 @@ repositories {
|
||||
dependencies {
|
||||
implementation 'com.google.guava:guava:12.0'
|
||||
testImplementation 'org.testng:testng:6.8'
|
||||
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
|
||||
}
|
||||
|
||||
test {
|
||||
|
||||
-26
@@ -1,26 +0,0 @@
|
||||
buildscript {
|
||||
repositories {
|
||||
mavenLocal()
|
||||
mavenCentral()
|
||||
}
|
||||
dependencies {
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||
}
|
||||
}
|
||||
|
||||
apply plugin: "kotlin"
|
||||
|
||||
repositories {
|
||||
mavenLocal()
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation 'com.google.guava:guava:12.0'
|
||||
testImplementation 'org.testng:testng:6.8'
|
||||
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
|
||||
}
|
||||
|
||||
test {
|
||||
useTestNG()
|
||||
}
|
||||
-18
@@ -1,18 +0,0 @@
|
||||
package demo
|
||||
|
||||
import sun.nio.cs.ext.Big5
|
||||
import sun.net.spi.nameservice.dns.DNSNameService
|
||||
import javax.crypto.Cipher
|
||||
import com.sun.crypto.provider.SunJCE
|
||||
import sun.nio.ByteBuffered
|
||||
|
||||
fun box(): String {
|
||||
val a = Big5() // charsets.jar
|
||||
val c = DNSNameService() // dnsns.ajr
|
||||
val e : Cipher? = null // jce.jar
|
||||
val f : SunJCE? = null // sunjce_provider.jar
|
||||
val j : ByteBuffered? = null // rt.jar
|
||||
return "OK"
|
||||
}
|
||||
|
||||
|
||||
-11
@@ -1,11 +0,0 @@
|
||||
package demo
|
||||
|
||||
import org.testng.Assert.*
|
||||
import org.testng.annotations.Test as test
|
||||
|
||||
class TestSource() {
|
||||
@test fun f() {
|
||||
assertEquals(box(), "OK")
|
||||
}
|
||||
}
|
||||
|
||||
+3
-15
@@ -1,25 +1,13 @@
|
||||
buildscript {
|
||||
repositories {
|
||||
mavenLocal()
|
||||
mavenCentral()
|
||||
}
|
||||
dependencies {
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||
}
|
||||
plugins {
|
||||
id "java"
|
||||
id "org.jetbrains.kotlin.jvm"
|
||||
}
|
||||
|
||||
apply plugin: "java"
|
||||
apply plugin: "kotlin"
|
||||
|
||||
repositories {
|
||||
mavenLocal()
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
|
||||
}
|
||||
|
||||
compileJava {
|
||||
options.incremental = true
|
||||
}
|
||||
-1
@@ -1 +0,0 @@
|
||||
org.gradle.jvmargs=-Xmx1024m -XX:MaxPermSize=512m
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
plugins {
|
||||
id "org.jetbrains.kotlin.multiplatform" version "<pluginMarkerVersion>" apply false
|
||||
id "org.jetbrains.kotlin.multiplatform" apply false
|
||||
}
|
||||
|
||||
allprojects {
|
||||
|
||||
+2
-11
@@ -1,15 +1,7 @@
|
||||
buildscript {
|
||||
repositories {
|
||||
mavenLocal()
|
||||
mavenCentral()
|
||||
}
|
||||
dependencies {
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||
}
|
||||
plugins {
|
||||
id "org.jetbrains.kotlin.jvm"
|
||||
}
|
||||
|
||||
apply plugin: "kotlin"
|
||||
|
||||
|
||||
repositories {
|
||||
mavenLocal()
|
||||
@@ -18,7 +10,6 @@ repositories {
|
||||
|
||||
dependencies {
|
||||
testImplementation 'org.testng:testng:6.8'
|
||||
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
|
||||
}
|
||||
|
||||
test {
|
||||
|
||||
+4
-3
@@ -1,7 +1,8 @@
|
||||
apply plugin: 'java'
|
||||
apply plugin: 'kotlin'
|
||||
plugins {
|
||||
id "java"
|
||||
id "org.jetbrains.kotlin.jvm"
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
|
||||
implementation project(':libB')
|
||||
}
|
||||
-10
@@ -1,13 +1,3 @@
|
||||
buildscript {
|
||||
repositories {
|
||||
mavenLocal()
|
||||
mavenCentral()
|
||||
}
|
||||
dependencies {
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||
}
|
||||
}
|
||||
|
||||
subprojects {
|
||||
repositories {
|
||||
mavenLocal()
|
||||
|
||||
+4
-2
@@ -1,5 +1,7 @@
|
||||
apply plugin: 'java-library'
|
||||
apply plugin: 'kotlin'
|
||||
plugins {
|
||||
id "java-library"
|
||||
id "org.jetbrains.kotlin.jvm"
|
||||
}
|
||||
|
||||
dependencies {
|
||||
api "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
|
||||
|
||||
+4
-2
@@ -1,5 +1,7 @@
|
||||
apply plugin: 'java-library'
|
||||
apply plugin: 'kotlin'
|
||||
plugins {
|
||||
id "java-library"
|
||||
id "org.jetbrains.kotlin.jvm"
|
||||
}
|
||||
|
||||
dependencies {
|
||||
api "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
|
||||
|
||||
+3
-15
@@ -1,23 +1,11 @@
|
||||
buildscript {
|
||||
repositories {
|
||||
mavenLocal()
|
||||
mavenCentral()
|
||||
}
|
||||
dependencies {
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||
}
|
||||
plugins {
|
||||
id "java"
|
||||
id "org.jetbrains.kotlin.jvm"
|
||||
}
|
||||
|
||||
apply plugin: 'java'
|
||||
apply plugin: 'kotlin'
|
||||
|
||||
repositories {
|
||||
mavenLocal()
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
|
||||
}
|
||||
|
||||
compileKotlin.javaPackagePrefix = "my.pack.name"
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
plugins {
|
||||
kotlin("js").version("<pluginMarkerVersion>").apply(false)
|
||||
kotlin("js").apply(false)
|
||||
}
|
||||
|
||||
group = "com.example"
|
||||
|
||||
+2
-10
@@ -1,15 +1,7 @@
|
||||
buildscript {
|
||||
repositories {
|
||||
mavenLocal()
|
||||
mavenCentral()
|
||||
}
|
||||
dependencies {
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||
}
|
||||
plugins {
|
||||
id "kotlin2js"
|
||||
}
|
||||
|
||||
apply plugin: "kotlin2js"
|
||||
|
||||
repositories {
|
||||
mavenLocal()
|
||||
mavenCentral()
|
||||
|
||||
+5
@@ -1,3 +1,8 @@
|
||||
/*
|
||||
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package foo
|
||||
|
||||
class A
|
||||
|
||||
+5
@@ -1,3 +1,8 @@
|
||||
/*
|
||||
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package foo
|
||||
|
||||
fun main() {
|
||||
|
||||
+3
-11
@@ -1,16 +1,8 @@
|
||||
buildscript {
|
||||
repositories {
|
||||
mavenLocal()
|
||||
mavenCentral()
|
||||
}
|
||||
dependencies {
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||
}
|
||||
plugins {
|
||||
id 'java'
|
||||
id 'org.jetbrains.kotlin.jvm'
|
||||
}
|
||||
|
||||
apply plugin: "kotlin"
|
||||
apply plugin: "java"
|
||||
|
||||
sourceSets {
|
||||
deploy
|
||||
}
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
import foo.bar.configureFromBuildSrc
|
||||
|
||||
plugins {
|
||||
kotlin("jvm") version "<pluginMarkerVersion>"
|
||||
kotlin("jvm")
|
||||
}
|
||||
|
||||
kotlin {
|
||||
|
||||
+3
-2
@@ -1,5 +1,5 @@
|
||||
plugins {
|
||||
kotlin("jvm") version "<pluginMarkerVersion>"
|
||||
kotlin("jvm")
|
||||
}
|
||||
|
||||
repositories {
|
||||
@@ -7,8 +7,9 @@ repositories {
|
||||
mavenLocal()
|
||||
}
|
||||
|
||||
val kotlin_version: String by extra
|
||||
allprojects {
|
||||
dependencies {
|
||||
implementation("org.jetbrains.kotlin:kotlin-gradle-plugin-api:<pluginMarkerVersion>")
|
||||
implementation("org.jetbrains.kotlin:kotlin-gradle-plugin-api:$kotlin_version")
|
||||
}
|
||||
}
|
||||
+2
@@ -5,7 +5,9 @@ pluginManagement {
|
||||
}
|
||||
|
||||
val test_fixes_version: String by settings
|
||||
val kotlin_version: String by settings
|
||||
plugins {
|
||||
id("org.jetbrains.kotlin.test.fixes.android") version test_fixes_version
|
||||
id("org.jetbrains.kotlin.jvm") version kotlin_version
|
||||
}
|
||||
}
|
||||
-10
@@ -1,13 +1,3 @@
|
||||
buildscript {
|
||||
repositories {
|
||||
mavenLocal()
|
||||
mavenCentral()
|
||||
}
|
||||
dependencies {
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||
}
|
||||
}
|
||||
|
||||
allprojects {
|
||||
repositories {
|
||||
mavenLocal()
|
||||
|
||||
-4
@@ -4,7 +4,3 @@ plugins {
|
||||
|
||||
group = "com.example.jvm"
|
||||
version = "1.0"
|
||||
|
||||
dependencies {
|
||||
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
|
||||
}
|
||||
|
||||
+1
-1
@@ -20,5 +20,5 @@ kotlin {
|
||||
}
|
||||
|
||||
// While this plugin seems not to do anything in this setup, IT IS needed to reproduce KT-29971
|
||||
apply plugin: "application"
|
||||
plugins.apply("application")
|
||||
mainClassName = "foo"
|
||||
+3
-2
@@ -1,6 +1,7 @@
|
||||
apply plugin: 'kotlin'
|
||||
plugins {
|
||||
id "org.jetbrains.kotlin.jvm"
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation project(':lib')
|
||||
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
|
||||
}
|
||||
|
||||
+2
-8
@@ -1,11 +1,5 @@
|
||||
buildscript {
|
||||
repositories {
|
||||
mavenLocal()
|
||||
mavenCentral()
|
||||
}
|
||||
dependencies {
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||
}
|
||||
plugins {
|
||||
id "org.jetbrains.kotlin.jvm" apply false
|
||||
}
|
||||
|
||||
subprojects {
|
||||
|
||||
+2
-4
@@ -1,5 +1,3 @@
|
||||
apply plugin: 'kotlin'
|
||||
|
||||
dependencies {
|
||||
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
|
||||
plugins {
|
||||
id "org.jetbrains.kotlin.jvm"
|
||||
}
|
||||
|
||||
+3
-2
@@ -1,9 +1,10 @@
|
||||
apply plugin: "kotlin"
|
||||
plugins {
|
||||
id "org.jetbrains.kotlin.jvm"
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation 'com.google.guava:guava:12.0'
|
||||
testImplementation 'org.testng:testng:6.8'
|
||||
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
|
||||
}
|
||||
|
||||
test {
|
||||
|
||||
+4
@@ -8,6 +8,10 @@ buildscript {
|
||||
}
|
||||
}
|
||||
|
||||
plugins {
|
||||
id "org.jetbrains.kotlin.jvm" apply false
|
||||
}
|
||||
|
||||
allprojects {
|
||||
repositories {
|
||||
mavenLocal()
|
||||
|
||||
+2
-4
@@ -1,5 +1,3 @@
|
||||
apply plugin: "kotlin"
|
||||
|
||||
dependencies {
|
||||
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
|
||||
plugins {
|
||||
id "org.jetbrains.kotlin.jvm"
|
||||
}
|
||||
|
||||
+3
-2
@@ -1,6 +1,7 @@
|
||||
apply plugin: "kotlin"
|
||||
plugins {
|
||||
id "org.jetbrains.kotlin.jvm"
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation project(':projA')
|
||||
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
|
||||
}
|
||||
|
||||
-13
@@ -1,14 +1 @@
|
||||
pluginManagement {
|
||||
repositories {
|
||||
mavenLocal()
|
||||
mavenCentral()
|
||||
google()
|
||||
gradlePluginPortal()
|
||||
}
|
||||
|
||||
plugins {
|
||||
id "org.jetbrains.kotlin.test.fixes.android" version "$test_fixes_version"
|
||||
}
|
||||
}
|
||||
|
||||
include 'projA', 'projB'
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
plugins {
|
||||
kotlin("jvm").version("<pluginMarkerVersion>")
|
||||
kotlin("jvm")
|
||||
`maven-publish`
|
||||
}
|
||||
|
||||
|
||||
+2
-14
@@ -1,20 +1,8 @@
|
||||
buildscript {
|
||||
repositories {
|
||||
mavenLocal()
|
||||
mavenCentral()
|
||||
}
|
||||
dependencies {
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||
}
|
||||
plugins {
|
||||
id "org.jetbrains.kotlin.jvm"
|
||||
}
|
||||
|
||||
apply plugin: "kotlin"
|
||||
|
||||
repositories {
|
||||
mavenLocal()
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
|
||||
}
|
||||
-1
@@ -1 +0,0 @@
|
||||
org.gradle.jvmargs=-Xmx1024m -XX:MaxPermSize=512m
|
||||
Reference in New Issue
Block a user