Browse Source

Fix build helpers publishing (#1416)

* Fix compatibility with Intellij 2021.3

Resolves #1373

* Use Java reflection

* Set Java source & target compatibility for build helpers

Otherwise, Gradle might set Gradle metadata attributes in such way,
that transitive dependencies of published modules are not resolved

* Configure shadow jar manually

Applying plugin configures additional publication,
so that both .jar and -shadow.jar are published,
and additional configurations are added to Gradle metadata.

To avoid unexpected metadata resolution results,
ShadowJar task is now configured manually

* Fix closeStagingRepo JSON request

* Update publishing build-helpers in compose
pull/1420/head
Alexey Tsvetkov 3 years ago committed by GitHub
parent
commit
588ad2c8c0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      build-helpers/build.gradle.kts
  2. 8
      build-helpers/publishing/build.gradle.kts
  3. 3
      build-helpers/publishing/src/main/kotlin/org/jetbrains/compose/internal/publishing/utils/SonatypeRestApiClient.kt
  4. 2
      compose/settings.gradle.kts
  5. 4
      idea-plugin/build.gradle.kts
  6. 4
      idea-plugin/gradle.properties
  7. 3
      idea-plugin/src/main/kotlin/org/jetbrains/compose/desktop/ide/preview/ConfigurePreviewTaskNameCache.kt
  8. 3
      idea-plugin/src/main/kotlin/org/jetbrains/compose/desktop/ide/preview/PreviewLocation.kt
  9. 4
      idea-plugin/src/main/kotlin/org/jetbrains/compose/desktop/ide/preview/PreviewStateService.kt
  10. 30
      idea-plugin/src/main/kotlin/org/jetbrains/compose/desktop/ide/preview/ijCompatibilityUtils.kt

2
build-helpers/build.gradle.kts

@ -14,6 +14,8 @@ subprojects {
plugins.withType(JavaBasePlugin::class.java) { plugins.withType(JavaBasePlugin::class.java) {
afterEvaluate { afterEvaluate {
configureIfExists<JavaPluginExtension> { configureIfExists<JavaPluginExtension> {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
if (sourceSets.names.contains(SourceSet.MAIN_SOURCE_SET_NAME)) { if (sourceSets.names.contains(SourceSet.MAIN_SOURCE_SET_NAME)) {
withJavadocJar() withJavadocJar()
withSourcesJar() withSourcesJar()

8
build-helpers/publishing/build.gradle.kts

@ -6,7 +6,7 @@ plugins {
`maven-publish` `maven-publish`
`java-gradle-plugin` `java-gradle-plugin`
id("org.jetbrains.kotlin.jvm") id("org.jetbrains.kotlin.jvm")
id("com.github.johnrengelman.shadow") id("com.github.johnrengelman.shadow") apply false
} }
repositories { repositories {
@ -34,7 +34,7 @@ dependencies {
embedded("de.undercouch:gradle-download-task:4.1.2") embedded("de.undercouch:gradle-download-task:4.1.2")
} }
val shadow = tasks.named<ShadowJar>("shadowJar") { val shadowJar by tasks.registering(ShadowJar::class) {
val fromPackage = "de.undercouch" val fromPackage = "de.undercouch"
val toPackage = "org.jetbrains.compose.internal.publishing.$fromPackage" val toPackage = "org.jetbrains.compose.internal.publishing.$fromPackage"
relocate(fromPackage, toPackage) relocate(fromPackage, toPackage)
@ -44,7 +44,7 @@ val shadow = tasks.named<ShadowJar>("shadowJar") {
} }
val jar = tasks.named<Jar>("jar") { val jar = tasks.named<Jar>("jar") {
dependsOn(shadow) dependsOn(shadowJar)
from(zipTree(shadow.get().archiveFile)) from(zipTree(shadowJar.get().archiveFile))
this.duplicatesStrategy = DuplicatesStrategy.INCLUDE this.duplicatesStrategy = DuplicatesStrategy.INCLUDE
} }

3
build-helpers/publishing/src/main/kotlin/org/jetbrains/compose/internal/publishing/utils/SonatypeRestApiClient.kt

@ -80,7 +80,8 @@ class SonatypeRestApiClient(
logger.info("Closing repository '${repo.id}'") logger.info("Closing repository '${repo.id}'")
buildRequest("service/local/staging/bulk/close") { buildRequest("service/local/staging/bulk/close") {
val request = "{\"data\":{\"stagedRepositoryIds\":[\"${repo.id}\"]}}" val request = "{\"data\":{\"stagedRepositoryIds\":[\"${repo.id}\"]}}"
post(Xml.serialize(request).toRequestBody(Json.mediaType)) post(request.toRequestBody(Json.mediaType))
.addHeader("Accept", Json.mediaType.toString())
}.execute { responseBody -> }.execute { responseBody ->
logger.info("Finished closing repository '${repo.id}': '${responseBody.string()}'") logger.info("Finished closing repository '${repo.id}': '${responseBody.string()}'")
} }

2
compose/settings.gradle.kts

@ -6,7 +6,7 @@ pluginManagement {
maven("https://maven.pkg.jetbrains.space/public/p/space/maven") maven("https://maven.pkg.jetbrains.space/public/p/space/maven")
} }
dependencies { dependencies {
classpath("org.jetbrains.compose.internal.build-helpers:publishing:0.1.0") classpath("org.jetbrains.compose.internal.build-helpers:publishing:0.1.3")
} }
} }
} }

4
idea-plugin/build.gradle.kts

@ -3,8 +3,8 @@ import org.jetbrains.kotlin.gradle.dsl.KotlinJvmCompile
plugins { plugins {
id("java") id("java")
id("org.jetbrains.kotlin.jvm") version "1.5.10" id("org.jetbrains.kotlin.jvm") version "1.5.10"
id("org.jetbrains.intellij") version "1.1.2" id("org.jetbrains.intellij") version "1.3.0"
id("org.jetbrains.changelog") version "1.1.2" id("org.jetbrains.changelog") version "1.3.1"
} }
val projectProperties = ProjectProperties(project) val projectProperties = ProjectProperties(project)

4
idea-plugin/gradle.properties

@ -1,12 +1,12 @@
# Opt-out flag for bundling Kotlin standard library. # Opt-out flag for bundling Kotlin standard library.
# See https://kotlinlang.org/docs/reference/using-gradle.html#dependency-on-the-standard-library for details. # See https://kotlinlang.org/docs/reference/using-gradle.html#dependency-on-the-standard-library for details.
kotlin.stdlib.default.dependency = false kotlin.stdlib.default.dependency=false
deploy.version=0.1-SNAPSHOT deploy.version=0.1-SNAPSHOT
plugin.channels=snapshots plugin.channels=snapshots
plugin.since.build=203 plugin.since.build=203
plugin.until.build=212.* plugin.until.build=213.*
## See https://jb.gg/intellij-platform-builds-list for available build versions. ## See https://jb.gg/intellij-platform-builds-list for available build versions.
plugin.verifier.ide.versions=2020.3.2, 2021.1 plugin.verifier.ide.versions=2020.3.2, 2021.1

3
idea-plugin/src/main/kotlin/org/jetbrains/compose/desktop/ide/preview/ConfigurePreviewTaskNameCache.kt

@ -13,7 +13,6 @@ import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil
import com.intellij.openapi.module.Module import com.intellij.openapi.module.Module
import com.intellij.openapi.project.Project import com.intellij.openapi.project.Project
import com.intellij.util.concurrency.annotations.RequiresReadLock import com.intellij.util.concurrency.annotations.RequiresReadLock
import org.jetbrains.kotlin.idea.configuration.KotlinTargetData
import org.jetbrains.plugins.gradle.settings.GradleSettings import org.jetbrains.plugins.gradle.settings.GradleSettings
import org.jetbrains.plugins.gradle.util.GradleConstants import org.jetbrains.plugins.gradle.util.GradleConstants
@ -30,7 +29,7 @@ internal class ConfigurePreviewTaskNameProviderImpl : ConfigurePreviewTaskNamePr
val modulePath = ExternalSystemApiUtil.getExternalProjectPath(module) ?: return null val modulePath = ExternalSystemApiUtil.getExternalProjectPath(module) ?: return null
val moduleNode = moduleDataNodeOrNull(module.project, modulePath) val moduleNode = moduleDataNodeOrNull(module.project, modulePath)
if (moduleNode != null) { if (moduleNode != null) {
val target = ExternalSystemApiUtil.getChildren(moduleNode, KotlinTargetData.KEY).singleOrNull() val target = ExternalSystemApiUtil.getChildren(moduleNode, kotlinTargetDataKey).singleOrNull()
if (target != null) { if (target != null) {
return previewTaskName(target.data.externalName) return previewTaskName(target.data.externalName)
} }

3
idea-plugin/src/main/kotlin/org/jetbrains/compose/desktop/ide/preview/PreviewLocation.kt

@ -8,7 +8,6 @@ package org.jetbrains.compose.desktop.ide.preview
import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil
import com.intellij.openapi.roots.ProjectFileIndex import com.intellij.openapi.roots.ProjectFileIndex
import com.intellij.util.concurrency.annotations.RequiresReadLock import com.intellij.util.concurrency.annotations.RequiresReadLock
import org.jetbrains.kotlin.idea.debugger.getService
import org.jetbrains.kotlin.psi.KtNamedFunction import org.jetbrains.kotlin.psi.KtNamedFunction
data class PreviewLocation(val fqName: String, val modulePath: String, val taskName: String) data class PreviewLocation(val fqName: String, val modulePath: String, val taskName: String)
@ -21,7 +20,7 @@ internal fun KtNamedFunction.asPreviewFunctionOrNull(): PreviewLocation? {
val module = ProjectFileIndex.getInstance(project).getModuleForFile(containingFile.virtualFile) val module = ProjectFileIndex.getInstance(project).getModuleForFile(containingFile.virtualFile)
if (module == null || module.isDisposed) return null if (module == null || module.isDisposed) return null
val service = project.getService<PreviewStateService>() val service = project.getService(PreviewStateService::class.java)
val previewTaskName = service.configurePreviewTaskNameOrNull(module) ?: DEFAULT_CONFIGURE_PREVIEW_TASK_NAME val previewTaskName = service.configurePreviewTaskNameOrNull(module) ?: DEFAULT_CONFIGURE_PREVIEW_TASK_NAME
val modulePath = ExternalSystemApiUtil.getExternalProjectPath(module) ?: return null val modulePath = ExternalSystemApiUtil.getExternalProjectPath(module) ?: return null
return PreviewLocation(fqName = fqName, modulePath = modulePath, taskName = previewTaskName) return PreviewLocation(fqName = fqName, modulePath = modulePath, taskName = previewTaskName)

4
idea-plugin/src/main/kotlin/org/jetbrains/compose/desktop/ide/preview/PreviewStateService.kt

@ -17,7 +17,7 @@ import com.intellij.openapi.util.Disposer
import com.intellij.ui.components.JBLoadingPanel import com.intellij.ui.components.JBLoadingPanel
import com.intellij.util.concurrency.annotations.RequiresReadLock import com.intellij.util.concurrency.annotations.RequiresReadLock
import org.jetbrains.compose.desktop.ui.tooling.preview.rpc.* import org.jetbrains.compose.desktop.ui.tooling.preview.rpc.*
import org.jetbrains.kotlin.idea.framework.GRADLE_SYSTEM_ID import org.jetbrains.plugins.gradle.util.GradleConstants
import javax.swing.JComponent import javax.swing.JComponent
import javax.swing.event.AncestorEvent import javax.swing.event.AncestorEvent
import javax.swing.event.AncestorListener import javax.swing.event.AncestorListener
@ -140,7 +140,7 @@ private class ConfigurePreviewTaskNameCacheInvalidator(
) : ExternalSystemTaskNotificationListenerAdapter(null) { ) : ExternalSystemTaskNotificationListenerAdapter(null) {
override fun onStart(id: ExternalSystemTaskId, workingDir: String?) { override fun onStart(id: ExternalSystemTaskId, workingDir: String?) {
if ( if (
id.projectSystemId == GRADLE_SYSTEM_ID && id.projectSystemId == GradleConstants.SYSTEM_ID &&
id.type == ExternalSystemTaskType.RESOLVE_PROJECT id.type == ExternalSystemTaskType.RESOLVE_PROJECT
) { ) {
configurePreviewTaskNameCache.invalidate() configurePreviewTaskNameCache.invalidate()

30
idea-plugin/src/main/kotlin/org/jetbrains/compose/desktop/ide/preview/ijCompatibilityUtils.kt

@ -0,0 +1,30 @@
/*
* Copyright 2020-2021 JetBrains s.r.o. and respective authors and developers.
* Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE.txt file.
*/
package org.jetbrains.compose.desktop.ide.preview
import com.intellij.openapi.externalSystem.model.Key
import com.intellij.openapi.externalSystem.model.project.AbstractNamedData
import java.lang.reflect.Modifier
internal val kotlinTargetDataKey: Key<out AbstractNamedData> = run {
val kotlinTargetDataClass = try {
Class.forName("org.jetbrains.kotlin.idea.gradle.configuration.KotlinTargetData")
} catch (e: ClassNotFoundException) {
try {
Class.forName("org.jetbrains.kotlin.idea.configuration.KotlinTargetData")
} catch (e: ClassNotFoundException) {
error("Could not find 'KotlinTargetData' class")
}
}
val companionField = kotlinTargetDataClass.fields.firstOrNull { Modifier.isStatic(it.modifiers) && it.name == "Companion" }
?: error("'${kotlinTargetDataClass.canonicalName}.Companion")
val companionInstance = companionField.get(kotlinTargetDataClass)
val companionClass = companionInstance.javaClass
val getKeyMethod = companionClass.methods.firstOrNull { it.name == "getKEY" }
?: error("Cannot find '${kotlinTargetDataClass.canonicalName}.Companion.getKEY'")
@Suppress("UNCHECKED_CAST")
getKeyMethod.invoke(companionInstance) as Key<out AbstractNamedData>
}
Loading…
Cancel
Save