Skip to content

Commit

Permalink
JetBrains#1779 Fixes compatibility with Gradle dependency verificatio…
Browse files Browse the repository at this point in the history
…n. Previously it was failing with "Failed to create MD5 hash for file".
  • Loading branch information
AlexanderBartash committed Oct 2, 2024
1 parent dbc44d9 commit bece820
Show file tree
Hide file tree
Showing 12 changed files with 137 additions and 32 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ class DependencyLockingAndVerificationIntegrationTest : IntelliJPlatformIntegrat
) {

@Test
@Ignore("https://github.com/JetBrains/intellij-platform-gradle-plugin/issues/1779")
fun `build plugin with dependency locks & hash verification`() {
build(
Tasks.External.CLEAN,
Expand All @@ -44,7 +43,6 @@ class DependencyLockingAndVerificationIntegrationTest : IntelliJPlatformIntegrat
}

@Test
@Ignore("https://github.com/JetBrains/intellij-platform-gradle-plugin/issues/1779")
fun `build plugin with dependency locks, hash & signature verification`() {
build(
Tasks.External.CLEAN,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@ class DependencyVerificationIgnoreIntellijIntegrationTest : IntelliJPlatformInte
}

@Test
@Ignore("https://github.com/JetBrains/intellij-platform-gradle-plugin/issues/1779")
fun `build plugin with dependency locks, hash & signature verification ignoring intellij artifacts`() {
build(
Tasks.External.CLEAN,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,8 @@ object Constants {
const val LOCAL_JETBRAINS_RUNTIME_GROUP = "localJetBrainsRuntime"
const val BUNDLED_MODULE_GROUP = "bundledModule"
const val BUNDLED_PLUGIN_GROUP = "bundledPlugin"
const val BUNDLED_PLUGIN_ARTIFACT_GROUP = "bundledPluginArtifact"
const val BUNDLED_MODULE_ARTIFACT_GROUP = "bundledModuleArtifact"
const val MARKETPLACE_GROUP = "com.jetbrains.plugins"
}

Expand Down Expand Up @@ -174,6 +176,10 @@ object Constants {
const val LOG = "log"
}

object RepositoryNames {
const val LOCAL_IVY = "Local IntelliJ Platform Artifacts Repository"
}

object Locations {
const val CACHE_REDIRECTOR = "https://cache-redirector.jetbrains.com"
const val CACHE_REDIRECTOR_INTELLIJ_DEPENDENCIES_REPOSITORY = "$CACHE_REDIRECTOR/intellij-dependencies"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,12 +87,9 @@ abstract class CollectorTransformer : TransformAction<CollectorTransformer.Param
}

isPlugin -> {
plugin.originalFile?.let { pluginPath ->
collectJars(
pluginPath.resolve("lib"),
pluginPath.resolve("lib/modules"),
).forEach { outputs.file(it) }
}
// Nothing to do, see:
// IntelliJPlatformRepositoriesHelper.Companion.updateLocalIvyRepoArtifactPattern
outputs.file(inputArtifact)
}

else -> throw GradleException("Unknown input: $path")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import org.gradle.api.artifacts.ConfigurationContainer
import org.gradle.api.artifacts.Dependency
import org.gradle.api.artifacts.ProjectDependency
import org.gradle.api.artifacts.dsl.DependencyHandler
import org.gradle.api.artifacts.dsl.RepositoryHandler
import org.gradle.api.file.Directory
import org.gradle.api.file.ProjectLayout
import org.gradle.api.model.ObjectFactory
Expand Down Expand Up @@ -51,6 +52,7 @@ import kotlin.io.path.absolute
@Suppress("unused", "MemberVisibilityCanBePrivate")
@IntelliJPlatform
abstract class IntelliJPlatformDependenciesExtension @Inject constructor(
repositories: RepositoryHandler,
configurations: ConfigurationContainer,
dependencies: DependencyHandler,
layout: ProjectLayout,
Expand All @@ -60,7 +62,7 @@ abstract class IntelliJPlatformDependenciesExtension @Inject constructor(
rootProjectDirectory: Path,
) {

private val delegate = IntelliJPlatformDependenciesHelper(configurations, dependencies, layout, objects, providers, resources, rootProjectDirectory)
private val delegate = IntelliJPlatformDependenciesHelper(repositories, configurations, dependencies, layout, objects, providers, resources, rootProjectDirectory)

/**
* Adds a dependency on the IntelliJ Platform.
Expand Down Expand Up @@ -1309,6 +1311,7 @@ abstract class IntelliJPlatformDependenciesExtension @Inject constructor(
override fun register(project: Project, target: Any) =
target.configureExtension<IntelliJPlatformDependenciesExtension>(
Extensions.INTELLIJ_PLATFORM,
project.repositories,
project.configurations,
project.dependencies,
project.layout,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import org.gradle.api.artifacts.ConfigurationContainer
import org.gradle.api.artifacts.Dependency
import org.gradle.api.artifacts.ProjectDependency
import org.gradle.api.artifacts.dsl.DependencyHandler
import org.gradle.api.artifacts.dsl.RepositoryHandler
import org.gradle.api.file.Directory
import org.gradle.api.file.ProjectLayout
import org.gradle.api.model.ObjectFactory
Expand Down Expand Up @@ -55,6 +56,7 @@ import kotlin.io.path.*
* @param rootProjectDirectory The root directory of the Gradle project.
*/
class IntelliJPlatformDependenciesHelper(
private val repositories: RepositoryHandler,
private val configurations: ConfigurationContainer,
private val dependencies: DependencyHandler,
private val layout: ProjectLayout,
Expand Down Expand Up @@ -129,6 +131,11 @@ class IntelliJPlatformDependenciesHelper(
get() = platformPath.map { it.productInfo() }

private val bundledPlugins by lazy {
// Update artifact pattern in our Local Ivy Repo to use the extracted IDE path.
// It has to be done lazily here, since the IDE is unzipped by ExtractorTransformer during artifact resolution,
// and that path is not available when we register this repo initially.
IntelliJPlatformRepositoriesHelper.updateLocalIvyRepoArtifactPattern(platformPath.get(), repositories)

platformPath.get()
.resolve("plugins")
.listDirectoryEntries()
Expand Down Expand Up @@ -742,6 +749,8 @@ class IntelliJPlatformDependenciesHelper(
*/
private fun DependencyHandler.createIntelliJPlatformBundledPlugin(id: String): Dependency {
val plugin = bundledPlugins[id]
val platformPath by lazy { platformPath.get() }

requireNotNull(plugin) {
val unresolvedPluginId = when (id) {
"copyright" -> "Use correct plugin ID 'com.intellij.copyright' instead of 'copyright'."
Expand Down Expand Up @@ -769,8 +778,8 @@ class IntelliJPlatformDependenciesHelper(
module = id,
revision = version,
),
publications = listOf(artifactPath.toIvyArtifact()),
dependencies = plugin.collectDependencies(),
publications = artifactPath.toBundledPluginIvyArtifacts(platformPath),
dependencies = plugin.collectBundledPluginDependencies(),
)
}

Expand All @@ -791,7 +800,9 @@ class IntelliJPlatformDependenciesHelper(
.find { layout -> layout.name == id }
.let { requireNotNull(it) { "Specified bundledModule '$id' doesn't exist." } }
val platformPath = platformPath.get()
val artifactPaths = bundledModule.classPath.map { path -> platformPath.resolve(path).toIvyArtifact() }
val artifactPaths = bundledModule.classPath.flatMap { path ->
platformPath.resolve(path).toBundledModuleIvyArtifacts(platformPath)
}
val version = baseVersion.orElse(productInfo.map { it.version }).get()

writeIvyModule(Dependencies.BUNDLED_MODULE_GROUP, id, version) {
Expand All @@ -818,7 +829,7 @@ class IntelliJPlatformDependenciesHelper(
*
* @param path IDs of already traversed plugins or modules.
*/
private fun IdePlugin.collectDependencies(path: List<String> = emptyList()): List<IvyModule.Dependency> {
private fun IdePlugin.collectBundledPluginDependencies(path: List<String> = emptyList()): List<IvyModule.Dependency> {
val id = requireNotNull(pluginId)
val dependencyIds = (dependencies.map { it.id } + optionalDescriptors.map { it.dependency.id } + modulesDescriptors.map { it.name } - id).toSet()
val buildNumber by lazy { productInfo.get().buildNumber }
Expand All @@ -835,10 +846,10 @@ class IntelliJPlatformDependenciesHelper(
writeIvyModule(group, name, version) {
IvyModule(
info = IvyModule.Info(group, name, version),
publications = listOf(artifactPath.toIvyArtifact()),
publications = artifactPath.toBundledPluginIvyArtifacts(platformPath),
dependencies = when {
id in path -> emptyList()
else -> plugin.collectDependencies(path + id)
else -> plugin.collectBundledPluginDependencies(path + id)
},
)
}
Expand All @@ -855,7 +866,9 @@ class IntelliJPlatformDependenciesHelper(
.mapNotNull { layoutItems.find { layout -> layout.name == it } }
.filterNot { it.classPath.isEmpty() }
.map {
val artifactPaths = it.classPath.map { path -> platformPath.resolve(path).toIvyArtifact() }
val artifactPaths = it.classPath.flatMap { path ->
platformPath.resolve(path).toBundledModuleIvyArtifacts(platformPath)
}
val group = Dependencies.BUNDLED_MODULE_GROUP
val name = it.name
val version = buildNumber
Expand Down Expand Up @@ -904,7 +917,7 @@ class IntelliJPlatformDependenciesHelper(
module = name,
revision = version,
),
publications = listOf(artifactPath.toIvyArtifact()),
publications = artifactPath.toLocalPluginIvyArtifacts(),
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import org.gradle.api.Action
import org.gradle.api.Project
import org.gradle.api.artifacts.ConfigurationContainer
import org.gradle.api.artifacts.dsl.DependencyHandler
import org.gradle.api.artifacts.dsl.RepositoryHandler
import org.gradle.api.file.Directory
import org.gradle.api.file.DirectoryProperty
import org.gradle.api.file.ProjectLayout
Expand Down Expand Up @@ -767,6 +768,7 @@ abstract class IntelliJPlatformExtension @Inject constructor(
*/
@IntelliJPlatform
abstract class Ides @Inject constructor(
repositories: RepositoryHandler,
configurations: ConfigurationContainer,
dependencies: DependencyHandler,
layout: ProjectLayout,
Expand All @@ -778,6 +780,7 @@ abstract class IntelliJPlatformExtension @Inject constructor(
) {

private val delegate = IntelliJPlatformDependenciesHelper(
repositories,
configurations,
dependencies,
layout,
Expand Down Expand Up @@ -950,6 +953,7 @@ abstract class IntelliJPlatformExtension @Inject constructor(
override fun register(project: Project, target: Any) =
target.configureExtension<Ides>(
Extensions.IDES,
project.repositories,
project.configurations,
project.dependencies,
project.layout,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import org.gradle.api.Project
import org.gradle.api.artifacts.ConfigurationContainer
import org.gradle.api.artifacts.ProjectDependency
import org.gradle.api.artifacts.dsl.DependencyHandler
import org.gradle.api.artifacts.dsl.RepositoryHandler
import org.gradle.api.file.Directory
import org.gradle.api.file.ProjectLayout
import org.gradle.api.model.ObjectFactory
Expand All @@ -32,6 +33,7 @@ import javax.inject.Inject
*/
@IntelliJPlatform
abstract class IntelliJPlatformPluginsExtension @Inject constructor(
repositories: RepositoryHandler,
configurations: ConfigurationContainer,
dependencies: DependencyHandler,
layout: ProjectLayout,
Expand All @@ -45,6 +47,7 @@ abstract class IntelliJPlatformPluginsExtension @Inject constructor(
internal val intellijPlatformPluginLocalConfigurationName = objects.property<String>()

private val delegate = IntelliJPlatformDependenciesHelper(
repositories,
configurations,
dependencies,
layout,
Expand Down Expand Up @@ -242,6 +245,7 @@ abstract class IntelliJPlatformPluginsExtension @Inject constructor(
override fun register(project: Project, target: Any) =
target.configureExtension<IntelliJPlatformPluginsExtension>(
Extensions.PLUGINS,
project.repositories,
project.configurations,
project.dependencies,
project.layout,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import org.gradle.api.model.ObjectFactory
import org.gradle.api.plugins.ExtensionAware
import org.gradle.api.provider.ProviderFactory
import org.gradle.kotlin.dsl.support.serviceOf
import org.jetbrains.intellij.platform.gradle.Constants
import org.jetbrains.intellij.platform.gradle.Constants.Extensions
import org.jetbrains.intellij.platform.gradle.Constants.Locations
import org.jetbrains.intellij.platform.gradle.CustomPluginRepositoryType
Expand Down Expand Up @@ -212,7 +213,7 @@ abstract class IntelliJPlatformRepositoriesExtension @Inject constructor(
*/
@JvmOverloads
fun localPlatformArtifacts(action: IvyRepositoryAction = {}) = delegate.createLocalIvyRepository(
repositoryName = "Local IntelliJ Platform Artifacts Repository",
repositoryName = Constants.RepositoryNames.LOCAL_IVY,
action = action,
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,31 @@

package org.jetbrains.intellij.platform.gradle.extensions

import org.gradle.api.Project
import org.gradle.api.artifacts.dsl.RepositoryHandler
import org.gradle.api.credentials.HttpHeaderCredentials
import org.gradle.api.credentials.PasswordCredentials
import org.gradle.api.flow.FlowProviders
import org.gradle.api.flow.FlowScope
import org.gradle.api.internal.artifacts.repositories.DefaultIvyArtifactRepository
import org.gradle.api.invocation.Gradle
import org.gradle.api.model.ObjectFactory
import org.gradle.api.provider.ProviderFactory
import org.gradle.authentication.http.HttpHeaderAuthentication
import org.gradle.internal.os.OperatingSystem
import org.gradle.kotlin.dsl.*
import org.jetbrains.intellij.platform.gradle.Constants
import org.jetbrains.intellij.platform.gradle.Constants.Configurations
import org.jetbrains.intellij.platform.gradle.CustomPluginRepositoryType
import org.jetbrains.intellij.platform.gradle.GradleProperties
import org.jetbrains.intellij.platform.gradle.artifacts.repositories.PluginArtifactRepository
import org.jetbrains.intellij.platform.gradle.flow.StopShimServerAction
import org.jetbrains.intellij.platform.gradle.get
import org.jetbrains.intellij.platform.gradle.services.ShimManagerService
import org.jetbrains.kotlin.util.removeSuffixIfPresent
import java.net.URI
import java.nio.file.Path
import kotlin.io.path.absolutePathString
import kotlin.io.path.pathString

private const val SHIM_MANAGER = "shimManager"
Expand Down Expand Up @@ -149,8 +154,8 @@ class IntelliJPlatformRepositoriesHelper(
val localPlatformArtifactsPath = providers.localPlatformArtifactsPath(rootProjectDirectory)
ivyPattern("${localPlatformArtifactsPath.pathString}/[organization]-[module]-[revision].[ext]")

// As all artifacts defined in Ivy repositories have a full artifact path set as their names, we can use them to locate artifact files
artifactPattern("/[artifact]")
// Later updated by updateLocalIvyRepoArtifactPattern when IDE is unzipped and its path is known.
//artifactPattern("/[artifact]")

/**
* Because artifact paths always start with `/` (see [toPublication] for details),
Expand All @@ -168,7 +173,19 @@ class IntelliJPlatformRepositoriesHelper(
includeGroup(Configurations.Dependencies.LOCAL_IDE_GROUP)
includeGroup(Configurations.Dependencies.LOCAL_PLUGIN_GROUP)
includeGroup(Configurations.Dependencies.LOCAL_JETBRAINS_RUNTIME_GROUP)
includeGroup(Configurations.Dependencies.BUNDLED_PLUGIN_ARTIFACT_GROUP)
includeGroup(Configurations.Dependencies.BUNDLED_MODULE_ARTIFACT_GROUP)
}
action()
}

companion object {
fun updateLocalIvyRepoArtifactPattern(platformPath: Path, repositories: RepositoryHandler) {
val absolutePathString = platformPath.absolutePathString().removeSuffixIfPresent("/")
val localIvyRepo = repositories[Constants.RepositoryNames.LOCAL_IVY]
(localIvyRepo as DefaultIvyArtifactRepository).artifactPattern(
"${absolutePathString}/[type]/[artifact].[ext]"
)
}
}
}
Loading

0 comments on commit bece820

Please sign in to comment.