mirror of
https://github.com/square/okhttp.git
synced 2025-07-31 05:04:26 +03:00
Remove japicmp (#7118)
This plugin served us very well for a long time. But the binary compatibility plugin is better suited for our current situation.
This commit is contained in:
@ -4,6 +4,7 @@ import java.net.URL
|
|||||||
import kotlinx.validation.ApiValidationExtension
|
import kotlinx.validation.ApiValidationExtension
|
||||||
import org.gradle.api.tasks.testing.logging.TestExceptionFormat
|
import org.gradle.api.tasks.testing.logging.TestExceptionFormat
|
||||||
import org.jetbrains.dokka.gradle.DokkaTask
|
import org.jetbrains.dokka.gradle.DokkaTask
|
||||||
|
import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootExtension
|
||||||
import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootPlugin
|
import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootPlugin
|
||||||
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
||||||
import ru.vyarus.gradle.plugin.animalsniffer.AnimalSnifferExtension
|
import ru.vyarus.gradle.plugin.animalsniffer.AnimalSnifferExtension
|
||||||
@ -17,7 +18,6 @@ buildscript {
|
|||||||
classpath(libs.gradlePlugin.graal)
|
classpath(libs.gradlePlugin.graal)
|
||||||
classpath(libs.gradlePlugin.bnd)
|
classpath(libs.gradlePlugin.bnd)
|
||||||
classpath(libs.gradlePlugin.shadow)
|
classpath(libs.gradlePlugin.shadow)
|
||||||
classpath(libs.gradlePlugin.japicmp)
|
|
||||||
classpath(libs.gradlePlugin.animalsniffer)
|
classpath(libs.gradlePlugin.animalsniffer)
|
||||||
classpath(libs.gradlePlugin.errorprone)
|
classpath(libs.gradlePlugin.errorprone)
|
||||||
classpath(libs.gradlePlugin.spotless)
|
classpath(libs.gradlePlugin.spotless)
|
||||||
@ -255,6 +255,5 @@ tasks.wrapper {
|
|||||||
|
|
||||||
// Fix until 1.6.20 https://youtrack.jetbrains.com/issue/KT-49109
|
// Fix until 1.6.20 https://youtrack.jetbrains.com/issue/KT-49109
|
||||||
rootProject.plugins.withType(NodeJsRootPlugin::class.java) {
|
rootProject.plugins.withType(NodeJsRootPlugin::class.java) {
|
||||||
rootProject.the<org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootExtension>().nodeVersion =
|
rootProject.the<NodeJsRootExtension>().nodeVersion = "16.13.0"
|
||||||
"16.13.0"
|
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import aQute.bnd.gradle.BundleTaskExtension
|
import aQute.bnd.gradle.BundleTaskExtension
|
||||||
import java.io.File
|
|
||||||
import org.gradle.api.Project
|
import org.gradle.api.Project
|
||||||
import org.gradle.api.plugins.ExtensionAware
|
import org.gradle.api.plugins.ExtensionAware
|
||||||
import org.gradle.api.tasks.SourceSetContainer
|
import org.gradle.api.tasks.SourceSetContainer
|
||||||
@ -62,23 +61,5 @@ private fun Project.applyOsgi(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a .jar file for the golden version of this project.
|
|
||||||
* https://github.com/Visistema/Groovy1/blob/ba5eb9b2f19ca0cc8927359ce414c4e1974b7016/gradle/binarycompatibility.gradle#L48
|
|
||||||
*/
|
|
||||||
fun Project.baselineJar(version: String = "3.14.1"): File? {
|
|
||||||
val originalGroup = group
|
|
||||||
return try {
|
|
||||||
val jarFile = "$name-$version.jar"
|
|
||||||
group = "virtual_group_for_japicmp"
|
|
||||||
val dependency = dependencies.create("$originalGroup:$name:$version@jar")
|
|
||||||
configurations.detachedConfiguration(dependency).files.find { (it.name == jarFile) }
|
|
||||||
} catch (e: Exception) {
|
|
||||||
null
|
|
||||||
} finally {
|
|
||||||
group = originalGroup
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val Project.sourceSets: SourceSetContainer
|
val Project.sourceSets: SourceSetContainer
|
||||||
get() = (this as ExtensionAware).extensions["sourceSets"] as SourceSetContainer
|
get() = (this as ExtensionAware).extensions["sourceSets"] as SourceSetContainer
|
||||||
|
@ -38,7 +38,6 @@ gradlePlugin-bnd = { module = "biz.aQute.bnd:biz.aQute.bnd.gradle", version.ref
|
|||||||
gradlePlugin-dokka = "org.jetbrains.dokka:dokka-gradle-plugin:1.6.10"
|
gradlePlugin-dokka = "org.jetbrains.dokka:dokka-gradle-plugin:1.6.10"
|
||||||
gradlePlugin-errorprone = "net.ltgt.gradle:gradle-errorprone-plugin:2.0.2"
|
gradlePlugin-errorprone = "net.ltgt.gradle:gradle-errorprone-plugin:2.0.2"
|
||||||
gradlePlugin-graal = "gradle.plugin.com.palantir.graal:gradle-graal:0.10.0"
|
gradlePlugin-graal = "gradle.plugin.com.palantir.graal:gradle-graal:0.10.0"
|
||||||
gradlePlugin-japicmp = "me.champeau.gradle:japicmp-gradle-plugin:0.3.1"
|
|
||||||
gradlePlugin-kotlin = { module = "org.jetbrains.kotlin:kotlin-gradle-plugin", version.ref = "org-jetbrains-kotlin" }
|
gradlePlugin-kotlin = { module = "org.jetbrains.kotlin:kotlin-gradle-plugin", version.ref = "org-jetbrains-kotlin" }
|
||||||
gradlePlugin-mavenPublish = "com.vanniktech:gradle-maven-publish-plugin:0.18.0"
|
gradlePlugin-mavenPublish = "com.vanniktech:gradle-maven-publish-plugin:0.18.0"
|
||||||
gradlePlugin-shadow = "gradle.plugin.com.github.johnrengelman:shadow:7.1.2"
|
gradlePlugin-shadow = "gradle.plugin.com.github.johnrengelman:shadow:7.1.2"
|
||||||
|
@ -1,14 +1,11 @@
|
|||||||
import com.android.build.gradle.internal.tasks.factory.dependsOn
|
|
||||||
import com.vanniktech.maven.publish.JavadocJar
|
import com.vanniktech.maven.publish.JavadocJar
|
||||||
import com.vanniktech.maven.publish.KotlinJvm
|
import com.vanniktech.maven.publish.KotlinJvm
|
||||||
import me.champeau.gradle.japicmp.JapicmpTask
|
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
kotlin("jvm")
|
kotlin("jvm")
|
||||||
id("org.jetbrains.dokka")
|
id("org.jetbrains.dokka")
|
||||||
id("com.vanniktech.maven.publish.base")
|
id("com.vanniktech.maven.publish.base")
|
||||||
id("binary-compatibility-validator")
|
id("binary-compatibility-validator")
|
||||||
id("me.champeau.gradle.japicmp")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks.jar {
|
tasks.jar {
|
||||||
@ -27,27 +24,6 @@ dependencies {
|
|||||||
testImplementation(libs.assertj.core)
|
testImplementation(libs.assertj.core)
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks.register<JapicmpTask>("japicmp") {
|
|
||||||
dependsOn("jar")
|
|
||||||
oldClasspath = files(project.baselineJar())
|
|
||||||
newClasspath = files(tasks.jar.get().archiveFile)
|
|
||||||
isOnlyBinaryIncompatibleModified = true
|
|
||||||
isFailOnModification = true
|
|
||||||
txtOutputFile = file("$buildDir/reports/japi.txt")
|
|
||||||
isIgnoreMissingClasses = true
|
|
||||||
isIncludeSynthetic = true
|
|
||||||
packageExcludes = listOf(
|
|
||||||
"okhttp3.internal.duplex",
|
|
||||||
"okhttp3.mockwebserver.internal",
|
|
||||||
"okhttp3.mockwebserver.internal.duplex",
|
|
||||||
)
|
|
||||||
classExcludes = listOf(
|
|
||||||
// Became "final" in 4.10.0.
|
|
||||||
"okhttp3.mockwebserver.QueueDispatcher"
|
|
||||||
)
|
|
||||||
}.let(tasks.check::dependsOn)
|
|
||||||
|
|
||||||
|
|
||||||
mavenPublishing {
|
mavenPublishing {
|
||||||
configure(KotlinJvm(javadocJar = JavadocJar.Dokka("dokkaGfm")))
|
configure(KotlinJvm(javadocJar = JavadocJar.Dokka("dokkaGfm")))
|
||||||
}
|
}
|
||||||
|
@ -1,14 +1,11 @@
|
|||||||
import com.android.build.gradle.internal.tasks.factory.dependsOn
|
|
||||||
import com.vanniktech.maven.publish.JavadocJar
|
import com.vanniktech.maven.publish.JavadocJar
|
||||||
import com.vanniktech.maven.publish.KotlinJvm
|
import com.vanniktech.maven.publish.KotlinJvm
|
||||||
import me.champeau.gradle.japicmp.JapicmpTask
|
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
kotlin("jvm")
|
kotlin("jvm")
|
||||||
id("org.jetbrains.dokka")
|
id("org.jetbrains.dokka")
|
||||||
id("com.vanniktech.maven.publish.base")
|
id("com.vanniktech.maven.publish.base")
|
||||||
id("binary-compatibility-validator")
|
id("binary-compatibility-validator")
|
||||||
id("me.champeau.gradle.japicmp")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
project.applyOsgi(
|
project.applyOsgi(
|
||||||
@ -30,17 +27,6 @@ dependencies {
|
|||||||
testImplementation(libs.assertj.core)
|
testImplementation(libs.assertj.core)
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks.register<JapicmpTask>("japicmp") {
|
|
||||||
dependsOn("jar")
|
|
||||||
oldClasspath = files(project.baselineJar())
|
|
||||||
newClasspath = files(tasks.jar.get().archiveFile)
|
|
||||||
isOnlyBinaryIncompatibleModified = true
|
|
||||||
isFailOnModification = true
|
|
||||||
txtOutputFile = file("$buildDir/reports/japi.txt")
|
|
||||||
isIgnoreMissingClasses = true
|
|
||||||
isIncludeSynthetic = true
|
|
||||||
}.let(tasks.check::dependsOn)
|
|
||||||
|
|
||||||
mavenPublishing {
|
mavenPublishing {
|
||||||
configure(KotlinJvm(javadocJar = JavadocJar.Dokka("dokkaGfm")))
|
configure(KotlinJvm(javadocJar = JavadocJar.Dokka("dokkaGfm")))
|
||||||
}
|
}
|
||||||
|
@ -1,14 +1,11 @@
|
|||||||
import com.android.build.gradle.internal.tasks.factory.dependsOn
|
|
||||||
import com.vanniktech.maven.publish.JavadocJar
|
import com.vanniktech.maven.publish.JavadocJar
|
||||||
import com.vanniktech.maven.publish.KotlinJvm
|
import com.vanniktech.maven.publish.KotlinJvm
|
||||||
import me.champeau.gradle.japicmp.JapicmpTask
|
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
kotlin("jvm")
|
kotlin("jvm")
|
||||||
id("org.jetbrains.dokka")
|
id("org.jetbrains.dokka")
|
||||||
id("com.vanniktech.maven.publish.base")
|
id("com.vanniktech.maven.publish.base")
|
||||||
id("binary-compatibility-validator")
|
id("binary-compatibility-validator")
|
||||||
id("me.champeau.gradle.japicmp")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
project.applyOsgi(
|
project.applyOsgi(
|
||||||
@ -29,20 +26,6 @@ dependencies {
|
|||||||
testCompileOnly(libs.findbugs.jsr305)
|
testCompileOnly(libs.findbugs.jsr305)
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks.register<JapicmpTask>("japicmp") {
|
|
||||||
dependsOn("jar")
|
|
||||||
oldClasspath = files(project.baselineJar())
|
|
||||||
newClasspath = files(tasks.jar.get().archiveFile)
|
|
||||||
isOnlyBinaryIncompatibleModified = true
|
|
||||||
isFailOnModification = true
|
|
||||||
txtOutputFile = file("$buildDir/reports/japi.txt")
|
|
||||||
isIgnoreMissingClasses = true
|
|
||||||
isIncludeSynthetic = true
|
|
||||||
packageExcludes = listOf(
|
|
||||||
"okhttp3.internal.sse"
|
|
||||||
)
|
|
||||||
}.let(tasks.check::dependsOn)
|
|
||||||
|
|
||||||
mavenPublishing {
|
mavenPublishing {
|
||||||
configure(KotlinJvm(javadocJar = JavadocJar.Dokka("dokkaGfm")))
|
configure(KotlinJvm(javadocJar = JavadocJar.Dokka("dokkaGfm")))
|
||||||
}
|
}
|
||||||
|
@ -1,14 +1,11 @@
|
|||||||
import com.android.build.gradle.internal.tasks.factory.dependsOn
|
|
||||||
import com.vanniktech.maven.publish.JavadocJar
|
import com.vanniktech.maven.publish.JavadocJar
|
||||||
import com.vanniktech.maven.publish.KotlinJvm
|
import com.vanniktech.maven.publish.KotlinJvm
|
||||||
import me.champeau.gradle.japicmp.JapicmpTask
|
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
kotlin("jvm")
|
kotlin("jvm")
|
||||||
id("org.jetbrains.dokka")
|
id("org.jetbrains.dokka")
|
||||||
id("com.vanniktech.maven.publish.base")
|
id("com.vanniktech.maven.publish.base")
|
||||||
id("binary-compatibility-validator")
|
id("binary-compatibility-validator")
|
||||||
id("me.champeau.gradle.japicmp")
|
|
||||||
id("ru.vyarus.animalsniffer")
|
id("ru.vyarus.animalsniffer")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -35,20 +32,6 @@ animalsniffer {
|
|||||||
ignore = listOf("javax.net.ssl.X509ExtendedTrustManager")
|
ignore = listOf("javax.net.ssl.X509ExtendedTrustManager")
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks.register<JapicmpTask>("japicmp") {
|
|
||||||
dependsOn("jar")
|
|
||||||
oldClasspath = files(project.baselineJar())
|
|
||||||
newClasspath = files(tasks.jar.get().archiveFile)
|
|
||||||
isOnlyBinaryIncompatibleModified = true
|
|
||||||
isFailOnModification = true
|
|
||||||
txtOutputFile = file("$buildDir/reports/japi.txt")
|
|
||||||
isIgnoreMissingClasses = true
|
|
||||||
isIncludeSynthetic = true
|
|
||||||
packageExcludes = listOf(
|
|
||||||
"okhttp3.tls.internal"
|
|
||||||
)
|
|
||||||
}.let(tasks.check::dependsOn)
|
|
||||||
|
|
||||||
mavenPublishing {
|
mavenPublishing {
|
||||||
configure(KotlinJvm(javadocJar = JavadocJar.Dokka("dokkaGfm")))
|
configure(KotlinJvm(javadocJar = JavadocJar.Dokka("dokkaGfm")))
|
||||||
}
|
}
|
||||||
|
@ -1,14 +1,11 @@
|
|||||||
import com.android.build.gradle.internal.tasks.factory.dependsOn
|
|
||||||
import com.vanniktech.maven.publish.JavadocJar
|
import com.vanniktech.maven.publish.JavadocJar
|
||||||
import com.vanniktech.maven.publish.KotlinJvm
|
import com.vanniktech.maven.publish.KotlinJvm
|
||||||
import me.champeau.gradle.japicmp.JapicmpTask
|
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
kotlin("jvm")
|
kotlin("jvm")
|
||||||
id("org.jetbrains.dokka")
|
id("org.jetbrains.dokka")
|
||||||
id("com.vanniktech.maven.publish.base")
|
id("com.vanniktech.maven.publish.base")
|
||||||
id("binary-compatibility-validator")
|
id("binary-compatibility-validator")
|
||||||
id("me.champeau.gradle.japicmp")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
project.applyOsgi(
|
project.applyOsgi(
|
||||||
@ -30,18 +27,6 @@ dependencies {
|
|||||||
testImplementation(libs.assertj.core)
|
testImplementation(libs.assertj.core)
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks.register<JapicmpTask>("japicmp") {
|
|
||||||
dependsOn("jar")
|
|
||||||
oldClasspath = files(project.baselineJar())
|
|
||||||
newClasspath = files(tasks.jar.get().archiveFile)
|
|
||||||
isOnlyBinaryIncompatibleModified = true
|
|
||||||
isFailOnModification = true
|
|
||||||
txtOutputFile = file("$buildDir/reports/japi.txt")
|
|
||||||
isIgnoreMissingClasses = true
|
|
||||||
isIncludeSynthetic = true
|
|
||||||
}.let(tasks.check::dependsOn)
|
|
||||||
|
|
||||||
|
|
||||||
mavenPublishing {
|
mavenPublishing {
|
||||||
configure(KotlinJvm(javadocJar = JavadocJar.Dokka("dokkaGfm")))
|
configure(KotlinJvm(javadocJar = JavadocJar.Dokka("dokkaGfm")))
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
import com.android.build.gradle.internal.tasks.factory.dependsOn
|
|
||||||
import com.vanniktech.maven.publish.JavadocJar
|
import com.vanniktech.maven.publish.JavadocJar
|
||||||
import com.vanniktech.maven.publish.KotlinMultiplatform
|
import com.vanniktech.maven.publish.KotlinMultiplatform
|
||||||
import me.champeau.gradle.japicmp.JapicmpTask
|
|
||||||
import org.jetbrains.kotlin.gradle.dsl.KotlinCompile
|
import org.jetbrains.kotlin.gradle.dsl.KotlinCompile
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
@ -9,7 +7,6 @@ plugins {
|
|||||||
id("org.jetbrains.dokka")
|
id("org.jetbrains.dokka")
|
||||||
id("com.vanniktech.maven.publish.base")
|
id("com.vanniktech.maven.publish.base")
|
||||||
id("binary-compatibility-validator")
|
id("binary-compatibility-validator")
|
||||||
id("me.champeau.gradle.japicmp")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
kotlin {
|
kotlin {
|
||||||
@ -185,69 +182,6 @@ dependencies {
|
|||||||
osgiTestDeploy(libs.kotlin.stdlib.osgi)
|
osgiTestDeploy(libs.kotlin.stdlib.osgi)
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks.register<JapicmpTask>("japicmp") {
|
|
||||||
dependsOn("jvmJar")
|
|
||||||
oldClasspath = files(project.baselineJar())
|
|
||||||
newClasspath = files(tasks.getByName<Jar>("jvmJar").archiveFile)
|
|
||||||
isOnlyBinaryIncompatibleModified = true
|
|
||||||
isFailOnModification = true
|
|
||||||
txtOutputFile = file("$buildDir/reports/japi.txt")
|
|
||||||
isIgnoreMissingClasses = true
|
|
||||||
isIncludeSynthetic = true
|
|
||||||
packageExcludes = listOf(
|
|
||||||
"okhttp3.internal",
|
|
||||||
"okhttp3.internal.annotations",
|
|
||||||
"okhttp3.internal.cache",
|
|
||||||
"okhttp3.internal.cache2",
|
|
||||||
"okhttp3.internal.connection",
|
|
||||||
"okhttp3.internal.http",
|
|
||||||
"okhttp3.internal.http1",
|
|
||||||
"okhttp3.internal.http2",
|
|
||||||
"okhttp3.internal.io",
|
|
||||||
"okhttp3.internal.platform",
|
|
||||||
"okhttp3.internal.proxy",
|
|
||||||
"okhttp3.internal.publicsuffix",
|
|
||||||
"okhttp3.internal.tls",
|
|
||||||
"okhttp3.internal.ws",
|
|
||||||
)
|
|
||||||
classExcludes = listOf(
|
|
||||||
// Package-private in 3.x, internal in 4.0.0:
|
|
||||||
"okhttp3.Cache\$CacheResponseBody\$1",
|
|
||||||
"okhttp3.RealCall\$AsyncCall",
|
|
||||||
)
|
|
||||||
methodExcludes = listOf(
|
|
||||||
// Became "final" despite a non-final enclosing class in 4.0.0:
|
|
||||||
"okhttp3.OkHttpClient#authenticator()",
|
|
||||||
"okhttp3.OkHttpClient#cache()",
|
|
||||||
"okhttp3.OkHttpClient#callTimeoutMillis()",
|
|
||||||
"okhttp3.OkHttpClient#certificatePinner()",
|
|
||||||
"okhttp3.OkHttpClient#connectionPool()",
|
|
||||||
"okhttp3.OkHttpClient#connectionSpecs()",
|
|
||||||
"okhttp3.OkHttpClient#connectTimeoutMillis()",
|
|
||||||
"okhttp3.OkHttpClient#cookieJar()",
|
|
||||||
"okhttp3.OkHttpClient#dispatcher()",
|
|
||||||
"okhttp3.OkHttpClient#dns()",
|
|
||||||
"okhttp3.OkHttpClient#eventListenerFactory()",
|
|
||||||
"okhttp3.OkHttpClient#followRedirects()",
|
|
||||||
"okhttp3.OkHttpClient#followSslRedirects()",
|
|
||||||
"okhttp3.OkHttpClient#hostnameVerifier()",
|
|
||||||
"okhttp3.OkHttpClient#interceptors()",
|
|
||||||
"okhttp3.OkHttpClient#networkInterceptors()",
|
|
||||||
"okhttp3.OkHttpClient#pingIntervalMillis()",
|
|
||||||
"okhttp3.OkHttpClient#protocols()",
|
|
||||||
"okhttp3.OkHttpClient#proxy()",
|
|
||||||
"okhttp3.OkHttpClient#proxyAuthenticator()",
|
|
||||||
"okhttp3.OkHttpClient#proxySelector()",
|
|
||||||
"okhttp3.OkHttpClient#readTimeoutMillis()",
|
|
||||||
"okhttp3.OkHttpClient#retryOnConnectionFailure()",
|
|
||||||
"okhttp3.OkHttpClient#socketFactory()",
|
|
||||||
"okhttp3.OkHttpClient#sslSocketFactory()",
|
|
||||||
"okhttp3.OkHttpClient#writeTimeoutMillis()",
|
|
||||||
"okhttp3.OkHttpClient#writeTimeoutMillis()",
|
|
||||||
"okhttp3.Request\$Builder#delete()",
|
|
||||||
)
|
|
||||||
}.let(tasks.check::dependsOn)
|
|
||||||
|
|
||||||
mavenPublishing {
|
mavenPublishing {
|
||||||
configure(KotlinMultiplatform(javadocJar = JavadocJar.Dokka("dokkaGfm")))
|
configure(KotlinMultiplatform(javadocJar = JavadocJar.Dokka("dokkaGfm")))
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user