From 2ad567e14c9d2c869c45c39aafd69079ba11aa89 Mon Sep 17 00:00:00 2001 From: Nikolay Krasko Date: Tue, 14 Feb 2023 10:07:58 +0100 Subject: [PATCH] Revert "[K/N][build] Cleanup obsolete build tasks" This reverts commit a9cae3fe87037e20228be419ebb128078b9bf55b. --- .../backend.native/tests/build.gradle | 33 ++++++ kotlin-native/build-tools/build.gradle.kts | 19 ++- .../org/jetbrains/kotlin/CollisionDetector.kt | 85 ++++++++++++++ .../jetbrains/kotlin/CollisionTransformer.kt | 50 ++++++++ .../jetbrains/kotlin/ExternalReportUtils.kt | 26 +++++ .../jetbrains/kotlin/KonanTestSuiteReport.kt | 5 +- .../org/jetbrains/kotlin/KotlinBuildPusher.kt | 106 +++++++++++++++++ .../kotlin/org/jetbrains/kotlin/Reporter.kt | 109 ++++++++++++++++++ .../main/kotlin/org/jetbrains/kotlin/Utils.kt | 3 - .../kotlin/org/jetbrains/kotlin/Wrappers.kt | 53 +++++++++ kotlin-native/build.gradle | 25 +++- kotlin-native/shared/build.gradle.kts | 15 +-- .../internal/KotlinNativePlatform.kt | 15 ++- .../kotlin/gradle/plugin/konan/KonanPlugin.kt | 1 + .../konan/tasks/KonanCompilerDownloadTask.kt | 77 +++++++++++++ 15 files changed, 598 insertions(+), 24 deletions(-) create mode 100644 kotlin-native/build-tools/src/main/kotlin/org/jetbrains/kotlin/CollisionDetector.kt create mode 100644 kotlin-native/build-tools/src/main/kotlin/org/jetbrains/kotlin/CollisionTransformer.kt create mode 100644 kotlin-native/build-tools/src/main/kotlin/org/jetbrains/kotlin/ExternalReportUtils.kt create mode 100644 kotlin-native/build-tools/src/main/kotlin/org/jetbrains/kotlin/KotlinBuildPusher.kt create mode 100644 kotlin-native/build-tools/src/main/kotlin/org/jetbrains/kotlin/Reporter.kt create mode 100644 kotlin-native/build-tools/src/main/kotlin/org/jetbrains/kotlin/Wrappers.kt create mode 100644 kotlin-native/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/konan/tasks/KonanCompilerDownloadTask.kt diff --git a/kotlin-native/backend.native/tests/build.gradle b/kotlin-native/backend.native/tests/build.gradle index 2239e10846f..cb9047c16da 100644 --- a/kotlin-native/backend.native/tests/build.gradle +++ b/kotlin-native/backend.native/tests/build.gradle @@ -212,6 +212,27 @@ task sanity { dependsOn(":kotlin-native-shared:check") } +// Collect reports in one json. +task resultsTask() { + doLast { + def statistics = new Statistics() + + tasks.withType(KonanGTest).matching { it.state.executed }.each { + statistics.add(it.statistics) + } + + ExternalReportUtilsKt.saveReport("$testOutputExternal/reports.json", statistics) + use(KonanTestSuiteReportKt) { + project.logger.quiet("DONE.\n\n" + + "TOTAL: $statistics.total\n" + + "PASSED: $statistics.passed\n" + + "FAILED: $statistics.failed\n" + + (statistics.error != 0 ? "ERROR: $statistics.error\n" : "") + + "SKIPPED: $statistics.skipped") + } + } +} + boolean isExcluded(String dir) { // List of tests that fail due to unresolved compiler bugs def excluded = [ ] @@ -312,6 +333,16 @@ Task dynamicTest(String name, Closure configureClosure) { } } +task slackReport(type:Reporter) { + reportHome = rootProject.file("test.output").absoluteFile +} + +task slackReportNightly(type:NightlyReporter) { + externalMacosReport = "external_macos_results/reports.json" + externalLinuxReport = "external_linux_results/reports.json" + externalWindowsReport = "external_windows_results/reports.json" +} + linkTest("localDelegatedPropertyLink") { source = "lower/local_delegated_property_link/main.kt" lib = "lower/local_delegated_property_link/lib.kt" @@ -6093,6 +6124,8 @@ KotlinNativeTestKt.createTest(project, 'harmonyRegexTest', KonanGTest) { task -> extraOpts project.globalTestArgs } } + + task.finalizedBy("resultsTask") } if (UtilsKt.getTestTargetSupportsCodeCoverage(project)) { diff --git a/kotlin-native/build-tools/build.gradle.kts b/kotlin-native/build-tools/build.gradle.kts index edfb036f5c4..eae89507d31 100644 --- a/kotlin-native/build-tools/build.gradle.kts +++ b/kotlin-native/build-tools/build.gradle.kts @@ -3,6 +3,7 @@ * that can be found in the license/LICENSE.txt file. */ +import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet import org.jetbrains.kotlin.gradle.tasks.KotlinCompile import java.util.Properties @@ -29,6 +30,8 @@ val rootProperties = Properties().apply { val kotlinVersion = project.bootstrapKotlinVersion val slackApiVersion: String by rootProperties +val ktorVersion: String by rootProperties +val shadowVersion: String by rootProperties val metadataVersion: String by rootProperties group = "org.jetbrains.kotlin" @@ -50,6 +53,9 @@ dependencies { implementation(commonDependency("org.jetbrains.kotlin:kotlin-reflect")) { isTransitive = false } implementation("org.jetbrains.kotlin:kotlin-build-gradle-plugin:${kotlinBuildProperties.buildGradlePluginVersion}") + implementation("com.ullink.slack:simpleslackapi:$slackApiVersion") { + exclude(group = "com.google.code.gson", module = "gson") // Workaround for Gradle dependency resolution error + } val versionProperties = Properties() project.rootProject.projectDir.resolve("gradle/versions.properties").inputStream().use { propInput -> versionProperties.load(propInput) @@ -64,17 +70,18 @@ dependencies { } } + implementation("io.ktor:ktor-client-auth:$ktorVersion") + implementation("io.ktor:ktor-client-core:$ktorVersion") + implementation("io.ktor:ktor-client-cio:$ktorVersion") + api(project(":native:kotlin-native-utils")) api(project(":kotlin-native-shared")) api(project(":kotlinx-metadata-klib")) + implementation("gradle.plugin.com.github.johnrengelman:shadow:${rootProject.extra["versions.shadow"]}") } -kotlin { - sourceSets { - main { - kotlin.srcDir("$projectDir/../tools/benchmarks/shared/src/main/kotlin/report") - } - } +sourceSets["main"].withConvention(KotlinSourceSet::class) { + kotlin.srcDir("$projectDir/../tools/benchmarks/shared/src/main/kotlin/report") } val compileKotlin: KotlinCompile by tasks diff --git a/kotlin-native/build-tools/src/main/kotlin/org/jetbrains/kotlin/CollisionDetector.kt b/kotlin-native/build-tools/src/main/kotlin/org/jetbrains/kotlin/CollisionDetector.kt new file mode 100644 index 00000000000..f0357738378 --- /dev/null +++ b/kotlin-native/build-tools/src/main/kotlin/org/jetbrains/kotlin/CollisionDetector.kt @@ -0,0 +1,85 @@ +/* + * Copyright 2010-2019 JetBrains s.r.o. 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 + +import org.gradle.api.DefaultTask +import org.gradle.api.tasks.TaskAction +import org.gradle.api.artifacts.Configuration +import org.gradle.api.tasks.Input +import org.gradle.api.tasks.InputFiles +import java.io.File +import java.util.zip.ZipFile + +/** + * Task to find out collisions before producing fat jar. + * + * @property configurations added to fat jar configurations + * @property resolvingRules a map containing rules to resolve conflicts. Key - conflicting file, value - a jar to copy the file from + * @property resolvingRulesWithRegexes a map containing rules to resolve conflicts. Key - regular expression describing conflicting file, value - a jar to copy the file from + * @property librariesWithIgnoredClassCollisions libraries which collision in class files are ignored + */ +open class CollisionDetector : DefaultTask() { + @InputFiles + var configurations = listOf() + @Input + val resolvingRules = mutableMapOf() + @Input + val resolvingRulesWithRegexes = mutableMapOf() + @Input + val librariesWithIgnoredClassCollisions = mutableListOf() + val resolvedConflicts = mutableMapOf() + + // Key - filename, value - jar file containing it. + private val filesInfo = mutableMapOf() + + @TaskAction + fun run() { + configurations.forEach { configuration -> + configuration.files.filter { it.name.endsWith(".jar") }.forEach { processedFile -> + ZipFile(processedFile).use { zip -> + zip.entries().asSequence().filterNot { + it.isDirectory || + it.name.equals("META-INF/MANIFEST.MF", ignoreCase = true) || + it.name.equals("META-INF/versions/9/module-info.class", ignoreCase = true) || + it.name.startsWith("META-INF/services/", ignoreCase = true) + }.forEach { + val outputPath = it.name + if (outputPath in filesInfo.keys) { + val rule = resolvingRules.getOrElse(outputPath) { + resolvingRulesWithRegexes.entries.firstOrNull { (key, _) -> key.matches(outputPath) }?.value + } + var ignoreJar = false + if (rule != null && processedFile.name.startsWith(rule)) { + resolvedConflicts[outputPath] = processedFile + } else { + // Skip class files from ignored libraries if version of libraries had collision are the same. + val versionRegex = "\\d+\\.\\d+(\\.\\d+)?(-M\\d)?(-\\w+(-\\d+)?)?".toRegex() + val currentVersion = versionRegex.find(processedFile.name)?.groupValues?.get(0) + val collisionLibVersion = versionRegex.find(filesInfo.getValue(outputPath))?.groupValues?.get(0) + if (outputPath.endsWith(".class") && currentVersion == collisionLibVersion) { + if (processedFile.name == filesInfo[outputPath]) { + ignoreJar = true + } else { + librariesWithIgnoredClassCollisions.forEach { + if (processedFile.name.startsWith(it)) { + ignoreJar = true + } + } + } + } + } + if (rule == null && !ignoreJar) { + error("Collision is detected. File $outputPath is found in ${filesInfo[outputPath]} and ${processedFile.name}") + } + } else { + filesInfo[outputPath] = processedFile.name + } + } + } + } + } + } +} diff --git a/kotlin-native/build-tools/src/main/kotlin/org/jetbrains/kotlin/CollisionTransformer.kt b/kotlin-native/build-tools/src/main/kotlin/org/jetbrains/kotlin/CollisionTransformer.kt new file mode 100644 index 00000000000..011c03488c6 --- /dev/null +++ b/kotlin-native/build-tools/src/main/kotlin/org/jetbrains/kotlin/CollisionTransformer.kt @@ -0,0 +1,50 @@ +/* + * Copyright 2010-2019 JetBrains s.r.o. 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 + +import com.github.jengelman.gradle.plugins.shadow.transformers.Transformer +import com.github.jengelman.gradle.plugins.shadow.transformers.TransformerContext +import org.gradle.api.file.FileTreeElement +import shadow.org.apache.tools.zip.ZipOutputStream +import java.io.File +import shadow.org.apache.commons.io.IOUtils +import shadow.org.apache.tools.zip.ZipEntry +import shadow.org.apache.tools.zip.ZipFile + +class CollisionTransformer : Transformer { + var resolvedConflicts = mutableMapOf() + private val foundConflictsFiles = mutableSetOf() + + override fun getName() = "CollisionTransformer" + + override fun canTransformResource(element: FileTreeElement): Boolean { + val result = element.name in resolvedConflicts.keys + if (result) { + foundConflictsFiles.add(element.name) + } + return result + } + + override fun transform(context: TransformerContext) {} + + override fun hasTransformedResource(): Boolean { + return foundConflictsFiles.isNotEmpty() + } + + override fun modifyOutputStream(jos: ZipOutputStream, preserveFileTimestamps: Boolean) { + foundConflictsFiles.forEach { + val entry = ZipEntry(it) + entry.time = TransformerContext.getEntryTimestamp(preserveFileTimestamps, entry.time) + jos.putNextEntry(entry) + val archive = ZipFile(resolvedConflicts[it]) + archive.getInputStream(archive.getEntry(it)).use { + IOUtils.copyLarge(it, jos) + } + jos.closeEntry() + } + foundConflictsFiles.clear() + } +} \ No newline at end of file diff --git a/kotlin-native/build-tools/src/main/kotlin/org/jetbrains/kotlin/ExternalReportUtils.kt b/kotlin-native/build-tools/src/main/kotlin/org/jetbrains/kotlin/ExternalReportUtils.kt new file mode 100644 index 00000000000..320a52da165 --- /dev/null +++ b/kotlin-native/build-tools/src/main/kotlin/org/jetbrains/kotlin/ExternalReportUtils.kt @@ -0,0 +1,26 @@ +package org.jetbrains.kotlin + + +import com.google.gson.annotations.* +import com.google.gson.* +import com.google.gson.stream.JsonReader +import java.io.File +import java.io.FileReader +import java.io.PrintWriter + + +data class ExternalTestReport(@Expose val statistics: Statistics, @Expose val groups: List) + +fun saveReport(reportFileName: String, statistics: Statistics){ + File(reportFileName).apply { + parentFile.mkdirs() + PrintWriter(this).use { + it.append(gson.toJson(ExternalTestReport(statistics, emptyList()))) + } + } +} + +internal val gson = GsonBuilder().excludeFieldsWithoutExposeAnnotation().create()!! +fun loadReport(reportFileName: String) : ExternalTestReport = JsonReader(FileReader(reportFileName)).use { + gson.fromJson(it, ExternalTestReport::class.java) +} diff --git a/kotlin-native/build-tools/src/main/kotlin/org/jetbrains/kotlin/KonanTestSuiteReport.kt b/kotlin-native/build-tools/src/main/kotlin/org/jetbrains/kotlin/KonanTestSuiteReport.kt index e43dad0be7c..66f13ee5b25 100644 --- a/kotlin-native/build-tools/src/main/kotlin/org/jetbrains/kotlin/KonanTestSuiteReport.kt +++ b/kotlin-native/build-tools/src/main/kotlin/org/jetbrains/kotlin/KonanTestSuiteReport.kt @@ -18,6 +18,7 @@ data class Statistics( @Expose var error: Int = 0, @Expose var skipped: Int = 0) { + fun pass(count: Int = 1) { passed += count } fun skip(count: Int = 1) { skipped += count } @@ -47,10 +48,8 @@ data class KonanTestSuiteReport(@Expose val name: String, val tests: List() - fun executeTest(testName: String, action:() -> Unit) { var test: KonanTestCaseReport? try { diff --git a/kotlin-native/build-tools/src/main/kotlin/org/jetbrains/kotlin/KotlinBuildPusher.kt b/kotlin-native/build-tools/src/main/kotlin/org/jetbrains/kotlin/KotlinBuildPusher.kt new file mode 100644 index 00000000000..3844a9a5850 --- /dev/null +++ b/kotlin-native/build-tools/src/main/kotlin/org/jetbrains/kotlin/KotlinBuildPusher.kt @@ -0,0 +1,106 @@ +package org.jetbrains.kotlin + +import io.ktor.client.HttpClient +import io.ktor.client.request.get +import io.ktor.client.request.header +import io.ktor.client.request.post +import io.ktor.content.TextContent +import io.ktor.http.ContentType +import kotlinx.coroutines.runBlocking +import org.gradle.api.DefaultTask +import org.gradle.api.tasks.Input +import org.gradle.api.tasks.TaskAction +import org.gradle.api.tasks.options.Option + +@Suppress("UnstableApiUsage") +open class KotlinBuildPusher : DefaultTask() { + @Input + @Option(option = "token", description = "Teamcity Bear token") + var token: String? = "" + + @Input + @Option(option = "buildServer", description = "Teamcity server") + var buildServer: String = "" + + @Input + @Option(option = "compilerConfigurationId", description = "Teamcity configuration id") + var compilerConfigurationId: String = "Kotlin_dev_Compiler" + + @Input + @Option(option = "overrideConfigurationId", description = "Teamcity kotlin override configuration id") + var overrideConfigurationId: String = "Kotlin_dev_DeployMavenArtifacts_OverrideNative" + + @Input + @Option(option = "kotlinVersion", description = "Kotlin Compiler Version") + var kotlinVersion: String = "" + + @Input + @Option(option = "konanVersion", description = "Kotlin Native Compiler Version") + var konanVersion: String = "" + + @TaskAction + fun run() { + requireNotNull(token, { "Teamcity Bear token required" }) + val client = HttpClient() + runBlocking { + val buildId = client.get( + scheme = "https", + host = buildServer, + path = "/app/rest/builds/buildType:(id:$compilerConfigurationId),number:$kotlinVersion/id" + ) { + header("Authorization", "Bearer $token") + } + project.logger.info("pusher: buildId: $buildId") + + /** + * + * + * + * + * + * + * + * + * + */ + val content = buildString { + build { + buildType(overrideConfigurationId) + lastChanges { + change(buildId) + } + properties { + property("system.versions.kotlin-native", konanVersion) + } + } + } + project.logger.info("pusher: content: \"$content\"") + + val res = client.post( + scheme = "https", + host = buildServer, + path = "/app/rest/buildQueue" + ) { + header("Authorization", "Bearer $token") + header("Origin", "https://$buildServer") + body = TextContent(content, ContentType.Application.Xml) + } + project.logger.info("pusher: result: \"$res\"") + } + client.close() + } +} + +internal fun StringBuilder.paired(tag:String, body:StringBuilder.()->Unit) { + appendln("<$tag>") + body() + appendln("") +} + +internal fun StringBuilder.build(body: StringBuilder.() -> Unit) = paired("build", body) +internal fun StringBuilder.buildType(id: String) = appendln("") +internal fun StringBuilder.lastChanges(body: StringBuilder.() -> Unit) = paired("lastChanges", body) +internal fun StringBuilder.change(build: String) = appendln("") +internal fun StringBuilder.properties(body: StringBuilder.() -> Unit) = paired("properties", body) +internal fun StringBuilder.property(key: String, value: String) = appendln("") + diff --git a/kotlin-native/build-tools/src/main/kotlin/org/jetbrains/kotlin/Reporter.kt b/kotlin-native/build-tools/src/main/kotlin/org/jetbrains/kotlin/Reporter.kt new file mode 100644 index 00000000000..a133be2de56 --- /dev/null +++ b/kotlin-native/build-tools/src/main/kotlin/org/jetbrains/kotlin/Reporter.kt @@ -0,0 +1,109 @@ +/* + * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the LICENSE file. + */ + +package org.jetbrains.kotlin + +import com.ullink.slack.simpleslackapi.impl.SlackSessionFactory +import org.gradle.api.DefaultTask +import org.gradle.api.tasks.Input +import org.gradle.api.tasks.TaskAction +import java.io.FileInputStream +import java.util.* + + +internal object Tc { + private val teamcityConfig = System.getenv("TEAMCITY_BUILD_PROPERTIES_FILE") + val enabled:Boolean = (teamcityConfig != null) + private val buildConfig by lazy { + teamcityConfig ?: return@lazy null + val properties = Properties() + properties.load(FileInputStream(teamcityConfig)) + properties + } + val buildId = buildConfig?.getProperty("teamcity.build.id") + val buildTypeId = buildConfig?.getProperty("teamcity.buildType.id") + val konanReporterToken = buildConfig?.getProperty("konan-reporter-token") + val konanChannelName = buildConfig?.getProperty("konan-channel-name") + +} + +private fun buildLogUrlTab(buildId: String?, buildTypeId: String?): String = tabUrl(buildId, buildTypeId, "buildLog") + +private fun tabUrl(buildId: String?, buildTypeId: String?, tab: String?): String = + "http://buildserver.labs.intellij.net/viewLog.html?buildId=$buildId&buildTypeId=$buildTypeId&tab=$tab" + +private fun testReportUrl(buildId: String?, buildTypeId: String?): String = tabUrl(buildId, buildTypeId, "testsInfo") + +private fun sendTextToSlack(report: String) { + with(SlackSessionFactory.createWebSocketSlackSession(Tc.konanReporterToken)) { + connect() + sendMessage(findChannelByName(Tc.konanChannelName), + "Hello, аборигены Котлина!\n текущий статус:\n$report") + disconnect() + } +} + +private fun reportEpilogue(): String { + val logUrl = buildLogUrlTab(Tc.buildId, Tc.buildTypeId) + val testReportUrl = testReportUrl(Tc.buildId, Tc.buildTypeId) + return "\nlog url: $logUrl\ntest report url: $testReportUrl" +} + +private val Statistics.report + get() = "total: $total\npassed: $passed\nfailed: $failed\nerror: $error\nskipped: $skipped" + +private val Statistics.oneLineReport + get() = "(total: $total, passed: $passed, failed: $failed, error: $error, skipped: $skipped)" + + +open class Reporter : DefaultTask() { + + @Input + lateinit var reportHome: String + + @TaskAction + fun report() { + + val reportJson = loadReport("$reportHome/external/results.json") + + val report: String = + "${reportJson.statistics.report}\n ${reportEpilogue()}" + + project.logger.info(report) + if (doSlackSending()) + sendTextToSlack(report) + } +} + +private fun DefaultTask.doSlackSending() = !project.hasProperty("build.reporter.noSlack") + || !project.property("build.reporter.noSlack").toString().toBoolean() + +open class NightlyReporter: DefaultTask() { + @Input + lateinit var externalMacosReport:String + @Input + lateinit var externalLinuxReport:String + @Input + lateinit var externalWindowsReport:String + + @TaskAction + fun report() { + val externalMacosJsonReport = loadReport("${project.rootDir.absolutePath}/$externalMacosReport") + val externalLinuxJsonReport = loadReport("${project.rootDir.absolutePath}/$externalLinuxReport") + val externalWindowsJsonReport = loadReport("${project.rootDir.absolutePath}/$externalWindowsReport") + val report = buildString { + append("Mac OS ") + appendln(externalMacosJsonReport.statistics.oneLineReport) + append("Linux ") + appendln(externalLinuxJsonReport.statistics.oneLineReport) + append("Windows ") + appendln(externalWindowsJsonReport.statistics.oneLineReport) + appendln(reportEpilogue()) + } + project.logger.info(report) + if (doSlackSending()) + sendTextToSlack(report) + } +} \ No newline at end of file diff --git a/kotlin-native/build-tools/src/main/kotlin/org/jetbrains/kotlin/Utils.kt b/kotlin-native/build-tools/src/main/kotlin/org/jetbrains/kotlin/Utils.kt index 1d3478289f3..13650b2cb4d 100644 --- a/kotlin-native/build-tools/src/main/kotlin/org/jetbrains/kotlin/Utils.kt +++ b/kotlin-native/build-tools/src/main/kotlin/org/jetbrains/kotlin/Utils.kt @@ -6,7 +6,6 @@ package org.jetbrains.kotlin -import com.google.gson.GsonBuilder import org.gradle.api.Project import org.gradle.api.Task import org.jetbrains.kotlin.konan.properties.loadProperties @@ -482,5 +481,3 @@ internal val Project.testTargetConfigurables: Configurables val testTarget = project.testTarget return platformManager.platform(testTarget).configurables } - -internal val gson = GsonBuilder().excludeFieldsWithoutExposeAnnotation().create()!! \ No newline at end of file diff --git a/kotlin-native/build-tools/src/main/kotlin/org/jetbrains/kotlin/Wrappers.kt b/kotlin-native/build-tools/src/main/kotlin/org/jetbrains/kotlin/Wrappers.kt new file mode 100644 index 00000000000..b37b3acd8e0 --- /dev/null +++ b/kotlin-native/build-tools/src/main/kotlin/org/jetbrains/kotlin/Wrappers.kt @@ -0,0 +1,53 @@ +package org.jetbrains.kotlin + +import org.gradle.api.Plugin +import org.gradle.api.Project +import org.gradle.api.tasks.Input +import org.gradle.api.tasks.Optional +import org.gradle.api.tasks.wrapper.Wrapper + +open class CustomWrapper : Wrapper() { + internal lateinit var mainWrapperTask: Wrapper + + val mainWrapperVersion: String + @Input get() = mainWrapperTask.gradleVersion + val mainWrapperDistrSha256: String? + @Optional @Input get() = mainWrapperTask.distributionSha256Sum +} + +open class WrappersExtension { + var projects = mutableListOf() + var distributionType = Wrapper.DistributionType.BIN +} + +class GradleWrappers : Plugin { + + override fun apply(project: Project): Unit = with(project) { + val mainWrapperTask = tasks.findByName("wrapper") as? Wrapper ?: return@with + val wrappers = extensions.create( + WrappersExtension::class.java, + "wrappers", + WrappersExtension::class.java + ) + afterEvaluate { + wrappers.projects.map { file(it) }.forEach { + tasks.create("${it.name}Wrapper", CustomWrapper::class.java).apply { + this.mainWrapperTask = mainWrapperTask + jarFile = it.resolve("gradle/wrapper/gradle-wrapper.jar") + scriptFile = it.resolve("gradlew") + distributionType = wrappers.distributionType + mainWrapperTask.dependsOn(this) + + // Get these parameters from the main wrapper task to support + // command line options like --gradle-version. + // Gradle doesn't provide access to the values passed in command line + // at the configuration phase, so we have to get these values at the execution phase. + doFirst { + gradleVersion = mainWrapperVersion + distributionSha256Sum = mainWrapperDistrSha256 + } + } + } + } + } +} diff --git a/kotlin-native/build.gradle b/kotlin-native/build.gradle index 1b3dc52ac28..ee395603a1a 100644 --- a/kotlin-native/build.gradle +++ b/kotlin-native/build.gradle @@ -38,11 +38,21 @@ buildscript { } dependencies { + //classpath project(":kotlin-native-utils") classpath 'gradle.plugin.com.github.johnrengelman:shadow:7.1.2' } } +import org.jetbrains.kotlin.konan.* -defaultTasks 'clean', 'dist' +// Allows generating wrappers for the root build and all the samples during execution of the default 'wrapper' task. +// Run './gradlew wrapper --gradle-version ' to update all the wrappers. +//apply plugin: org.jetbrains.kotlin.GradleWrappers +// +//wrappers.projects = ['samples', 'samples/calculator', 'samples/cocoapods/kotlin-library'] +//wrapper.distributionType = Wrapper.DistributionType.ALL + +// FIXME: Remove until IDEA-231214 is fixed. +//defaultTasks 'clean', 'dist' convention.plugins.platformInfo = PlatformInfo @@ -148,6 +158,7 @@ dependencies { distPack project(':kotlin-native:utilities:basic-utils') distPack project(':kotlin-native:klib') distPack project(path: ':kotlin-native:endorsedLibraries:kotlinx.cli', configuration: "jvmRuntimeElements") + //distPack "org.jetbrains.kotlin:kotlin-native-shared:$konanVersion" commonSources project(path: ':kotlin-stdlib-common', configuration: 'sources') commonSources project(path: ':kotlin-test:kotlin-test-common', configuration: 'sources') commonSources project(path: ':kotlin-test:kotlin-test-annotations-common', configuration: 'sources') @@ -160,6 +171,18 @@ apply plugin: GitClangFormatPlugin apply plugin: 'maven-publish' apply plugin: BasePlugin +//task sharedJar { +// dependsOn gradle.includedBuild('shared').task(':jar') +//} + +//task gradlePluginJar { +// dependsOn gradle.includedBuild('kotlin-native-gradle-plugin').task(':shadowJar') +//} + +//task gradlePluginCheck { +// dependsOn gradle.includedBuild('kotlin-native-gradle-plugin').task(':check') +//} + task dist_compiler(dependsOn: "distCompiler") task dist_runtime(dependsOn: "distRuntime") task cross_dist(dependsOn: "crossDist") diff --git a/kotlin-native/shared/build.gradle.kts b/kotlin-native/shared/build.gradle.kts index 2a415066537..87f6a838b5c 100644 --- a/kotlin-native/shared/build.gradle.kts +++ b/kotlin-native/shared/build.gradle.kts @@ -16,13 +16,14 @@ @file:Suppress("UnstableApiUsage") import org.jetbrains.kotlin.gradle.tasks.KotlinCompile +import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet plugins { id("kotlin") } val rootBuildDirectory by extra(file("..")) -apply(from = "../gradle/loadRootProperties.gradle") +apply(from="../gradle/loadRootProperties.gradle") val kotlinVersion = project.bootstrapKotlinVersion @@ -33,16 +34,12 @@ repositories { mavenCentral() } -kotlin { - sourceSets { - main { - kotlin.srcDir("src/main/kotlin") - kotlin.srcDir("src/library/kotlin") - } - } +sourceSets["main"].withConvention(KotlinSourceSet::class) { + kotlin.srcDir("src/main/kotlin") + kotlin.srcDir("src/library/kotlin") } -tasks.withType().configureEach { +tasks.withType { kotlinOptions.jvmTarget = "1.8" kotlinOptions.freeCompilerArgs += listOf("-Xskip-prerelease-check") } diff --git a/kotlin-native/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/experimental/internal/KotlinNativePlatform.kt b/kotlin-native/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/experimental/internal/KotlinNativePlatform.kt index 81b7a62339b..641e327c8af 100644 --- a/kotlin-native/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/experimental/internal/KotlinNativePlatform.kt +++ b/kotlin-native/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/experimental/internal/KotlinNativePlatform.kt @@ -1,6 +1,17 @@ /* - * Copyright 2010-2023 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. + * Copyright 2010-2018 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package org.jetbrains.kotlin.gradle.plugin.experimental.internal diff --git a/kotlin-native/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/konan/KonanPlugin.kt b/kotlin-native/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/konan/KonanPlugin.kt index bad3096ce5c..b06df07ae56 100644 --- a/kotlin-native/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/konan/KonanPlugin.kt +++ b/kotlin-native/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/konan/KonanPlugin.kt @@ -355,6 +355,7 @@ class KonanPlugin @Inject constructor(private val registry: ToolingModelBuilderR project.plugins.apply("base") project.plugins.apply("java") // Create necessary tasks and extensions. + project.tasks.create(KONAN_DOWNLOAD_TASK_NAME, KonanCompilerDownloadTask::class.java) project.extensions.create(KONAN_EXTENSION_NAME, KonanExtension::class.java) val container = project.extensions.create( KonanArtifactContainer::class.java, diff --git a/kotlin-native/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/konan/tasks/KonanCompilerDownloadTask.kt b/kotlin-native/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/konan/tasks/KonanCompilerDownloadTask.kt new file mode 100644 index 00000000000..2a3b30a5bff --- /dev/null +++ b/kotlin-native/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/konan/tasks/KonanCompilerDownloadTask.kt @@ -0,0 +1,77 @@ +/* + * Copyright 2010-2017 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.kotlin.gradle.plugin.tasks + +import org.gradle.api.DefaultTask +import org.gradle.api.GradleScriptException +import org.gradle.api.tasks.Internal +import org.gradle.api.tasks.TaskAction +import org.jetbrains.kotlin.gradle.plugin.konan.* +import org.jetbrains.kotlin.konan.MetaVersion +import org.jetbrains.kotlin.konan.util.DependencyProcessor +import org.jetbrains.kotlin.konan.util.DependencySource +import java.io.IOException +import org.jetbrains.kotlin.* + +open class KonanCompilerDownloadTask : DefaultTask() { + + internal companion object { + internal const val BASE_DOWNLOAD_URL = "https://download.jetbrains.com/kotlin/native/builds" + } + + /** + * If true the task will also download dependencies for targets specified by the konan.targets project extension. + */ + @Internal + var downloadDependencies: Boolean = false + + @TaskAction + fun downloadAndExtract() { + if (!project.hasProperty(KonanPlugin.ProjectProperty.DOWNLOAD_COMPILER)) { + val konanHome = project.kotlinNativeDist + logger.info("Use a user-defined compiler path: $konanHome") + } else { + try { + val downloadUrlDirectory = buildString { + append("$BASE_DOWNLOAD_URL/") + val version = project.konanVersion + if (version.contains("-dev-")) append("dev/") else append("releases/") + append("$version/") + append(project.simpleOsName) + } + val konanCompiler = project.konanCompilerName() + val parentDir = DependencyProcessor.localKonanDir + logger.info("Downloading Kotlin/Native compiler from $downloadUrlDirectory/$konanCompiler into $parentDir") + DependencyProcessor( + parentDir, + downloadUrlDirectory, + mapOf(konanCompiler to listOf(DependencySource.Remote.Public)) + ).run() + } catch (e: IOException) { + throw GradleScriptException("Cannot download Kotlin/Native compiler", e) + } + } + + // Download dependencies if a user said so. + if (downloadDependencies) { + val runner = KonanCliCompilerRunner(project, project.konanExtension.jvmArgs) + project.konanTargets.forEach { + runner.run("-Xcheck_dependencies", "-target", it.visibleName) + } + } + } +}